@@ -164,18 +164,10 @@ pub const Scale = enum(u8) {
164164 /// Map a floating number representing the user interface scale
165165 /// back to the enum value. `.normal = 1`.
166166 pub fn from_float (value : f32 ) Scale {
167- if (value == 0.5 ) {
168- return .tiny ;
169- }
170- if (value == 0.75 ) {
171- return .small ;
172- }
173- if (value == 1.25 ) {
174- return .large ;
175- }
176- if (value == 1.5 ) {
177- return .extra_large ;
178- }
167+ if (value == 0.5 ) return .tiny ;
168+ if (value == 0.75 ) return .small ;
169+ if (value == 1.25 ) return .large ;
170+ if (value == 1.5 ) return .extra_large ;
179171 return .normal ;
180172 }
181173
@@ -3084,8 +3076,8 @@ pub const Display = struct {
30843076 try display .draw ();
30853077 }
30863078
3087- /// Relayout the size and position of all elements on
3088- /// the display .
3079+ /// Apply the relayout algorithm to the currently visible root
3080+ /// panels/scenes, then descend to relayout each of the child panels .
30893081 pub fn relayout (display : * Display ) void {
30903082 display .need_relayout = false ;
30913083
@@ -3122,49 +3114,52 @@ pub const Display = struct {
31223114 scene .* .rect .height = display .root .rect .height ;
31233115 }
31243116 }
3125- if ( scene .* . layout . x == .shrinks and scene .* . minimum . width > 0 ) {
3126- // Root panels don't shrink past the width requested.
3117+ // Clamp minimum width and height
3118+ if ( scene .* . layout . x == .shrinks and scene .* . minimum . width > 0 )
31273119 scene .* .rect .width = @max (scene .* .rect .width , scene .* .minimum .width );
3128- }
3129- if (scene .* .layout .y == .shrinks and scene .* .maximum .height > 0 ) {
3130- // Root panels don't shrink past the width requested.
3120+ if (scene .* .layout .y == .shrinks and scene .* .maximum .height > 0 )
31313121 scene .* .rect .height = @max (scene .* .rect .height , scene .* .minimum .height );
3132- }
3122+
3123+ // Place panel at start, centre or end.
31333124 switch (scene .* .child_align .x ) {
31343125 .start = > scene .* .rect .x = 0 ,
31353126 .end = > scene .* .rect .x = display .root .rect .width - scene .* .rect .width ,
3136- else = > scene .* .rect .x = display .root .rect .width / 2 - scene .* .rect .width / 2 ,
3127+ .centre = > scene .* .rect .x = display .root .rect .width / 2 - scene .* .rect .width / 2 ,
31373128 }
31383129 switch (scene .* .child_align .y ) {
31393130 .start = > scene .* .rect .y = 0 ,
31403131 .end = > scene .* .rect .y = display .root .rect .height - scene .* .rect .height ,
3141- else = > scene .* .rect .y = display .root .rect .height / 2 - scene .* .rect .height / 2 ,
3132+ .centre = > scene .* .rect .y = display .root .rect .height / 2 - scene .* .rect .height / 2 ,
31423133 }
31433134
3144- do_relayout (display , scene .* );
3135+ // After root panel sizes are established, the child elements
3136+ // are layed out inside the panel.
3137+ relayout_panel (display , scene .* );
31453138 display .propogate_resize_event (scene .* );
3146- do_relayout (display , scene .* ); //TODO: fix
3139+ relayout_panel (display , scene .* ); //TODO: fix
3140+
3141+ // Children are given opportunity to resize themselves
3142+ // in response to the resize event.
31473143 var did_resize = false ;
31483144 if (display .on_resized .func != null ) {
31493145 if (display .on_resized .func .? (display .on_resized .ptr , display , scene .* )) {
31503146 did_resize = true ;
31513147 }
31523148 }
3153-
3154- if (did_resize ) {
3155- do_relayout (display , scene .* );
3156- }
3149+ if (did_resize )
3150+ relayout_panel (display , scene .* );
31573151
31583152 scene .* .pad = user_pad ;
31593153 }
31603154 }
31613155
3162- /// Starting with the root parent panel, recursively layout each element
3163- /// and child panel.
3164- fn do_relayout (self : * Display , parent : * Element ) void {
3156+ /// Relayout the contents of an individual panel that is sitting
3157+ /// somewhere n the tree below the root panel (scene) .
3158+ fn relayout_panel (self : * Display , parent : * Element ) void {
31653159 std .debug .assert (parent .type == .panel );
3166- //debug("relayout: {d}x{d}", .{ parent.width, parent.rect.height });
31673160
3161+ // Keep track of each expander in the panel. At the end, expand
3162+ // each expander according to the leftover space.
31683163 var expanders = BoundedArray (* Element , 10 ){};
31693164 var expander_weights : f32 = 0 ;
31703165
@@ -3189,14 +3184,13 @@ pub const Display = struct {
31893184 //
31903185 // Children of this panel are either fixed positioned, growing, or shrinking.
31913186 //
3192- // Fixed elements are not touched, they retain their requested size.
3193- // Shrinking elements shrink to the space they need.
3194- // Growing elements grow to the width or height of the parent.
3187+ // - `.fixed` elements are not altered, keep retain their requested `rect` size.
3188+ // - `.shrinks` elements shrink to the `minimum` space they need.
3189+ // - `.grows` enlarges the width or height of the parent `rect` .
31953190 //
31963191 for (parent .type .panel .children .items ) | element | {
3197- if (element .visible == .hidden ) {
3198- continue ;
3199- }
3192+ if (element .visible == .hidden ) continue ;
3193+
32003194 var child_resized = false ;
32013195 if ((dev_build or dev_mode ) and element .layout .position == .float ) {
32023196 if (element .layout .x == .grows ) {
@@ -3210,7 +3204,7 @@ pub const Display = struct {
32103204 }
32113205 switch (element .layout .x ) {
32123206 .grows = > {
3213- // Grow to the maximum the parent will allow
3207+ // Grow to the parent width, not including padding.
32143208 element .rect .x = 0 ;
32153209 var new_width = parent .rect .width - (parent .pad .left + parent .pad .right );
32163210 if (element .maximum .width > 0 and new_width > element .maximum .width ) {
@@ -3222,13 +3216,13 @@ pub const Display = struct {
32223216 }
32233217 },
32243218 .shrinks = > {
3225- // Shrink to the smallest the children will allow
3226- // Shrink to the left, centre, or right.
3219+ // Shrink to the smallest the children will allow.
32273220 const new_width = element .shrink_width (self , parent .rect .width );
32283221 if (element .rect .width != new_width ) {
32293222 element .rect .width = new_width ;
32303223 child_resized = true ;
32313224 }
3225+ // Shrink to the left, centre, or right.
32323226 switch (element .child_align .x ) {
32333227 .start = > element .rect .x = 0 ,
32343228 .end = > element .rect .x = parent .rect .width - element .rect .width ,
@@ -3239,13 +3233,10 @@ pub const Display = struct {
32393233 // No shrinking or growing applies.
32403234 },
32413235 }
3242- if (child_resized and element .on_resized .func != null ) {
3243- debug ("element {s} resized. callback = {any}" , .{ element .name , element .on_resized .func != null });
3244- _ = element .on_resized .func .? (element .on_resized .ptr , self , element );
3245- }
3236+
32463237 switch (element .layout .y ) {
32473238 .grows = > {
3248- // Grow to the maximum the parent will allow
3239+ // Grow to the parent height, not including padding.
32493240 element .rect .y = 0 ;
32503241 element .rect .height = parent .rect .height - (parent .pad .top + parent .pad .bottom );
32513242 if (element .maximum .height > 0 and element .rect .height > element .maximum .height ) {
@@ -3254,7 +3245,11 @@ pub const Display = struct {
32543245 },
32553246 .shrinks = > {
32563247 // Shrink to the smallest the children will allow
3257- element .rect .height = element .shrink_height (self , parent .rect .width );
3248+ const new_height = element .shrink_height (self , parent .rect .width );
3249+ if (element .rect .height != new_height ) {
3250+ element .rect .height = new_height ;
3251+ child_resized = true ;
3252+ }
32583253 switch (element .child_align .y ) {
32593254 .start = > element .rect .y = 0 ,
32603255 .end = > element .rect .y = parent .rect .height - element .rect .height ,
@@ -3265,6 +3260,12 @@ pub const Display = struct {
32653260 // No shrinking or growing applies.
32663261 },
32673262 }
3263+
3264+ if (child_resized and element .on_resized .func != null ) {
3265+ debug ("element {s} resized. callback = {any}" , .{ element .name , element .on_resized .func != null });
3266+ _ = element .on_resized .func .? (element .on_resized .ptr , self , element );
3267+ }
3268+
32683269 if (element .type == .expander ) {
32693270 expanders .appendAssumeCapacity (element );
32703271 expander_weights += element .type .expander .weight ;
@@ -3289,10 +3290,10 @@ pub const Display = struct {
32893290 .centre = > relayout_centre (self , parent ),
32903291 }
32913292
3293+ // Descend into child elements to allow child panels to also resize.
32923294 for (parent .type .panel .children .items ) | child | {
3293- if (child .type == .panel ) {
3294- self .do_relayout (child );
3295- }
3295+ if (child .type == .panel )
3296+ self .relayout_panel (child );
32963297 }
32973298
32983299 if (panel_resized and parent .on_resized .func != null ) {
@@ -3303,14 +3304,10 @@ pub const Display = struct {
33033304 inline fn relayout_centre (_ : * Display , parent : * Element ) void {
33043305 // First pass just does a layout assuming top/left positioning.
33053306 for (parent .type .panel .children .items ) | child | {
3306- if (child .visible == .hidden ) {
3307- // Layout the clipped and visible items,
3308- // but not the hidden items.
3309- continue ;
3310- }
3311- if (child .layout .position == .float ) {
3312- continue ;
3313- }
3307+ if (child .layout .position == .float ) continue ;
3308+ if (child .visible == .hidden ) continue ;
3309+ if (child .type == .expander ) continue ;
3310+
33143311 child .rect .x = parent .rect .width / 2 - child .rect .width / 2 ;
33153312 child .rect .y = parent .rect .height / 2 - child .rect .height / 2 ;
33163313 if (dev_build or dev_mode ) {
0 commit comments