libui/darwin/menu.m

143 lines
4.2 KiB
Objective-C

// 20 april 2015
#import "uipriv_darwin.h"
struct menuConfig {
BOOL hasQuit;
BOOL hasPreferences;
BOOL hasAbout;
};
static NSMenuItem *quitItem;
static NSMenuItem *preferencesItem;
static NSMenuItem *aboutItem;
void appendMenuItem(NSMenu *menu, const uiMenuItem *item, struct menuConfig *menuConfig)
{
NSMenuItem *mitem;
switch (item->Type) {
case uiMenuItemTypeCommand:
case uiMenuItemTypeCheckbox:
mitem = [[NSMenuItem alloc] initWithTitle:toNSString(item->Name) action:NULL keyEquivalent:@""];
[menu addItem:mitem];
return;
case uiMenuItemTypeQuit:
// TODO verify name
menuConfig->hasQuit = YES;
return;
case uiMenuItemTypePreferences:
// TODO verify name
menuConfig->hasPreferences = YES;
return;
case uiMenuItemTypeAbout:
// TODO verify name
menuConfig->hasAbout = YES;
return;
case uiMenuItemTypeSeparator:
// TODO verify name
[menu addItem:[NSMenuItem separatorItem]];
return;
}
// TODO complain
}
NSMenuItem *makeMenu(const char *name, const uiMenuItem *items, struct menuConfig *menuConfig)
{
NSMenuItem *menubarItem;
NSMenu *menu;
const uiMenuItem *i;
menubarItem = [[NSMenuItem alloc] initWithTitle:toNSString(name) action:NULL keyEquivalent:@""];
menu = [[NSMenu alloc] initWithTitle:toNSString(name)];
for (i = items; i->Type != 0; i++)
appendMenuItem(menu, i, menuConfig);
[menubarItem setSubmenu:menu];
return menubarItem;
}
// Cocoa constructs the default application menu by hand for each program; that's what MainMenu.[nx]ib does
// TODO investigate setAppleMenu:
static void buildApplicationMenu(NSMenu *menubar)
{
NSString *appName;
NSMenuItem *appMenuItem;
NSMenu *appMenu;
NSMenuItem *item;
NSString *title;
appName = [[NSProcessInfo processInfo] processName];
appMenuItem = [[NSMenuItem alloc] initWithTitle:appName action:NULL keyEquivalent:@""];
appMenu = [[NSMenu alloc] initWithTitle:appName];
[appMenuItem setSubmenu:appMenu];
[menubar addItem:appMenuItem];
// first is About
title = [@"About " stringByAppendingString:appName];
item = [[NSMenuItem alloc] initWithTitle:title action:NULL keyEquivalent:@""];
[item setEnabled:NO];
[appMenu addItem:item];
aboutItem = item;
[appMenu addItem:[NSMenuItem separatorItem]];
// next is Preferences
item = [[NSMenuItem alloc] initWithTitle:@"Preferences…" action:NULL keyEquivalent:@","];
[item setEnabled:NO];
[appMenu addItem:item];
preferencesItem = item;
[appMenu addItem:[NSMenuItem separatorItem]];
// next is Services
item = [[NSMenuItem alloc] initWithTitle:@"Services" action:NULL keyEquivalent:@""];
// TODO build this part
[appMenu addItem:[NSMenuItem separatorItem]];
// next are the three hiding options
title = [@"Hide " stringByAppendingString:appName];
item = [[NSMenuItem alloc] initWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
// TODO set target for all three of these? the .xib file says they go to -1 ("First Responder", which sounds wrong...)
[appMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
[appMenu addItem:item];
item = [[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
[appMenu addItem:item];
[appMenu addItem:[NSMenuItem separatorItem]];
// and finally Quit
// DON'T use @selector(terminate:) as the action; we handle termination ourselves (TODO figure out how)
title = [@"Quit " stringByAppendingString:appName];
item = [[NSMenuItem alloc] initWithTitle:title action:NULL keyEquivalent:@"q"];
[appMenu addItem:item];
quitItem = item;
}
NSMenu *makeMenubar(void)
{
NSMenu *menubar;
struct menuConfig menuConfig;
const uiMenu *m;
menubar = [[NSMenu alloc] initWithTitle:@""];
// always build the application menu
buildApplicationMenu(menubar);
memset(&menuConfig, 0, sizeof (struct menuConfig));
if (options.Menu != NULL)
for (m = options.Menu; m->Name != NULL; m++)
[menubar addItem:makeMenu(m->Name, m->Items, &menuConfig)];
if (menuConfig.hasQuit)
[quitItem setEnabled:YES];
if (menuConfig.hasPreferences)
[preferencesItem setEnabled:YES];
if (menuConfig.hasAbout)
[aboutItem setEnabled:YES];
return menubar;
}