From 4152fbecb6ee8360575aa4c24e9cedf822f159dc Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Wed, 25 Mar 2026 19:59:14 -0700 Subject: Implement vertical and horizontal layouts. Use widget position properly when rendering. Toolbar, buttons and edit bars WIP --- src/widget/widget.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) (limited to 'src/widget/widget.c') diff --git a/src/widget/widget.c b/src/widget/widget.c index ebcaf10..2c525cc 100644 --- a/src/widget/widget.c +++ b/src/widget/widget.c @@ -2,6 +2,8 @@ #include +#include + // ----------------------------------------------------------------------------- // Widget. @@ -30,14 +32,19 @@ void DestroyWidget(uiWidget** ppWidget) { UI_DEL(ppWidget); } -void uiWidgetSetParent(uiPtr child_, uiPtr parent_) { +void WidgetSetParent(uiPtr child_, uiPtr parent_) { uiWidget* child = child_.widget; uiWidget* parent = parent_.widget; assert(child); assert(parent); - list_add(parent->children, child); + if (!uiIsNullptr(child->parent)) { + list_remove(child->parent.widget->children, child); + } + + list_push(parent->children, child); + child->parent = parent_; } // ----------------------------------------------------------------------------- @@ -58,6 +65,11 @@ uiPtr uiMakeLabelPtr(uiLabel* label) { return (uiPtr){.type = uiTypeLabel, .label = label}; } +uiPtr uiMakeLayoutPtr(uiLayout* layout) { + assert(layout); + return (uiPtr){.type = uiTypeLayout, .layout = layout}; +} + uiPtr uiMakeTablePtr(uiTable* table) { assert(table); return (uiPtr){.type = uiTypeTable, .table = table}; @@ -72,6 +84,8 @@ uiPtr uiMakeWidgetPtr(uiWidget* widget) { return uiMakeFramePtr((uiFrame*)widget); case uiTypeLabel: return uiMakeLabelPtr((uiLabel*)widget); + case uiTypeLayout: + return uiMakeLayoutPtr((uiLayout*)widget); case uiTypeTable: return uiMakeTablePtr((uiTable*)widget); default: @@ -103,8 +117,99 @@ uiLabel* uiGetLabelPtr(uiPtr ptr) { return ptr.label; } +uiLayout* uiGetLayoutPtr(uiPtr ptr) { + assert(ptr.type == uiTypeLayout); + assert(ptr.layout); + return ptr.layout; +} + +uiEdit* uiGetEditPtr(uiPtr ptr) { + assert(ptr.type == uiTypeEdit); + assert(ptr.edit); + return ptr.edit; +} + uiTable* uiGetTablePtr(uiPtr ptr) { assert(ptr.type == uiTypeTable); assert(ptr.table); return ptr.table; } + +typedef struct PrintState { + mstring pad; + mstring rect; +} PrintState; + +static void RectToString(uiRect rect, mstring* out) { + assert(out); + out->length = snprintf( + out->str, sizeof(out->str), "rect{(x:%d, y:%d), (w:%d, h:%d)", rect.x, + rect.y, rect.width, rect.height); +} + +static void uiPrintRec(uiPtr ptr, PrintState* state) { + if (uiIsNullptr(ptr)) { + return; + } + RectToString(ptr.widget->rect, &state->rect); + switch (ptr.type) { + case uiTypeButton: { + const uiButton* button = uiGetButtonPtr(ptr); + printf( + "%sbutton{rect=%s, text=\"%s\"}\n", mstring_cstr(&state->pad), + mstring_cstr(&state->rect), string_cstr(&button->text)); + break; + } + case uiTypeLabel: { + const uiLabel* label = uiGetLabelPtr(ptr); + printf( + "%sbutton{rect=%s, text=\"%s\"}\n", mstring_cstr(&state->pad), + mstring_cstr(&state->rect), string_cstr(&label->text)); + break; + } + case uiTypeLayout: { + const uiLayout* layout = uiGetLayoutPtr(ptr); + const char* direction = ""; + switch (layout->direction) { + case uiHorizontal: + direction = "horizontal"; + break; + case uiVertical: + direction = "vertical"; + break; + } + printf( + "%s%s_layout{rect=%s}\n", mstring_cstr(&state->pad), direction, + mstring_cstr(&state->rect)); + break; + } + case uiTypeFrame: { + printf( + "%sframe{rect=%s}\n", mstring_cstr(&state->pad), + mstring_cstr(&state->rect)); + break; + } + case uiTypeTable: { + const uiTable* table = uiGetTablePtr(ptr); + printf( + "%stable{rect=%s}\n", mstring_cstr(&state->pad), + mstring_cstr(&state->rect)); + break; + } + default: + printf("%swidget\n", mstring_cstr(&state->pad)); + break; + } + const mstring pad = state->pad; + state->pad = mstring_concat(state->pad, mstring_make(" ")); + list_foreach(ptr.widget->children, child, { + uiPrintRec(uiMakeWidgetPtr(child), state); + }); + state->pad = pad; +} + +void uiPrint(uiPtr ptr) { + PrintState state = + (PrintState){.pad = mstring_make_empty(), .rect = mstring_make_empty()}; + uiPrintRec(ptr, &state); +} -- cgit v1.2.3