add menu toggle/radio button (Motif) newapi

Sun, 15 Dec 2024 22:53:51 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 15 Dec 2024 22:53:51 +0100
branch
newapi
changeset 419
7d15cad351fc
parent 418
a57268d20ed9
child 420
28a5920bebe0

add menu toggle/radio button (Motif)

application/main.c file | annotate | diff | comparison | revisions
ui/common/menu.c file | annotate | diff | comparison | revisions
ui/common/menu.h file | annotate | diff | comparison | revisions
ui/motif/button.c file | annotate | diff | comparison | revisions
ui/motif/button.h file | annotate | diff | comparison | revisions
ui/motif/menu.c file | annotate | diff | comparison | revisions
--- a/application/main.c	Sun Dec 15 22:16:12 2024 +0100
+++ b/application/main.c	Sun Dec 15 22:53:51 2024 +0100
@@ -564,6 +564,12 @@
         ui_menuitem(.label = "Test 1", .onclick = action_test);
         ui_menuitem(.label = "Test 2", .onclick = action_test);
         ui_menuitem(.label = "Test 3", .onclick = action_test);
+        ui_menu_toggleitem(.label = "Toggle 1");
+        ui_menu_toggleitem(.label = "Toggle 2");
+        ui_menu_radioitem(.label = "Radio 1", .varname = "menu_radio");
+        ui_menu_radioitem(.label = "Radio 2", .varname = "menu_radio");
+        ui_menu_radioitem(.label = "Radio 3", .varname = "menu_radio");
+        ui_menu_radioitem(.label = "Radio 4", .varname = "menu_radio");
     }
     
     ui_main();
--- a/ui/common/menu.c	Sun Dec 15 22:16:12 2024 +0100
+++ b/ui/common/menu.c	Sun Dec 15 22:53:51 2024 +0100
@@ -175,7 +175,7 @@
     mitem_set_id(&item->item);
     item->item.prev = NULL;
     item->item.next = NULL;
-    item->item.type = UI_MENU_CHECK_ITEM;
+    item->item.type = UI_MENU_RADIO_ITEM;
 
     item->label = nl_strdup(args.label);
     item->stockid = nl_strdup(args.stockid);
--- a/ui/common/menu.h	Sun Dec 15 22:16:12 2024 +0100
+++ b/ui/common/menu.h	Sun Dec 15 22:53:51 2024 +0100
@@ -101,6 +101,7 @@
     char           *label;
     char           *stockid;
     char           *icon;
+    char           *varname;
     ui_callback    callback;
     void           *userdata;
     int            *groups;
--- a/ui/motif/button.c	Sun Dec 15 22:16:12 2024 +0100
+++ b/ui/motif/button.c	Sun Dec 15 22:53:51 2024 +0100
@@ -291,6 +291,55 @@
     }
 }
 
+void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, int enable_group) {
+    UiVar* var = uic_widget_var(obj->ctx, obj->ctx, value, varname, UI_VAR_INTEGER);
+    if(var) {
+        UiInteger *value = var->value;
+        CxList *rb = value->obj;
+        if(!rb) {
+            // first button in the radiobutton group
+            // create a list for all buttons and use the list as value obj
+            rb = cxArrayListCreateSimple(CX_STORE_POINTERS, 4);
+            value->obj = rb;
+            value->get = ui_radiobutton_get;
+            value->set = ui_radiobutton_set;
+            
+            // the first radio button is also responsible for cleanup
+            XtAddCallback(
+                    rbutton,
+                    XmNdestroyCallback,
+                    (XtCallbackProc)destroy_list,
+                    rb);
+        }
+        cxListAdd(rb, rbutton);
+        
+        // set the radiobutton state, if the value is already set
+        if(cxListSize(rb) == value->value) {
+            XmToggleButtonSetState(rbutton, True, False);
+        }
+    }
+    
+    // the radio button needs to handle change events to update all
+    // other buttons in the radio button group
+    UiVarEventData *event = malloc(sizeof(UiVarEventData));
+    event->obj = obj;
+    event->callback = onchange;
+    event->userdata = onchangedata;
+    event->observers = NULL;
+    event->var = var;
+    event->value = enable_group;
+    XtAddCallback(
+            rbutton,
+            XmNvalueChangedCallback,
+            (XtCallbackProc)radiobutton_changed,
+            event);
+    XtAddCallback(
+            rbutton,
+            XmNdestroyCallback,
+            (XtCallbackProc)ui_destroy_eventdata,
+            event);
+}
+
 UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) {
     Arg xargs[16];
     int n = 0;
--- a/ui/motif/button.h	Sun Dec 15 22:16:12 2024 +0100
+++ b/ui/motif/button.h	Sun Dec 15 22:53:51 2024 +0100
@@ -50,6 +50,8 @@
 int64_t ui_togglebutton_get(UiInteger *i);
 void ui_togglebutton_set(UiInteger *i, int64_t value);
 
+void ui_bind_radiobutton(UiObject *obj, Widget rbutton, UiInteger *value, const char *varname, ui_callback onchange, void *onchangedata, int enable_group);
+
 int64_t ui_radiobutton_get(UiInteger *i);
 void ui_radiobutton_set(UiInteger *i, int64_t value);
 
--- a/ui/motif/menu.c	Sun Dec 15 22:16:12 2024 +0100
+++ b/ui/motif/menu.c	Sun Dec 15 22:53:51 2024 +0100
@@ -147,6 +147,8 @@
                 (XtCallbackProc)ui_destroy_eventdata,
                 eventdata);
     }
+    
+    ui_set_widget_groups(obj->ctx, mitem, it->groups);
 }
 
 void add_menuseparator_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) {
@@ -155,11 +157,48 @@
 }
 
 void add_checkitem_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) {
+    UiMenuCheckItem *it = (UiMenuCheckItem*)item;
     
+    Arg args[4];
+    int n = 0;
+    XmString s = NULL;
+    if(it->label) {
+        s = XmStringCreateLocalized(it->label);
+        XtSetArg(args[n], XmNlabelString, s); n++;
+    }
+    
+    //XtSetArg(args[n], XmNvisibleWhenOff, 0); n++;
+    Widget checkbox = XtCreateManagedWidget(
+            "menutogglebutton",
+            xmToggleButtonWidgetClass,
+            p,
+            args,
+            n);
+    if(s) {
+        XmStringFree(s);
+    }
+    
+    ui_bind_togglebutton(obj, checkbox, it->varname, NULL, it->callback, it->userdata, 0);
+    
+    ui_set_widget_groups(obj->ctx, checkbox, it->groups);
 }
 
 void add_radioitem_widget(Widget p, int index, UiMenuItemI *item, UiObject *obj) {
+    UiMenuRadioItem *it = (UiMenuRadioItem*)item;
     
+    Arg args[4];
+    int n = 0;
+    XmString s = NULL;
+    if(it->label) {
+        s = XmStringCreateLocalized(it->label);
+        XtSetArg(args[n], XmNlabelString, s); n++;
+    }
+    XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY_ROUND); n++;
+    
+    Widget button = XmCreateToggleButton(p, "menuradiobutton", args, n);
+    XtManageChild(button);
+    
+    ui_bind_radiobutton(obj, button, NULL, it->varname, it->callback, it->userdata, 0);
 }
 
 void add_checkitemnv_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) {

mercurial