Fri, 12 Dec 2025 11:38:47 +0100
add box/grid containers (Server)
| application/main.c | file | annotate | diff | comparison | revisions | |
| ui/server/args.h | file | annotate | diff | comparison | revisions | |
| ui/server/container.c | file | annotate | diff | comparison | revisions | |
| ui/server/container.h | file | annotate | diff | comparison | revisions | |
| ui/server/toolkit.h | file | annotate | diff | comparison | revisions | |
| ui/server/window.c | file | annotate | diff | comparison | revisions |
--- a/application/main.c Thu Dec 11 21:05:40 2025 +0100 +++ b/application/main.c Fri Dec 12 11:38:47 2025 +0100 @@ -1292,7 +1292,14 @@ void application_startup(UiEvent *event, void *userdata) { UiObject *obj = ui_window("Test"); - ui_button(obj, .label = "Button"); + ui_vbox(obj, .margin = 10, .spacing = 10) { + ui_button(obj, .label = "Test"); + ui_hbox(obj, .spacing = 10) { + ui_button(obj, .label = "Test 1"); + ui_button(obj, .label = "Test 2"); + ui_button(obj, .label = "Test 3"); + } + } ui_show(obj); }
--- a/ui/server/args.h Thu Dec 11 21:05:40 2025 +0100 +++ b/ui/server/args.h Fri Dec 12 11:38:47 2025 +0100 @@ -61,6 +61,10 @@ if(args->icon) ui_argstr_add_str(buf, "icon", args->icon); \ if(args->tooltip) ui_argstr_add_str(buf, "tooltip", args->tooltip) +#define UI_SPACING_ARGS(buf, args) \ + if(args->spacing != 0) ui_argstr_add_int(buf, "spacing", args->spacing); \ + if(args->columnspacing != 0) ui_argstr_add_int(buf, "columnspacing", args->columnspacing); \ + if(args->rowspacing != 0) ui_argstr_add_int(buf, "rowspacing", args->rowspacing) #ifdef __cplusplus }
--- a/ui/server/container.c Thu Dec 11 21:05:40 2025 +0100 +++ b/ui/server/container.c Fri Dec 12 11:38:47 2025 +0100 @@ -26,10 +26,114 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <cx/linked_list.h> +#include <cx/buffer.h> + #include "container.h" +#include "args.h" + +void ui_container_begin_close(UiObject *obj) { + UiContainerX *ct = obj->container_end; + ct->close = 1; +} + +int ui_container_finish(UiObject *obj) { + UiContainerX *ct = obj->container_end; + if(ct->close) { + ui_end_new(obj); + return 0; + } + return 1; +} UiContainerX* ui_widget_container(UiWidget *w) { UiContainerX *container = cxZalloc(w->obj->ctx->allocator, sizeof(UiContainerX)); container->container = w; return container; } + +cxmutstr ui_container_args_to_string(UiContext *ctx, UiContainerArgs *args) { + CxBuffer buf; + cxBufferInit(&buf, NULL, 256, ctx->allocator, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_FREE_CONTENTS); + + cxBufferPutString(&buf, "{"); + + UI_STANDARD_ARGS(&buf, args); + UI_SPACING_ARGS(&buf, args); + if(args->def_hfill) cxBufferPutString(&buf, "\"def_hfill\":true,"); + if(args->def_vfill) cxBufferPutString(&buf, "\"def_vfill\":true,"); + if(args->def_hexpand) cxBufferPutString(&buf, "\"def_hexpand\":true,"); + if(args->def_vexpand) cxBufferPutString(&buf, "\"def_vexpand\":true,"); + + if(buf.size > 0 && buf.space[buf.size-1] == ',') { + buf.space[buf.size-1] = ' '; + } + cxBufferPutString(&buf, "}"); + return cx_mutstrn(buf.space, buf.size); +} + +static UIWIDGET container_create(UiObject *obj, const char *type, UiContainerArgs *args) { + const CxAllocator *a = obj->ctx->allocator; + UiWidget *widget = cxZalloc(a, sizeof(UiWidget)); + widget->obj = obj->widget->obj; + widget->type = cx_str(type); + widget->args = ui_container_args_to_string(obj->ctx, args); + widget->children = cxLinkedListCreate(a, NULL, CX_STORE_POINTERS); + widget->serialize = ui_container_serialize; + uic_object_push_container(obj, ui_widget_container(widget)); + ui_reg_widget((UiWidget*)widget); + + UiWidget *parent = obj->container_end->container; + cxListAdd(parent->children, widget); + + return widget; +} + +void ui_serialize_children(UiWidget *w, CxBuffer *buf) { + size_t numchildren = cxListSize(w->children); + if(numchildren > 0) { + cxBufferPutString(buf, ",\"children\":["); + CxIterator i = cxListIterator(w->children); + cx_foreach(UiWidget *, child, i) { + cxmutstr child_str = child->serialize(child); + cxBufferWrite(child_str.ptr, 1, child_str.length, buf); + if(i.index+1 < numchildren) { + cxBufferPut(buf, ','); + } + } + cxBufferPutString(buf, "]"); + } +} + +cxmutstr ui_container_serialize(UiWidget *w) { + CxBuffer buf; + cxBufferInit(&buf, NULL, 1024, NULL, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_FREE_CONTENTS); + + cxBufferPutString(&buf, "{\"type\":\""); + cxBufferPutString(&buf, w->type.ptr); + cxBufferPutString(&buf, "\",\"args\":\""); + cxBufferPutString(&buf, w->args.ptr); + cxBufferPutString(&buf, "\",\"obj\":"); + cxBufferPutString(&buf, w->obj->id.ptr); + cxBufferPutString(&buf, "\",\"id\":"); + cxBufferPutString(&buf, w->id.ptr); + cxBufferPutString(&buf, "\""); + + ui_serialize_children(w, &buf); + + cxBufferPutString(&buf, "}\n"); + + return cx_mutstrn(buf.space, buf.size); +} + +UIWIDGET ui_vbox_create(UiObject *obj, UiContainerArgs *args) { + return container_create(obj, "vbox", args); +} + +UIWIDGET ui_hbox_create(UiObject *obj, UiContainerArgs *args) { + return container_create(obj, "hbox", args); +} + +UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) { + return container_create(obj, "grid", args); +}
--- a/ui/server/container.h Thu Dec 11 21:05:40 2025 +0100 +++ b/ui/server/container.h Fri Dec 12 11:38:47 2025 +0100 @@ -32,12 +32,20 @@ #include "toolkit.h" #include "../common/container.h" +#include <cx/buffer.h> + #ifdef __cplusplus extern "C" { #endif UiContainerX* ui_widget_container(UiWidget *w); +cxmutstr ui_container_args_to_string(UiContext *ctx, UiContainerArgs *args); + +void ui_serialize_children(UiWidget *w, CxBuffer *buf); + +cxmutstr ui_container_serialize(UiWidget *w); + #ifdef __cplusplus } #endif
--- a/ui/server/toolkit.h Thu Dec 11 21:05:40 2025 +0100 +++ b/ui/server/toolkit.h Fri Dec 12 11:38:47 2025 +0100 @@ -72,6 +72,7 @@ struct UiWidget { UiSrvObj *obj; cxmutstr id; + cxstring type; UiVar *var; cxmutstr var_id; UiVarType var_type;
--- a/ui/server/window.c Thu Dec 11 21:05:40 2025 +0100 +++ b/ui/server/window.c Fri Dec 12 11:38:47 2025 +0100 @@ -97,19 +97,7 @@ cxBufferPutString(&buf, "\""); } - size_t numchildren = cxListSize(w->widget.children); - if(numchildren > 0) { - cxBufferPutString(&buf, ",\"children\":["); - CxIterator i = cxListIterator(w->widget.children); - cx_foreach(UiWidget *, child, i) { - cxmutstr child_str = child->serialize(child); - cxBufferWrite(child_str.ptr, 1, child_str.length, &buf); - if(i.index+1 < numchildren) { - cxBufferPut(&buf, ','); - } - } - cxBufferPutString(&buf, "]"); - } + ui_serialize_children(&w->widget, &buf); cxBufferPutString(&buf, "}\n");