@@ -149,6 +149,7 @@ pub const LayoutDirection = enum {
149149 //right_to_left,
150150 //bottom_to_top,
151151 centre ,
152+ left_to_right_wrap ,
152153};
153154
154155/// The `normal` scale is designed for a regular person with regular
@@ -3305,8 +3306,9 @@ pub const Display = struct {
33053306 parent .type .panel .scrollable .size .width = parent .minimum .width ;
33063307 parent .type .panel .scrollable .size .height = parent .minimum .height ;
33073308 switch (parent .type .panel .direction ) {
3308- .left_to_right = > place_children_left_to_right (self , parent , & expanders , expander_weights ),
3309- .top_to_bottom = > place_children_top_to_bottom (self , parent , & expanders , expander_weights ),
3309+ .left_to_right = > place_children_left_to_right (self , parent , expanders .slice (), expander_weights ),
3310+ .left_to_right_wrap = > place_children_left_to_right_wrap (self , parent ),
3311+ .top_to_bottom = > place_children_top_to_bottom (self , parent , expanders .slice (), expander_weights ),
33103312 .centre = > place_children_centred (self , parent ),
33113313 }
33123314
@@ -3333,7 +3335,7 @@ pub const Display = struct {
33333335
33343336 child .rect .x = parent .rect .x + parent .pad .left + (parent_width / 2 - child .rect .width / 2 );
33353337 child .rect .y = parent .rect .y + parent .pad .top + (parent_height / 2 - child .rect .height / 2 );
3336- if (dev_build or dev_mode ) {
3338+ if (dev_build and dev_mode ) {
33373339 err ("in parent {s} ({d}x{d} {d}x{d}) centre {s} at={d}x{d} size={d}x{d}" , .{
33383340 parent .name ,
33393341 parent .rect .x ,
@@ -3358,7 +3360,7 @@ pub const Display = struct {
33583360 inline fn place_children_top_to_bottom (
33593361 _ : * Display ,
33603362 parent : * Element ,
3361- expanders : * BoundedArray ( * Element , 10 ) ,
3363+ expanders : [] * Element ,
33623364 expander_weights : f32 ,
33633365 ) void {
33643366 // Layout each item from top to bottom, initially ignoring
@@ -3410,7 +3412,7 @@ pub const Display = struct {
34103412
34113413 if (parent .rect .height > needed_height ) {
34123414 const spare_height = parent .rect .height - needed_height ;
3413- for (expanders . slice () ) | expander | {
3415+ for (expanders ) | expander | {
34143416 if (expander .type .expander .weight <= 0 ) {
34153417 continue ;
34163418 }
@@ -3481,15 +3483,15 @@ pub const Display = struct {
34813483 }
34823484 }
34833485
3486+ /// Draw panel children from top left corner of the panel
3487+ /// assuming no scrolling of the child elements. Offsets
3488+ /// applied at runtime.
34843489 inline fn place_children_left_to_right (
34853490 _ : * Display ,
34863491 parent : * Element ,
3487- _ : * BoundedArray ( * Element , 10 ) ,
3492+ _ : [] * Element ,
34883493 _ : f32 ,
34893494 ) void {
3490- // Draw panel children from top left corner of the panel
3491- // assuming no scrolling of the child elements. Offsets
3492- // applied at runtime.
34933495 var current : Vector = .{
34943496 .x = parent .rect .x + parent .pad .left ,
34953497 .y = parent .rect .y + parent .pad .top ,
@@ -3566,6 +3568,57 @@ pub const Display = struct {
35663568 }
35673569 }
35683570
3571+ // Draw panel children from top left corner of the panel
3572+ // assuming no scrolling of the child elements. Offsets
3573+ // applied at runtime. Track the height of each element
3574+ // so wrapping can occur down to the next line.
3575+ inline fn place_children_left_to_right_wrap (
3576+ _ : * Display ,
3577+ parent : * Element ,
3578+ ) void {
3579+ var current : Vector = .{
3580+ .x = parent .rect .x + parent .pad .left ,
3581+ .y = parent .rect .y + parent .pad .top ,
3582+ };
3583+
3584+ // Track how much hight the current line needs
3585+ var line_height : f32 = 0 ;
3586+
3587+ // Draw along the line, and wrap when we hit the end of the line
3588+ const line_end : f32 = parent .rect .x + parent .rect .width - parent .pad .right ;
3589+
3590+ var i : usize = 0 ;
3591+ for (parent .type .panel .children .items ) | child | {
3592+ if (child .visible == .hidden ) continue ;
3593+ if (child .layout .position == .float ) continue ;
3594+ if (child .type == .expander ) continue ;
3595+
3596+ // Spacing is inserted before all items except the first item in a line/row
3597+ if (i > 0 )
3598+ current .x += parent .type .panel .spacing ;
3599+ i += 1 ;
3600+
3601+ if (current .x + child .rect .width > line_end ) {
3602+ current .x = parent .rect .x + parent .pad .left ;
3603+ current .y += line_height + parent .type .panel .spacing ;
3604+ line_height = 0 ;
3605+ i = 0 ;
3606+ //TODO: We could y grow the elements that want grow.
3607+ //TODO We could centre the items on this line `parent.child_align.x`
3608+ }
3609+
3610+ child .rect .x = current .x ;
3611+ child .rect .y = current .y ;
3612+ current .x += child .rect .width ;
3613+ const item_height = @max (child .rect .height , child .minimum .height );
3614+ line_height = @max (item_height , line_height );
3615+ }
3616+ current .y += parent .pad .bottom ;
3617+ const needed_height = current .y - parent .rect .y ;
3618+ parent .type .panel .scrollable .size .height = @max (needed_height , parent .rect .height );
3619+ //const overflow_height = parent.rect.height - needed_height;
3620+ }
3621+
35693622 pub fn set_language (display : * Display , allocator : Allocator , language : Lang ) ! void {
35703623 if (language == display .current_language ) {
35713624 debug ("set_language({s}) unchanged." , .{@tagName (display .current_language )});
@@ -4986,7 +5039,7 @@ fn find_minimum_panel_height(parent: *const Element, display: *Display) f32 {
49865039 return result ;
49875040 },
49885041
4989- .centre , .left_to_right = > {
5042+ .centre , .left_to_right , .left_to_right_wrap = > {
49905043 // centred all together
49915044 // a, next to b, next c.
49925045 //
@@ -5044,18 +5097,15 @@ fn find_minimum_panel_width(parent: *const Element, display: *Display) f32 {
50445097 var minimum_needed : f32 = parent .pad .left + parent .pad .right ;
50455098 var first = true ;
50465099 for (parent .type .panel .children .items ) | element | {
5047- if (element .layout .position == .float ) {
5048- continue ;
5049- }
5050- if (element .visible == .hidden ) {
5051- continue ;
5052- }
5053- if (first ) {
5054- first = false ;
5055- } else {
5056- // Add spacing before next element, if needed
5100+ if (element .layout .position == .float ) continue ;
5101+ if (element .visible == .hidden ) continue ;
5102+
5103+ // Add space between each element.
5104+ if (first )
5105+ first = false
5106+ else
50575107 minimum_needed += parent .type .panel .spacing ;
5058- }
5108+
50595109 const width = element .shrink_width (display , parent .rect .width );
50605110 minimum_needed += width ;
50615111 }
@@ -5067,6 +5117,29 @@ fn find_minimum_panel_width(parent: *const Element, display: *Display) f32 {
50675117 result = @max (result , parent .minimum .width );
50685118 return result ;
50695119 },
5120+ .left_to_right_wrap = > {
5121+ var minimum_needed : f32 = parent .pad .left + parent .pad .right ;
5122+ var first = true ;
5123+ for (parent .type .panel .children .items ) | element | {
5124+ if (element .layout .position == .float ) continue ;
5125+ if (element .visible == .hidden ) continue ;
5126+
5127+ // Add space between each element.
5128+ if (first )
5129+ first = false
5130+ else
5131+ minimum_needed += parent .type .panel .spacing ;
5132+
5133+ const width = element .shrink_width (display , parent .rect .width );
5134+ minimum_needed = @max (minimum_needed , width );
5135+ }
5136+ // Bound to the minimum/maximum width
5137+ minimum_needed += parent .pad .left + parent .pad .right ;
5138+ if (parent .maximum .width > 0 and parent .maximum .width < minimum_needed ) {
5139+ minimum_needed = parent .maximum .width ;
5140+ }
5141+ return @max (minimum_needed , parent .minimum .width );
5142+ },
50705143 .centre , .top_to_bottom = > {
50715144 // a, centred upon b, centred upon c
50725145 // a, then b underneath, thn c underneath...
0 commit comments