add content toggle button (GTK)

Wed, 17 Jun 2026 20:42:21 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 17 Jun 2026 20:42:21 +0200
changeset 1205
749a32e91513
parent 1204
bc12e849a0fe
child 1206
4637da12bc6c

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

mercurial