Wed, 17 Jun 2026 20:42:21 +0200
add content toggle button (GTK)
| application/main.c | file | annotate | diff | comparison | revisions | |
| ui/gtk/button.c | file | annotate | diff | comparison | revisions | |
| ui/gtk/button.h | file | annotate | diff | comparison | revisions | |
| ui/ui/button.h | file | annotate | diff | comparison | revisions |
--- a/application/main.c Wed Jun 17 19:50:57 2026 +0200 +++ b/application/main.c Wed Jun 17 20:42:21 2026 +0200 @@ -679,6 +679,11 @@ ui_show(obj); } +static void content_toggled(UiEvent *event, void *userdata) { + int i = ui_var_get_int(event->obj->ctx, "ctntoggle"); + printf("content toggled: %d : %d\n", i, event->intval); +} + void application_startup(UiEvent *event, void *data) { // test window destruction UiObject *testobj = ui_window("testwindow"); @@ -726,6 +731,9 @@ ui_button(obj, .label = "Disable Group 2", .onclick = action_group2, .onclickdata = "disable"); ui_newline(obj); + ui_content_togglebutton(obj, .label0 = "Off", .label1 = "On", .tooltip0 = "enable", .tooltip1 = "disable", .istogglebutton = TRUE, .onchange = content_toggled, .varname = "ctntoggle"); + ui_newline(obj); + ui_button(obj, .label = "Groups 1,2", .colspan = 2, .states = UI_STATES(1, 2)); ui_newline(obj);
--- a/ui/gtk/button.c Wed Jun 17 19:50:57 2026 +0200 +++ b/ui/gtk/button.c Wed Jun 17 20:42:21 2026 +0200 @@ -334,7 +334,7 @@ event); } - if(onchange) { + if(onchange || action) { UiEventData *event = malloc(sizeof(UiEventData)); event->obj = obj; event->userdata = onchangedata; @@ -577,6 +577,148 @@ #endif +static void content_toggle_button_changed(UiContentToggleButton *button) { + if(button->toggled) { + gtk_button_set_label(GTK_BUTTON(button->widget), button->label1); + ui_button_set_icon_name(button->widget, button->icon1); + gtk_widget_set_tooltip_text(button->widget, button->tooltip1); + } else { + gtk_button_set_label(GTK_BUTTON(button->widget), button->label0); + ui_button_set_icon_name(button->widget, button->icon0); + gtk_widget_set_tooltip_text(button->widget, button->tooltip0); + } + + UiEvent e; + e.obj = button->obj; + e.window = button->obj->window; + e.document = button->obj->ctx->document; + e.eventdata = NULL; + e.eventdatatype = 0; + e.intval = button->toggled; + e.set = ui_get_setop(); + + if(button->onchange) { + button->onchange(&e, button->onchangedata); + } + + if(button->onchange_action) { + uic_action_callback(&e, button->onchange_action); + } +} + +static void ui_content_toggle_button_toggled(GtkWidget *widget, UiContentToggleButton *button) { + button->toggled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); + if(ui_get_setop() == 0) { + content_toggle_button_changed(button); + } +} + +static void ui_content_toggle_button_clicked(GtkWidget *widget, UiContentToggleButton *button) { + button->toggled = !button->toggled; + content_toggle_button_changed(button); +} + +static void ui_destroy_content_togglebutton(GtkWidget *widget, UiContentToggleButton *button) { + free(button->label0); + free(button->icon0); + free(button->tooltip0); + free(button->label1); + free(button->icon1); + free(button->tooltip1); + free(button->onchange_action); + free(button); +} + +UIWIDGET ui_create_content_togglebutton(UiObject *obj, UiContentToggleArgs *args) { + UiContentToggleButton *button = malloc(sizeof(UiContentToggleButton)); + memset(button, 0, sizeof(UiContentToggleButton)); + button->obj = obj; + button->label0 = args->label0 ? strdup(args->label0) : NULL; + button->icon0 = args->icon0 ? strdup(args->icon0) : NULL; + button->tooltip0 = args->tooltip0 ? strdup(args->tooltip0) : NULL; + button->label1 = args->label1 ? strdup(args->label1) : NULL; + button->icon1 = args->icon1 ? strdup(args->icon1) : NULL; + button->tooltip1 = args->tooltip1 ? strdup(args->tooltip1) : NULL; + button->enable_state = args->enable_state; + button->var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER); + button->onchange = args->onchange; + button->onchangedata = args->onchangedata; + button->onchange_action = args->action ? strdup(args->action) : NULL; + + const char *label = args->label0; + const char *icon = args->icon0; + const char *tooltip = args->tooltip0; + if(button->var) { + UiInteger *i = button->var->value; + i->obj = button; + i->get = ui_ctntogglebutton_get; + i->set = ui_ctntogglebutton_set; + + if(i->value) { + label = args->label1; + icon = args->label1; + tooltip = args->tooltip1; + button->toggled = 1; + } + } + + GtkWidget *widget; + if(args->istogglebutton) { + widget = gtk_toggle_button_new_with_label(label); + + g_signal_connect( + widget, + "toggled", + G_CALLBACK(ui_content_toggle_button_toggled), + button); + } else { + widget = gtk_button_new_with_label(label); + + g_signal_connect( + widget, + "clicked", + G_CALLBACK(ui_content_toggle_button_clicked), + button); + } + ui_button_set_icon_name(widget, icon); + gtk_widget_set_tooltip_text(widget, tooltip); + button->widget = widget; + + g_signal_connect( + widget, + "destroy", + G_CALLBACK(ui_destroy_content_togglebutton), + button); + + g_object_set_data(G_OBJECT(widget), "ui_content_togglebutton", button); + return widget; +} + +UIWIDGET ui_content_togglebutton_create(UiObject *obj, UiContentToggleArgs *args) { + GtkWidget *widget = ui_create_content_togglebutton(obj, args); + + ui_set_name_and_style(widget, args->name, args->style_class); + ui_set_widget_states(obj->ctx, widget, args->states); + UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; + UiLayout layout = UI_ARGS2LAYOUT(args); + ct->add(ct, widget, &layout); + uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states); + return widget; +} + +int64_t ui_ctntogglebutton_get(UiInteger *value) { + UiContentToggleButton *button = value->obj; + value->value = button->toggled; + return value->value; +} + +void ui_ctntogglebutton_set(UiInteger *value, int64_t i) { + UiContentToggleButton *button = value->obj; + button->toggled = i != 0; + value->value = button->toggled; + content_toggle_button_changed(button); +} + #if GTK_MAJOR_VERSION >= 4 #define RADIOBUTTON_NEW(group, label) gtk_check_button_new_with_label(label) #define RADIOBUTTON_SET_GROUP(button, group)
--- a/ui/gtk/button.h Wed Jun 17 19:50:57 2026 +0200 +++ b/ui/gtk/button.h Wed Jun 17 20:42:21 2026 +0200 @@ -37,6 +37,23 @@ extern "C" { #endif +typedef struct UiContentToggleButton { + UiObject *obj; + UiVar *var; + GtkWidget *widget; + char *label0; + char *icon0; + char *tooltip0; + char *label1; + char *icon1; + char *tooltip1; + ui_callback onchange; + void *onchangedata; + char *onchange_action; + int toggled; + int enable_state; +} UiContentToggleButton; + typedef struct UiLinkButton { UiObject *obj; GtkWidget *widget; @@ -101,9 +118,14 @@ void ui_radio_obs(GtkToggleButton *widget, UiVarEventData *event); +UIWIDGET ui_create_content_togglebutton(UiObject *obj, UiContentToggleArgs *args); + int64_t ui_switch_get(UiInteger *value); void ui_switch_set(UiInteger *value, int64_t i); +int64_t ui_ctntogglebutton_get(UiInteger *value); +void ui_ctntogglebutton_set(UiInteger *value, int64_t i); + int64_t ui_radiobutton_get(UiInteger *value); void ui_radiobutton_set(UiInteger *value, int64_t i);
--- a/ui/ui/button.h Wed Jun 17 19:50:57 2026 +0200 +++ b/ui/ui/button.h Wed Jun 17 20:42:21 2026 +0200 @@ -102,6 +102,43 @@ const int *visibility_states; } UiToggleArgs; +typedef struct UiContentToggleArgs { + UiBool fill; + 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; + const char *name; + const char *style_class; + + const char *label0; + const char *icon0; + const char *tooltip0; + const char *label1; + const char *icon1; + const char *tooltip1; + UiLabelType labeltype; + UiInteger *value; + const char *varname; + ui_callback onchange; + void *onchangedata; + const char *action; + UiBool istogglebutton; + int enable_state; + int enabled_by_state; + + const int *states; + const int *visibility_states; +} UiContentToggleArgs; + typedef struct UiLinkButtonArgs { UiBool fill; UiBool hexpand; @@ -137,6 +174,7 @@ #define ui_togglebutton(obj, ...) ui_togglebutton_create(obj, &(UiToggleArgs){ __VA_ARGS__ } ) #define ui_checkbox(obj, ...) ui_checkbox_create(obj, &(UiToggleArgs){ __VA_ARGS__ } ) #define ui_switch(obj, ...) ui_switch_create(obj, &(UiToggleArgs){ __VA_ARGS__ } ) +#define ui_content_togglebutton(obj, ...) ui_content_togglebutton_create(obj, &(UiContentToggleArgs){ __VA_ARGS__ } ) #define ui_radiobutton(obj, ...) ui_radiobutton_create(obj, &(UiToggleArgs){ __VA_ARGS__ } ) #define ui_linkbutton(obj, ...) ui_linkbutton_create(obj, &(UiLinkButtonArgs){ __VA_ARGS__ }) @@ -144,6 +182,7 @@ UIEXPORT UIWIDGET ui_togglebutton_create(UiObject *obj, UiToggleArgs *args); UIEXPORT UIWIDGET ui_checkbox_create(UiObject *obj, UiToggleArgs *args); UIEXPORT UIWIDGET ui_switch_create(UiObject *obj, UiToggleArgs *args); +UIEXPORT UIWIDGET ui_content_togglebutton_create(UiObject *obj, UiContentToggleArgs *args); UIEXPORT UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args); UIEXPORT UIWIDGET ui_linkbutton_create(UiObject *obj, UiLinkButtonArgs *args);