6 weeks ago
implement togglebutton, checkbox, switch and unfinished radiobutton (Cocoa)
make/xcode/toolkit/toolkit/main.m | file | annotate | diff | comparison | revisions | |
ui/cocoa/EventData.h | file | annotate | diff | comparison | revisions | |
ui/cocoa/EventData.m | file | annotate | diff | comparison | revisions | |
ui/cocoa/MainWindow.m | file | annotate | diff | comparison | revisions | |
ui/cocoa/button.h | file | annotate | diff | comparison | revisions | |
ui/cocoa/button.m | file | annotate | diff | comparison | revisions | |
ui/ui/button.h | file | annotate | diff | comparison | revisions |
--- a/make/xcode/toolkit/toolkit/main.m Thu Jan 23 21:08:43 2025 +0100 +++ b/make/xcode/toolkit/toolkit/main.m Sun Feb 02 13:50:38 2025 +0100 @@ -37,18 +37,32 @@ void application_startup(UiEvent *event, void *data) { UiObject *obj = ui_window("My Window", NULL); + ui_grid(obj, .rowspacing = 10) { + ui_button(obj, .label = "Button X1 -------------------------------------------------- END", .onclick = action_button); + ui_newline(obj); + + ui_togglebutton(obj, .label = "Togglebutton"); + ui_newline(obj); + + ui_checkbox(obj, .label = "Checkbox"); + ui_newline(obj); + + ui_switch(obj, .label = "Switch"); + ui_newline(obj); + + ui_radiobutton(obj, .label = "Z Radio 1", .varname = "radio1"); + ui_radiobutton(obj, .label = "Z Radio 2", .varname = "radio1"); + ui_radiobutton(obj, .label = "Z Radio 3", .varname = "radio1"); + + ui_newline(obj); + + ui_radiobutton(obj, .label = "X Radio 1", .varname = "radio2"); + ui_radiobutton(obj, .label = "X Radio 2", .varname = "radio2"); + ui_radiobutton(obj, .label = "X Radio 3", .varname = "radio2"); + ui_newline(obj); + } - ui_button(obj, .label = "Button X1 -------------------------------------------------- END", .onclick = action_button, .hfill = 1); - ui_newline(obj); - ui_button(obj, .label = "Button X2", .hfill = 1); - ui_button(obj, .label = "Button X3", .hexpand = TRUE, .hfill = 1); - ui_button(obj, .label = "Button X4", .hfill = 1); - ui_newline(obj); - ui_button(obj, .label = "Button X5", .hfill = 0); - ui_button(obj, .label = "Button X5.1", .hfill = 1); - ui_button(obj, .label = "Button X5.6", .rowspan = 2); - ui_newline(obj); - ui_button(obj, .label = "Button X6", .hfill = 1, .colspan = 2); + ui_show(obj);
--- a/ui/cocoa/EventData.h Thu Jan 23 21:08:43 2025 +0100 +++ b/ui/cocoa/EventData.h Sun Feb 02 13:50:38 2025 +0100 @@ -29,15 +29,24 @@ #import "../ui/toolkit.h" #import "../common/context.h" +typedef void(*get_eventdata_func)(id sender, UiVar *var, void **eventdata, int *value); + @interface EventData : NSObject -@property UiObject *obj; -@property ui_callback callback; -@property void *userdata; -@property void *data; -@property int value; +@property UiObject *obj; +@property UiVar *var; +@property int vartype; +@property ui_callback callback; +@property void *userdata; +@property void *data; +@property int value; +@property get_eventdata_func get_eventdata; - (EventData*)init:(ui_callback)cb userdata:(void*)userdata; - (void)handleEvent:(id)sender; +- (void)handleEventWithEventData:(id)sender; + +- (SEL)addDynamicMethod:(unsigned long long)method_id; + @end
--- a/ui/cocoa/EventData.m Thu Jan 23 21:08:43 2025 +0100 +++ b/ui/cocoa/EventData.m Sun Feb 02 13:50:38 2025 +0100 @@ -28,6 +28,9 @@ #import "EventData.h" +#import <objc/runtime.h> + + @implementation EventData - (EventData*)init:(ui_callback)cb userdata:(void*)userdata { @@ -37,7 +40,7 @@ } - (void)handleEvent:(id)sender { - if(self.callback) { + if(_callback) { UiEvent event; event.obj = self.obj; event.window = event.obj->window; @@ -48,5 +51,19 @@ } } +- (void)handleEventWithEventData:(id)sender { + UiEvent event; + event.obj = self.obj; + event.window = event.obj->window; + event.document = event.obj->ctx->document; + event.eventdata = NULL; + event.intval = 0; + if(_get_eventdata) { + _get_eventdata(sender, _var, &event.eventdata, &event.intval); + } + if(self.callback) { + self.callback(&event, self.userdata); + } +} @end
--- a/ui/cocoa/MainWindow.m Thu Jan 23 21:08:43 2025 +0100 +++ b/ui/cocoa/MainWindow.m Sun Feb 02 13:50:38 2025 +0100 @@ -46,8 +46,8 @@ defer:false]; // create a vertical stackview as default container - //BoxContainer *vbox = [[BoxContainer alloc] init:NSUserInterfaceLayoutOrientationVertical spacing:0]; - GridLayout *vbox = [[GridLayout alloc] init]; + BoxContainer *vbox = [[BoxContainer alloc] init:NSUserInterfaceLayoutOrientationVertical spacing:0]; + //GridLayout *vbox = [[GridLayout alloc] init]; vbox.translatesAutoresizingMaskIntoConstraints = false; [self.contentView addSubview:vbox]; [NSLayoutConstraint activateConstraints:@[
--- a/ui/cocoa/button.h Thu Jan 23 21:08:43 2025 +0100 +++ b/ui/cocoa/button.h Sun Feb 02 13:50:38 2025 +0100 @@ -29,3 +29,12 @@ #import "toolkit.h" #import "../ui/button.h" + +int64_t ui_togglebutton_get(UiInteger *i); +void ui_togglebutton_set(UiInteger *i, int64_t value); + +int64_t ui_switch_get(UiInteger *i); +void ui_switch_set(UiInteger *i, int64_t value); + +int64_t ui_radiobuttons_get(UiInteger *i); +void ui_radiobuttons_set(UiInteger *i, int64_t value);
--- a/ui/cocoa/button.m Thu Jan 23 21:08:43 2025 +0100 +++ b/ui/cocoa/button.m Sun Feb 02 13:50:38 2025 +0100 @@ -51,3 +51,178 @@ return (__bridge void*)button; } + + +static void togglebutton_eventdata(id button, UiVar *var, void **eventdata, int *value) { + NSButton *btn = (NSButton*)button; + NSControlStateValue state = btn.state; + *value = (int)state; +} + +UIWIDGET togglebutton_create(UiObject* obj, UiToggleArgs args, enum NSButtonType type) { + NSButton *button = [[NSButton alloc] init]; + [button setButtonType:type]; + //[button setAllowsMixedState:YES]; + + if(args.label) { + NSString *label = [[NSString alloc] initWithUTF8String:args.label]; + button.title = label; + } + + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_INTEGER); + if(var) { + UiInteger *i = var->value; + i->obj = (__bridge void*)button; + i->get = ui_togglebutton_get; + i->set = ui_togglebutton_set; + } + + if(args.onchange) { + EventData *event = [[EventData alloc] init:args.onchange userdata:args.onchangedata]; + event.get_eventdata = togglebutton_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); + } + + UiLayout layout = UI_INIT_LAYOUT(args); + ui_container_add(obj, button, &layout, FALSE); + + return (__bridge void*)button; +} + +int64_t ui_togglebutton_get(UiInteger *i) { + NSButton *button = (__bridge NSButton*)i->obj; + NSControlStateValue state = button.state; + i->value = (int64_t)state; + return (int64_t)state; +} + +void ui_togglebutton_set(UiInteger *i, int64_t value) { + NSButton *button = (__bridge NSButton*)i->obj; + NSControlStateValue state; + switch(value) { + case 0: state = NSControlStateValueOff; break; + case 1: state = NSControlStateValueOff; break; + default: state = NSControlStateValueMixed; + } + i->value = (int64_t)state; + button.state = state; +} + +UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args) { + return togglebutton_create(obj, args, NSButtonTypePushOnPushOff); +} + +UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args) { + return togglebutton_create(obj, args, NSButtonTypeSwitch); +} + +static void switch_eventdata(id button, UiVar *var, void **eventdata, int *value) { + NSSwitch *btn = (NSSwitch*)button; + NSControlStateValue state = btn.state; + *value = (int)state; +} + +UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) { + NSSwitch *button = [[NSSwitch alloc] init]; + + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_INTEGER); + if(var) { + UiInteger *i = var->value; + i->obj = (__bridge void*)button; + i->get = ui_switch_get; + i->set = ui_switch_set; + } + + if(args.onchange) { + EventData *event = [[EventData alloc] init:args.onchange userdata:args.onchangedata]; + event.get_eventdata = switch_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); + } + + UiLayout layout = UI_INIT_LAYOUT(args); + ui_container_add(obj, button, &layout, FALSE); + + return (__bridge void*)button; +} + +int64_t ui_switch_get(UiInteger *i) { + NSSwitch *button = (__bridge NSSwitch*)i->obj; + NSControlStateValue state = button.state; + i->value = (int64_t)state; + return (int64_t)state; +} + +void ui_switch_set(UiInteger *i, int64_t value) { + NSSwitch *button = (__bridge NSSwitch*)i->obj; + NSControlStateValue state; + switch(value) { + case 0: state = NSControlStateValueOff; break; + case 1: state = NSControlStateValueOff; break; + default: state = NSControlStateValueMixed; + } + i->value = (int64_t)state; + button.state = state; +} + +static void radiobutton_eventdata(id button, UiVar *var, void **eventdata, int *value) { + if(var) { + printf("switch radiobutton\n"); + } +} + +UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) { + NSButton *button = [[NSButton alloc] init]; + [button setButtonType:NSButtonTypeRadio]; + + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_INTEGER); + NSMutableArray *buttons = nil; + if(var) { + UiInteger *i = var->value; + buttons = (__bridge NSMutableArray*)i->obj; + if(!buttons) { + buttons = [[NSMutableArray alloc] init]; + i->obj = (__bridge void*)buttons; + i->get = ui_radiobuttons_get; + i->set = ui_radiobuttons_set; + } + [buttons addObject:button]; + objc_setAssociatedObject(button, "radiogroup", buttons, OBJC_ASSOCIATION_RETAIN); + } + + if(args.onchange || var) { + EventData *event = [[EventData alloc] init:args.onchange userdata:args.onchangedata]; + 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); + } + + UiLayout layout = UI_INIT_LAYOUT(args); + ui_container_add(obj, button, &layout, FALSE); + + return (__bridge void*)button; +} + +int64_t ui_radiobuttons_get(UiInteger *i) { + return 0; +} + +void ui_radiobuttons_set(UiInteger *i, int64_t value) { + +}