summaryrefslogtreecommitdiff
path: root/src/static-ui.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-03-11 14:48:36 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-03-11 14:48:36 -0400
commiteae4525970d5a689f09d82e1f73218cb16168b9b (patch)
tree80dbdd603c70d0bc5ab1578e6eeea425e8528ed3 /src/static-ui.cpp
parent5be32bb8735cf8dad61ae672c3ddf0d1295b8c3c (diff)
checkpoint: pke: static ui flex pre-work
Diffstat (limited to 'src/static-ui.cpp')
-rw-r--r--src/static-ui.cpp73
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;
}