diff -r 77254bd6dccb -r c3dfcb8f0be7 ui/cocoa/menu.m --- a/ui/cocoa/menu.m Sun Jul 20 22:04:39 2025 +0200 +++ b/ui/cocoa/menu.m Sun Aug 24 15:24:16 2025 +0200 @@ -50,6 +50,28 @@ return self; } +- (void)handleToggleEvent:(id)sender { + NSMenuItem *item = (NSMenuItem*)sender; + if(!_state) { + item.state = NSControlStateValueOn; + } else { + item.state = NSControlStateValueOff; + } + _state = !_state; + + if(_callback) { + UiEvent event; + event.obj = _obj; + event.window = event.obj->window; + event.document = event.obj->ctx->document; + event.eventdata = NULL; + event.eventdatatype = 0; + event.intval = _state; + event.set = ui_get_setop(); + _callback(&event, _userdata); + } +} + @end static ui_menu_add_f createMenuItem[] = { @@ -63,61 +85,84 @@ /* UI_MENU_SEPARATOR */ add_menuseparator_widget }; -static void add_menu_items(NSMenu *parent, int i, UiMenu *menu) { +void ui_add_menu_items(UiObject *obj, NSMenu *parent, int i, UiMenu *menu) { UiMenuItemI *it = menu->items_begin; int index = 0; while(it) { - createMenuItem[it->type](parent, index, it); + createMenuItem[it->type](obj, parent, index, it); it = it->next; index++; } } -void add_menu_widget(NSMenu *parent, int i, UiMenuItemI *item) { +void add_menu_widget(UiObject *obj, NSMenu *parent, int i, UiMenuItemI *item) { UiMenu *it = (UiMenu*)item; NSString *str = [[NSString alloc] initWithUTF8String:it->label]; NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; NSMenuItem *menuItem = [parent addItemWithTitle:str action:nil keyEquivalent:@""]; [parent setSubmenu:menu forItem:menuItem]; - add_menu_items(menu, i, it); + ui_add_menu_items(obj, menu, i, it); } -void add_menuitem_widget(NSMenu *parent, int i, UiMenuItemI *item) { +void add_menuitem_widget(UiObject *obj, NSMenu *parent, int i, UiMenuItemI *item) { UiMenuItem *it = (UiMenuItem*)item; NSString *str = [[NSString alloc] initWithUTF8String:it->label]; - NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuItemAction:) keyEquivalent:@""]; + NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuItemAction) keyEquivalent:@""]; if(it->callback) { EventData *event = [[EventData alloc] init:it->callback userdata:it->userdata]; + if(obj) { + event.obj = obj; + menuItem.target = event; + menuItem.action = @selector(handleEvent:); + } objc_setAssociatedObject(menuItem, "eventdata", event, OBJC_ASSOCIATION_RETAIN); } } -void add_menuseparator_widget(NSMenu *parent, int i, UiMenuItemI *item) { +void add_menuseparator_widget(UiObject *obj, NSMenu *parent, int i, UiMenuItemI *item) { NSMenuItem *menuItem = [NSMenuItem separatorItem]; [parent addItem:menuItem]; } static int nItem = 0; -void add_checkitem_widget(NSMenu *parent, int i, UiMenuItemI *item) { +void add_checkitem_widget(UiObject *obj, NSMenu *parent, int i, UiMenuItemI *item) { UiMenuCheckItem *it = (UiMenuCheckItem*)item; NSString *str = [[NSString alloc] initWithUTF8String:it->label]; NSMenuItem *menuItem = [parent addItemWithTitle:str action:@selector(menuCheckItemAction:) keyEquivalent:@""]; MenuItem *mItem = [[MenuItem alloc] init:nItem++]; + mItem.menuItem = menuItem; + mItem.obj = obj; mItem.callback = it->callback; mItem.userdata = it->userdata; mItem.checkItem = it; + if(it->varname) { + mItem.varname = [[NSString alloc] initWithUTF8String:it->varname]; + } objc_setAssociatedObject(menuItem, "menuitem", mItem, OBJC_ASSOCIATION_RETAIN); - [bindingItems addObject:mItem]; + + if(!obj) { + [bindingItems addObject:mItem]; + } else { + mItem.var = uic_widget_var(obj->ctx, obj->ctx, NULL, it->varname, UI_VAR_INTEGER); + if(mItem.var) { + UiInteger *i = mItem.var->value; + i->obj = (__bridge void*)mItem; + i->get = ui_menu_toggleitem_get; + i->set = ui_menu_toggleitem_set; + } + menuItem.target = mItem; + menuItem.action = @selector(handleToggleEvent:); + } } -void add_radioitem_widget(NSMenu *parent, int index, UiMenuItemI *item) { +void add_radioitem_widget(UiObject *obj, NSMenu *parent, int index, UiMenuItemI *item) { UiMenuRadioItem *it = (UiMenuRadioItem*)item; NSString *str = [[NSString alloc] initWithUTF8String:it->label]; @@ -132,11 +177,11 @@ [bindingItems addObject:mItem]; } -void add_checkitemnv_widget(NSMenu *parent, int i, UiMenuItemI *item) { +void add_checkitemnv_widget(UiObject *obj, NSMenu *parent, int i, UiMenuItemI *item) { } -void add_menuitem_list_widget(NSMenu *parent, int i, UiMenuItemI *item) { +void add_menuitem_list_widget(UiObject *obj, NSMenu *parent, int i, UiMenuItemI *item) { } @@ -154,7 +199,7 @@ NSMenuItem *menuItem = [[NSApp mainMenu] insertItemWithTitle:str action:nil keyEquivalent:@"" atIndex:index]; [[NSApp mainMenu] setSubmenu:menu forItem:menuItem]; - add_menu_items(menu, 0, ls); + ui_add_menu_items(NULL, menu, 0, ls); } ls = (UiMenu*)ls->item.next; index++; @@ -164,3 +209,20 @@ NSArray* ui_get_binding_items(void) { return bindingItems; } + + +int64_t ui_menu_toggleitem_get(UiInteger *i) { + MenuItem *item = (__bridge MenuItem*)i->obj; + i->value = item.state; + return i->value; +} + +void ui_menu_toggleitem_set(UiInteger *i, int64_t value) { + MenuItem *item = (__bridge MenuItem*)i->obj; + i->value = value; + if(value != 0) { + item.menuItem.state = NSControlStateValueOn; + } else { + item.menuItem.state = NSControlStateValueOff; + } +}