summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-10-30 15:22:57 -0400
committerJonathan Bradley <jcb@pikum.xyz>2025-10-30 15:49:35 -0400
commitf986f2b422d9167604964108b7f2e71f77b6da14 (patch)
tree347b05f3243b0c6021ad25c212edbfbbaa41c632
parent754981501322727aec9e91a91008ce8f117bc728 (diff)
pke: static-ui add flex_padding
-rw-r--r--src/serialization-static-ui.cpp16
-rw-r--r--src/serialization.hpp1
-rw-r--r--src/static-ui.cpp20
-rw-r--r--src/static-ui.hpp3
-rw-r--r--tests/pke-test-static-ui.cpp85
5 files changed, 112 insertions, 13 deletions
diff --git a/src/serialization-static-ui.cpp b/src/serialization-static-ui.cpp
index 8c21d7c..ae948ab 100644
--- a/src/serialization-static-ui.cpp
+++ b/src/serialization-static-ui.cpp
@@ -309,6 +309,13 @@ pk_handle pke_serialize_ui_box(srlztn_serialize_helper *h, pke_ui_box *box) {
kve.val = s;
kve.end = SRLZTN_KVE_END;
pk_arr_append_t(&kvec.arr, kve);
+ kve.key = SRLZTN_UI_BOX_FLEX_PADDING;
+ len = snprintf(NULL, 0, "%f", box->flex_padding);
+ s = pk_new_arr<char>(len+1, h->bkt);
+ sprintf(s, "%f", box->flex_padding);
+ kve.val = s;
+ kve.end = SRLZTN_KVE_END;
+ pk_arr_append_t(&kvec.arr, kve);
}
{
kve.key = SRLZTN_UI_BOX_TYPE;
@@ -462,6 +469,14 @@ void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kve
}
continue;
}
+ if (strstr(SRLZTN_UI_BOX_FLEX_PADDING, kve->key)) {
+ res = pk_stn(&bx.flex_padding, kve->val, &stn_end);
+ if (res != PK_STN_RES_SUCCESS) {
+ fprintf(stderr, "[pke_deserialize_ui_box] Failed to parse value for: '%s', err: %i\n", SRLZTN_UI_BOX_FLEX_PADDING, res);
+ continue;
+ }
+ continue;
+ }
if (strstr(SRLZTN_UI_BOX_FLEX_DIRECTION, kve->key)) {
res = pk_stn(&bx.flex_direction, kve->val, &stn_end);
if (res != PK_STN_RES_SUCCESS) {
@@ -564,6 +579,7 @@ void pke_deserialize_ui_box(srlztn_deserialize_helper *h, pke_kve_container *kve
box->min_size = bx.min_size;
box->max_size = bx.max_size;
box->flex_weight = bx.flex_weight;
+ box->flex_padding = bx.flex_padding;
box->type = bx.type;
box->flex_direction = bx.flex_direction;
box->layer = bx.layer;
diff --git a/src/serialization.hpp b/src/serialization.hpp
index a4ea7e4..777976b 100644
--- a/src/serialization.hpp
+++ b/src/serialization.hpp
@@ -55,6 +55,7 @@ iccsc SRLZTN_UI_BOX_POS_TOP_LEFT = "PosTopLeft:";
iccsc SRLZTN_UI_BOX_MIN_SIZE = "MinSize:";
iccsc SRLZTN_UI_BOX_MAX_SIZE = "MaxSize:";
iccsc SRLZTN_UI_BOX_FLEX_WEIGHT = "FlexWeight:";
+iccsc SRLZTN_UI_BOX_FLEX_PADDING = "FlexPadding:";
iccsc SRLZTN_UI_BOX_FLEX_DIRECTION = "FlexDirection:";
iccsc SRLZTN_UI_BOX_LAYER = "Layer:";
iccsc SRLZTN_UI_BOX_TYPE = "Type:";
diff --git a/src/static-ui.cpp b/src/static-ui.cpp
index 2682de1..72bd298 100644
--- a/src/static-ui.cpp
+++ b/src/static-ui.cpp
@@ -256,9 +256,10 @@ struct pke_ui_flex_params {
float used_units;
};
-bool pke_ui_calc_px(pk_arr_t<pke_ui_box_instance_buffer_item> &buffer, pk_arr_t<std::pair<pke_ui_box*,pke_ui_box_instance_buffer_item>> &tmp_txtr_buffer, pke_ui_flex_params *flex_params, pke_ui_box *box) {
+bool pke_ui_calc_px(pk_arr_t<pke_ui_box_instance_buffer_item> &buffer, pk_arr_t<std::pair<pke_ui_box*,pke_ui_box_instance_buffer_item>> &tmp_txtr_buffer, pke_ui_flex_params *flex_params, pke_ui_box *box, uint8_t child_index) {
assert(box != nullptr);
pke_ui_box_count_T i;
+ float flex_padding;
glm::vec2 px_size;
glm::vec2 px_min_size;
glm::vec2 px_max_size;
@@ -333,14 +334,17 @@ bool pke_ui_calc_px(pk_arr_t<pke_ui_box_instance_buffer_item> &buffer, pk_arr_t<
if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX)) {
assert(flex_params != nullptr);
assert(box->internal.parent != nullptr);
+ flex_padding = box->internal.parent->flex_padding * float(child_index + 1);
if (box->internal.parent->flex_direction == 0) {
px_size.x = flex_params->px_per_unit * box->flex_weight;
px_size.y = parent_size_padded.y;
box->internal.px_corner.x += flex_params->used_units * flex_params->px_per_unit;
+ box->internal.px_corner.x += flex_padding;
} else {
px_size.x = parent_size_padded.x;
px_size.y = flex_params->px_per_unit * box->flex_weight;
box->internal.px_corner.y += flex_params->used_units * flex_params->px_per_unit;
+ box->internal.px_corner.y += flex_padding;
}
flex_params->used_units += box->flex_weight;
} else if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC)) {
@@ -482,6 +486,7 @@ bool pke_ui_calc_px(pk_arr_t<pke_ui_box_instance_buffer_item> &buffer, pk_arr_t<
void pke_ui_recalc_sizes_recursive(pk_arr_t<pke_ui_box_instance_buffer_item> &arr, pk_arr_t<std::pair<pke_ui_box*,pke_ui_box_instance_buffer_item>> &tmp_txtr_buffer, pke_ui_box *box) {
PKE_UI_BOX_FLAG_T flags_masked;
uint8_t flex_count = 0;
+ float available_size = 0;
pke_ui_flex_params flex_params{};
flex_params.px_per_unit = 0;
flex_params.unit_total = 0;
@@ -507,14 +512,17 @@ void pke_ui_recalc_sizes_recursive(pk_arr_t<pke_ui_box_instance_buffer_item> &ar
return;
}
if (flex_count != 0) {
- flex_params.px_per_unit =
+ assert(box->flex_padding == box->flex_padding); // NaN
+ available_size =
box->flex_direction == 0
- ? (box->internal.px_size.x - box->internal.px_padding_l - box->internal.px_padding_r) / flex_params.unit_total
- : (box->internal.px_size.y - box->internal.px_padding_t - box->internal.px_padding_b) / flex_params.unit_total;
+ ? (box->internal.px_size.x - box->internal.px_padding_l - box->internal.px_padding_r)
+ : (box->internal.px_size.y - box->internal.px_padding_t - box->internal.px_padding_b);
+ available_size -= (float)(flex_count+1) * (box->flex_padding);
+ flex_params.px_per_unit = available_size / flex_params.unit_total;
}
for (pke_ui_box_count_T i = 0; i < box->internal.h_children; ++i) {
- if (!pke_ui_calc_px(arr, tmp_txtr_buffer, &flex_params, box->internal.children[i])) {
+ if (!pke_ui_calc_px(arr, tmp_txtr_buffer, &flex_params, box->internal.children[i], i)) {
i -= 1;
continue;
}
@@ -670,7 +678,7 @@ void pke_ui_tick(double delta) {
continue;
}
// root boxes marked for removal were already skipped
- pke_ui_calc_px(arr, tmp_txtr_arr, nullptr, box);
+ pke_ui_calc_px(arr, tmp_txtr_arr, nullptr, box, 0);
pke_ui_recalc_sizes_recursive(arr, tmp_txtr_arr, box);
}
diff --git a/src/static-ui.hpp b/src/static-ui.hpp
index ec99456..e4c86af 100644
--- a/src/static-ui.hpp
+++ b/src/static-ui.hpp
@@ -113,6 +113,7 @@ struct pke_ui_box : public Entity_Base {
glm::vec2 min_size;
glm::vec2 max_size;
float flex_weight;
+ float flex_padding;
PKE_UI_BOX_TYPE type;
uint8_t flex_direction;
uint8_t layer;
@@ -194,7 +195,7 @@ pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent, const PKE_UI_BOX_TYPE type
void pke_ui_box_update_textures(pke_ui_box *box);
#ifdef PKE_TEST_EXPOSE
-void pke_ui_calc_px(pk_arr_t<pke_ui_box_instance_buffer_item> &buffer, pk_arr_t<std::pair<pke_ui_box*,pke_ui_box_instance_buffer_item>> &tmp_txtr_buffer, pke_ui_flex_params *flex_params, pke_ui_box *box);
+void pke_ui_calc_px(pk_arr_t<pke_ui_box_instance_buffer_item> &buffer, pk_arr_t<std::pair<pke_ui_box*,pke_ui_box_instance_buffer_item>> &tmp_txtr_buffer, pke_ui_flex_params *flex_params, pke_ui_box *box, uint8_t child_index);
void pke_ui_recalc_sizes_recursive(pk_arr_t<pke_ui_box_instance_buffer_item> &arr, pk_arr_t<std::pair<pke_ui_box*,pke_ui_box_instance_buffer_item>> &tmp_txtr_buffer, pke_ui_box *box);
#endif
diff --git a/tests/pke-test-static-ui.cpp b/tests/pke-test-static-ui.cpp
index aa989cc..09affb9 100644
--- a/tests/pke-test-static-ui.cpp
+++ b/tests/pke-test-static-ui.cpp
@@ -19,6 +19,7 @@ struct pke_ui_box_instance_buffer_item {
struct pke_ui_flex_params {
float px_per_unit;
float unit_total;
+ float used_units;
};
#define PKE_TEST_EXPOSE
@@ -72,7 +73,7 @@ int pke_test_static_ui_000() {
calculated_offset = ui_box->pos_top_left.x + c_ui_box->pos_top_left.x + built_in_offset;
- pke_ui_calc_px(arr, txtr_arr, nullptr, ui_box);
+ pke_ui_calc_px(arr, txtr_arr, nullptr, ui_box, 0);
pke_ui_recalc_sizes_recursive(arr, txtr_arr, ui_box);
PKE_TEST_ASSERT(ui_box->internal.parent == nullptr, err_index);
@@ -117,6 +118,9 @@ int pke_test_static_ui_100() {
c_ui_box->max_size.x = 0.8;
c_ui_box->max_size.y = 0.8;
+ pke_ui_calc_px(arr, txtr_arr, nullptr, ui_box, 0);
+ pke_ui_recalc_sizes_recursive(arr, txtr_arr, ui_box);
+
unit = Extent.width * 0.1;
calculated_offset_x = (unit * 8) - (built_in_offset * 2); // padded parent
calculated_offset_x = (calculated_offset_x * 0.1) + unit + built_in_offset;
@@ -125,9 +129,6 @@ int pke_test_static_ui_100() {
calculated_offset_y = (unit * 8) - (built_in_offset * 2); // padded parent
calculated_offset_y = (calculated_offset_y * 0.1) + unit + built_in_offset;
- pke_ui_calc_px(arr, txtr_arr, nullptr, ui_box);
- pke_ui_recalc_sizes_recursive(arr, txtr_arr, ui_box);
-
PKE_TEST_ASSERT(ui_box->internal.parent == nullptr, err_index);
PKE_TEST_ASSERT(ui_box->internal.h_children == 1, err_index);
PKE_TEST_ASSERT(c_ui_box->internal.parent != nullptr, err_index);
@@ -184,7 +185,7 @@ int pke_test_static_ui_200() {
unit = Extent.height * 0.1;
calculated_offset_y = unit + 1 + built_in_offset;
- pke_ui_calc_px(arr, txtr_arr, nullptr, ui_box);
+ pke_ui_calc_px(arr, txtr_arr, nullptr, ui_box, 0);
pke_ui_recalc_sizes_recursive(arr, txtr_arr, ui_box);
PKE_TEST_ASSERT(ui_box->internal.parent == nullptr, err_index);
@@ -206,8 +207,75 @@ int pke_test_static_ui_200() {
return 0;
}
+// test flex with padding
+int pke_test_static_ui_300() {
+ pk_arr_t<pke_ui_box_instance_buffer_item> arr{};
+ pk_arr_t<std::pair<pke_ui_box*,pke_ui_box_instance_buffer_item>> txtr_arr{};
+ unsigned int u;
+ float flex_box_height;
+ const uint8_t child_count = 5;
+ pke_ui_box *c_ui_boxes[child_count];
+
+ pke_ui_box *ui_box = pke_ui_box_new_root();
+ ui_box->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC;
+ ui_box->flags |= PKE_UI_BOX_FLAG_CENTER_BOTH;
+ ui_box->flex_direction = 1;
+ ui_box->flex_padding = 1;
+ ui_box->pos_top_left.x = 0;
+ ui_box->pos_top_left.y = 0;
+ ui_box->min_size.x = 0;
+ ui_box->min_size.y = 0;
+ ui_box->max_size.x = 0.95;
+ ui_box->max_size.y = 0.95;
+
+ for (u = 0; u < child_count; ++u) {
+ c_ui_boxes[u] = pke_ui_box_new_child(ui_box);
+ c_ui_boxes[u]->flags |= PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX;
+ c_ui_boxes[u]->flex_weight = 1;
+ c_ui_boxes[u]->pos_top_left.x = 0;
+ c_ui_boxes[u]->pos_top_left.y = 0;
+ c_ui_boxes[u]->min_size.x = 0;
+ c_ui_boxes[u]->min_size.y = 0;
+ c_ui_boxes[u]->max_size.x = 8000;
+ c_ui_boxes[u]->max_size.y = 8000;
+ }
+
+ pke_ui_calc_px(arr, txtr_arr, nullptr, ui_box, 0);
+ pke_ui_recalc_sizes_recursive(arr, txtr_arr, ui_box);
+
+ PK_TEST_ASSERT_EQ_RET(nullptr, ui_box->internal.parent);
+ PK_TEST_ASSERT_EQ_RET(child_count, ui_box->internal.h_children);
+ PK_TEST_ASSERT_EQ_RET(48, ui_box->internal.px_corner.x);
+ PK_TEST_ASSERT_EQ_RET(27, ui_box->internal.px_corner.y);
+ PK_TEST_ASSERT_EQ_RET(1824, ui_box->internal.px_size.x);
+ PK_TEST_ASSERT_EQ_RET(1026, ui_box->internal.px_size.y);
+
+ flex_box_height = 1016 / float(child_count);
+ for (u = 0; u < child_count; ++u) {
+ PK_TEST_ASSERT_NEQ_RET(nullptr, c_ui_boxes[u]->internal.parent);
+ PK_TEST_ASSERT_EQ_RET(0, c_ui_boxes[u]->internal.h_children);
+ PK_TEST_ASSERT_EQ_RET(0, c_ui_boxes[u]->internal.r_children);
+ PK_TEST_ASSERT_EQ_RET(1820, c_ui_boxes[u]->internal.px_size.x);
+ // (((parent-size - parent border (both) - built-in-padding (both) - flex padding(total)) / child_count
+ // (((1026 - 2) - 2) - 6) / 5
+ PK_TEST_ASSERT_EQ_RET(1016 / float(child_count), c_ui_boxes[u]->internal.px_size.y);
+ PK_TEST_ASSERT_EQ_RET(flex_box_height, c_ui_boxes[u]->internal.px_size.y);
+ // parent pos + parent border + built-in-padding
+ PK_TEST_ASSERT_EQ_RET(48 + 1 + 1, c_ui_boxes[u]->internal.px_corner.x);
+ }
+
+ // (pos calc) + parent_pos + parent_border + built-in-padding + flex padding
+ PK_TEST_ASSERT_EQ_RET((flex_box_height * 0) + 27 + 1 + 1 + 1, c_ui_boxes[0]->internal.px_corner.y);
+ PK_TEST_ASSERT_EQ_RET((flex_box_height * 1) + 27 + 1 + 1 + 2, c_ui_boxes[1]->internal.px_corner.y);
+ PK_TEST_ASSERT_EQ_RET((flex_box_height * 2) + 27 + 1 + 1 + 3, c_ui_boxes[2]->internal.px_corner.y);
+ PK_TEST_ASSERT_EQ_RET((flex_box_height * 3) + 27 + 1 + 1 + 4, c_ui_boxes[3]->internal.px_corner.y);
+ PK_TEST_ASSERT_EQ_RET((flex_box_height * 4) + 27 + 1 + 1 + 5, c_ui_boxes[4]->internal.px_corner.y);
+
+ return 0;
+}
+
pk_test_group *pke_test_static_ui_get_group() {
- static const uint64_t test_count = 3;
+ static const uint64_t test_count = 4;
static struct pk_test tests[test_count] = {
{
.title = "test 000",
@@ -224,6 +292,11 @@ pk_test_group *pke_test_static_ui_get_group() {
.func = pke_test_static_ui_200,
.expected_result = 0,
},
+ {
+ .title = "test 300",
+ .func = pke_test_static_ui_300,
+ .expected_result = 0,
+ },
};
static struct pk_test_group group = {};
group.title = "static_ui";