implement actions for buttons (Cocoa) default tip

Tue, 21 Apr 2026 10:11:44 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 21 Apr 2026 10:11:44 +0200
changeset 1099
a5057a367c8f
parent 1098
1f45788e0bac

implement actions for buttons (Cocoa)

ui/cocoa/EventData.h file | annotate | diff | comparison | revisions
ui/cocoa/EventData.m file | annotate | diff | comparison | revisions
ui/cocoa/Toolbar.m file | annotate | diff | comparison | revisions
ui/cocoa/action.h file | annotate | diff | comparison | revisions
ui/cocoa/action.m file | annotate | diff | comparison | revisions
ui/cocoa/button.m file | annotate | diff | comparison | revisions
ui/cocoa/menu.m file | annotate | diff | comparison | revisions
ui/cocoa/window.m file | annotate | diff | comparison | revisions
--- a/ui/cocoa/EventData.h	Mon Apr 20 21:19:13 2026 +0200
+++ b/ui/cocoa/EventData.h	Tue Apr 21 10:11:44 2026 +0200
@@ -37,11 +37,12 @@
 @property int                vartype;
 @property ui_callback        callback;
 @property void               *userdata;
+@property NSString           *action;
 @property void               *data;
 @property int                value;
 @property get_eventdata_func get_eventdata;
 
-- (EventData*)init:(ui_callback)cb userdata:(void*)userdata;
+- (EventData*)init:(ui_callback)cb userdata:(void*)userdata action:(const char*)action;
 
 - (void)handleEvent:(id)sender;
 
--- a/ui/cocoa/EventData.m	Mon Apr 20 21:19:13 2026 +0200
+++ b/ui/cocoa/EventData.m	Tue Apr 21 10:11:44 2026 +0200
@@ -27,29 +27,38 @@
  */
 
 #import "EventData.h"
+#import "action.h"
 
 #import <objc/runtime.h>
 
 
 @implementation EventData
 
-- (EventData*)init:(ui_callback)cb userdata:(void*)userdata {
+- (EventData*)init:(ui_callback)cb userdata:(void*)userdata action:(const char*)action {
     _callback = cb;
     _userdata = userdata;
+    if(action != nil) {
+        _action = [[NSString alloc]initWithUTF8String:action];
+    }
     return self;
 }
 
 - (void)handleEvent:(id)sender {
-    if(_callback) {
-        UiEvent event;
-        event.obj = self.obj;
-        event.window = event.obj->window;
-        event.document = event.obj->ctx->document;
-        event.eventdata = self.data;
-        event.intval = self.value;
-        event.set = ui_get_setop();
+    UiEvent event;
+    event.obj = self.obj;
+    event.window = event.obj->window;
+    event.document = event.obj->ctx->document;
+    event.eventdata = self.data;
+    event.intval = self.value;
+    event.set = ui_get_setop();
+    
+    if(_callback != nil) {
         self.callback(&event, self.userdata);
     }
+    
+    if(_action != nil) {
+        uic_action_callback(&event, self.action.UTF8String);
+    }
 }
 
 - (void)handleEventWithEventData:(id)sender {
--- a/ui/cocoa/Toolbar.m	Mon Apr 20 21:19:13 2026 +0200
+++ b/ui/cocoa/Toolbar.m	Tue Apr 21 10:11:44 2026 +0200
@@ -220,7 +220,7 @@
     }
     
     if(item->args.onclick) {
-        EventData *event = [[EventData alloc] init:item->args.onclick userdata:item->args.onclickdata];
+        EventData *event = [[EventData alloc] init:item->args.onclick userdata:item->args.onclickdata action:item->args.action];
         event.obj = obj;
         button.target = event;
         button.action = @selector(handleEvent:);
--- a/ui/cocoa/action.h	Mon Apr 20 21:19:13 2026 +0200
+++ b/ui/cocoa/action.h	Tue Apr 21 10:11:44 2026 +0200
@@ -28,3 +28,7 @@
 
 #include "../ui/toolkit.h"
 #include "../common/action.h"
+
+#import "widget.h"
+
+void ui_cocoa_view_bind_action(UiContext *ctx, NSView *view, const char *action);
--- a/ui/cocoa/action.m	Mon Apr 20 21:19:13 2026 +0200
+++ b/ui/cocoa/action.m	Tue Apr 21 10:11:44 2026 +0200
@@ -51,3 +51,15 @@
     
     // TODO: accelerator
 }
+
+
+void ui_cocoa_view_bind_action(UiContext *ctx, NSView *view, const char *action) {
+    if(action) {
+        void *widget = (__bridge void*)view;
+        uic_bind_action(ctx, action, widget, (ui_enablefunc)ui_set_enabled);
+        UiAction *ui_action = uic_resolve_action(ctx, action);
+        if(!ui_action) {
+            ui_set_enabled(widget, FALSE);
+        }
+    }
+}
--- a/ui/cocoa/button.m	Mon Apr 20 21:19:13 2026 +0200
+++ b/ui/cocoa/button.m	Tue Apr 21 10:11:44 2026 +0200
@@ -30,6 +30,7 @@
 #import "EventData.h"
 #import "container.h"
 #import "image.h"
+#import "action.h"
 #import <objc/runtime.h>
 
 #import <cx/buffer.h>
@@ -47,7 +48,7 @@
     }
     
     if(args->onclick) {
-        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:args->action];
         event.obj = obj;
         button.target = event;
         button.action = @selector(handleEvent:);
@@ -88,8 +89,8 @@
         i->set = ui_togglebutton_set;
     }
     
