implement var binding for menu check items (GTK3)

Wed, 31 Dec 2025 11:36:42 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 31 Dec 2025 11:36:42 +0100
changeset 1038
832e9288f8e2
parent 1037
fbe4bb4eba8c
child 1039
6691e007cef7

implement var binding for menu check items (GTK3)

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/menu.c file | annotate | diff | comparison | revisions
ui/gtk/menu.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Wed Dec 31 11:06:54 2025 +0100
+++ b/application/main.c	Wed Dec 31 11:36:42 2025 +0100
@@ -620,6 +620,15 @@
     printf("option: %d\n", event->intval);
 }
 
+static void action_menu_toggle(UiEvent *event, void *userdata) {
+    if(event->eventdatatype != UI_EVENT_DATA_INTEGER_VALUE) {
+        printf("Error: action_menu_toggle: wrong event data type\n");
+        return;
+    }
+    UiInteger *i = event->eventdata;
+    printf("action_menu_toggle value: %d\n", ui_get(i));
+}
+
 void application_startup(UiEvent *event, void *data) {
     // global list
     UiContext *global = ui_global_context();
@@ -852,6 +861,16 @@
     // menu
     ui_menu("File") {
         ui_menuitem(.label = "Test");
+        ui_menuseparator();
+        ui_menu_toggleitem(.label = "Toggle 1", .varname = "menu_toggle1", .onchange = action_menu_toggle);
+        ui_menu_toggleitem(.label = "Toggle 2", .varname = "menu_toggle2", .onchange = action_menu_toggle);
+        ui_menuseparator();
+        ui_menu_radioitem(.label = "Option 1", .varname = "menu_radio");
+        ui_menu_radioitem(.label = "Option 2", .varname = "menu_radio");
+        ui_menu_radioitem(.label = "Option 3", .varname = "menu_radio");
+        ui_menu_radioitem(.label = "Option 4", .varname = "menu_radio");
+        ui_menu_radioitem(.label = "Option 5", .varname = "menu_radio");
+        ui_menuseparator();
     }
     
     ui_contextmenu(&menubuilder) {
--- a/ui/gtk/menu.c	Wed Dec 31 11:06:54 2025 +0100
+++ b/ui/gtk/menu.c	Wed Dec 31 11:36:42 2025 +0100
@@ -153,25 +153,32 @@
     GtkWidget *widget = gtk_check_menu_item_new_with_mnemonic(ci->label);
     gtk_menu_shell_append(GTK_MENU_SHELL(p), widget);
     
-    if(ci->callback) {
-        UiEventData *event = malloc(sizeof(UiEventData));
-        event->obj = obj;
-        event->userdata = ci->userdata;
-        event->callback = ci->callback;
-        event->value = 0;
-        event->customdata = NULL;
-        
-        g_signal_connect(
-                widget,
-                "toggled",
-                G_CALLBACK(ui_menu_event_toggled),
-                event);
-        g_signal_connect(
-                widget,
-                "destroy",
-                G_CALLBACK(ui_destroy_userdata),
-                event);
+    UiVarEventData *event = malloc(sizeof(UiVarEventData));
+    memset(event, 0, sizeof(UiVarEventData));
+    event->obj = obj;
+    event->userdata = ci->userdata;
+    event->callback = ci->callback;
+    event->var = uic_widget_var(obj->ctx, obj->ctx, NULL, ci->varname, UI_VAR_INTEGER);
+    if(event->var) {
+        UiInteger *v = event->var->value;
+        v->obj = widget;
+        v->get = ui_checkitem_get;
+        v->set = ui_checkitem_set;
+        if(v->value != 0) {
+            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), TRUE);
+        }
     }
+
+    g_signal_connect(
+            widget,
+            "toggled",
+            G_CALLBACK(ui_menu_event_toggled),
+            event);
+    g_signal_connect(
+            widget,
+            "destroy",
+            G_CALLBACK(ui_destroy_userdata),
+            event);
 }
 
 void add_radioitem_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) {
@@ -323,14 +330,23 @@
     uic_set_tmp_eventdata(NULL, 0);
 }
 
-void ui_menu_event_toggled(GtkCheckMenuItem *ci, UiEventData *event) {
+void ui_menu_event_toggled(GtkCheckMenuItem *ci, UiVarEventData *event) {
+    UiInteger *i = event->var ? event->var->value : NULL;
+    
     UiEvent evt;
     evt.obj = event->obj;
     evt.window = event->obj->window;
     evt.document = event->obj->ctx->document;
-    evt.eventdata = NULL;
+    evt.eventdata = i;
+    evt.eventdatatype = i ? UI_EVENT_DATA_INTEGER_VALUE : 0;
     evt.intval = gtk_check_menu_item_get_active(ci);
-    event->callback(&evt, event->userdata);    
+    if(event->callback) {
+        event->callback(&evt, event->userdata);
+    }
+    
+    if(i) {
+        ui_notify_evt(i->observers, &evt);
+    }
 }
 
 int64_t ui_checkitem_get(UiInteger *i) {
@@ -341,7 +357,7 @@
 
 void ui_checkitem_set(UiInteger *i, int64_t value) {
     i->value = value;
-    gtk_check_menu_item_set_active(i->obj, value);
+    gtk_check_menu_item_set_active(i->obj, (gboolean)value);
 }
 
 
--- a/ui/gtk/menu.h	Wed Dec 31 11:06:54 2025 +0100
+++ b/ui/gtk/menu.h	Wed Dec 31 11:36:42 2025 +0100
@@ -75,7 +75,7 @@
 void ui_menulist_update(UiList *list, int ignored);
 void ui_update_menuitem_list(UiActiveMenuItemList *list);
 void ui_menu_event_wrapper(GtkMenuItem *item, UiEventData *event);
-void ui_menu_event_toggled(GtkCheckMenuItem *ci, UiEventData *event);
+void ui_menu_event_toggled(GtkCheckMenuItem *ci, UiVarEventData *event);
 int64_t ui_checkitem_get(UiInteger *i);
 void ui_checkitem_set(UiInteger *i, int64_t value);
 

mercurial