diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-12 17:26:48 -0400 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-12 17:26:48 -0400 |
| commit | 85a2ba407b1ae285b4080e14f8a18ecf4ec7da2c (patch) | |
| tree | 0abe7044b6af5820e9f3c143733047b254e78e15 /src/static-ui.cpp | |
| parent | 68ef51ed3247dc4e7bd5970b9279a7d6a938ca52 (diff) | |
pke: more testing features + more ui flex work
Diffstat (limited to 'src/static-ui.cpp')
| -rw-r--r-- | src/static-ui.cpp | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/src/static-ui.cpp b/src/static-ui.cpp index 01af0db..fff8ecc 100644 --- a/src/static-ui.cpp +++ b/src/static-ui.cpp @@ -83,14 +83,19 @@ Some restrictions: - 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) { +struct pke_ui_flex_params { + float px_per_unit; + float unit_total; +}; + +void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_flex_params *flex_params, pke_ui_box *box) { assert(box != nullptr); - static const float built_in_offset = 2.0; glm::vec2 px_size; + glm::vec2 px_min_size; + glm::vec2 px_max_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); @@ -114,7 +119,20 @@ void pke_ui_calc_px(pke_ui_box *box, DynArray<pke_ui_box_instance_buffer_item> & px_size = glm::vec2(Extent.width, Extent.height); } + px_min_size.x = box->min_width; + px_min_size.y = box->min_height; + px_max_size.x = box->max_width; + px_max_size.y = box->max_height; + 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; + if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX)) { + assert(flex_params != nullptr); + assert(box->internal.parent != nullptr); // 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, @@ -122,19 +140,14 @@ void pke_ui_calc_px(pke_ui_box *box, DynArray<pke_ui_box_instance_buffer_item> & // 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); + if (box->internal.parent->flex_direction == 0) { + px_size.x = flex_params->px_per_unit * box->flex_weight; + } else { + px_size.y = flex_params->px_per_unit * box->flex_weight; + } } 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; - 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); @@ -144,33 +157,43 @@ void pke_ui_calc_px(pke_ui_box *box, DynArray<pke_ui_box_instance_buffer_item> & 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; - 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); + px_size.x -= px_left; + px_size.y -= px_top; + px_min_size.x = box->min_width * parent_size_padded.x; + px_min_size.y = box->min_height * parent_size_padded.y; + px_max_size.x = box->max_width * parent_size_padded.x; + px_max_size.y = box->max_height * parent_size_padded.y; } + + px_size = glm::clamp(px_size, px_min_size, px_max_size); + // built-in padding box->internal.px_offset_x = built_in_offset; box->internal.px_offset_y = built_in_offset; 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; + box->internal.px_corner_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_corner_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_x += px_size.x; box->internal.parent->internal.px_offset_y += px_size.y; } + if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_VISIBILITY_INVISIBLE)) { + return; + } + // update buffer glm::vec3 scale = glm::vec3(box->internal.px_width / (float)Extent.width, box->internal.px_height / (float)Extent.height, 1.0); glm::vec3 translate = glm::vec3(1); @@ -200,17 +223,35 @@ void pke_ui_calc_px(pke_ui_box *box, DynArray<pke_ui_box_instance_buffer_item> & void pke_ui_recalc_sizes_recursive(DynArray<pke_ui_box_instance_buffer_item> &arr, pke_ui_box *box, uint8_t depth = 0) { uint64_t flags_masked; + uint8_t flex_count = 0; + pke_ui_flex_params flex_params{}; + + flags_masked = box->flags & (PKE_UI_BOX_FLAG_POSITION_TYPE_ALL); + if (flags_masked == 0b000 || flags_masked == 0b011 || flags_masked == 0b101 || flags_masked == 0b110 || flags_masked == 0b111) { + fprintf(stderr, "[%s] ui box invalid flags: position type", __FILE__); + return; + } for (pke_ui_box_count_T i = 0; i < box->internal.h_children; ++i) { - 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; + if (PK_HAS_FLAG(box->internal.children[i]->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX)) { + flex_count += 1; + flex_params.unit_total += box->internal.children[i]->flex_weight; } } + if (flex_count != 0 && flex_count != box->internal.h_children) { + fprintf(stderr, "[%s] ui box invalid flags: if one child is type FLEX, then all children must be type FLEX", __FILE__); + return; + } + if (flex_count != 0) { + flex_params.px_per_unit = + box->flex_direction == 0 + ? box->internal.px_width / flex_params.unit_total + : box->internal.px_height / flex_params.unit_total; + } + for (pke_ui_box_count_T i = 0; i < box->internal.h_children; ++i) { - pke_ui_calc_px(box->internal.children[i], arr); + pke_ui_calc_px(arr, &flex_params, box->internal.children[i]); pke_ui_recalc_sizes_recursive(arr, box->internal.children[i], depth + 1); } } @@ -316,7 +357,7 @@ void pke_ui_tick(double delta) { ); for (pke_ui_box_count_T i = 0; i < pke_ui_master.h_root_boxes; ++i) { pke_ui_box *box = pke_ui_master.root_boxes[i]; - pke_ui_calc_px(box, arr); + pke_ui_calc_px(arr, nullptr, box); pke_ui_recalc_sizes_recursive(arr, box, 0); } pke_ui_update_instance_buffer(arr); |