-    if(args->onchange) {
-        EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata];
+    if(args->onchange || args->action) {
+        EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata action:args->action];
         event.get_eventdata = togglebutton_eventdata;
         event.obj = obj;
         event.var = var;
@@ -97,6 +98,8 @@
         button.target = event;
         button.action = @selector(handleEventWithEventData:);
         objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+        
+        ui_cocoa_view_bind_action(obj->ctx, button, args->action);
     }
     
     UiLayout layout = UI_INIT_LAYOUT(args);
@@ -149,8 +152,8 @@
         i->set = ui_switch_set;
     }
     
-    if(args->onchange) {
-        EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata];
+    if(args->onchange || args->action) {
+        EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata action:args->action];
         event.get_eventdata = switch_eventdata;
         event.obj = obj;
         event.var = var;
@@ -158,6 +161,7 @@
         button.target = event;
         button.action = @selector(handleEventWithEventData:);
         objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+        ui_cocoa_view_bind_action(obj->ctx, button, args->action);
     }
     
     UiLayout layout = UI_INIT_LAYOUT(args);
@@ -238,18 +242,19 @@
         objc_setAssociatedObject(button, "radiogroup", buttons, OBJC_ASSOCIATION_RETAIN);
     }
     
-    if(args->onchange || var) {
-        EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata];
+    if(args->onchange || args->action || var) {
+        EventData *event = [[EventData alloc] init:args->onchange userdata:args->onchangedata action:args->action];
         event.get_eventdata = radiobutton_eventdata;
         event.obj = obj;
         event.var = var;
         event.vartype = UI_VAR_INTEGER;
         button.target = event;
         
-        
         button.action = @selector(handleEventWithEventData:);
         
         objc_setAssociatedObject(button, "eventdata", event, OBJC_ASSOCIATION_RETAIN);
+        
+        ui_cocoa_view_bind_action(obj->ctx, button, args->action);
     }
     
     UiLayout layout = UI_INIT_LAYOUT(args);
--- a/ui/cocoa/menu.m	Mon Apr 20 21:19:13 2026 +0200
+++ b/ui/cocoa/menu.m	Tue Apr 21 10:11:44 2026 +0200
@@ -112,7 +112,7 @@
     NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuItemAction) keyEquivalent:@""];
     
     if(it->callback) {
-        EventData *event = [[EventData alloc] init:it->callback userdata:it->userdata];
+        EventData *event = [[EventData alloc] init:it->callback userdata:it->userdata action:it->action];
         if(obj) {
             event.obj = obj;
             menuItem.target = event;
--- a/ui/cocoa/window.m	Mon Apr 20 21:19:13 2026 +0200
+++ b/ui/cocoa/window.m	Tue Apr 21 10:11:44 2026 +0200
@@ -343,7 +343,7 @@
             [lbutton1.leadingAnchor constraintEqualToAnchor:buttonArea.leadingAnchor constant:0]
         ]];
         
-        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:nil];
         event.obj = obj;
         event.value = 1;
         lbutton1.target = event;
@@ -363,7 +363,7 @@
             [lbutton2.leadingAnchor constraintEqualToAnchor:anchor constant:off]
         ]];
         
-        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:nil];
         event.obj = obj;
         event.value = 2;
         lbutton2.target = event;
@@ -382,7 +382,7 @@
             [rbutton4.trailingAnchor constraintEqualToAnchor:buttonArea.trailingAnchor constant:0]
         ]];
         
-        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:nil];
         event.obj = obj;
         event.value = 2;
         rbutton4.target = event;
@@ -402,7 +402,7 @@
             [rbutton3.trailingAnchor constraintEqualToAnchor:anchor constant:off]
         ]];
         
-        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata];
+        EventData *event = [[EventData alloc] init:args->onclick userdata:args->onclickdata action:nil];
         event.obj = obj;
         event.value = 2;
         rbutton3.target = event;

mercurial