@@ -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
@@ -232,7 +322,7 @@ impl Tree {
232322 } = & mut self . nodes [ parent_id]
233323 {
234324 if let Some ( pos) = container. children . iter ( ) . position ( |& child| child == index) {
235- container. children . remove ( pos) ;
325+ container. remove_child ( pos) ;
236326 // TODO: if container now only has one child, remove it and place child in parent
237327 if container. children . is_empty ( ) && parent_id != self . root {
238328 // if container now empty, remove it
@@ -360,11 +450,17 @@ impl Tree {
360450 Layout :: Horizontal => {
361451 let len = container. children . len ( ) ;
362452
363- let height = area. height / len as u16 ;
453+ let slots = container. calculate_slots_height ( ) ;
454+ let slot_height = area. height as f32 / slots as f32 ;
364455
365456 let mut child_y = area. y ;
366457
367458 for ( i, child) in container. children . iter ( ) . enumerate ( ) {
459+ let bounds = container. node_bounds [ i] ;
460+ let height = match bounds. expand {
461+ true => ( 40.0 * slot_height) as u16 ,
462+ false => ( slot_height * bounds. height as f32 ) . floor ( ) as u16 ,
463+ } ;
368464 let mut area = Rect :: new (
369465 container. area . x ,
370466 child_y,
@@ -373,7 +469,7 @@ impl Tree {
373469 ) ;
374470 child_y += height;
375471
376- // last child takes the remaining width because we can get uneven
472+ // last child takes the remaining height because we can get uneven
377473 // space from rounding
378474 if i == len - 1 {
379475 area. height = container. area . y + container. area . height - area. y ;
@@ -385,14 +481,19 @@ impl Tree {
385481 Layout :: Vertical => {
386482 let len = container. children . len ( ) ;
387483
388- let width = area . width / len as u16 ;
389-
484+ let slots = container . calculate_slots_width ( ) ;
485+ let slot_width : f32 = area . width as f32 / slots as f32 ;
390486 let inner_gap = 1u16 ;
391487 // let total_gap = inner_gap * (len as u16 - 1);
392488
393489 let mut child_x = area. x ;
394490
395491 for ( i, child) in container. children . iter ( ) . enumerate ( ) {
492+ let bounds = container. node_bounds [ i] ;
493+ let width = match bounds. expand {
494+ true => ( 40.0 * slot_width) as u16 ,
495+ false => ( slot_width * bounds. width as f32 ) . floor ( ) as u16 ,
496+ } ;
396497 let mut area = Rect :: new (
397498 child_x,
398499 container. area . y ,
@@ -571,6 +672,83 @@ impl Tree {
571672 }
572673 }
573674
675+ fn get_active_node_bounds_mut (
676+ & mut self ,
677+ expect_layout : Layout ,
678+ ) -> Option < & mut ContainerBounds > {
679+ let mut focus = self . focus ;
680+ let mut parent = self . nodes [ focus] . parent ;
681+
682+ // Parent expected to be container
683+ if let Some ( focused_layout) = match & self . nodes [ parent] . content {
684+ Content :: View ( _) => unreachable ! ( ) ,
685+ Content :: Container ( node) => Some ( node. layout ) ,
686+ } {
687+ // if we want to make a width change and we have a `Horizontal` layout focused,
688+ // alter the parent `Vertical` layout instead and vice versa
689+ if focused_layout != expect_layout {
690+ focus = parent;
691+ parent = self . nodes [ parent] . parent ;
692+ }
693+
694+ if let Content :: Container ( node) = & mut self . nodes [ parent] . content {
695+ return node. as_mut ( ) . get_child_by_view_id ( focus) ;
696+ } ;
697+ }
698+ None
699+ }
700+
701+ pub fn resize_buffer ( & mut self , resize_type : Resize , dimension : Dimension ) {
702+ match dimension {
703+ Dimension :: Width => {
704+ if let Some ( bounds) = self . get_active_node_bounds_mut ( Layout :: Vertical ) {
705+ match resize_type {
706+ Resize :: Shrink => {
707+ if bounds. width > 1 {
708+ bounds. width -= 1 ;
709+ }
710+ }
711+ Resize :: Grow => {
712+ if bounds. width < 20 {
713+ bounds. width += 1 ;
714+ }
715+ }
716+ } ;
717+ self . recalculate ( ) ;
718+ }
719+ }
720+ Dimension :: Height => {
721+ if let Some ( bounds) = self . get_active_node_bounds_mut ( Layout :: Horizontal ) {
722+ match resize_type {
723+ Resize :: Shrink => {
724+ if bounds. height > 1 {
725+ bounds. height -= 1 ;
726+ }
727+ }
728+ Resize :: Grow => {
729+ if bounds. height < 20 {
730+ bounds. height += 1 ;
731+ }
732+ }
733+ } ;
734+ self . recalculate ( ) ;
735+ }
736+ }
737+ }
738+ }
739+
740+ pub fn toggle_focus_window ( & mut self ) {
741+ if let Some ( bounds) = self . get_active_node_bounds_mut ( Layout :: Horizontal ) {
742+ bounds. expand = !bounds. expand ;
743+ }
744+
745+ if let Some ( bounds) = self . get_active_node_bounds_mut ( Layout :: Vertical ) {
746+ bounds. expand = !bounds. expand ;
747+ }
748+
749+ self . recalculate ( ) ;
750+ }
751+
574752 pub fn swap_split_in_direction ( & mut self , direction : Direction ) -> Option < ( ) > {
575753 let focus = self . focus ;
576754 let target = self . find_split_in_direction ( focus, direction) ?;
0 commit comments