summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/static-ui.cpp71
-rw-r--r--src/static-ui.hpp19
-rw-r--r--tests/pke-test-static-ui.cpp48
3 files changed, 75 insertions, 63 deletions
diff --git a/src/static-ui.cpp b/src/static-ui.cpp
index fff8ecc..7df5a34 100644
--- a/src/static-ui.cpp
+++ b/src/static-ui.cpp
@@ -106,12 +106,17 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
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;
- parent_pos_and_offset.y = box->internal.parent->internal.px_corner_y + box->internal.parent->internal.px_offset_y;
- parent_size_padded.x = box->internal.parent->internal.px_width;
- parent_size_padded.y = box->internal.parent->internal.px_height;
+ parent_pos_and_offset.x = box->internal.parent->internal.px_corner.x
+ + box->internal.parent->internal.px_padding_l;
+ parent_pos_and_offset.y = box->internal.parent->internal.px_corner.y
+ + box->internal.parent->internal.px_padding_t;
+ parent_size_padded.x = box->internal.parent->internal.px_size.x;
+ parent_size_padded.y = box->internal.parent->internal.px_size.y;
// built-in padding
- parent_size_padded -= glm::vec2(built_in_offset * 2);
+ parent_size_padded.x -= box->internal.parent->internal.px_padding_l
+ + box->internal.parent->internal.px_padding_r;
+ parent_size_padded.y -= box->internal.parent->internal.px_padding_t
+ + box->internal.parent->internal.px_padding_b;
px_size = parent_size_padded;
} else {
parent_pos_and_offset = glm::vec2(0);
@@ -123,23 +128,16 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
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
+ box->internal.px_corner.x = 0
+ parent_pos_and_offset.x
+ box->pos_top_left_x;
- box->internal.px_corner_y = 0
+ 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,
- // 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?
if (box->internal.parent->flex_direction == 0) {
px_size.x = flex_params->px_per_unit * box->flex_weight;
} else {
@@ -151,12 +149,12 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
} 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;
+ box->internal.px_corner.x = parent_pos_and_offset.x;
+ box->internal.px_corner.y = parent_pos_and_offset.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;
+ box->internal.px_corner.x += px_left;
+ box->internal.px_corner.y += px_top;
px_size.x -= px_left;
px_size.y -= px_top;
px_min_size.x = box->min_width * parent_size_padded.x;
@@ -168,26 +166,33 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
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;
+ box->internal.px_padding_l = built_in_offset;
+ box->internal.px_padding_b = built_in_offset;
+ box->internal.px_padding_r = built_in_offset;
+ box->internal.px_padding_t = 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_corner_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_corner_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;
+ box->internal.px_size.x = px_size.x;
+ box->internal.px_size.y = 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;
+ // TODO change this based on the parent's 'direction'
+ // 2025-03-13 JCB
+ // optional: auto-wrapping boxes possible if we keep track of two sizes:
+ // - remaining in active row/column
+ // - unused space
+ // box->internal.parent->internal.px_padding_l += px_size.x;
+ box->internal.parent->internal.px_padding_t += px_size.y;
}
if (PK_HAS_FLAG(box->flags, PKE_UI_BOX_FLAG_VISIBILITY_INVISIBLE)) {
@@ -195,20 +200,20 @@ void pke_ui_calc_px(DynArray<pke_ui_box_instance_buffer_item> &buffer, pke_ui_fl
}
// 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 scale = glm::vec3(box->internal.px_size.x / (float)Extent.width, box->internal.px_size.y / (float)Extent.height, 1.0);
glm::vec3 translate = glm::vec3(1);
// ((val) - (width/2)) / (width/2)
// place left line of box at edge of screen
- translate.x = (box->internal.px_width / 2.0);
+ translate.x = (box->internal.px_size.x / 2.0);
// box position
- translate.x += box->internal.px_corner_x;
+ translate.x += box->internal.px_corner.x;
translate.x -= ((float)Extent.width / 2.0);
translate.x /= ((float)Extent.width / 2.0);
// ((val) - (height/2)) / (height/2)
// place top line of box at edge of screen
- translate.y = (box->internal.px_height / 2.0);
+ translate.y = (box->internal.px_size.y / 2.0);
// box position
- translate.y += box->internal.px_corner_y;
+ translate.y += box->internal.px_corner.y;
translate.y -= ((float)Extent.height / 2.0);
translate.y /= ((float)Extent.height / 2.0);
translate.z = 0;
@@ -246,8 +251,8 @@ void pke_ui_recalc_sizes_recursive(DynArray<pke_ui_box_instance_buffer_item> &ar
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;
+ ? box->internal.px_size.x / flex_params.unit_total
+ : box->internal.px_size.y / flex_params.unit_total;
}
for (pke_ui_box_count_T i = 0; i < box->internal.h_children; ++i) {
diff --git a/src/static-ui.hpp b/src/static-ui.hpp
index a9b751b..6586a02 100644
--- a/src/static-ui.hpp
+++ b/src/static-ui.hpp
@@ -2,6 +2,8 @@
#define PKE_STATIC_UI_HPP
#include "components-vk.hpp"
+#include "vendor-glm-include.hpp"
+
#include <cstdint>
#define built_in_offset 2.0
@@ -16,18 +18,19 @@ struct MSDFGlyphSettings {
enum PKE_UI_BOX_FLAGS : uint64_t {
PKE_UI_BOX_FLAG_NONE = 0,
- // position type [0-4]
+ // [00-04] position type
// exact screen coordinates
PKE_UI_BOX_FLAG_POSITION_TYPE_FLEX = (1 << 0),
PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC = (1 << 1),
PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC = (1 << 2),
PKE_UI_BOX_FLAG_POSITION_TYPE_ALL = (1 << 0) | (1 << 1) | (1 << 2),
- // center [5-6]
+ // [05-06] center
PKE_UI_BOX_FLAG_CENTER_HORIZONTAL = (1 << 5),
PKE_UI_BOX_FLAG_CENTER_VERTICAL = (1 << 6),
PKE_UI_BOX_FLAG_CENTER_BOTH = (1 << 5) | (1 << 6),
- // visibility [7-9]
+ // [07-09] visibility
PKE_UI_BOX_FLAG_VISIBILITY_INVISIBLE = (1 << 7),
+ // [10-??]
};
typedef uint16_t pke_ui_box_count_T;
@@ -43,9 +46,13 @@ struct pke_ui_box {
uint8_t flex_direction;
uint8_t layer;
struct pke_ui_box_internals {
- float px_corner_x, px_corner_y;
- float px_width, px_height;
- float px_offset_x, px_offset_y;
+ // the exact px to translate (shader)
+ glm::vec2 px_corner;
+ // the exact px for scaling (shader)
+ glm::vec2 px_size;
+ // internal padding + running offset for adding children
+ // glm::vec4 px_padding;
+ float px_padding_l, px_padding_b, px_padding_r, px_padding_t;
pke_ui_box *parent;
pke_ui_box **children;
pke_ui_box_count_T h_children;
diff --git a/tests/pke-test-static-ui.cpp b/tests/pke-test-static-ui.cpp
index 43ce76d..9ca4cdd 100644
--- a/tests/pke-test-static-ui.cpp
+++ b/tests/pke-test-static-ui.cpp
@@ -58,15 +58,15 @@ int pke_test_static_ui_000() {
PKE_TEST_ASSERT(c_ui_box->internal.h_children == 0, err_index);
PKE_TEST_ASSERT(c_ui_box->internal.r_children == 0, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_corner_x == 10, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_corner_y == 10, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_corner_x == calculated_offset, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_corner_y == calculated_offset, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_corner.x == 10, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_corner.y == 10, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_corner.x == calculated_offset, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_corner.y == calculated_offset, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_width == 500, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_height == 500, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_width == 100, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_height == 100, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_size.x == 500, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_size.y == 500, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_size.x == 100, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_size.y == 100, err_index);
return 0;
}
@@ -109,18 +109,18 @@ int pke_test_static_ui_100() {
PKE_TEST_ASSERT(c_ui_box->internal.h_children == 0, err_index);
PKE_TEST_ASSERT(c_ui_box->internal.r_children == 0, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_corner_x == Extent.width * 0.1, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_corner_y == Extent.height * 0.1, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_corner_x == calculated_offset_x, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_corner_y == calculated_offset_y, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_corner.x == Extent.width * 0.1, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_corner.y == Extent.height * 0.1, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_corner.x == calculated_offset_x, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_corner.y == calculated_offset_y, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_width == (Extent.width * 0.1) * 8, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_height == (Extent.height * 0.1) * 8, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_size.x == (Extent.width * 0.1) * 8, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_size.y == (Extent.height * 0.1) * 8, err_index);
// TODO rounding?
// using a debugger, the actual and calculated values are ~0.01 off
// this is either a real issue or a rounding issue, either here or within pke
- PKE_TEST_ASSERT(c_ui_box->internal.px_width == (ui_box->internal.px_width - (built_in_offset * 2)) * 0.8, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_height == (ui_box->internal.px_height - (built_in_offset * 2)) * 0.8, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_size.x == (ui_box->internal.px_size.x - (built_in_offset * 2)) * 0.8, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_size.y == (ui_box->internal.px_size.y - (built_in_offset * 2)) * 0.8, err_index);
return 0;
}
@@ -162,15 +162,15 @@ int pke_test_static_ui_200() {
PKE_TEST_ASSERT(c_ui_box->internal.h_children == 0, err_index);
PKE_TEST_ASSERT(c_ui_box->internal.r_children == 0, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_corner_x == Extent.width * 0.1, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_corner_y == Extent.height * 0.1, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_corner_x == calculated_offset_x, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_corner_y == calculated_offset_y, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_corner.x == Extent.width * 0.1, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_corner.y == Extent.height * 0.1, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_corner.x == calculated_offset_x, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_corner.y == calculated_offset_y, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_width == (Extent.width * 0.1) * 8, err_index);
- PKE_TEST_ASSERT(ui_box->internal.px_height == (Extent.height * 0.1) * 8, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_width == 300, err_index);
- PKE_TEST_ASSERT(c_ui_box->internal.px_height == 300, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_size.x == (Extent.width * 0.1) * 8, err_index);
+ PKE_TEST_ASSERT(ui_box->internal.px_size.y == (Extent.height * 0.1) * 8, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_size.x == 300, err_index);
+ PKE_TEST_ASSERT(c_ui_box->internal.px_size.y == 300, err_index);
return 0;
}