# HG changeset patch # User Olaf Wintermann # Date 1728336412 -7200 # Node ID 08ce6680d1cf4ead6ec53479cd07493cb1260a1b # Parent 059cba080ab4caeb1b27d655a8e6bdcf4c924279# Parent 216d8912714c6c138e91a9610796189d636cfe99 merge diff -r 216d8912714c -r 08ce6680d1cf application/main.c --- a/application/main.c Sun Oct 06 18:45:47 2024 +0200 +++ b/application/main.c Mon Oct 07 23:26:52 2024 +0200 @@ -134,49 +134,57 @@ MyDocument *doc = create_doc(); ui_attach_document(obj->ctx, doc); - ui_vbox(obj, .fill = UI_OFF, .margin = 15, .spacing = 15) { - ui_button(obj, .label = "Test Button", .icon = "application-x-generic", .onclick = action_button); - ui_togglebutton(obj, .label = "Toggle"); - ui_checkbox(obj, .label = "My Checkbox"); - } - ui_grid(obj, .fill = UI_OFF, .columnspacing = 15, .rowspacing = 15, .margin = 15) { - ui_button(obj, .label = "cell1", .hexpand = TRUE); - ui_button(obj, .label = "cell2"); - ui_newline(obj); - ui_button(obj, .label = "cell_colspan2", .colspan = 2); - ui_newline(obj); - - ui_label(obj, .label = "Label Col 1", .align = UI_ALIGN_LEFT); - ui_label(obj, .label = "Label Col 2", .align = UI_ALIGN_RIGHT); - ui_newline(obj); - - ui_spinner(obj, .step = 5); - ui_newline(obj); - - ui_progressbar(obj, .colspan = 2, .varname = "progress"); - ui_set(doc->progress, 0.75); - ui_newline(obj); - - ui_textfield(obj, .value = doc->str1); - ui_newline(obj); - - //ui_button(obj, .label="Test"); - ui_path_textfield(obj, .varname = "path"); - ui_set(doc->path, "/test/path/longdirectoryname/123"); - ui_newline(obj); - - //UiModel *model = ui_model(obj->ctx, UI_ICON_TEXT, "Col 1", UI_STRING, "Col 2", -1); - //model->getvalue = list_getvalue; - ui_combobox(obj, .hexpand = true, .vexpand = false, .colspan = 2, .varname = "list", .getvalue = list_getvalue); - ui_newline(obj); - - ui_hbox0(obj) { - ui_radiobutton(obj, .label = "Radio 1", .varname = "radio"); - ui_radiobutton(obj, .label = "Radio 2", .varname = "radio"); - ui_radiobutton(obj, .label = "Radio 3", .varname = "radio"); + ui_tabview(obj, .spacing=10, .margin=10) { + ui_tab(obj, "Tab 1") { + ui_vbox(obj, .fill = UI_OFF, .margin = 15, .spacing = 15) { + ui_button(obj, .label = "Test Button", .icon = "application-x-generic", .onclick = action_button); + ui_togglebutton(obj, .label = "Toggle"); + ui_checkbox(obj, .label = "My Checkbox"); + } + ui_grid(obj, .fill = UI_OFF, .columnspacing = 15, .rowspacing = 15, .margin = 15) { + ui_button(obj, .label = "cell1", .hexpand = TRUE); + ui_button(obj, .label = "cell2"); + ui_newline(obj); + ui_button(obj, .label = "cell_colspan2", .colspan = 2); + ui_newline(obj); + + ui_label(obj, .label = "Label Col 1", .align = UI_ALIGN_LEFT); + ui_label(obj, .label = "Label Col 2", .align = UI_ALIGN_RIGHT); + ui_newline(obj); + + ui_spinner(obj, .step = 5); + ui_newline(obj); + + ui_progressbar(obj, .colspan = 2, .varname = "progress"); + ui_set(doc->progress, 0.75); + ui_newline(obj); + + ui_textfield(obj, .value = doc->str1); + ui_newline(obj); + + //ui_button(obj, .label="Test"); + ui_path_textfield(obj, .varname = "path"); + ui_set(doc->path, "/test/path/longdirectoryname/123"); + ui_newline(obj); + + //UiModel *model = ui_model(obj->ctx, UI_ICON_TEXT, "Col 1", UI_STRING, "Col 2", -1); + //model->getvalue = list_getvalue; + ui_combobox(obj, .hexpand = true, .vexpand = false, .colspan = 2, .varname = "list", .getvalue = list_getvalue); + ui_newline(obj); + + ui_hbox0(obj) { + ui_radiobutton(obj, .label = "Radio 1", .varname = "radio"); + ui_radiobutton(obj, .label = "Radio 2", .varname = "radio"); + ui_radiobutton(obj, .label = "Radio 3", .varname = "radio"); + } + } } } + /* + + */ + ui_show(obj); } diff -r 216d8912714c -r 08ce6680d1cf ui/common/object.c --- a/ui/common/object.c Sun Oct 06 18:45:47 2024 +0200 +++ b/ui/common/object.c Mon Oct 07 23:26:52 2024 +0200 @@ -51,8 +51,10 @@ UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget) { - UiContext *ctx = toplevel->ctx; - + 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; newobj->widget = widget; diff -r 216d8912714c -r 08ce6680d1cf ui/common/object.h --- a/ui/common/object.h Sun Oct 06 18:45:47 2024 +0200 +++ b/ui/common/object.h Mon Oct 07 23:26:52 2024 +0200 @@ -36,6 +36,7 @@ #endif 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); diff -r 216d8912714c -r 08ce6680d1cf ui/gtk/container.c --- a/ui/gtk/container.c Sun Oct 06 18:45:47 2024 +0200 +++ b/ui/gtk/container.c Mon Oct 07 23:26:52 2024 +0200 @@ -228,10 +228,12 @@ } void ui_tabview_container_add(UiContainer *ct, GtkWidget *widget, UiBool fill) { - gtk_notebook_append_page( - GTK_NOTEBOOK(ct->widget), - widget, - gtk_label_new(ct->layout.label)); + 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); ui_reset_layout(ct->layout); ct->current = widget; @@ -334,6 +336,147 @@ gtk_notebook_set_current_page(GTK_NOTEBOOK(tabview), tab); } +void ui_notebook_tab_select(UIWIDGET tabview, int tab) { + gtk_notebook_set_current_page(GTK_NOTEBOOK(tabview), tab); +} + +void ui_notebook_tab_remove(UIWIDGET tabview, int tab) { + gtk_notebook_remove_page(GTK_NOTEBOOK(tabview), tab); +} + +void ui_notebook_tab_add(UIWIDGET widget, int index, const char *name, UIWIDGET child) { + gtk_notebook_insert_page( + GTK_NOTEBOOK(widget), + child, + gtk_label_new(name), + index); +} + +UiGtkTabView* ui_widget_get_tabview_data(UIWIDGET tabview) { + return g_object_get_data(G_OBJECT(tabview), "ui_tabview"); +} + +UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs args) { + UiGtkTabView *data = malloc(sizeof(UiGtkTabView)); + data->margin = args.margin; + data->spacing = args.spacing; + data->columnspacing = args.columnspacing; + data->rowspacing = args.rowspacing; + + GtkWidget *widget = NULL; + switch(args.tabview) { + case UI_TABVIEW_DOC: { + // TODO + break; + } + case UI_TABVIEW_NAVIGATION_SIDE: { + // TODO + break; + } + case UI_TABVIEW_DEFAULT: + case UI_TABVIEW_NAVIGATION_TOP: + case UI_TABVIEW_NAVIGATION_TOP2: { + widget = gtk_notebook_new(); + data->select_tab = ui_notebook_tab_select; + data->remove_tab = ui_notebook_tab_remove; + data->add_tab = ui_notebook_tab_add; + break; + } + case UI_TABVIEW_INVISIBLE: { + widget = gtk_notebook_new(); + gtk_notebook_set_show_tabs(GTK_NOTEBOOK(widget), FALSE); + gtk_notebook_set_show_border(GTK_NOTEBOOK(widget), FALSE); + data->select_tab = ui_notebook_tab_select; + data->remove_tab = ui_notebook_tab_remove; + data->add_tab = ui_notebook_tab_add; + break; + } + } + + g_object_set_data(G_OBJECT(widget), "ui_tabview", data); + data->widget = widget; + data->subcontainer = args.subcontainer; + + UiObject* current = uic_current_obj(obj); + UI_APPLY_LAYOUT1(current, args); + current->container->add(current->container, widget, TRUE); + + UiObject *newobj = uic_object_new(obj, widget); + newobj->container = ui_tabview_container(obj, widget); + uic_obj_add(obj, newobj); + data->obj = newobj; + + return widget; +} + +void ui_tab_create(UiObject* obj, const char* title) { + UiObject* current = uic_current_obj(obj); + UiGtkTabView *data = ui_widget_get_tabview_data(current->widget); + if(!data) { + fprintf(stderr, "UI Error: widget is not a tabview\n"); + return; + } + + UiObject *newobj = ui_tabview_add(data->widget, title, -1); + current->next = newobj; +} + + + +void ui_tabview_select(UIWIDGET tabview, int tab) { + UiGtkTabView *data = ui_widget_get_tabview_data(tabview); + if(!data) { + fprintf(stderr, "UI Error: widget is not a tabview\n"); + return; + } + data->select_tab(tabview, tab); +} + +void ui_tabview_remove(UIWIDGET tabview, int tab) { + UiGtkTabView *data = ui_widget_get_tabview_data(tabview); + if(!data) { + fprintf(stderr, "UI Error: widget is not a tabview\n"); + return; + } + data->remove_tab(tabview, tab); +} + +UiObject* ui_tabview_add(UIWIDGET tabview, const char *name, int tab_index) { + UiGtkTabView *data = ui_widget_get_tabview_data(tabview); + if(!data) { + fprintf(stderr, "UI Error: widget is not a tabview\n"); + 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 = create_grid(data->columnspacing, data->rowspacing); + newobj->container = ui_grid_container(newobj, sub); + break; + } + } + newobj->widget = sub; + GtkWidget *widget = box_set_margin(sub, data->margin); + + data->add_tab(data->widget, tab_index, name, widget); + + return newobj; +} + /* -------------------- Splitpane -------------------- */ static GtkWidget* create_paned(UiOrientation orientation) { diff -r 216d8912714c -r 08ce6680d1cf ui/gtk/container.h --- a/ui/gtk/container.h Sun Oct 06 18:45:47 2024 +0200 +++ b/ui/gtk/container.h Mon Oct 07 23:26:52 2024 +0200 @@ -33,6 +33,8 @@ #include "../ui/container.h" #include +#include + #ifdef __cplusplus extern "C" { #endif @@ -104,6 +106,22 @@ UiContainer container; } UiTabViewContainer; +typedef void (*ui_select_tab_func)(UIWIDGET widget, int tab); +typedef void (*ui_add_tab_func)(UIWIDGET widget, int index, const char *name, UIWIDGET child); + +typedef struct UiGtkTabView { + UiObject *obj; + GtkWidget *widget; + ui_select_tab_func select_tab; + ui_select_tab_func remove_tab; + ui_add_tab_func add_tab; + UiSubContainerType subcontainer; + int margin; + int spacing; + int columnspacing; + int rowspacing; +} UiGtkTabView; + GtkWidget* ui_gtk_vbox_new(int spacing); GtkWidget* ui_gtk_hbox_new(int spacing); @@ -129,10 +147,9 @@ void ui_split_container_add1(UiContainer *ct, GtkWidget *widget, UiBool fill); void ui_split_container_add2(UiContainer *ct, GtkWidget *widget, UiBool fill); +UiGtkTabView* ui_widget_get_tabview_data(UIWIDGET tabview); -UiObject* ui_add_document_tab(UiDocumentView *view); -void ui_tab_set_document(UiContext *ctx, void *document); -void ui_tab_detach_document(UiContext *ctx); +void ui_gtk_notebook_select_tab(GtkWidget *widget, int tab); #ifdef __cplusplus } diff -r 216d8912714c -r 08ce6680d1cf ui/ui/container.h --- a/ui/ui/container.h Sun Oct 06 18:45:47 2024 +0200 +++ b/ui/ui/container.h Mon Oct 07 23:26:52 2024 +0200 @@ -148,9 +148,9 @@ UIEXPORT UIWIDGET ui_hsplitpane(UiObject *obj, int max); UIEXPORT UIWIDGET ui_vsplitpane(UiObject *obj, int max); -UIEXPORT UIWIDGET ui_tabview_deprecated(UiObject *obj); - -UIEXPORT void ui_select_tab(UIWIDGET tabview, int tab); +UIEXPORT void ui_tabview_select(UIWIDGET tabview, int tab); +UIEXPORT void ui_tabview_remove(UIWIDGET tabview, int tab); +UIEXPORT UiObject* ui_tabview_add(UIWIDGET tabview, const char *name, int tab_index); // box container layout functions UIEXPORT void ui_layout_fill(UiObject *obj, UiBool fill);