Sun, 05 Oct 2025 18:13:15 +0200
refactor gtk container hierarchy
--- a/ui/common/object.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/common/object.c Sun Oct 05 18:13:15 2025 +0200 @@ -100,6 +100,13 @@ ui_free(obj->ctx, rm); } +void ui_newline(UiObject *obj) { + UiContainerX *container = obj->container_end; + if(container) { + container->newline = TRUE; + } +} + void ui_object_ref(UiObject *obj) { obj->ref++; } @@ -141,10 +148,6 @@ return obj; } -UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget) { - return uic_ctx_object_new(toplevel->ctx, widget); -} - UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget) { UiObject *newobj = cxCalloc(ctx->allocator, 1, sizeof(UiObject)); newobj->ctx = ctx; @@ -153,26 +156,6 @@ return newobj; } -void uic_obj_add(UiObject *toplevel, UiObject *ctobj) { - UiObject *current = uic_current_obj(toplevel); - current->next = ctobj; -} - -UiObject* uic_current_obj(UiObject *toplevel) { - if(!toplevel) { - return NULL; - } - UiObject *obj = toplevel; - while(obj->next) { - obj = obj->next; - } - return obj; -} - -UiContainer* uic_get_current_container(UiObject *obj) { - return uic_current_obj(obj)->container; -} - void uic_object_push_container(UiObject *toplevel, UiContainerX *newcontainer) { newcontainer->prev = toplevel->container_end; if(toplevel->container_end) {
--- a/ui/common/object.h Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/common/object.h Sun Oct 05 18:13:15 2025 +0200 @@ -48,10 +48,6 @@ UiObject* uic_object_new_toplevel(void); UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget); UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget); -void uic_obj_add(UiObject *toplevel, UiObject *ctobj); -UiObject* uic_current_obj(UiObject *toplevel); - -UiContainer* uic_get_current_container(UiObject *obj); // deprecated void uic_object_push_container(UiObject *toplevel, UiContainerX *newcontainer); void uic_object_pop_container(UiObject *toplevel);
--- a/ui/gtk/button.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/button.c Sun Oct 05 18:13:15 2025 +0200 @@ -100,12 +100,12 @@ } UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs *args) { - UiObject* current = uic_current_obj(obj); GtkWidget *button = ui_create_button(obj, args->label, args->icon, args->onclick, args->onclickdata, 0, FALSE); ui_set_name_and_style(button, args->name, args->style_class); ui_set_widget_groups(obj->ctx, button, args->groups); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, button); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, button, &layout); return button; } @@ -220,8 +220,7 @@ void (*enable_state_func)(void*, void*), int enable_state) { - UiObject* current = uic_current_obj(obj); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, value, varname, UI_VAR_INTEGER); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname, UI_VAR_INTEGER); if (var) { UiInteger* value = (UiInteger*)var->value; value->obj = widget; @@ -291,8 +290,6 @@ } static UIWIDGET togglebutton_create(UiObject *obj, GtkWidget *widget, UiToggleArgs *args) { - UiObject* current = uic_current_obj(obj); - ui_setup_togglebutton( obj, widget, @@ -306,8 +303,9 @@ ui_set_name_and_style(widget, args->name, args->style_class); ui_set_widget_groups(obj->ctx, widget, args->groups); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); return widget; } @@ -350,9 +348,7 @@ } } -UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs *args) { - UiObject* current = uic_current_obj(obj); - +UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs *args) { GtkWidget *widget = gtk_check_button_new_with_label(args->label); ui_bind_togglebutton( obj, @@ -370,8 +366,9 @@ ui_set_name_and_style(widget, args->name, args->style_class); ui_set_widget_groups(obj->ctx, widget, args->groups); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); return widget; } @@ -411,12 +408,11 @@ } UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs *args) { - UiObject* current = uic_current_obj(obj); GtkWidget *widget = gtk_switch_new(); ui_set_name_and_style(widget, args->name, args->style_class); ui_set_widget_groups(obj->ctx, widget, args->groups); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER); if(var) { UiInteger *value = var->value; value->obj = widget; @@ -449,8 +445,9 @@ G_CALLBACK(ui_destroy_vardata), event); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); return widget; } @@ -519,12 +516,10 @@ } UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args) { - UiObject* current = uic_current_obj(obj); - GSList *rg = NULL; UiInteger *rgroup; - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER); UiBool first = FALSE; if(var) { @@ -600,8 +595,9 @@ event); } - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, rbutton); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, rbutton, &layout); return rbutton; } @@ -860,8 +856,7 @@ data->widget = button; - UiObject* current = uic_current_obj(obj); - UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING); + UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_STRING); if(var) { UiString *str = var->value; char *current_value = ui_get(str); @@ -876,8 +871,9 @@ ui_set_name_and_style(button, args->name, args->style_class); ui_set_widget_groups(obj->ctx, button, args->groups); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, button); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, button, &layout); return button; }
--- a/ui/gtk/container.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/container.c Sun Oct 05 18:13:15 2025 +0200 @@ -42,14 +42,14 @@ void ui_container_begin_close(UiObject *obj) { - UiContainer *ct = uic_get_current_container(obj); + UiContainerX *ct = obj->container_end; ct->close = 1; } int ui_container_finish(UiObject *obj) { - UiContainer *ct = uic_get_current_container(obj); + UiContainerX *ct = obj->container_end; if(ct->close) { - ui_end(obj); + ui_end_new(obj); return 0; } return 1; @@ -71,9 +71,10 @@ #endif } +// TODO: refactoring GtkWidget* ui_subcontainer_create( UiSubContainerType type, - UiObject *newobj, + UiObject *obj, int spacing, int columnspacing, int rowspacing, @@ -81,38 +82,39 @@ { GtkWidget *sub = NULL; GtkWidget *add = NULL; + UiContainerX *container = NULL; switch(type) { default: { sub = ui_gtk_vbox_new(spacing); add = ui_box_set_margin(sub, margin); - newobj->container = ui_box_container(newobj, sub, type); - newobj->widget = sub; + container = ui_box_container(obj, sub, type); break; } case UI_CONTAINER_HBOX: { sub = ui_gtk_hbox_new(spacing); add = ui_box_set_margin(sub, margin); - newobj->container = ui_box_container(newobj, sub, type); - newobj->widget = sub; + container = ui_box_container(obj, sub, type); break; } case UI_CONTAINER_GRID: { sub = ui_create_grid_widget(columnspacing, rowspacing); add = ui_box_set_margin(sub, margin); - newobj->container = ui_grid_container(newobj, sub, FALSE, FALSE, FALSE, FALSE); - newobj->widget = sub; + container = ui_grid_container(obj, sub, FALSE, FALSE, FALSE, FALSE); break; } case UI_CONTAINER_NO_SUB: { break; } } + if(container) { + uic_object_push_container(obj, container); + } return add; } /* -------------------- Box Container -------------------- */ -UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) { +UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) { UiBoxContainer *ct = cxCalloc( obj->ctx->allocator, 1, @@ -120,12 +122,12 @@ ct->container.widget = box; ct->container.add = ui_box_container_add; ct->type = type; - return (UiContainer*)ct; + return (UiContainerX*)ct; } -void ui_box_container_add(UiContainer *ct, GtkWidget *widget) { +void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { UiBoxContainer *bc = (UiBoxContainer*)ct; - UiBool fill = ct->layout.fill; + UiBool fill = layout->fill; if(bc->has_fill && fill) { fprintf(stderr, "UiError: container has 2 filled widgets"); fill = FALSE; @@ -152,11 +154,10 @@ gtk_box_pack_start(GTK_BOX(ct->widget), widget, expand, fill, 0); #endif - ui_reset_layout(ct->layout); ct->current = widget; } -UiContainer* ui_grid_container( +UiContainerX* ui_grid_container( UiObject *obj, GtkWidget *grid, UiBool def_hexpand, @@ -176,142 +177,105 @@ ct->container.add = ui_grid_container_add; UI_GTK_V2(ct->width = 0); UI_GTK_V2(ct->height = 1); - return (UiContainer*)ct; + return (UiContainerX*)ct; +} + +/* + * TODO: move to common + * prepares the layout horizontal and vertical fill/expand settings + * based on fill and defaults + */ +static void layout_setup_expand_fill( + UiLayout *layout, + UiBool def_hexpand, + UiBool def_vexpand, + UiBool def_hfill, + UiBool def_vfill) +{ + if(layout->fill) { + layout->hfill = TRUE; + layout->vfill = TRUE; + layout->hexpand = TRUE; + layout->vexpand = TRUE; + return; + } + + if(!layout->override_defaults) { + if(def_hexpand) { + layout->hexpand = TRUE; + } + if(def_hfill) { + layout->hfill = TRUE; + } + if(def_vexpand) { + layout->vexpand = TRUE; + } + if(def_vfill) { + layout->vfill = TRUE; + } + } } #if GTK_MAJOR_VERSION >= 3 -void ui_grid_container_add(UiContainer *ct, GtkWidget *widget) { +void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { UiGridContainer *grid = (UiGridContainer*)ct; - if(ct->layout.newline) { + if(ct->container.newline) { grid->x = 0; grid->y++; - ct->layout.newline = FALSE; + ct->container.newline = FALSE; } - int hexpand = FALSE; - int vexpand = FALSE; - int hfill = FALSE; - int vfill = FALSE; - if(!ct->layout.override_defaults) { - if(grid->def_hexpand) { - hexpand = TRUE; - } - if(grid->def_hfill) { - hfill = TRUE; - } - if(grid->def_vexpand) { - vexpand = TRUE; - } - if(grid->def_vfill) { - vfill = TRUE; - } - } + layout_setup_expand_fill(layout, grid->def_hexpand, grid->def_vexpand, grid->def_hfill, grid->def_vfill); - UiBool fill = ct->layout.fill; - if(ct->layout.hexpand) { - hexpand = TRUE; - } - if(ct->layout.hfill) { - hfill = TRUE; - } - if(ct->layout.vexpand) { - vexpand = TRUE; - } - if(ct->layout.vfill) { - vfill = TRUE; - } - if(fill) { - hfill = TRUE; - vfill = TRUE; - hexpand = TRUE; - vexpand = TRUE; - } - - if(!hfill) { + if(!layout->hfill) { gtk_widget_set_halign(widget, GTK_ALIGN_START); } - if(!vfill) { + if(!layout->vfill) { gtk_widget_set_valign(widget, GTK_ALIGN_START); } - gtk_widget_set_hexpand(widget, hexpand); - gtk_widget_set_vexpand(widget, vexpand); + gtk_widget_set_hexpand(widget, layout->hexpand); + gtk_widget_set_vexpand(widget, layout->vexpand); - int colspan = ct->layout.colspan > 0 ? ct->layout.colspan : 1; - int rowspan = ct->layout.rowspan > 0 ? ct->layout.rowspan : 1; + int colspan = layout->colspan > 0 ? layout->colspan : 1; + int rowspan = layout->rowspan > 0 ? layout->rowspan : 1; gtk_grid_attach(GTK_GRID(ct->widget), widget, grid->x, grid->y, colspan, rowspan); grid->x += colspan; - ui_reset_layout(ct->layout); - ct->current = widget; + grid->container.current = widget; } #endif #ifdef UI_GTK2 -void ui_grid_container_add(UiContainer *ct, GtkWidget *widget) { +void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget) { UiGridContainer *grid = (UiGridContainer*)ct; - if(ct->layout.newline) { + if(ct->container.newline) { grid->x = 0; grid->y++; - ct->layout.newline = FALSE; + ct->container.newline = FALSE; } - int hexpand = FALSE; - int vexpand = FALSE; - int hfill = FALSE; - int vfill = FALSE; - if(!ct->layout.override_defaults) { - if(grid->def_hexpand) { - hexpand = TRUE; - hfill = TRUE; - } else if(grid->def_hfill) { - hfill = TRUE; - } - if(grid->def_vexpand) { - vexpand = TRUE; - vfill = TRUE; - } else if(grid->def_vfill) { - vfill = TRUE; - } - } - - UiBool fill = ct->layout.fill; - if(ct->layout.hexpand) { - hexpand = TRUE; - hfill = TRUE; - } else if(ct->layout.hfill) { - hfill = TRUE; - } - if(ct->layout.vexpand) { - vexpand = TRUE; - vfill = TRUE; - } else if(ct->layout.vfill) { - vfill = TRUE; - } - if(fill) { - hfill = TRUE; - vfill = TRUE; - } + layout_setup_expand_fill(layout, grid->def_hexpand, grid->def_vexpand, grid->def_hfill, grid->def_vfill); GtkAttachOptions xoptions = 0; GtkAttachOptions yoptions = 0; - if(hexpand) { + if(layout->hexpand) { xoptions = GTK_EXPAND; } - if(hfill) { + if(layout->hfill) { xoptions |= GTK_FILL; } - if(vexpand) { + if(layout->vexpand) { yoptions = GTK_EXPAND; } - if(vfill) { + if(layout->vfill) { yoptions |= GTK_FILL; } - int colspan = ct->layout.colspan > 0 ? ct->layout.colspan : 1; - int rowspan = ct->layout.rowspan > 0 ? ct->layout.rowspan : 1; + int colspan = layout->colspan > 0 ? layout->colspan : 1; + int rowspan = layout->rowspan > 0 ? layout->rowspan : 1; // TODO: use colspan/rowspan gtk_table_attach(GTK_TABLE(ct->widget), widget, grid->x, grid->x+1, grid->y, grid->y+1, xoptions, yoptions, 0, 0); @@ -323,75 +287,74 @@ gtk_table_resize(GTK_TABLE(ct->widget), grid->width, grid->height); } - ui_reset_layout(ct->layout); ct->current = widget; } #endif -UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame) { - UiContainer *ct = cxCalloc( +UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame) { + UiContainerPrivate *ct = cxCalloc( obj->ctx->allocator, 1, - sizeof(UiContainer)); + sizeof(UiContainerPrivate)); ct->widget = frame; ct->add = ui_frame_container_add; - return ct; -} - -void ui_frame_container_add(UiContainer *ct, GtkWidget *widget) { - FRAME_SET_CHILD(ct->widget, widget); + return (UiContainerX*)ct; } -UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander) { - UiContainer *ct = cxCalloc( - obj->ctx->allocator, - 1, - sizeof(UiContainer)); - ct->widget = expander; - ct->add = ui_expander_container_add; - return ct; -} - -void ui_expander_container_add(UiContainer *ct, GtkWidget *widget) { - EXPANDER_SET_CHILD(ct->widget, widget); -} - -void ui_scrolledwindow_container_add(UiContainer *ct, GtkWidget *widget) { - // TODO: check if the widget implements GtkScrollable - SCROLLEDWINDOW_SET_CHILD(ct->widget, widget); - ui_reset_layout(ct->layout); +void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { + FRAME_SET_CHILD(ct->widget, widget); ct->current = widget; } -UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) { - UiContainer *ct = cxCalloc( +UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander) { + UiContainerPrivate *ct = cxCalloc( obj->ctx->allocator, 1, - sizeof(UiContainer)); + sizeof(UiContainerPrivate)); + ct->widget = expander; + ct->add = ui_expander_container_add; + return (UiContainerX*)ct; +} + +void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { + EXPANDER_SET_CHILD(ct->widget, widget); + ct->current = widget; +} + +void ui_scrolledwindow_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { + // TODO: check if the widget implements GtkScrollable + SCROLLEDWINDOW_SET_CHILD(ct->widget, widget); + ct->current = widget; +} + +UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) { + UiContainerPrivate *ct = cxCalloc( + obj->ctx->allocator, + 1, + sizeof(UiContainerPrivate)); ct->widget = scrolledwindow; ct->add = ui_scrolledwindow_container_add; - return ct; + return (UiContainerX*)ct; } -UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview) { +UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview) { UiTabViewContainer *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiTabViewContainer)); ct->container.widget = tabview; ct->container.add = ui_tabview_container_add; - return (UiContainer*)ct; + return (UiContainerX*)ct; } -void ui_tabview_container_add(UiContainer *ct, GtkWidget *widget) { +void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { UiGtkTabView *data = ui_widget_get_tabview_data(ct->widget); if(!data) { fprintf(stderr, "UI Error: widget is not a tabview"); return; } - data->add_tab(ct->widget, -1, ct->layout.label, widget); + data->add_tab(ct->widget, -1, layout->label, widget); - ui_reset_layout(ct->layout); ct->current = widget; } @@ -419,18 +382,16 @@ } UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type) { - UiObject *current = uic_current_obj(obj); - UiContainer *ct = current->container; - UI_APPLY_LAYOUT2(current, args); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); GtkWidget *box = type == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args->spacing) : ui_gtk_hbox_new(args->spacing); ui_set_name_and_style(box, args->name, args->style_class); - GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box; - ct->add(ct, widget); + GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box; // TODO: remove, margin will be handled by container add-functions + ct->add(ct, widget, &layout); - UiObject *newobj = uic_object_new(obj, box); - newobj->container = ui_box_container(obj, box, type); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_box_container(obj, box, type); + uic_object_push_container(obj, container); return widget; } @@ -457,81 +418,59 @@ } UIWIDGET ui_grid_create(UiObject *obj, UiContainerArgs *args) { - UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT2(current, args); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); GtkWidget *widget; GtkWidget *grid = ui_create_grid_widget(args->columnspacing, args->rowspacing); ui_set_name_and_style(grid, args->name, args->style_class); widget = ui_box_set_margin(grid, args->margin); - current->container->add(current->container, widget); + ct->add(ct, widget, &layout); - UiObject *newobj = uic_object_new(obj, grid); - newobj->container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill); + uic_object_push_container(obj, container); return widget; } UIWIDGET ui_frame_create(UiObject *obj, UiFrameArgs *args) { - UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT2(current, args); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); GtkWidget *frame = gtk_frame_new(args->label); - UiObject *newobj = uic_object_new(obj, frame); - GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin); - if(sub) { - FRAME_SET_CHILD(frame, sub); - } else { - newobj->widget = frame; - newobj->container = ui_frame_container(obj, frame); - } - current->container->add(current->container, frame); - uic_obj_add(obj, newobj); + ct->add(ct, frame, &layout); + + UiContainerX *container = ui_frame_container(obj, frame); + uic_object_push_container(obj, container); return frame; } UIEXPORT UIWIDGET ui_expander_create(UiObject *obj, UiFrameArgs *args) { - UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT2(current, args); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); GtkWidget *expander = gtk_expander_new(args->label); gtk_expander_set_expanded(GTK_EXPANDER(expander), args->isexpanded); - UiObject *newobj = uic_object_new(obj, expander); - GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin); - if(sub) { - EXPANDER_SET_CHILD(expander, sub); - } else { - newobj->widget = expander; - newobj->container = ui_expander_container(obj, expander); - } - current->container->add(current->container, expander); - uic_obj_add(obj, newobj); + ct->add(ct, expander, &layout); + + UiContainerX *container = ui_expander_container(obj, expander); + uic_object_push_container(obj, container); return expander; } UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) { - UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT2(current, args); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); GtkWidget *sw = SCROLLEDWINDOW_NEW(); ui_set_name_and_style(sw, args->name, args->style_class); - GtkWidget *widget = ui_box_set_margin(sw, args->margin); - current->container->add(current->container, widget); + ct->add(ct, sw, &layout); - UiObject *newobj = uic_object_new(obj, sw); - GtkWidget *sub = ui_subcontainer_create(args->subcontainer, newobj, args->spacing, args->columnspacing, args->rowspacing, args->margin); - if(sub) { - SCROLLEDWINDOW_SET_CHILD(sw, sub); - } else { - newobj->widget = sw; - newobj->container = ui_scrolledwindow_container(obj, sw); - } - - uic_obj_add(obj, newobj); + UiContainerX *container = ui_scrolledwindow_container(obj, sw); + uic_object_push_container(obj, container); return sw; } @@ -741,7 +680,7 @@ UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) { UiGtkTabView *data = malloc(sizeof(UiGtkTabView)); memset(data, 0, sizeof(UiGtkTabView)); - data->margin = args->margin; + data->padding = args->padding; data->spacing = args->spacing; data->columnspacing = args->columnspacing; data->rowspacing = args->rowspacing; @@ -801,9 +740,8 @@ } } - UiObject* current = uic_current_obj(obj); if(args->value || args->varname) { - UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER); + UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER); UiInteger *i = var->value; i->get = getfunc; i->set = setfunc; @@ -812,29 +750,56 @@ g_object_set_data(G_OBJECT(widget), "ui_tabview", data); data->widget = data_widget; - data->subcontainer = args->subcontainer; - - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, widget); - UiObject *newobj = uic_object_new(obj, widget); - newobj->container = ui_tabview_container(obj, widget); - uic_obj_add(obj, newobj); - data->obj = newobj; + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); + + UiContainerX *container = ui_tabview_container(obj, widget); + uic_object_push_container(obj, container); return widget; } +static GtkWidget* create_tab(UiObject *obj, UiGtkTabView *tabview, const char *title, int tab) { + UiContainerX *container; + GtkWidget *sub; + switch(tabview->subcontainer) { + default: { + sub = ui_gtk_vbox_new(tabview->spacing); + container = ui_box_container(obj, sub, tabview->subcontainer); + break; + } + case UI_CONTAINER_HBOX: { + sub = ui_gtk_hbox_new(tabview->spacing); + container = ui_box_container(obj, sub, tabview->subcontainer); + break; + } + case UI_CONTAINER_GRID: { + sub = ui_create_grid_widget(tabview->columnspacing, tabview->rowspacing); + container = ui_grid_container(obj, sub, FALSE, FALSE, FALSE, FALSE); + break; + } + } + + uic_object_push_container(obj, container); + + GtkWidget *widget = ui_box_set_margin(sub, tabview->padding); + tabview->add_tab(tabview->widget, tab, title, widget); + + return sub; +} + void ui_tab_create(UiObject* obj, const char* title) { - UiObject* current = uic_current_obj(obj); - UiGtkTabView *data = ui_widget_get_tabview_data(current->widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + GtkWidget *tabview = ct->widget; + UiGtkTabView *data = ui_widget_get_tabview_data(tabview); if(!data) { fprintf(stderr, "UI Error: widget is not a tabview\n"); return; } - UiObject *newobj = ui_tabview_add(current->widget, title, -1); - current->next = newobj; + create_tab(obj, data, title, -1); } @@ -864,31 +829,8 @@ return NULL; } - UiObject *newobj = cxCalloc(data->obj->ctx->allocator, 1, sizeof(UiObject)); - newobj->ctx = data->obj->ctx; - - GtkWidget *sub; - switch(data->subcontainer) { - default: { - sub = ui_gtk_vbox_new(data->spacing); - newobj->container = ui_box_container(newobj, sub, data->subcontainer); - break; - } - case UI_CONTAINER_HBOX: { - sub = ui_gtk_hbox_new(data->spacing); - newobj->container = ui_box_container(newobj, sub, data->subcontainer); - break; - } - case UI_CONTAINER_GRID: { - sub = ui_create_grid_widget(data->columnspacing, data->rowspacing); - newobj->container = ui_grid_container(newobj, sub, FALSE, FALSE, FALSE, FALSE); - break; - } - } - newobj->widget = sub; - GtkWidget *widget = ui_box_set_margin(sub, data->margin); - - data->add_tab(data->widget, tab_index, name, widget); + UiObject *newobj = uic_object_new_toplevel(); + newobj->widget = create_tab(newobj, data, name, tab_index); return newobj; } @@ -897,20 +839,16 @@ /* -------------------- Headerbar -------------------- */ static void hb_set_part(UiObject *obj, int part) { - UiObject* current = uic_current_obj(obj); - GtkWidget *headerbar = current->widget; + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + GtkWidget *headerbar = ct->widget; UiHeaderbarContainer *hb = cxCalloc( obj->ctx->allocator, 1, sizeof(UiHeaderbarContainer)); - memcpy(hb, current->container, sizeof(UiHeaderbarContainer)); - - UiObject *newobj = uic_object_new(obj, headerbar); - newobj->container = (UiContainer*)hb; - uic_obj_add(obj, newobj); - + memcpy(hb, ct, sizeof(UiHeaderbarContainer)); hb->part = part; + uic_object_push_container(obj, (UiContainerX*)hb); } void ui_headerbar_start_create(UiObject *obj) { @@ -926,74 +864,70 @@ } UIWIDGET ui_headerbar_fallback_create(UiObject *obj, UiHeaderbarArgs *args) { - UiObject *current = uic_current_obj(obj); - UiContainer *ct = current->container; - UI_APPLY_LAYOUT2(current, args); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); GtkWidget *box = ui_gtk_hbox_new(args->alt_spacing); ui_set_name_and_style(box, args->name, args->style_class); - ct->add(ct, box); + ct->add(ct, box, &layout); - UiObject *newobj = uic_object_new(obj, box); - newobj->container = ui_headerbar_fallback_container(obj, box); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_headerbar_fallback_container(obj, box); + uic_object_push_container(obj, container); return box; } static void hb_fallback_set_part(UiObject *obj, int part) { - UiObject* current = uic_current_obj(obj); - GtkWidget *headerbar = current->widget; + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + GtkWidget *headerbar = ct->widget; - UiObject *newobj = uic_object_new(obj, headerbar); - newobj->container = ui_headerbar_container(obj, headerbar); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_headerbar_container(obj, headerbar); + uic_object_push_container(obj, container); - UiHeaderbarContainer *hb = (UiHeaderbarContainer*)newobj->container; + UiHeaderbarContainer *hb = (UiHeaderbarContainer*)container; hb->part = part; } -UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) { +UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) { UiHeaderbarContainer *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiHeaderbarContainer)); ct->container.widget = headerbar; ct->container.add = ui_headerbar_fallback_container_add; - return (UiContainer*)ct; + return (UiContainerX*)ct; } -void ui_headerbar_fallback_container_add(UiContainer *ct, GtkWidget *widget) { +void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { UiHeaderbarContainer *hb = (UiHeaderbarContainer*)ct; BOX_ADD(ct->widget, widget); } #if GTK_CHECK_VERSION(3, 10, 0) -UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) { +UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) { GtkWidget *headerbar = g_object_get_data(G_OBJECT(obj->widget), "ui_headerbar"); if(!headerbar) { return ui_headerbar_fallback_create(obj, args); } - UiObject *newobj = uic_object_new(obj, headerbar); - newobj->container = ui_headerbar_container(obj, headerbar); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_headerbar_container(obj, headerbar); + uic_object_push_container(obj, container); return headerbar; } -UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) { +UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) { UiHeaderbarContainer *ct = cxCalloc( obj->ctx->allocator, 1, sizeof(UiHeaderbarContainer)); ct->container.widget = headerbar; ct->container.add = ui_headerbar_container_add; - return (UiContainer*)ct; + return (UiContainerX*)ct; } -void ui_headerbar_container_add(UiContainer *ct, GtkWidget *widget) { +void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { UiHeaderbarContainer *hb = (UiHeaderbarContainer*)ct; if(hb->part == 0) { UI_HEADERBAR_PACK_START(ct->widget, widget); @@ -1031,9 +965,8 @@ ui_box_set_margin(box, args->margin); adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(sidebar_toolbar_view), box); - UiObject *newobj = uic_object_new(obj, box); - newobj->container = ui_box_container(obj, box, UI_CONTAINER_VBOX); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); + uic_object_push_container(obj, container); return box; } @@ -1045,9 +978,8 @@ ui_box_set_margin(box, args->margin); BOX_ADD_EXPAND(sidebar_vbox, box); - UiObject *newobj = uic_object_new(obj, box); - newobj->container = ui_box_container(obj, box, UI_CONTAINER_VBOX); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); + uic_object_push_container(obj, container); return box; } @@ -1066,9 +998,8 @@ ui_box_set_margin(box, args->margin); BOX_ADD_EXPAND(pbox, box); - UiObject *newobj = uic_object_new(obj, box); - newobj->container = ui_box_container(obj, box, UI_CONTAINER_VBOX); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX); + uic_object_push_container(obj, container); return box; } @@ -1108,12 +1039,11 @@ } static UIWIDGET splitpane_create(UiObject *obj, UiOrientation orientation, UiSplitPaneArgs *args) { - UiObject* current = uic_current_obj(obj); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); GtkWidget *pane0 = create_paned(orientation); - - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, pane0); + ct->add(ct, pane0, &layout); int max = args->max_panes == 0 ? 2 : args->max_panes; @@ -1134,15 +1064,14 @@ strdup(args->position_property)); } - UiObject *newobj = uic_object_new(obj, pane0); - newobj->container = ui_splitpane_container(obj, pane0, orientation, max, args->initial_position); - uic_obj_add(obj, newobj); + UiContainerX *container = ui_splitpane_container(obj, pane0, orientation, max, args->initial_position); + uic_object_push_container(obj, container); - g_object_set_data(G_OBJECT(pane0), "ui_splitpane", newobj->container); + g_object_set_data(G_OBJECT(pane0), "ui_splitpane", container); - UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER); + UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER); if(var) { - UiSplitPaneContainer *s = (UiSplitPaneContainer*)newobj->container; + UiSplitPaneContainer *s = (UiSplitPaneContainer*)container; UiInteger *i = var->value; s->initial_position = i->value; @@ -1162,7 +1091,7 @@ return splitpane_create(obj, UI_VERTICAL, args); } -UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiOrientation orientation, int max, int init) { +UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiOrientation orientation, int max, int init) { UiSplitPaneContainer *ct = ui_calloc(obj->ctx, 1, sizeof(UiSplitPaneContainer)); ct->container.widget = pane; ct->container.add = ui_splitpane_container_add; @@ -1171,10 +1100,10 @@ ct->max = max; ct->initial_position = init; ct->children = cxArrayListCreateSimple(CX_STORE_POINTERS, 4); - return (UiContainer*)ct; + return (UiContainerX*)ct; } -void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget) { +void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) { UiSplitPaneContainer *s = (UiSplitPaneContainer*)ct; if(s->nchildren >= s->max) { @@ -1279,13 +1208,12 @@ UiObject *item_obj = cxMapGet(ct->current_items, key); if(item_obj) { // re-add previously created widget - ui_box_container_add(ct->container, item_obj->widget); + UiLayout layout = {0}; + ui_box_container_add(ct->container, item_obj->widget, &layout); } else { // create new widget and object for this list element - CxMempool *mp = cxMempoolCreateSimple(256); - const CxAllocator *a = mp->allocator; - UiObject *obj = cxCalloc(a, 1, sizeof(UiObject)); - obj->ctx = uic_context(obj, mp); + UiObject *obj = uic_object_new_toplevel(); + obj->ctx->parent = ct->parent->ctx; obj->window = NULL; obj->widget = ui_subcontainer_create( ct->subcontainer, @@ -1294,7 +1222,8 @@ ct->columnspacing, ct->rowspacing, ct->margin); - ui_box_container_add(ct->container, obj->widget); + UiLayout layout = {0}; + ui_box_container_add(ct->container, obj->widget, &layout); if(ct->create_ui) { ct->create_ui(obj, index, elm, ct->userdata); } @@ -1316,19 +1245,18 @@ } UIWIDGET ui_itemlist_create(UiObject *obj, UiItemListContainerArgs *args) { - UiObject *current = uic_current_obj(obj); - UiContainer *ct = current->container; - UI_APPLY_LAYOUT2(current, args); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); GtkWidget *box = args->container == UI_CONTAINER_VBOX ? ui_gtk_vbox_new(args->spacing) : ui_gtk_hbox_new(args->spacing); ui_set_name_and_style(box, args->name, args->style_class); GtkWidget *widget = args->margin > 0 ? ui_box_set_margin(box, args->margin) : box; - ct->add(ct, widget); + ct->add(ct, widget, &layout); UiGtkItemListContainer *container = malloc(sizeof(UiGtkItemListContainer)); container->parent = obj; container->widget = box; - container->container = ui_box_container(current, box, args->container); + container->container = (UiContainerPrivate*)ui_box_container(obj, box, args->container); container->create_ui = args->create_ui; container->userdata = args->userdata; container->subcontainer = args->subcontainer; @@ -1341,7 +1269,7 @@ container->rowspacing = args->sub_rowspacing; container->remove_items = TRUE; - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_LIST); if(var) { UiList *list = var->value; list->obj = container; @@ -1358,56 +1286,3 @@ } - -/* - * -------------------- Layout Functions -------------------- - * - * functions for setting layout attributes for the current container - * - */ - -void ui_layout_fill(UiObject *obj, UiBool fill) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.fill = fill; -} - -void ui_layout_hexpand(UiObject *obj, UiBool expand) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.hexpand = expand; -} - -void ui_layout_vexpand(UiObject *obj, UiBool expand) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.vexpand = expand; -} - -void ui_layout_hfill(UiObject *obj, UiBool fill) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.hfill = fill; -} - -void ui_layout_vfill(UiObject *obj, UiBool fill) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.vfill = fill; -} - -UIEXPORT void ui_layout_override_defaults(UiObject *obj, UiBool d) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.override_defaults = d; -} - -void ui_layout_colspan(UiObject* obj, int cols) { - UiContainer* ct = uic_get_current_container(obj); - ct->layout.colspan = cols; -} - -void ui_layout_rowspan(UiObject* obj, int rows) { - UiContainer* ct = uic_get_current_container(obj); - ct->layout.rowspan = rows; -} - -void ui_newline(UiObject *obj) { - UiContainer *ct = uic_get_current_container(obj); - ct->layout.newline = TRUE; -} -
--- a/ui/gtk/container.h Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/container.h Sun Oct 05 18:13:15 2025 +0200 @@ -45,45 +45,30 @@ #define ui_reset_layout(layout) memset(&(layout), 0, sizeof(UiLayout)) -typedef void (*ui_container_add_f)(UiContainer*, GtkWidget*); typedef struct UiDocumentView UiDocumentView; - -typedef struct UiLayout UiLayout; -struct UiLayout { - UiBool fill; - UiBool newline; - char *label; - UiBool hexpand; - UiBool vexpand; - UiBool hfill; - UiBool vfill; - UiBool override_defaults; - int width; - int colspan; - int rowspan; -}; - -struct UiContainer { +typedef struct UiContainerPrivate UiContainerPrivate; +struct UiContainerPrivate { + UiContainerX container; GtkWidget *widget; UIMENU menu; - GtkWidget *current; + GtkWidget *current; // TODO: remove - void (*add)(UiContainer*, GtkWidget*); + void (*add)(UiContainerPrivate*, GtkWidget*, UiLayout *layout); UiLayout layout; int close; }; typedef struct UiBoxContainer { - UiContainer container; + UiContainerPrivate container; UiSubContainerType type; UiBool has_fill; } UiBoxContainer; typedef struct UiGridContainer { - UiContainer container; + UiContainerPrivate container; UiBool def_hexpand; UiBool def_vexpand; UiBool def_hfill; @@ -97,7 +82,7 @@ } UiGridContainer; typedef struct UiTabViewContainer { - UiContainer container; + UiContainerPrivate container; } UiTabViewContainer; typedef void (*ui_select_tab_func)(UIWIDGET widget, int tab); @@ -110,7 +95,7 @@ ui_select_tab_func remove_tab; ui_add_tab_func add_tab; UiSubContainerType subcontainer; - int margin; + int padding; int spacing; int columnspacing; int rowspacing; @@ -120,7 +105,7 @@ typedef struct UiSplitPaneContainer { - UiContainer container; + UiContainerPrivate container; GtkWidget *current_pane; CxList *children; UiOrientation orientation; @@ -131,7 +116,7 @@ } UiSplitPaneContainer; typedef struct UiHeaderbarContainer { - UiContainer container; + UiContainerPrivate container; GtkWidget *centerbox; int part; UiHeaderbarAlternative alternative; /* only used by fallback headerbar */ @@ -140,7 +125,7 @@ typedef struct UiGtkItemListContainer { UiObject *parent; GtkWidget *widget; - UiContainer *container; + UiContainerPrivate *container; void (*create_ui)(UiObject *, int, void *, void *); void *userdata; UiSubContainerType subcontainer; @@ -163,39 +148,36 @@ int rowspacing, int margin); -UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame); -void ui_frame_container_add(UiContainer *ct, GtkWidget *widget); - GtkWidget* ui_box_set_margin(GtkWidget *box, int margin); UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type); -UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type); -void ui_box_container_add(UiContainer *ct, GtkWidget *widget); +UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type); +void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); GtkWidget* ui_create_grid_widget(int colspacing, int rowspacing); -UiContainer* ui_grid_container( +UiContainerX* ui_grid_container( UiObject *obj, GtkWidget *grid, UiBool def_hexpand, UiBool def_vexpand, UiBool def_hfill, UiBool def_vfill); -void ui_grid_container_add(UiContainer *ct, GtkWidget *widget); +void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame); -void ui_frame_container_add(UiContainer *ct, GtkWidget *widget); +UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame); +void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander); -void ui_expander_container_add(UiContainer *ct, GtkWidget *widget); +UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander); +void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow); -void ui_scrolledwindow_container_add(UiContainer *ct, GtkWidget *widget); +UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow); +void ui_scrolledwindow_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview); -void ui_tabview_container_add(UiContainer *ct, GtkWidget *widget); +UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview); +void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); -UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiOrientation orientation, int max, int init); -void ui_splitpane_container_add(UiContainer *ct, GtkWidget *widget); +UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiOrientation orientation, int max, int init); +void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); int64_t ui_splitpane_get(UiInteger *i); void ui_splitpane_set(UiInteger *i, int64_t value); @@ -205,12 +187,12 @@ void ui_gtk_notebook_select_tab(GtkWidget *widget, int tab); #if GTK_CHECK_VERSION(3, 10, 0) -UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar); -void ui_headerbar_container_add(UiContainer *ct, GtkWidget *widget); +UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar); +void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); #endif -UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar); -void ui_headerbar_fallback_container_add(UiContainer *ct, GtkWidget *widget); +UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar); +void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout); #ifdef __cplusplus }
--- a/ui/gtk/display.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/display.c Sun Oct 05 18:13:15 2025 +0200 @@ -47,8 +47,6 @@ } UIWIDGET ui_label_create(UiObject *obj, UiLabelArgs *args) { - UiObject* current = uic_current_obj(obj); - const char *css_class = NULL; char *markup = NULL; if(args->label) { @@ -105,7 +103,7 @@ } - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_STRING); if(var) { UiString* value = (UiString*)var->value; value->obj = widget; @@ -113,8 +111,9 @@ value->set = ui_label_set; } - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); return widget; } @@ -147,10 +146,12 @@ } } +/* UIWIDGET ui_space_deprecated(UiObject *obj) { GtkWidget *widget = gtk_label_new(""); - UiContainer *ct = uic_get_current_container(obj); - ct->add(ct, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); return widget; } @@ -161,12 +162,14 @@ #else GtkWidget *widget = gtk_hseparator_new(); #endif - UiContainer *ct = uic_get_current_container(obj); - ct->add(ct, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); return widget; } - +*/ + /* ------------------------- progress bar ------------------------- */ typedef struct UiProgressBarRange { @@ -175,8 +178,6 @@ } UiProgressBarRange; UIWIDGET ui_progressbar_create(UiObject *obj, UiProgressbarArgs *args) { - UiObject* current = uic_current_obj(obj); - GtkWidget *progressbar = gtk_progress_bar_new(); if(args->max > args->min) { UiProgressBarRange *range = malloc(sizeof(UiProgressBarRange)); @@ -191,7 +192,7 @@ } - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_DOUBLE); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_DOUBLE); if(var && var->value) { UiDouble *value = var->value; value->get = ui_progressbar_get; @@ -200,8 +201,9 @@ ui_progressbar_set(value, value->value); } - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, progressbar); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, progressbar, &layout); return progressbar; } @@ -229,11 +231,9 @@ /* ------------------------- progress spinner ------------------------- */ UIWIDGET ui_progressspinner_create(UiObject* obj, UiProgressbarSpinnerArgs *args) { - UiObject* current = uic_current_obj(obj); - GtkWidget *spinner = gtk_spinner_new(); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER); if(var && var->value) { UiInteger *value = var->value; value->get = ui_spinner_get; @@ -242,8 +242,9 @@ ui_spinner_set(value, value->value); } - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, spinner); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, spinner, &layout); return spinner; }
--- a/ui/gtk/entry.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/entry.c Sun Oct 05 18:13:15 2025 +0200 @@ -39,8 +39,6 @@ double min = args->min; double max = args->max != 0 ? args->max : 1000; - UiObject* current = uic_current_obj(obj); - UiVar *var = NULL; UiVarType vartype = 0; if(args->varname) { @@ -48,20 +46,20 @@ if(var) { vartype = var->type; } else { - var = uic_widget_var(obj->ctx, current->ctx, args->rangevalue, args->varname, UI_VAR_RANGE); + var = uic_widget_var(obj->ctx, obj->ctx, args->rangevalue, args->varname, UI_VAR_RANGE); vartype = UI_VAR_RANGE; } } if(!var) { if(args->intvalue) { - var = uic_widget_var(obj->ctx, current->ctx, args->intvalue, NULL, UI_VAR_INTEGER); + var = uic_widget_var(obj->ctx, obj->ctx, args->intvalue, NULL, UI_VAR_INTEGER); vartype = UI_VAR_INTEGER; } else if(args->doublevalue) { - var = uic_widget_var(obj->ctx, current->ctx, args->doublevalue, NULL, UI_VAR_DOUBLE); + var = uic_widget_var(obj->ctx, obj->ctx, args->doublevalue, NULL, UI_VAR_DOUBLE); vartype = UI_VAR_DOUBLE; } else if(args->rangevalue) { - var = uic_widget_var(obj->ctx, current->ctx, args->rangevalue, NULL, UI_VAR_RANGE); + var = uic_widget_var(obj->ctx, obj->ctx, args->rangevalue, NULL, UI_VAR_RANGE); vartype = UI_VAR_RANGE; } } @@ -144,8 +142,9 @@ G_CALLBACK(ui_destroy_vardata), event); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, spin); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, spin, &layout); return spin; }
--- a/ui/gtk/graphics.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/graphics.c Sun Oct 05 18:13:15 2025 +0200 @@ -44,8 +44,10 @@ ui_connect_draw_handler(widget, event); } - UiContainer *ct = uic_get_current_container(obj); - ct->add(ct, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + //UiLayout layout = UI_ARGS2LAYOUT(args); + UiLayout layout = {0}; + ct->add(ct, widget, &layout); return widget; }
--- a/ui/gtk/image.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/image.c Sun Oct 05 18:13:15 2025 +0200 @@ -64,8 +64,6 @@ #endif UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs *args) { - UiObject *current = uic_current_obj(obj); - GtkWidget *drawingarea = gtk_drawing_area_new(); GtkWidget *toplevel; GtkWidget *widget = drawingarea; @@ -111,7 +109,7 @@ g_object_set_data_full(G_OBJECT(drawingarea), "uiimageviewer", imgviewer, (GDestroyNotify)imageviewer_destroy); - UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_GENERIC); + UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_GENERIC); imgviewer->var = var; imgviewer->widget = drawingarea; @@ -187,8 +185,9 @@ ui_widget_set_contextmenu(widget, menu); } - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, toplevel); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, toplevel, &layout); return toplevel; }
--- a/ui/gtk/list.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/list.c Sun Oct 05 18:13:15 2025 +0200 @@ -435,8 +435,6 @@ } UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { - UiObject* current = uic_current_obj(obj); - // to simplify things and share code with ui_table_create, we also // use a UiModel for the listview UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); @@ -464,7 +462,7 @@ GtkSelectionModel *selection_model = create_selection_model(listview, ls, args->multiselection); GtkWidget *view = gtk_list_view_new(GTK_SELECTION_MODEL(selection_model), factory); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); // init listview listview->widget = view; @@ -513,19 +511,14 @@ GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS SCROLLEDWINDOW_SET_CHILD(scroll_area, view); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, scroll_area); - - // ct->current should point to view, not scroll_area, to make it possible - // to add a context menu - current->container->current = view; + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, scroll_area, &layout); return scroll_area; } UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { - UiObject* current = uic_current_obj(obj); - // to simplify things and share code with ui_tableview_create, we also // use a UiModel for the listview UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); @@ -554,7 +547,7 @@ GtkWidget *view = gtk_drop_down_new(G_LIST_MODEL(ls), NULL); gtk_drop_down_set_factory(GTK_DROP_DOWN(view), factory); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); // init listview listview->widget = view; @@ -589,8 +582,10 @@ } // add widget to parent - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, view); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, view, &layout); + return view; } @@ -604,8 +599,6 @@ } UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) { - UiObject* current = uic_current_obj(obj); - GListStore *ls = g_list_store_new(G_TYPE_OBJECT); //g_list_store_append(ls, v1); @@ -616,7 +609,7 @@ GtkSelectionModel *selection_model = create_selection_model(tableview, ls, args->multiselection); GtkWidget *view = gtk_column_view_new(GTK_SELECTION_MODEL(selection_model)); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); // init tableview tableview->widget = view; @@ -697,12 +690,9 @@ GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS SCROLLEDWINDOW_SET_CHILD(scroll_area, view); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, scroll_area); - - // ct->current should point to view, not scroll_area, to make it possible - // to add a context menu - current->container->current = view; + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, scroll_area, &layout); return scroll_area; } @@ -1126,8 +1116,6 @@ UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { - UiObject* current = uic_current_obj(obj); - // create treeview GtkWidget *view = gtk_tree_view_new(); ui_set_name_and_style(view, args->name, args->style_class); @@ -1161,7 +1149,7 @@ G_CALLBACK(ui_listview_destroy), listview); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); // init listview listview->widget = view; @@ -1221,12 +1209,9 @@ GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS SCROLLEDWINDOW_SET_CHILD(scroll_area, view); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, scroll_area); - - // ct->current should point to view, not scroll_area, to make it possible - // to add a context menu - current->container->current = view; + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, scroll_area, &layout); return scroll_area; } @@ -1243,8 +1228,6 @@ } UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) { - UiObject* current = uic_current_obj(obj); - // create treeview GtkWidget *view = gtk_tree_view_new(); @@ -1343,7 +1326,7 @@ #endif - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); //g_signal_connect(view, "drag-begin", G_CALLBACK(drag_begin), NULL); //g_signal_connect(view, "drag-end", G_CALLBACK(drag_end), NULL); @@ -1425,12 +1408,9 @@ #endif } - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, scroll_area); - - // ct->current should point to view, not scroll_area, to make it possible - // to add a context menu - current->container->current = view; + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, scroll_area, &layout); return scroll_area; } @@ -1476,15 +1456,13 @@ /* --------------------------- ComboBox --------------------------- */ UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { - UiObject* current = uic_current_obj(obj); - GtkWidget *combobox = gtk_combo_box_new(); ui_set_name_and_style(combobox, args->name, args->style_class); ui_set_widget_groups(obj->ctx, combobox, args->groups); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, combobox); - current->container->current = combobox; + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, combobox, &layout); UiListView *listview = create_listview(obj, args); listview->widget = combobox; @@ -1496,7 +1474,7 @@ G_CALLBACK(ui_listview_destroy), listview); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); UiList *list = var ? var->value : NULL; GtkListStore *listmodel = create_list_store(listview, list); if(var) { @@ -2110,8 +2088,6 @@ } UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs *args) { - UiObject* current = uic_current_obj(obj); - #ifdef UI_GTK3 GtkWidget *listbox = g_object_new(ui_sidebar_list_box_get_type(), NULL); #else @@ -2130,8 +2106,9 @@ ui_set_name_and_style(listbox, args->name, args->style_class); ui_set_widget_groups(obj->ctx, listbox, args->groups); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, scroll_area); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, scroll_area, &layout); UiListBox *uilistbox = malloc(sizeof(UiListBox)); uilistbox->obj = obj; @@ -2164,7 +2141,7 @@ // fill items ui_listbox_update(uilistbox, 0, cxListSize(uilistbox->sublists)); } else { - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->dynamic_sublist, args->varname, UI_VAR_LIST); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->dynamic_sublist, args->varname, UI_VAR_LIST); if(var) { UiList *list = var->value; list->obj = uilistbox;
--- a/ui/gtk/menu.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/menu.c Sun Oct 05 18:13:15 2025 +0200 @@ -33,6 +33,7 @@ #include "menu.h" #include "toolkit.h" +#include "widget.h" #include "../common/context.h" #include "../common/menu.h" #include "../common/types.h"
--- a/ui/gtk/range.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/range.c Sun Oct 05 18:13:15 2025 +0200 @@ -76,8 +76,10 @@ event); } - UiContainer *ct = uic_get_current_container(obj); - ct->add(ct, scrollbar); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + //UiLayout layout = UI_ARGS2LAYOUT(args); + UiLayout layout = {0}; + ct->add(ct, scrollbar, &layout); return scrollbar; }
--- a/ui/gtk/text.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/text.c Sun Oct 05 18:13:15 2025 +0200 @@ -108,8 +108,7 @@ } UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs *args) { - UiObject* current = uic_current_obj(obj); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_TEXT); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_TEXT); GtkWidget *text_area = gtk_text_view_new(); ui_set_name_and_style(text_area, args->name, args->style_class); @@ -155,8 +154,9 @@ gtk_text_view_set_right_margin(GTK_TEXT_VIEW(text_area), 2); // add - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, scroll_area); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, scroll_area, &layout); // bind value if(var) { @@ -598,8 +598,7 @@ ui_set_name_and_style(textfield, args->name, args->style_class); ui_set_widget_groups(obj->ctx, textfield, args->groups); - UiObject* current = uic_current_obj(obj); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_STRING); UiTextField *uitext = malloc(sizeof(UiTextField)); uitext->obj = obj; @@ -630,8 +629,9 @@ gtk_entry_set_visibility(GTK_ENTRY(textfield), FALSE); } - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, textfield); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, textfield, &layout); if(var) { UiString *value = var->value; @@ -922,8 +922,6 @@ } UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs *args) { - UiObject* current = uic_current_obj(obj); - UiPathTextField *pathtf = malloc(sizeof(UiPathTextField)); memset(pathtf, 0, sizeof(UiPathTextField)); pathtf->obj = obj; @@ -946,8 +944,9 @@ pathtf->stack = gtk_stack_new(); gtk_widget_set_name(pathtf->stack, "path-textfield-box"); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, pathtf->stack); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, pathtf->stack, &layout); pathtf->entry_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); pathtf->entry = gtk_entry_new(); @@ -979,7 +978,7 @@ gtk_stack_set_visible_child(GTK_STACK(pathtf->stack), pathtf->entry_box); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_STRING); if (var) { UiString* value = (UiString*)var->value; value->obj = pathtf; @@ -1083,8 +1082,6 @@ } UIWIDGET ui_path_textfield_create(UiObject* obj, UiPathTextFieldArgs *args) { - UiObject* current = uic_current_obj(obj); - UiPathTextField *pathtf = malloc(sizeof(UiPathTextField)); memset(pathtf, 0, sizeof(UiPathTextField)); pathtf->obj = obj; @@ -1118,8 +1115,9 @@ G_CALLBACK(ui_path_textfield_destroy), pathtf); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, eventbox); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, eventbox, &layout); // hbox as parent for the GtkEntry and GtkButtonBox GtkWidget *hbox = ui_gtk_hbox_new(0); @@ -1143,7 +1141,7 @@ G_CALLBACK(ui_path_textfield_key_press), pathtf); - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_STRING); + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_STRING); if (var) { UiString* value = (UiString*)var->value; value->obj = pathtf;
--- a/ui/gtk/webview.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/webview.c Sun Oct 05 18:13:15 2025 +0200 @@ -34,13 +34,11 @@ #ifdef UI_WEBVIEW UIWIDGET ui_webview_create(UiObject *obj, UiWebviewArgs *args) { - UiObject* current = uic_current_obj(obj); - GtkWidget *webview = webkit_web_view_new(); ui_set_name_and_style(webview, args->name, args->style_class); - UiVar *var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_GENERIC); + UiVar *var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_GENERIC); if(var) { WebViewData *data = malloc(sizeof(WebViewData)); memset(data, 0, sizeof(WebViewData)); @@ -60,8 +58,9 @@ } ui_set_widget_groups(obj->ctx, webview, args->groups); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, webview); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, webview, &layout); return webview; }
--- a/ui/gtk/widget.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/widget.c Sun Oct 05 18:13:15 2025 +0200 @@ -32,22 +32,21 @@ #include "../common/object.h" UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs *args) { - UiObject* current = uic_current_obj(obj); - UIWIDGET widget = create_widget(obj, args, userdata); - UI_APPLY_LAYOUT2(current, args); - current->container->add(current->container, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); return widget; } UIWIDGET ui_separator_create(UiObject *obj, UiWidgetArgs *args) { - UiObject* current = uic_current_obj(obj); GtkWidget *widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL); ui_set_name_and_style(widget, args->name, args->style_class); - UI_APPLY_LAYOUT1(current, (*args)); - current->container->add(current->container, widget); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); return widget; }
--- a/ui/gtk/window.c Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/gtk/window.c Sun Oct 05 18:13:15 2025 +0200 @@ -372,7 +372,8 @@ gtk_container_add(GTK_CONTAINER(frame), content_box); obj->container = ui_box_container(obj, content_box); */ - obj->container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX); + UiContainerX *container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX); + uic_object_push_container(obj, container); nwindows++; return obj; @@ -932,7 +933,8 @@ #endif GtkWidget *content_vbox = ui_gtk_vbox_new(0); - obj->container = ui_box_container(obj, content_vbox, UI_CONTAINER_VBOX); + UiContainerX *container = ui_box_container(obj, content_vbox, UI_CONTAINER_VBOX); + uic_object_push_container(obj, container); if(args->lbutton1 || args->lbutton2 || args->rbutton3 || args->rbutton4) { #if GTK_CHECK_VERSION(3, 10, 0) if(args->titlebar_buttons != UI_OFF) {
--- a/ui/ui/container.h Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/ui/container.h Sun Oct 05 18:13:15 2025 +0200 @@ -101,8 +101,6 @@ const char *name; const char *style_class; - UiSubContainerType subcontainer; - int spacing; int columnspacing; int rowspacing; @@ -137,6 +135,7 @@ UiInteger *value; const char* varname; + int padding; int spacing; int columnspacing; int rowspacing; @@ -149,6 +148,11 @@ UiBool hfill; UiBool vfill; UiBool override_defaults; + int margin; + int margin_left; + int margin_right; + int margin_top; + int margin_bottom; int colspan; int rowspan; const char *name; @@ -249,9 +253,29 @@ UiSubContainerType subcontainer; } UiItemListContainerArgs; + +typedef struct UiLayout UiLayout; +struct UiLayout { + UiBool fill; + char *label; + UiBool hexpand; + UiBool vexpand; + UiBool hfill; + UiBool vfill; + UiBool override_defaults; + int margin; + int margin_left; + int margin_right; + int margin_top; + int margin_bottom; + int colspan; + int rowspan; +}; + struct UiContainerX { void *container; - int close; + UiBool close; + UiBool newline; UiContainerX *prev; UiContainerX *next; }; @@ -384,7 +408,21 @@ if(args->rowspan > 0) ui_layout_rowspan(obj, args->rowspan); \ /*force caller to add ';'*/(void)0 - +#define UI_ARGS2LAYOUT(args) { \ + .fill = args->fill, \ + .hexpand = args->hexpand, \ + .vexpand = args->vexpand, \ + .hfill = args->hfill, \ + .vfill = args->vfill, \ + .override_defaults = args->override_defaults, \ + .margin = args->margin, \ + .margin_left = args->margin_left, \ + .margin_right = args->margin_right, \ + .margin_top = args->margin_top, \ + .margin_bottom = args->margin_bottom, \ + .colspan = args->colspan, \ + .rowspan = args->rowspan } + #ifdef __cplusplus } #endif
--- a/ui/ui/toolkit.h Sun Oct 05 13:30:19 2025 +0200 +++ b/ui/ui/toolkit.h Sun Oct 05 18:13:15 2025 +0200 @@ -286,11 +286,6 @@ UiContext *ctx; /* - * container interface (deprecated) - */ - UiContainer *container; - - /* * container list * TODO: remove old UiContainer and rename UiContainerX to UiContainer */