--- 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; -} -