@@ -538,20 +538,72 @@ impl Tree {
541− pub fn swap_split_in_direction(&mut self, direction: Direction) {
541+ pub fn swap_split_in_direction(&mut self, direction: Direction) -> Option<()> {
542+ let focus = self.focus;
542− if let Some(id) = self.find_split_in_direction(self.focus, direction) {
543+ let target = self.find_split_in_direction(focus, direction)?;
544+ let focus_parent = self.nodes[focus].parent;
545+ let target_parent = self.nodes[target].parent;
547+ if focus_parent == target_parent {
548+ let parent = focus_parent;
543− if let Some([focused, target]) = self.nodes.get_disjoint_mut([self.focus, id]) {
549+ let [parent, focus, target] = self.nodes.get_disjoint_mut([parent, focus, target])?;
544− match (&mut focused.content, &mut target.content) {
550+ match (&mut parent.content, &mut focus.content, &mut target.content) {
545− (Content::View(focused), Content::View(target)) => {
551+ (
546− std::mem::swap(&mut focused.doc, &mut target.doc);
552+ Content::Container(parent),
547− std::mem::swap(&mut focused.id, &mut target.id);
553+ Content::View(focus_view),
548− self.focus = id;
554+ Content::View(target_view),
550− // self.focus always points to a view which has a content of Content::View
556+ let focus_pos = parent.children.iter().position(|id| focus_view.id == *id)?;
551− // and find_split_in_direction() only returns a view which has content of
557+ let target_pos = parent
552− // Content::View.
558+ .children
553− _ => unreachable!(),
559+ .iter()
560+ .position(|id| target_view.id == *id)?;
561+ // swap node positions so that traversal order is kept
562+ parent.children[focus_pos] = target_view.id;
563+ parent.children[target_pos] = focus_view.id;
564+ // swap area so that views rendered at the correct location
565+ std::mem::swap(&mut focus_view.area, &mut target_view.area);
569+ _ => unreachable!(),
572+ let [focus_parent, target_parent, focus, target] =
574+ .get_disjoint_mut([focus_parent, target_parent, focus, target])?;
576+ &mut focus_parent.content,
577+ &mut target_parent.content,
579+ &mut target.content,
582+ Content::Container(focus_parent),
583+ Content::Container(target_parent),
584+ Content::View(focus_view),
585+ Content::View(target_view),
587+ let focus_pos = focus_parent
590+ .position(|id| focus_view.id == *id)?;
591+ let target_pos = target_parent
594+ .position(|id| target_view.id == *id)?;
595+ // re-parent target and focus nodes
597+ &mut focus_parent.children[focus_pos],
598+ &mut target_parent.children[target_pos],
600+ std::mem::swap(&mut focus.parent, &mut target.parent);
601+ // swap area so that views rendered at the correct location
602+ std::mem::swap(&mut focus_view.area, &mut target_view.area);
606+ _ => unreachable!(),
@@ -738,7 +790,7 @@ mod test {
738 tree.swap_split_in_direction(Direction::Down);
790 tree.swap_split_in_direction(Direction::Down);
739 // | l1 | l2 | |
791 // | l1 | l2 | |
740 // | l0* | r0 |
792 // | l0* | r0 |
741− assert_eq!(tree.focus, l1);
793+ assert_eq!(tree.focus, l0);
742 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
794 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
743 assert_eq!(doc_id(&tree, l1), Some(doc_l0));
795 assert_eq!(doc_id(&tree, l1), Some(doc_l0));
744 assert_eq!(doc_id(&tree, l2), Some(doc_l2));
796 assert_eq!(doc_id(&tree, l2), Some(doc_l2));
@@ -748,7 +800,7 @@ mod test {
749 // | l1 | l2 | |
801 // | l1 | l2 | |
750 // | r0 | l0* |
802 // | r0 | l0* |
751− assert_eq!(tree.focus, r0);
803+ assert_eq!(tree.focus, l0);
752 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
804 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
753 assert_eq!(doc_id(&tree, l1), Some(doc_r0));
805 assert_eq!(doc_id(&tree, l1), Some(doc_r0));
754 assert_eq!(doc_id(&tree, l2), Some(doc_l2));
806 assert_eq!(doc_id(&tree, l2), Some(doc_l2));
@@ -758,7 +810,7 @@ mod test {
758 tree.swap_split_in_direction(Direction::Up);
810 tree.swap_split_in_direction(Direction::Up);
759 // | l1 | l2 | |
811 // | l1 | l2 | |
760 // | r0 | l0* |
812 // | r0 | l0* |
761− assert_eq!(tree.focus, r0);
813+ assert_eq!(tree.focus, l0);
762 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
814 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
763 assert_eq!(doc_id(&tree, l1), Some(doc_r0));
815 assert_eq!(doc_id(&tree, l1), Some(doc_r0));
764 assert_eq!(doc_id(&tree, l2), Some(doc_l2));
816 assert_eq!(doc_id(&tree, l2), Some(doc_l2));
@@ -768,7 +820,7 @@ mod test {
768 tree.swap_split_in_direction(Direction::Down);
820 tree.swap_split_in_direction(Direction::Down);
769 // | l1 | l2 | |
821 // | l1 | l2 | |
770 // | r0 | l0* |
822 // | r0 | l0* |
771− assert_eq!(tree.focus, r0);
823+ assert_eq!(tree.focus, l0);
772 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
824 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
773 assert_eq!(doc_id(&tree, l1), Some(doc_r0));
825 assert_eq!(doc_id(&tree, l1), Some(doc_r0));
774 assert_eq!(doc_id(&tree, l2), Some(doc_l2));
826 assert_eq!(doc_id(&tree, l2), Some(doc_l2));
@@ -781,7 +833,7 @@ mod test {
781 tree.swap_split_in_direction(Direction::Down);
833 tree.swap_split_in_direction(Direction::Down);
782 // | l1 | r0 | |
834 // | l1 | r0 | |
783 // | l2* | l0 |
835 // | l2* | l0 |
784− assert_eq!(tree.focus, l1);
836+ assert_eq!(tree.focus, l2);
785 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
837 assert_eq!(doc_id(&tree, l0), Some(doc_l1));
786 assert_eq!(doc_id(&tree, l1), Some(doc_l2));
838 assert_eq!(doc_id(&tree, l1), Some(doc_l2));
787 assert_eq!(doc_id(&tree, l2), Some(doc_r0));
839 assert_eq!(doc_id(&tree, l2), Some(doc_r0));
@@ -790,7 +842,7 @@ mod test {
790 tree.swap_split_in_direction(Direction::Up);
842 tree.swap_split_in_direction(Direction::Up);
791 // | l2* | r0 | |
843 // | l2* | r0 | |
792 // | l1 | l0 |
844 // | l1 | l0 |
793− assert_eq!(tree.focus, l0);
845+ assert_eq!(tree.focus, l2);
794 assert_eq!(doc_id(&tree, l0), Some(doc_l2));
846 assert_eq!(doc_id(&tree, l0), Some(doc_l2));
795 assert_eq!(doc_id(&tree, l1), Some(doc_l1));
847 assert_eq!(doc_id(&tree, l1), Some(doc_l1));
796 assert_eq!(doc_id(&tree, l2), Some(doc_r0));
848 assert_eq!(doc_id(&tree, l2), Some(doc_r0));