fix gtk4 checkbox and radiobutton newapi tip

Wed, 18 Sep 2024 22:54:50 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Wed, 18 Sep 2024 22:54:50 +0200
branch
newapi
changeset 301
f9e7c57e1e2f
parent 300
2f924f7ca901

fix gtk4 checkbox and radiobutton

application/main.c file | annotate | diff | comparison | revisions
ui/gtk/button.c file | annotate | diff | comparison | revisions
--- a/application/main.c	Tue Sep 17 22:07:57 2024 +0200
+++ b/application/main.c	Wed Sep 18 22:54:50 2024 +0200
@@ -110,7 +110,7 @@
     
     ui_button(obj, .label = "Test Button", .icon = "application-x-generic", .onclick = action_button);
     ui_togglebutton(obj, .label = "Toggle");
-    ui_checkbox(obj, .label = "Checkbox");
+    ui_checkbox(obj, .label = "My Checkbox");
     
     ui_grid(obj, .fill = 1, .columnspacing = 15, .rowspacing = 15, .margin = 15) {
         ui_button(obj, .label = "cell1", .hexpand = TRUE);
@@ -142,13 +142,11 @@
         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);
--- a/ui/gtk/button.c	Tue Sep 17 22:07:57 2024 +0200
+++ b/ui/gtk/button.c	Wed Sep 18 22:54:50 2024 +0200
@@ -113,14 +113,14 @@
 }
 
 void ui_toggled_obs(GtkToggleButton *widget, UiVarEventData *event) {
+    UiInteger *i = event->var->value;
     UiEvent e;
     e.obj = event->obj;
     e.window = event->obj->window;
     e.document = event->obj->ctx->document;
     e.eventdata = event->var->value;
-    e.intval = gtk_toggle_button_get_active(widget);
+    e.intval = i->get(i);  
     
-    UiInteger *i = event->var->value;
     ui_notify_evt(i->observers, &e);
 }
 
@@ -168,9 +168,62 @@
     return togglebutton_create(obj, gtk_toggle_button_new(), args);
 }
 
+#if GTK_MAJOR_VERSION >= 4
+
+int64_t ui_check_button_get(UiInteger *integer) {
+    GtkCheckButton *button = integer->obj;
+    integer->value = (int)gtk_check_button_get_active(button);
+    return integer->value;
+}
+
+void ui_check_button_set(UiInteger *integer, int64_t value) {
+    GtkCheckButton *button = integer->obj;
+    integer->value = value;
+    gtk_check_button_set_active(button, value != 0 ? TRUE : FALSE);
+}
+
+UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
+    UiObject* current = uic_current_obj(obj);
+    
+    GtkWidget *widget = gtk_check_button_new_with_label(args.label);
+    
+    UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER);
+    if (var) {
+        UiInteger* value = (UiInteger*)var->value;
+        value->obj = widget;
+        value->get = ui_check_button_get;
+        value->set = ui_check_button_set;
+        
+        UiVarEventData *event = malloc(sizeof(UiVarEventData));
+        event->obj = obj;
+        event->var = var;
+        event->observers = NULL;
+        event->callback = NULL;
+        event->userdata = NULL;
+
+        g_signal_connect(
+                widget,
+                "toggled",
+                G_CALLBACK(ui_toggled_obs),
+                event);
+        g_signal_connect(
+                widget,
+                "destroy",
+                G_CALLBACK(ui_destroy_vardata),
+                event);
+    }
+    
+    UI_APPLY_LAYOUT1(current, args);
+    current->container->add(current->container, widget, FALSE);
+    
+    return widget;
+}
+
+#else
 UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) {
     return togglebutton_create(obj, gtk_check_button_new(), args);
 }
+#endif
 
 UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) {
 #ifdef UI_GTK3
@@ -181,12 +234,10 @@
 }
 
 #if GTK_MAJOR_VERSION >= 4
-#define RADIO_GROUP GtkCheckButton
 #define RADIOBUTTON_NEW(group, label) gtk_check_button_new_with_label(label)
 #define RADIOBUTTON_SET_GROUP(button, group) 
 #define RADIOBUTTON_GET_GROUP(button) GTK_CHECK_BUTTON(button)
 #else
-#define RADIO_GROUP GSList
 #define RADIOBUTTON_NEW(group, label) gtk_radio_button_new_with_label(group, label)
 #define RADIOBUTTON_SET_GROUP(button, group) /* noop */
 #define RADIOBUTTON_GET_GROUP(button) gtk_radio_button_get_group(GTK_RADIO_BUTTON(button))
@@ -195,7 +246,7 @@
 UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs args) {
     UiObject* current = uic_current_obj(obj);
     
-    RADIO_GROUP *rg = NULL;
+    GSList *rg = NULL;
     UiInteger *rgroup;
     
     UiVar* var = NULL;
@@ -214,10 +265,18 @@
         }
     }
     
-    GtkWidget *rbutton = RADIOBUTTON_NEW(rg, args.label);
-    rg = RADIOBUTTON_GET_GROUP(rbutton);
-    
+    GtkWidget *rbutton = RADIOBUTTON_NEW(rg, args.label); 
     if(rgroup) {
+#if GTK_MAJOR_VERSION >= 4
+        if(rg) {
+            gtk_check_button_set_group(GTK_CHECK_BUTTON(rbutton), rg->data);
+        }
+        rg = g_slist_prepend(rg, rbutton);
+#else
+        gtk_radio_button_set_group(GTK_RADIO_BUTTON(rbutton), rg);
+        rg = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbutton));
+#endif
+        
         rgroup->obj = rg;
         rgroup->get = ui_radiobutton_get;
         rgroup->set = ui_radiobutton_set;
@@ -233,7 +292,7 @@
         
         g_signal_connect(
                 rbutton,
-                "clicked",
+                "toggled",
                 G_CALLBACK(ui_radio_obs),
                 event);
         if(first) {
@@ -264,6 +323,41 @@
     ui_notify_evt(i->observers, &e);
 }
 
+#if GTK_MAJOR_VERSION >= 4
+int64_t ui_radiobutton_get(UiInteger *value) {
+    int selection = 0;
+    GSList *ls = value->obj;
+    int i = 0;
+    guint len = g_slist_length(ls);
+    while(ls) {
+        if(gtk_check_button_get_active(GTK_CHECK_BUTTON(ls->data))) {
+            selection = len - i - 1;
+            break;
+        }
+        ls = ls->next;
+        i++;
+    }
+    
+    value->value = selection;
+    return selection;
+}
+
+void ui_radiobutton_set(UiInteger *value, int64_t i) {
+    GSList *ls = value->obj;
+    int s = g_slist_length(ls) - 1 - i;
+    int j = 0;
+    while(ls) {
+        if(j == s) {
+            gtk_check_button_set_active(GTK_CHECK_BUTTON(ls->data), TRUE);
+            break;
+        }
+        ls = ls->next;
+        j++;
+    }
+    
+    value->value = i;
+}
+#else
 int64_t ui_radiobutton_get(UiInteger *value) {
     int selection = 0;
     GSList *ls = value->obj;
@@ -297,4 +391,4 @@
     
     value->value = i;
 }
-
+#endif

mercurial