diff options
Diffstat (limited to 'src/widget/widget.c')
| -rw-r--r-- | src/widget/widget.c | 109 |
1 files changed, 107 insertions, 2 deletions
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 @@ | |||
| 2 | 2 | ||
| 3 | #include <cassert.h> | 3 | #include <cassert.h> |
| 4 | 4 | ||
| 5 | #include <stdio.h> | ||
| 6 | |||
| 5 | // ----------------------------------------------------------------------------- | 7 | // ----------------------------------------------------------------------------- |
| 6 | // Widget. | 8 | // Widget. |
| 7 | 9 | ||
| @@ -30,14 +32,19 @@ void DestroyWidget(uiWidget** ppWidget) { | |||
| 30 | UI_DEL(ppWidget); | 32 | UI_DEL(ppWidget); |
| 31 | } | 33 | } |
| 32 | 34 | ||
| 33 | void uiWidgetSetParent(uiPtr child_, uiPtr parent_) { | 35 | void WidgetSetParent(uiPtr child_, uiPtr parent_) { |
| 34 | uiWidget* child = child_.widget; | 36 | uiWidget* child = child_.widget; |
| 35 | uiWidget* parent = parent_.widget; | 37 | uiWidget* parent = parent_.widget; |
| 36 | 38 | ||
| 37 | assert(child); | 39 | assert(child); |
| 38 | assert(parent); | 40 | assert(parent); |
| 39 | 41 | ||
| 40 | list_add(parent->children, child); | 42 | if (!uiIsNullptr(child->parent)) { |
| 43 | list_remove(child->parent.widget->children, child); | ||
| 44 | } | ||
| 45 | |||
| 46 | list_push(parent->children, child); | ||
| 47 | child->parent = parent_; | ||
| 41 | } | 48 | } |
| 42 | 49 | ||
| 43 | // ----------------------------------------------------------------------------- | 50 | // ----------------------------------------------------------------------------- |
| @@ -58,6 +65,11 @@ uiPtr uiMakeLabelPtr(uiLabel* label) { | |||
| 58 | return (uiPtr){.type = uiTypeLabel, .label = label}; | 65 | return (uiPtr){.type = uiTypeLabel, .label = label}; |
| 59 | } | 66 | } |
| 60 | 67 | ||
| 68 | uiPtr uiMakeLayoutPtr(uiLayout* layout) { | ||
| 69 | assert(layout); | ||
| 70 | return (uiPtr){.type = uiTypeLayout, .layout = layout}; | ||
| 71 | } | ||
| 72 | |||
| 61 | uiPtr uiMakeTablePtr(uiTable* table) { | 73 | uiPtr uiMakeTablePtr(uiTable* table) { |
| 62 | assert(table); | 74 | assert(table); |
| 63 | return (uiPtr){.type = uiTypeTable, .table = table}; | 75 | return (uiPtr){.type = uiTypeTable, .table = table}; |
| @@ -72,6 +84,8 @@ uiPtr uiMakeWidgetPtr(uiWidget* widget) { | |||
| 72 | return uiMakeFramePtr((uiFrame*)widget); | 84 | return uiMakeFramePtr((uiFrame*)widget); |
| 73 | case uiTypeLabel: | 85 | case uiTypeLabel: |
| 74 | return uiMakeLabelPtr((uiLabel*)widget); | 86 | return uiMakeLabelPtr((uiLabel*)widget); |
| 87 | case uiTypeLayout: | ||
| 88 | return uiMakeLayoutPtr((uiLayout*)widget); | ||
| 75 | case uiTypeTable: | 89 | case uiTypeTable: |
| 76 | return uiMakeTablePtr((uiTable*)widget); | 90 | return uiMakeTablePtr((uiTable*)widget); |
| 77 | default: | 91 | default: |
| @@ -103,8 +117,99 @@ uiLabel* uiGetLabelPtr(uiPtr ptr) { | |||
| 103 | return ptr.label; | 117 | return ptr.label; |
| 104 | } | 118 | } |
| 105 | 119 | ||
| 120 | uiLayout* uiGetLayoutPtr(uiPtr ptr) { | ||
| 121 | assert(ptr.type == uiTypeLayout); | ||
| 122 | assert(ptr.layout); | ||
| 123 | return ptr.layout; | ||
| 124 | } | ||
| 125 | |||
| 126 | uiEdit* uiGetEditPtr(uiPtr ptr) { | ||
| 127 | assert(ptr.type == uiTypeEdit); | ||
| 128 | assert(ptr.edit); | ||
| 129 | return ptr.edit; | ||
| 130 | } | ||
| 131 | |||
| 106 | uiTable* uiGetTablePtr(uiPtr ptr) { | 132 | uiTable* uiGetTablePtr(uiPtr ptr) { |
| 107 | assert(ptr.type == uiTypeTable); | 133 | assert(ptr.type == uiTypeTable); |
| 108 | assert(ptr.table); | 134 | assert(ptr.table); |
| 109 | return ptr.table; | 135 | return ptr.table; |
| 110 | } | 136 | } |
| 137 | |||
| 138 | typedef struct PrintState { | ||
| 139 | mstring pad; | ||
| 140 | mstring rect; | ||
| 141 | } PrintState; | ||
| 142 | |||
| 143 | static void RectToString(uiRect rect, mstring* out) { | ||
| 144 | assert(out); | ||
| 145 | out->length = snprintf( | ||
| 146 | out->str, sizeof(out->str), "rect{(x:%d, y:%d), (w:%d, h:%d)", rect.x, | ||
| 147 | rect.y, rect.width, rect.height); | ||
| 148 | } | ||
| 149 | |||
| 150 | static void uiPrintRec(uiPtr ptr, PrintState* state) { | ||
| 151 | if (uiIsNullptr(ptr)) { | ||
| 152 | return; | ||
| 153 | } | ||
| 154 | RectToString(ptr.widget->rect, &state->rect); | ||
| 155 | switch (ptr.type) { | ||
| 156 | case uiTypeButton: { | ||
| 157 | const uiButton* button = uiGetButtonPtr(ptr); | ||
| 158 | printf( | ||
| 159 | "%sbutton{rect=%s, text=\"%s\"}\n", mstring_cstr(&state->pad), | ||
| 160 | mstring_cstr(&state->rect), string_cstr(&button->text)); | ||
| 161 | break; | ||
| 162 | } | ||
| 163 | case uiTypeLabel: { | ||
| 164 | const uiLabel* label = uiGetLabelPtr(ptr); | ||
| 165 | printf( | ||
| 166 | "%sbutton{rect=%s, text=\"%s\"}\n", mstring_cstr(&state->pad), | ||
| 167 | mstring_cstr(&state->rect), string_cstr(&label->text)); | ||
| 168 | break; | ||
| 169 | } | ||
| 170 | case uiTypeLayout: { | ||
| 171 | const uiLayout* layout = uiGetLayoutPtr(ptr); | ||
| 172 | const char* direction = ""; | ||
| 173 | switch (layout->direction) { | ||
| 174 | case uiHorizontal: | ||
| 175 | direction = "horizontal"; | ||
| 176 | break; | ||
| 177 | case uiVertical: | ||
| 178 | direction = "vertical"; | ||
| 179 | break; | ||
| 180 | } | ||
| 181 | printf( | ||
| 182 | "%s%s_layout{rect=%s}\n", mstring_cstr(&state->pad), direction, | ||
| 183 | mstring_cstr(&state->rect)); | ||
| 184 | break; | ||
| 185 | } | ||
| 186 | case uiTypeFrame: { | ||
| 187 | printf( | ||
| 188 | "%sframe{rect=%s}\n", mstring_cstr(&state->pad), | ||
| 189 | mstring_cstr(&state->rect)); | ||
| 190 | break; | ||
| 191 | } | ||
| 192 | case uiTypeTable: { | ||
| 193 | const uiTable* table = uiGetTablePtr(ptr); | ||
| 194 | printf( | ||
| 195 | "%stable{rect=%s}\n", mstring_cstr(&state->pad), | ||
| 196 | mstring_cstr(&state->rect)); | ||
| 197 | break; | ||
| 198 | } | ||
| 199 | default: | ||
| 200 | printf("%swidget\n", mstring_cstr(&state->pad)); | ||
| 201 | break; | ||
| 202 | } | ||
| 203 | const mstring pad = state->pad; | ||
| 204 | state->pad = mstring_concat(state->pad, mstring_make(" ")); | ||
| 205 | list_foreach(ptr.widget->children, child, { | ||
| 206 | uiPrintRec(uiMakeWidgetPtr(child), state); | ||
| 207 | }); | ||
| 208 | state->pad = pad; | ||
| 209 | } | ||
| 210 | |||
| 211 | void uiPrint(uiPtr ptr) { | ||
| 212 | PrintState state = | ||
| 213 | (PrintState){.pad = mstring_make_empty(), .rect = mstring_make_empty()}; | ||
| 214 | uiPrintRec(ptr, &state); | ||
| 215 | } | ||
