diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/static-ui.cpp | 73 | ||||
| -rw-r--r-- | src/static-ui.hpp | 22 |
2 files changed, 64 insertions, 31 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; } diff --git a/src/static-ui.hpp b/src/static-ui.hpp index 185b218..0cc7aa2 100644 --- a/src/static-ui.hpp +++ b/src/static-ui.hpp @@ -16,17 +16,20 @@ enum PKE_UI_BOX_FLAGS : uint64_t { PKE_UI_BOX_FLAG_NONE = 0, // position type [0-1] // exact screen coordinates - PKE_UI_BOX_FLAG_POSITION_TYPE_STATIC = (1 << 0), - PKE_UI_BOX_FLAG_POSITION_TYPE_DYNAMIC = (1 << 1), - PKE_UI_BOX_FLAG_POSITION_TYPE_BOTH = (1 << 0) | (1 << 1), + 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), + /* // grow [2-3] - PKE_UI_BOX_FLAG_GROW_HORIZONTAL = (1 << 2), - PKE_UI_BOX_FLAG_GROW_VERTICAL = (1 << 3), - PKE_UI_BOX_FLAG_GROW_BOTH = (1 << 2) | (1 << 3), + PKE_UI_BOX_FLAG_GROW_HORIZONTAL = (1 << 3), + PKE_UI_BOX_FLAG_GROW_VERTICAL = (1 << 4), + PKE_UI_BOX_FLAG_GROW_BOTH = (1 << 3) | (1 << 4), + */ // center [4-5] - PKE_UI_BOX_FLAG_CENTER_HORIZONTAL = (1 << 4), - PKE_UI_BOX_FLAG_CENTER_VERTICAL = (1 << 5), - PKE_UI_BOX_FLAG_CENTER_BOTH = (1 << 4) | (1 << 5), + 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), }; typedef uint16_t pke_ui_box_count_T; @@ -36,6 +39,7 @@ struct pke_ui_box; struct pke_ui_box { PKE_UI_BOX_FLAGS flags; float pos_top_left_x, pos_top_left_y; + float min_width, min_height; float max_width, max_height; uint8_t layer; struct pke_ui_box_internals { |
