@@ -29,6 +29,16 @@ pub enum Content {
2929 Container ( Box < Container > ) ,
3030}
3131
32+ pub enum Resize {
33+ Shrink ,
34+ Grow ,
35+ }
36+
37+ pub enum Dimension {
38+ Width ,
39+ Height ,
40+ }
41+
3242impl Node {
3343 pub fn container ( layout : Layout ) -> Self {
3444 Self {
@@ -65,6 +75,14 @@ pub struct Container {
6575 layout : Layout ,
6676 children : Vec < ViewId > ,
6777 area : Rect ,
78+ node_bounds : Vec < ContainerBounds > ,
79+ }
80+
81+ #[ derive( Debug , Clone , Copy ) ]
82+ pub struct ContainerBounds {
83+ width : usize ,
84+ height : usize ,
85+ expand : bool ,
6886}
6987
7088impl Container {
@@ -73,8 +91,80 @@ impl Container {
7391 layout,
7492 children : Vec :: new ( ) ,
7593 area : Rect :: default ( ) ,
94+ node_bounds : Vec :: new ( ) ,
7695 }
7796 }
97+
98+ fn get_child_by_view_id ( & mut self , node : ViewId ) -> Option < & mut ContainerBounds > {
99+ self . children
100+ . iter ( )
101+ . position ( |child| child == & node)
102+ . and_then ( |index| self . node_bounds . get_mut ( index) )
103+ }
104+
105+ fn push_child ( & mut self , node : ViewId ) -> & mut Self {
106+ self . children . push ( node) ;
107+ self . add_child_bounds ( ) ;
108+ self
109+ }
110+
111+ fn insert_child ( & mut self , index : usize , node : ViewId ) -> & mut Self {
112+ self . children . insert ( index, node) ;
113+ self . insert_child_bounds ( index) ;
114+ self
115+ }
116+
117+ fn remove_child ( & mut self , index : usize ) -> & mut Self {
118+ self . children . remove ( index) ;
119+ self . remove_child_bounds ( index) ;
120+ self
121+ }
122+
123+ fn add_child_bounds ( & mut self ) -> & mut Self {
124+ self . node_bounds . push ( ContainerBounds {
125+ width : 10 ,
126+ height : 10 ,
127+ expand : false ,
128+ } ) ;
129+ self
130+ }
131+
132+ fn insert_child_bounds ( & mut self , index : usize ) -> & mut Self {
133+ self . node_bounds . insert (
134+ index,
135+ ContainerBounds {
136+ width : 10 ,
137+ height : 10 ,
138+ expand : false ,
139+ } ,
140+ ) ;
141+ self
142+ }
143+
144+ fn remove_child_bounds ( & mut self , index : usize ) -> & mut Self {
145+ self . node_bounds . remove ( index) ;
146+ self
147+ }
148+
149+ fn calculate_slots_width ( & self ) -> usize {
150+ self . node_bounds
151+ . iter ( )
152+ . map ( |bounds| match bounds. expand {
153+ true => 40 ,
154+ false => bounds. width ,
155+ } )
156+ . sum ( )
157+ }
158+
159+ fn calculate_slots_height ( & self ) -> usize {
160+ self . node_bounds
161+ . iter ( )
162+ . map ( |bounds| match bounds. expand {
163+ true => 40 ,
164+ false => bounds. height ,
165+ } )
166+ . sum ( )
167+ }
78168}
79169
80170impl Default for Container {
@@ -131,7 +221,7 @@ impl Tree {
131221 pos + 1
132222 } ;
133223
134- container. children . insert ( pos, node) ;
224+ container. insert_child ( pos, node) ;
135225 // focus the new node
136226 self . focus = node;
137227
@@ -168,7 +258,7 @@ impl Tree {
168258 . unwrap ( ) ;
169259 pos + 1
170260 } ;
171- container. children . insert ( pos, node) ;
261+ container. insert_child ( pos, node) ;
172262 self . nodes [ node] . parent = parent;
173263 } else {
174264 let mut split = Node :: container ( layout) ;
@@ -182,8 +272,8 @@ impl Tree {
182272 } => container,
183273 _ => unreachable ! ( ) ,
184274 } ;
185- container. children . push ( focus) ;
186- container. children . push ( node) ;
275+ container. push_child ( focus) ;
276+ container. push_child ( node) ;
187277 self . nodes [ focus] . parent = split;
188278 self . nodes [ node] . parent = split;
189279
@@ -359,12 +449,17 @@ impl Tree {
359449 match container. layout {
360450 Layout :: Horizontal => {
361451 let len = container. children . len ( ) ;
362-
363- let height = area. height / len as u16 ;
364-
452+ let slots = container. calculate_slots_height ( ) ;
453+ let slot_height = area. height as f32 / slots as f32 ;
365454 let mut child_y = area. y ;
366455
367456 for ( i, child) in container. children . iter ( ) . enumerate ( ) {
457+ let bounds = container. node_bounds [ i] ;
458+ let height = match bounds. expand {
459+ true => ( 40.0 * slot_height) as u16 ,
460+ false => ( slot_height * bounds. height as f32 ) . floor ( ) as u16 ,
461+ } ;
462+
368463 let mut area = Rect :: new (
369464 container. area . x ,
370465 child_y,
@@ -373,7 +468,7 @@ impl Tree {
373468 ) ;
374469 child_y += height;
375470
376- // last child takes the remaining width because we can get uneven
471+ // last child takes the remaining height because we can get uneven
377472 // space from rounding
378473 if i == len - 1 {
379474 area. height = container. area . y + container. area . height - area. y ;
@@ -384,15 +479,20 @@ impl Tree {
384479 }
385480 Layout :: Vertical => {
386481 let len = container. children . len ( ) ;
387-
388- let width = area. width / len as u16 ;
482+ let slots = container. calculate_slots_width ( ) ;
483+ let slot_width: f32 = area. width as f32 / slots as f32 ;
484+ let mut child_x = area. x ;
389485
390486 let inner_gap = 1u16 ;
391487 // let total_gap = inner_gap * (len as u16 - 1);
392488
393- let mut child_x = area. x ;
394-
395489 for ( i, child) in container. children . iter ( ) . enumerate ( ) {
490+ let bounds = container. node_bounds [ i] ;
491+ let width = match bounds. expand {
492+ true => ( 40.0 * slot_width) as u16 ,
493+ false => ( slot_width * bounds. width as f32 ) . floor ( ) as u16 ,
494+ } ;
495+
396496 let mut area = Rect :: new (
397497 child_x,
398498 container. area . y ,
@@ -571,6 +671,83 @@ impl Tree {
571671 }
572672 }
573673
674+ fn get_active_node_bounds_mut (
675+ & mut self ,
676+ expect_layout : Layout ,
677+ ) -> Option < & mut ContainerBounds > {
678+ let mut focus = self . focus ;
679+ let mut parent = self . nodes [ focus] . parent ;
680+
681+ // Parent expected to be container
682+ if let Some ( focused_layout) = match & self . nodes [ parent] . content {
683+ Content :: View ( _) => unreachable ! ( ) ,
684+ Content :: Container ( node) => Some ( node. layout ) ,
685+ } {
686+ // if we want to make a width change and we have a `Horizontal` layout focused,
687+ // alter the parent `Vertical` layout instead and vice versa
688+ if focused_layout != expect_layout {
689+ focus = parent;
690+ parent = self . nodes [ parent] . parent ;
691+ }
692+
693+ if let Content :: Container ( node) = & mut self . nodes [ parent] . content {
694+ return node. as_mut ( ) . get_child_by_view_id ( focus) ;
695+ } ;
696+ }
697+ None
698+ }
699+
700+ pub fn resize_buffer ( & mut self , resize_type : Resize , dimension : Dimension ) {
701+ match dimension {
702+ Dimension :: Width => {
703+ if let Some ( bounds) = self . get_active_node_bounds_mut ( Layout :: Vertical ) {
704+ match resize_type {
705+ Resize :: Shrink => {
706+ if bounds. width > 1 {
707+ bounds. width -= 1 ;
708+ }
709+ }
710+ Resize :: Grow => {
711+ if bounds. width < 20 {
712+ bounds. width += 1 ;
713+ }
714+ }
715+ } ;
716+ self . recalculate ( ) ;
717+ }
718+ }
719+ Dimension :: Height => {
720+ if let Some ( bounds) = self . get_active_node_bounds_mut ( Layout :: Horizontal ) {
721+ match resize_type {
722+ Resize :: Shrink => {
723+ if bounds. height > 1 {
724+ bounds. height -= 1 ;
725+ }
726+ }
727+ Resize :: Grow => {
728+ if bounds. height < 20 {
729+ bounds. height += 1 ;
730+ }
731+ }
732+ } ;
733+ self . recalculate ( ) ;
734+ }
735+ }
736+ }
737+ }
738+
739+ pub fn toggle_focus_window ( & mut self ) {
740+ if let Some ( bounds) = self . get_active_node_bounds_mut ( Layout :: Horizontal ) {
741+ bounds. expand = !bounds. expand ;
742+ }
743+
744+ if let Some ( bounds) = self . get_active_node_bounds_mut ( Layout :: Vertical ) {
745+ bounds. expand = !bounds. expand ;
746+ }
747+
748+ self . recalculate ( ) ;
749+ }
750+
574751 pub fn swap_split_in_direction ( & mut self , direction : Direction ) -> Option < ( ) > {
575752 let focus = self . focus ;
576753 let target = self . find_split_in_direction ( focus, direction) ?;
0 commit comments