diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-11 14:48:36 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-11 14:48:36 -0400 |
| commit | eae4525970d5a689f09d82e1f73218cb16168b9b (patch) | |
| tree | 80dbdd603c70d0bc5ab1578e6eeea425e8528ed3 /src/static-ui.cpp | |
| parent | 5be32bb8735cf8dad61ae672c3ddf0d1295b8c3c (diff) | |
checkpoint: pke: static ui flex pre-work
Diffstat (limited to 'src/static-ui.cpp')
| -rw-r--r-- | src/static-ui.cpp | 73 |
1 files changed, 51 insertions, 22 deletions
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<pke_ui_box_instance_buffer_item> &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<pke_ui_box_instance_buffer_item> & 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<pke_ui_box_instance_buffer_item> &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; } |
