diff -r 64ded9f6a6c6 -r 6606616eca9f ui/cocoa/menu.m --- a/ui/cocoa/menu.m Tue Feb 25 21:11:00 2025 +0100 +++ b/ui/cocoa/menu.m Sat Apr 05 16:46:11 2025 +0200 @@ -33,287 +33,77 @@ #import "menu.h" #import "window.h" -#import "stock.h" - -@implementation UiMenuDelegate -- (UiMenuDelegate*) init { - items = NULL; - itemlists = NULL; - return self; -} +static ui_menu_add_f createMenuItem[] = { + /* UI_MENU */ add_menu_widget, + /* UI_MENU_ITEM */ add_menuitem_widget, + /* UI_MENU_CHECK_ITEM */ add_checkitem_widget, + /* UI_MENU_RADIO_ITEM */ add_radioitem_widget, + /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget, + /* UI_MENU_CHECKITEM_LIST */ add_menuitem_list_widget, + /* UI_MENU_RADIOITEM_LIST */ add_menuitem_list_widget, + /* UI_MENU_SEPARATOR */ add_menuseparator_widget +}; -- (void) menuNeedsUpdate:(NSMenu *) menu { - NSWindow *activeWindow = [NSApp keyWindow]; - [(UiCocoaWindow*)activeWindow updateMenu: menu]; +static void add_menu_items(NSMenu *parent, int i, UiMenu *menu) { + UiMenuItemI *it = menu->items_begin; + int index = 0; + while(it) { + createMenuItem[it->type](parent, index, it); + it = it->next; + index++; + } } -- (void) addItem:(NSMenuItem*) item var: (char*)name { - UiStateItem *i = malloc(sizeof(UiStateItem)); - i->item = item; - i->var = name; - items = ucx_list_append(items, i); +void add_menu_widget(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); } -- (void) addList:(UiList*) list menu:(NSMenu*)menu index: (int)i callback: (ui_callback)f data:(void*) data { - UiMenuItemList *itemList = malloc(sizeof(UiMenuItemList)); - itemList->list = list; - itemList->menu = menu; - itemList->first = NULL; - itemList->index = i; - itemList->oldcount = 0; - itemList->callback = f; - itemList->data = data; - itemlists = ucx_list_append(itemlists, itemList); +void add_menuitem_widget(NSMenu *parent, int i, UiMenuItemI *item) { + UiMenuItem *it = (UiMenuItem*)item; + NSString *str = [[NSString alloc] initWithUTF8String:it->label]; + NSMenuItem *menuItem = [parent addItemWithTitle:str action:nil keyEquivalent:@""]; } -- (UcxList*) items { - return items; -} - -- (UcxList*) lists { - return itemlists; +void add_menuseparator_widget(NSMenu *parent, int i, UiMenuItemI *item) { } -@end - - -@implementation UiGroupMenuItem - -- (id)initWithTitle:(NSString*)title action:(SEL)action keyEquivalent:(NSString*)s { - [super initWithTitle:title action:action keyEquivalent:s]; - groups = [[NSMutableArray alloc]initWithCapacity: 8]; - return self; -} - -- (void) addGroup:(int)group { - NSNumber *groupNumber = [NSNumber numberWithInteger:group]; - [groups addObject:groupNumber]; +void add_checkitem_widget(NSMenu *parent, int i, UiMenuItemI *item) { + } -- (void) checkGroups:(int*)g count:(int)n { - int c = [groups count]; +void add_radioitem_widget(NSMenu *parent, int index, UiMenuItemI *item) { - char *check = calloc(1, c); - for(int i=0;idata; - - NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; - NSMenuItem *menuItem = [currentMenu addItemWithTitle:str - action:nil keyEquivalent:@""]; - [menu setDelegate: delegate]; - [menu setAutoenablesItems:NO]; - - [currentMenu setSubmenu:menu forItem:menuItem]; - //currentMenu = menu; - currentItemIndex = 0; - - current = ucx_list_prepend(current, menu); -} - -void ui_submenu_end() { - if(ucx_list_size(current) < 2) { - return; - } - current = ucx_list_remove(current, current); -} - -void ui_menuitem(char *label, ui_callback f, void *data) { - ui_menuitem_gr(label, f, data, -1); -} - -void ui_menuitem_st(char *stockid, ui_callback f, void *data) { - ui_menuitem_stgr(stockid, f, data, -1); -} - -void ui_menuitem_gr(char *label, ui_callback f, void *userdata, ...) { - // create menu item - EventWrapper *event = [[EventWrapper alloc]initWithData:userdata callback:f]; - NSString *title = [[NSString alloc] initWithUTF8String:label]; - UiGroupMenuItem *item = [[UiGroupMenuItem alloc]initWithTitle:title action:@selector(handleEvent:) keyEquivalent:@""]; - [item setTarget:event]; - - // add groups - va_list ap; - va_start(ap, userdata); - int group; - while((group = va_arg(ap, int)) != -1) { - [item addGroup: group]; - } - va_end(ap); - - NSMenu *currentMenu = current->data; - [currentMenu addItem:item]; - - currentItemIndex++; -} - -void ui_menuitem_stgr(char *stockid, ui_callback f, void *userdata, ...) { - // create menu item - EventWrapper *event = [[EventWrapper alloc]initWithData:userdata callback:f]; - UiStockItem *si = ui_get_stock_item(stockid); - UiGroupMenuItem *item = [[UiGroupMenuItem alloc]initWithTitle:si->label - action:@selector(handleEvent:) - keyEquivalent:si->keyEquivalent]; - [item setTarget:event]; - - // add groups - va_list ap; - va_start(ap, userdata); - int group; - while((group = va_arg(ap, int)) != -1) { - [item addGroup: group]; +void ui_menu_init(void) { + UiMenu *menus_begin = uic_get_menu_list(); + UiMenu *ls = menus_begin; + while(ls) { + if(ls->item.type == UI_MENU) { + NSString *str = [[NSString alloc] initWithUTF8String:ls->label]; + NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; + NSMenuItem *menuItem = [[NSApp mainMenu] addItemWithTitle:str action:nil keyEquivalent:@""]; + [[NSApp mainMenu] setSubmenu:menu forItem:menuItem]; + + add_menu_items(menu, 0, ls); + } + ls = (UiMenu*)ls->item.next; } - va_end(ap); - - NSMenu *currentMenu = current->data; - [currentMenu addItem:item]; - - currentItemIndex++; } - -void ui_checkitem(char *label, ui_callback f, void *data) { - EventWrapper *event = [[EventWrapper alloc]initWithData:data callback:f]; - NSString *str = [[NSString alloc] initWithUTF8String:label]; - - NSMenu *currentMenu = current->data; - NSMenuItem *item = [currentMenu addItemWithTitle:str - action:@selector(handleStateEvent:) keyEquivalent:@""]; - [item setTarget:event]; - - [delegate addItem: item var:NULL]; - currentItemIndex++; -} - -void ui_checkitem_nv(char *label, char *vname) { - EventWrapper *event = [[EventWrapper alloc]initWithData:NULL callback:NULL]; - NSString *str = [[NSString alloc] initWithUTF8String:label]; - - NSMenu *currentMenu = current->data; - NSMenuItem *item = [currentMenu addItemWithTitle:str - action:@selector(handleStateEvent:) keyEquivalent:@""]; - [item setTarget:event]; - - [delegate addItem: item var:vname]; - currentItemIndex++; -} - -void ui_menuseparator() { - NSMenu *currentMenu = current->data; - [currentMenu addItem: [NSMenuItem separatorItem]]; - currentItemIndex++; -} - -void ui_menuitem_list (UiList *items, ui_callback f, void *data) { - NSMenu *currentMenu = current->data; - [delegate addList:items menu:currentMenu index:currentItemIndex callback:f data:data]; -} - - - -int ui_menuitem_get(UiInteger *i) { - UiMenuItem *item = i->obj; - i->value = [item->item state]; - return i->value; -} - -void ui_menuitem_set(UiInteger *i, int value) { - UiMenuItem *item = i->obj; - [item->item setState: value]; - i->value = value; - item->state = value; -} - - -int ui_update_item(UiCocoaWindow *window, void *data) { - UiMenuItem *item = data; - [item->item setState: item->state]; - return 0; -} - -int ui_update_item_list(UiCocoaWindow *window, void *data) { - UiMenuItemList *itemList = data; - UiList *list = itemList->list; - - for(int r=0;roldcount;r++) { - [itemList->menu removeItemAtIndex:itemList->index]; - } - - char *str = ui_list_first(list); - int i = itemList->index; - [itemList->menu insertItem: [NSMenuItem separatorItem] atIndex: i]; - i++; - while(str) { - EventWrapper *event = [[EventWrapper alloc]initWithData:itemList->data callback:itemList->callback]; - [event setIntval: i - itemList->index - 1]; - - NSString *title = [[NSString alloc] initWithUTF8String:str]; - NSMenuItem *item = [[NSMenuItem alloc]initWithTitle:title action:@selector(handleEvent:) keyEquivalent:@""]; - [item setTarget:event]; - - [itemList->menu insertItem:item atIndex:i]; - - str = ui_list_next(list); - i++; - } - - itemList->oldcount = i - itemList->index; - - return 0; -}