ui/gtk/menu.c

changeset 1039
6691e007cef7
parent 1038
832e9288f8e2
--- a/ui/gtk/menu.c	Wed Dec 31 11:36:42 2025 +0100
+++ b/ui/gtk/menu.c	Wed Dec 31 12:37:09 2025 +0100
@@ -181,8 +181,72 @@
             event);
 }
 
+static void ui_menu_event_radio_item_toggled(GtkRadioMenuItem *ri, UiVarEventData *event) {
+    UiInteger *i = event->var->value;
+    
+    UiEvent evt;
+    evt.obj = event->obj;
+    evt.window = event->obj->window;
+    evt.document = event->obj->ctx->document;
+    evt.eventdata = i;
+    evt.eventdatatype = i ? UI_EVENT_DATA_INTEGER_VALUE : 0;
+    evt.intval = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(ri));
+    
+    if(event->callback) {
+        event->callback(&evt, event->userdata);
+    }
+    
+    if(evt.intval) {
+        evt.intval = ui_get(i);
+        ui_notify_evt(i->observers, &evt);
+    }
+}
+
+static void ui_destroy_menu_radio_item(GtkWidget *unused, UiVarEventData *event) {
+    if(event->customint1) {
+        uic_unbind_var(event->var);
+    }
+    free(event);
+}
+
 void add_radioitem_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) {
-    // TODO
+    UiMenuRadioItem *ri = (UiMenuRadioItem*)item;
+    
+    UiVar *var = uic_widget_var(obj->ctx, obj->ctx, NULL, ri->varname, UI_VAR_INTEGER);
+    if(!var) {
+        fprintf(stderr, "Error: menu radioitem varname is null\n");
+        return;
+    }
+    int first = 0;
+    UiInteger *i = var->value;
+    GSList *group = i->obj;
+    GtkWidget *widget = gtk_radio_menu_item_new_with_label(group, ri->label);
+    gtk_menu_shell_append(GTK_MENU_SHELL(p), widget);
+    if(!group) {
+        i->get = ui_radioitem_get;
+        i->set = ui_radioitem_set;
+        first = 1;
+    }
+    i->obj = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(widget));
+    
+    UiVarEventData *event = malloc(sizeof(UiVarEventData));
+    memset(event, 0, sizeof(UiVarEventData));
+    event->obj = obj;
+    event->var = var;
+    event->callback = ri->callback;
+    event->userdata = ri->userdata;
+    event->customint1 = first;
+    
+    g_signal_connect(
+            widget,
+            "toggled",
+            G_CALLBACK(ui_menu_event_radio_item_toggled),
+            event);
+    g_signal_connect(
+            widget,
+            "destroy",
+            G_CALLBACK(ui_destroy_menu_radio_item),
+            event);
 }
 
 static void menuitem_list_remove_binding(void *obj) {
@@ -360,6 +424,47 @@
     gtk_check_menu_item_set_active(i->obj, (gboolean)value);
 }
 
+int64_t ui_radioitem_get(UiInteger *value) {
+    int selection = 0;
+    GSList *ls = value->obj;
+    guint len = g_slist_length(ls);
+    int i = 0;
+    while(ls) {
+        if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(ls->data))) {
+            selection = len - i;
+            break;
+        }
+        ls = ls->next;
+        i++;
+    }
+    
+    value->value = selection;
+    return selection;
+}
+
+void ui_radioitem_set(UiInteger *i, int64_t value) {
+    GSList *ls = i->obj;
+    
+    int len = g_slist_length(ls);
+    if(value > len) {
+        value = len;
+    }
+    int s = len - value;
+    int j = 0;
+    int unset = 1;
+    while(ls) {
+        if(j == s) {
+            gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ls->data), TRUE);
+            unset = 0;
+            break;
+        }
+        ls = ls->next;
+        j++;
+    }
+    
+    i->value = value;
+}
+
 
 /*
  * widget menu functions

mercurial