From eae4525970d5a689f09d82e1f73218cb16168b9b Mon Sep 17 00:00:00 2001 From: Jonathan Bradley Date: Tue, 11 Mar 2025 14:48:36 -0400 Subject: checkpoint: pke: static ui flex pre-work --- src/static-ui.cpp | 73 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 22 deletions(-) (limited to 'src/static-ui.cpp') diff --git a/src/static-ui.cpp b/src/static-ui.cpp index 8c8f920..01af0db 100644 --- a/src/static-ui.cpp +++ b/src/static-ui.cpp @@ -79,20 +79,26 @@ Some restrictions: - children cannot change the size of a parent, parents must be sized manually - e.g.: exact font width - consider writing a method to calculate text +- Children can ONLY be horizontal or vertical + - this means that tables or similar need to consist of rows of columns */ void pke_ui_calc_px(pke_ui_box *box, DynArray &buffer) { assert(box != nullptr); - // val = desired_padding + border_width static const float built_in_offset = 2.0; - glm::vec2 size; + glm::vec2 px_size; glm::vec2 parent_size_padded; glm::vec2 parent_pos_and_offset; + assert(PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_ALL)); assert(box->pos_top_left_x >= 0.0); assert(box->pos_top_left_y >= 0.0); assert(box->max_width >= 0.0); assert(box->max_height >= 0.0); + assert(box->min_width >= 0.0); + assert(box->min_height >= 0.0); + assert(box->min_width <= box->max_width); + assert(box->min_height <= box->max_height); if (box->internal.parent != nullptr) { parent_pos_and_offset.x = box->internal.parent->internal.px_corner_x + box->internal.parent->internal.px_offset_x; @@ -101,46 +107,69 @@ void pke_ui_calc_px(pke_ui_box *box, DynArray & parent_size_padded.y = box->internal.parent->internal.px_height; // built-in padding parent_size_padded -= glm::vec2(built_in_offset * 2); - size = parent_size_padded; + px_size = parent_size_padded; } else { parent_pos_and_offset = glm::vec2(0); parent_size_padded = glm::vec2(Extent.width, Extent.height); - size = glm::vec2(Extent.width, Extent.height); + px_size = glm::vec2(Extent.width, Extent.height); } - if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC)) { - size.x -= box->pos_top_left_x; - size.y -= box->pos_top_left_y; + if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX)) { + // TODO - think through how to organize this. + // It's almost like the parent needs to set the widths/heights of the children + // In every other method, the child determines its size, + // in flex, the parent sums the weights and distributes the available size. + // Could pass a struct around with all the needed details: + // - width or height per weight unit, current used weight or current offset + // Parent should assert that all or none of the children are position type flex? + px_size.x = PK_CLAMP(parent_size_padded.x, box->min_width, box->max_width); + px_size.y = PK_CLAMP(parent_size_padded.y, box->min_height, box->max_height); + } else if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC)) { + px_size.x -= box->pos_top_left_x; + px_size.y -= box->pos_top_left_y; box->internal.px_corner_x = 0 + parent_pos_and_offset.x + box->pos_top_left_x; box->internal.px_corner_y = 0 + parent_pos_and_offset.y + box->pos_top_left_y; - size.x = PK_MIN(size.x, box->max_width); - size.y = PK_MIN(size.y, box->max_height); + px_size.x = PK_CLAMP(parent_size_padded.x, box->min_width, box->max_width); + px_size.y = PK_CLAMP(parent_size_padded.y, box->min_height, box->max_height); } else { assert(box->pos_top_left_x < 1.0); assert(box->pos_top_left_y < 1.0); box->internal.px_corner_x = parent_pos_and_offset.x; box->internal.px_corner_y = parent_pos_and_offset.y; - float px_left = size.x * box->pos_top_left_x; - float px_top = size.y * box->pos_top_left_y; + float px_left = px_size.x * box->pos_top_left_x; + float px_top = px_size.y * box->pos_top_left_y; box->internal.px_corner_x += px_left; box->internal.px_corner_y += px_top; - size -= px_left; - size -= px_top; - size.x = PK_MIN(size.x, box->max_width * parent_size_padded.x); - size.y = PK_MIN(size.y, box->max_height * parent_size_padded.y); - } - if (box->internal.parent != nullptr) { - box->internal.parent->internal.px_offset_y += size.y; + px_size -= px_left; + px_size -= px_top; + px_size.x = PK_CLAMP(parent_size_padded.x, box->min_width * parent_size_padded.x, box->max_width * parent_size_padded.x); + px_size.y = PK_CLAMP(parent_size_padded.y, box->min_height * parent_size_padded.y, box->max_height * parent_size_padded.y); } // built-in padding box->internal.px_offset_x = built_in_offset; box->internal.px_offset_y = built_in_offset; - box->internal.px_width = size.x; - box->internal.px_height = size.y; + + if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_CENTER_HORIZONTAL)) { + if (parent_size_padded.x > px_size.x) { + box->internal.px_offset_x += (parent_size_padded.x - px_size.x) / 2.0; + } + } + + if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_CENTER_VERTICAL)) { + if (parent_size_padded.y > px_size.y) { + box->internal.px_offset_y += (parent_size_padded.y - px_size.y) / 2.0; + } + } + + box->internal.px_width = px_size.x; + box->internal.px_height = px_size.y; + if (box->internal.parent != nullptr) { + box->internal.parent->internal.px_offset_y += px_size.y; + } // update buffer glm::vec3 scale = glm::vec3(box->internal.px_width / (float)Extent.width, box->internal.px_height / (float)Extent.height, 1.0); @@ -173,8 +202,8 @@ void pke_ui_recalc_sizes_recursive(DynArray &ar uint64_t flags_masked; for (pke_ui_box_count_T i = 0; i < box->internal.h_children; ++i) { - flags_masked = box->flags & (PKE_UI_BOX_FLAG_POSITION_TYPE_BOTH); - if (flags_masked == 0 || flags_masked == PKE_UI_BOX_FLAG_POSITION_TYPE_BOTH) { + flags_masked = box->flags & (PKE_UI_BOX_FLAG_POSITION_TYPE_ALL); + if (flags_masked == 0 || flags_masked == 3 || flags_masked == 5 || flags_masked == 6 || flags_masked == 7) { fprintf(stderr, "[%s] ui box invalid flags: position", __FILE__); return; } -- cgit v1.2.3