From fe69cedd45c8ff3a06e4fe4b9481155547806fb8 Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Fri, 15 Sep 2023 19:45:44 +0200 Subject: [PATCH] Remove OC_UI_FLAG_OVERFLOW_FIT. Now OC_UI_FLAG_OVERFLOW_ALLOW controls both shrinking children to the parent's size and fitting parent to shrunk children size. We can still emulate all combination of shrink * fit with this single flag (and sometimes a parent box). This also makes fitting the default, which is more practical since fitting a box contents often requires fitting on all children. --- samples/ui/src/main.c | 22 +++++++------- src/ui/ui.c | 69 ++++++++++++++++++++++++------------------- src/ui/ui.h | 16 +++++----- 3 files changed, 56 insertions(+), 51 deletions(-) diff --git a/samples/ui/src/main.c b/samples/ui/src/main.c index 968fd6f..e9a999c 100644 --- a/samples/ui/src/main.c +++ b/samples/ui/src/main.c @@ -106,7 +106,7 @@ void column_begin(const char* header, f32 widthFraction) | OC_UI_STYLE_BORDER_COLOR | OC_UI_STYLE_BORDER_SIZE | OC_UI_STYLE_ROUNDNESS); - oc_ui_box_begin(header, OC_UI_FLAG_DRAW_BACKGROUND | OC_UI_FLAG_DRAW_BORDER | OC_UI_FLAG_OVERFLOW_FIT_X | OC_UI_FLAG_OVERFLOW_FIT_Y); + oc_ui_box_begin(header, OC_UI_FLAG_DRAW_BACKGROUND | OC_UI_FLAG_DRAW_BORDER); oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, .layout.align.x = OC_UI_ALIGN_CENTER }, @@ -128,7 +128,7 @@ void column_begin(const char* header, f32 widthFraction) | OC_UI_STYLE_LAYOUT_ALIGN_X | OC_UI_STYLE_LAYOUT_MARGIN_X | OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_box_begin("contents", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_X | OC_UI_FLAG_OVERFLOW_FIT_Y); + oc_ui_box_begin("contents", OC_UI_FLAG_NONE); } void column_end() @@ -189,7 +189,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void) .size.height = { OC_UI_SIZE_PARENT, 1, .minSize = 400 } }, OC_UI_STYLE_SIZE); - oc_ui_container("top level", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_Y) + oc_ui_container("top level", OC_UI_FLAG_NONE) { //-------------------------------------------------------------------------------------------- // Menu bar @@ -228,7 +228,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void) | OC_UI_STYLE_LAYOUT_MARGINS | OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND | OC_UI_FLAG_OVERFLOW_FIT_Y) + oc_ui_container("background", OC_UI_FLAG_DRAW_BACKGROUND) { column("Widgets", 1.0 / 3) { @@ -239,7 +239,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void) OC_UI_STYLE_SIZE_WIDTH | OC_UI_STYLE_LAYOUT_AXIS | OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_container("top", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_X) + oc_ui_container("top", OC_UI_FLAG_NONE) { oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_Y, .layout.spacing = 24 }, @@ -555,13 +555,13 @@ ORCA_EXPORT void oc_on_frame_refresh(void) .layout.spacing = 32 }, OC_UI_STYLE_LAYOUT_AXIS | OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_container("controls", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_X) + oc_ui_container("controls", OC_UI_FLAG_NONE) { oc_ui_style_next(&(oc_ui_style){ .layout.axis = OC_UI_AXIS_Y, .layout.spacing = 16 }, OC_UI_STYLE_LAYOUT_AXIS | OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_container("unselected", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_X) + oc_ui_container("unselected", OC_UI_FLAG_NONE) { oc_ui_style_next(&(oc_ui_style){ .fontSize = 16 }, OC_UI_STYLE_FONT_SIZE); @@ -569,7 +569,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void) oc_ui_style_next(&(oc_ui_style){ .layout.spacing = 4 }, OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_container("size", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_X) + oc_ui_container("size", OC_UI_FLAG_NONE) { f32 widthSlider = (unselectedWidth - 8) / 16; labeled_slider("Width", &widthSlider); @@ -644,7 +644,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void) .layout.spacing = 16 }, OC_UI_STYLE_LAYOUT_AXIS | OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_container("selected", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_X) + oc_ui_container("selected", OC_UI_FLAG_NONE) { oc_ui_style_next(&(oc_ui_style){ .fontSize = 16 }, OC_UI_STYLE_FONT_SIZE); @@ -652,7 +652,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void) oc_ui_style_next(&(oc_ui_style){ .layout.spacing = 4 }, OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_container("size", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_X) + oc_ui_container("size", OC_UI_FLAG_NONE) { f32 widthSlider = (selectedWidth - 8) / 16; labeled_slider("Width", &widthSlider); @@ -727,7 +727,7 @@ ORCA_EXPORT void oc_on_frame_refresh(void) .layout.spacing = 16 }, OC_UI_STYLE_LAYOUT_AXIS | OC_UI_STYLE_LAYOUT_SPACING); - oc_ui_container("label", OC_UI_FLAG_NONE | OC_UI_FLAG_OVERFLOW_FIT_X | OC_UI_FLAG_OVERFLOW_FIT_Y) + oc_ui_container("label", OC_UI_FLAG_NONE) { oc_ui_style_next(&(oc_ui_style){ .fontSize = 16 }, OC_UI_STYLE_FONT_SIZE); diff --git a/src/ui/ui.c b/src/ui/ui.c index 458aef1..c09174e 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -1092,7 +1092,7 @@ void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int a } //NOTE: solve downard conflicts - int overflowAllowFlag = (OC_UI_FLAG_OVERFLOW_ALLOW_X << axis); + int overflowFlag = (OC_UI_FLAG_OVERFLOW_ALLOW_X << axis); if(box->style.layout.axis == axis) { @@ -1111,7 +1111,7 @@ void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int a } } - if(!(box->flags & overflowAllowFlag)) + if(!(box->flags & overflowFlag)) { //NOTE: then remove excess proportionally to each box slack f32 totalContents = sum + box->spacing[axis] + 2 * box->style.layout.margin.c[axis]; @@ -1137,7 +1137,7 @@ void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int a { if(!oc_ui_box_hidden(child) && !child->style.floating.c[axis]) { - if(!(box->flags & overflowAllowFlag)) + if(!(box->flags & overflowFlag)) { f32 totalContents = child->rect.c[2 + axis] + 2 * box->style.layout.margin.c[axis]; f32 excess = oc_clamp_low(totalContents - box->rect.c[2 + axis], 0); @@ -1158,20 +1158,22 @@ void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int a { oc_ui_layout_upward_dependent_size(ui, child, axis); - if(box->style.layout.axis == axis) + if(!oc_ui_box_hidden(child) + && !child->style.floating.c[axis]) { - sum += child->rect.c[2 + axis]; - } - else - { - sum = oc_max(sum, child->rect.c[2 + axis]); + if(box->style.layout.axis == axis) + { + sum += child->rect.c[2 + axis]; + } + else + { + sum = oc_max(sum, child->rect.c[2 + axis]); + } } } box->childrenSum[axis] = sum; - int overflowFitFlag = (OC_UI_FLAG_OVERFLOW_FIT_X << axis); - - if(box->flags & overflowFitFlag) + if(!(box->flags & overflowFlag) && !oc_list_empty(box->children)) { f32 minSize = sum + 2 * box->style.layout.margin.c[axis] + box->spacing[axis]; box->rect.c[2 + axis] = oc_max(minSize, box->rect.c[2 + axis]); @@ -1209,25 +1211,29 @@ void oc_ui_layout_upward_dependent_fixup(oc_ui_context* ui, oc_ui_box* box, int } availableToParentSized -= child->rect.c[2 + axis]; } + availableToParentSized = oc_max(0, availableToParentSized); - oc_list_for(box->children, child, oc_ui_box, listElt) + if(availableToParentSized && relaxSum) { - oc_ui_size* size = &child->style.size.c[axis]; - if(size->kind == OC_UI_SIZE_PARENT || size->kind == OC_UI_SIZE_PARENT_MINUS_PIXELS) + oc_list_for(box->children, child, oc_ui_box, listElt) { - f32 wantedSize = 0; - if(size->kind == OC_UI_SIZE_PARENT) + oc_ui_size* size = &child->style.size.c[axis]; + if(size->kind == OC_UI_SIZE_PARENT || size->kind == OC_UI_SIZE_PARENT_MINUS_PIXELS) { - wantedSize = availableSize * size->value; - } - else - { - wantedSize = availableSize - size->value; - } + f32 wantedSize = 0; + if(size->kind == OC_UI_SIZE_PARENT) + { + wantedSize = availableSize * size->value; + } + else + { + wantedSize = availableSize - size->value; + } - if(wantedSize > child->rect.c[2 + axis]) - { - child->rect.c[2 + axis] += availableToParentSized * (size->relax / relaxSum); + if(wantedSize > child->rect.c[2 + axis]) + { + child->rect.c[2 + axis] += availableToParentSized * (size->relax / relaxSum); + } } } } @@ -1236,11 +1242,7 @@ void oc_ui_layout_upward_dependent_fixup(oc_ui_context* ui, oc_ui_box* box, int oc_list_for(box->children, child, oc_ui_box, listElt) { //TODO also give back to parent dependent in layout direction if parent has grown - - if(axis == box->style.layout.axis) - { - } - else + if(axis != box->style.layout.axis) { oc_ui_size* size = &child->style.size.c[axis]; if(size->kind == OC_UI_SIZE_PARENT) @@ -1333,6 +1335,11 @@ void oc_ui_layout_compute_rect(oc_ui_context* ui, oc_ui_box* box, oc_vec2 pos) currentPos.c[layoutAxis] += child->rect.c[2 + layoutAxis] + spacing; } } + if(isnan(box->rect.w) || isnan(box->rect.h)) + { + oc_log_error("error in box %.*s\n", oc_str8_ip(box->string)); + OC_ASSERT(0); + } } void oc_ui_layout_find_next_hovered_recursive(oc_ui_context* ui, oc_ui_box* box, oc_vec2 p) diff --git a/src/ui/ui.h b/src/ui/ui.h index 8ec3d77..d0a22dd 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -477,18 +477,16 @@ typedef enum OC_UI_FLAG_BLOCK_MOUSE = (1 << 3), OC_UI_FLAG_HOT_ANIMATION = (1 << 4), OC_UI_FLAG_ACTIVE_ANIMATION = (1 << 5), - //WARN: these four following flags need to be kept as consecutive bits to + //WARN: these two following flags need to be kept as consecutive bits to // play well with axis-agnostic functions OC_UI_FLAG_OVERFLOW_ALLOW_X = (1 << 6), OC_UI_FLAG_OVERFLOW_ALLOW_Y = (1 << 7), - OC_UI_FLAG_OVERFLOW_FIT_X = (1 << 8), - OC_UI_FLAG_OVERFLOW_FIT_Y = (1 << 9), - OC_UI_FLAG_CLIP = (1 << 10), - OC_UI_FLAG_DRAW_BACKGROUND = (1 << 11), - OC_UI_FLAG_DRAW_FOREGROUND = (1 << 12), - OC_UI_FLAG_DRAW_BORDER = (1 << 13), - OC_UI_FLAG_DRAW_TEXT = (1 << 14), - OC_UI_FLAG_DRAW_PROC = (1 << 15), + OC_UI_FLAG_CLIP = (1 << 8), + OC_UI_FLAG_DRAW_BACKGROUND = (1 << 9), + OC_UI_FLAG_DRAW_FOREGROUND = (1 << 10), + OC_UI_FLAG_DRAW_BORDER = (1 << 11), + OC_UI_FLAG_DRAW_TEXT = (1 << 12), + OC_UI_FLAG_DRAW_PROC = (1 << 13), OC_UI_FLAG_OVERLAY = (1 << 16), } oc_ui_flags;