diff options
Diffstat (limited to 'src/libui_sdl/libui/darwin/menu.m')
-rw-r--r-- | src/libui_sdl/libui/darwin/menu.m | 368 |
1 files changed, 0 insertions, 368 deletions
diff --git a/src/libui_sdl/libui/darwin/menu.m b/src/libui_sdl/libui/darwin/menu.m deleted file mode 100644 index 735cac5..0000000 --- a/src/libui_sdl/libui/darwin/menu.m +++ /dev/null @@ -1,368 +0,0 @@ -// 28 april 2015 -#import "uipriv_darwin.h" - -static NSMutableArray *menus = nil; -static BOOL menusFinalized = NO; - -struct uiMenu { - NSMenu *menu; - NSMenuItem *item; - NSMutableArray *items; -}; - -struct uiMenuItem { - NSMenuItem *item; - int type; - BOOL disabled; - void (*onClicked)(uiMenuItem *, uiWindow *, void *); - void *onClickedData; -}; - -enum { - typeRegular, - typeCheckbox, - typeQuit, - typePreferences, - typeAbout, - typeSeparator, -}; - -static void mapItemReleaser(void *key, void *value) -{ - uiMenuItem *item; - - item = (uiMenuItem *)value; - [item->item release]; -} - -@implementation menuManager - -- (id)init -{ - self = [super init]; - if (self) { - self->items = newMap(); - self->hasQuit = NO; - self->hasPreferences = NO; - self->hasAbout = NO; - } - return self; -} - -- (void)dealloc -{ - mapWalk(self->items, mapItemReleaser); - mapReset(self->items); - mapDestroy(self->items); - uninitMenus(); - [super dealloc]; -} - -- (IBAction)onClicked:(id)sender -{ - uiMenuItem *item; - - item = (uiMenuItem *) mapGet(self->items, sender); - if (item->type == typeCheckbox) - uiMenuItemSetChecked(item, !uiMenuItemChecked(item)); - // use the key window as the source of the menu event; it's the active window - (*(item->onClicked))(item, windowFromNSWindow([realNSApp() keyWindow]), item->onClickedData); -} - -- (IBAction)onQuitClicked:(id)sender -{ - if (shouldQuit()) - uiQuit(); -} - -- (void)register:(NSMenuItem *)item to:(uiMenuItem *)smi -{ - switch (smi->type) { - case typeQuit: - if (self->hasQuit) - userbug("You can't have multiple Quit menu items in one program."); - self->hasQuit = YES; - break; - case typePreferences: - if (self->hasPreferences) - userbug("You can't have multiple Preferences menu items in one program."); - self->hasPreferences = YES; - break; - case typeAbout: - if (self->hasAbout) - userbug("You can't have multiple About menu items in one program."); - self->hasAbout = YES; - break; - } - mapSet(self->items, item, smi); -} - -// on OS X there are two ways to handle menu items being enabled or disabled: automatically and manually -// unfortunately, the application menu requires automatic menu handling for the Hide, Hide Others, and Show All items to work correctly -// therefore, we have to handle enabling of the other options ourselves -- (BOOL)validateMenuItem:(NSMenuItem *)item -{ - uiMenuItem *smi; - - // disable the special items if they aren't present - if (item == self.quitItem && !self->hasQuit) - return NO; - if (item == self.preferencesItem && !self->hasPreferences) - return NO; - if (item == self.aboutItem && !self->hasAbout) - return NO; - // then poll the item's enabled/disabled state - smi = (uiMenuItem *) mapGet(self->items, item); - return !smi->disabled; -} - -// Cocoa constructs the default application menu by hand for each program; that's what MainMenu.[nx]ib does -- (void)buildApplicationMenu:(NSMenu *)menubar -{ - NSString *appName; - NSMenuItem *appMenuItem; - NSMenu *appMenu; - NSMenuItem *item; - NSString *title; - NSMenu *servicesMenu; - - // note: no need to call setAppleMenu: on this anymore; see https://developer.apple.com/library/mac/releasenotes/AppKit/RN-AppKitOlderNotes/#X10_6Notes - appName = [[NSProcessInfo processInfo] processName]; - appMenuItem = [[[NSMenuItem alloc] initWithTitle:appName action:NULL keyEquivalent:@""] autorelease]; - appMenu = [[[NSMenu alloc] initWithTitle:appName] autorelease]; - [appMenuItem setSubmenu:appMenu]; - [menubar addItem:appMenuItem]; - - // first is About - title = [@"About " stringByAppendingString:appName]; - item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(onClicked:) keyEquivalent:@""] autorelease]; - [item setTarget:self]; - [appMenu addItem:item]; - self.aboutItem = item; - - [appMenu addItem:[NSMenuItem separatorItem]]; - - // next is Preferences - item = [[[NSMenuItem alloc] initWithTitle:@"Preferences…" action:@selector(onClicked:) keyEquivalent:@","] autorelease]; - [item setTarget:self]; - [appMenu addItem:item]; - self.preferencesItem = item; - - [appMenu addItem:[NSMenuItem separatorItem]]; - - // next is Services - item = [[[NSMenuItem alloc] initWithTitle:@"Services" action:NULL keyEquivalent:@""] autorelease]; - servicesMenu = [[[NSMenu alloc] initWithTitle:@"Services"] autorelease]; - [item setSubmenu:servicesMenu]; - [realNSApp() setServicesMenu:servicesMenu]; - [appMenu addItem:item]; - - [appMenu addItem:[NSMenuItem separatorItem]]; - - // next are the three hiding options - title = [@"Hide " stringByAppendingString:appName]; - item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(hide:) keyEquivalent:@"h"] autorelease]; - // the .xib file says they go to -1 ("First Responder", which sounds wrong...) - // to do that, we simply leave the target as nil - [appMenu addItem:item]; - item = [[[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"] autorelease]; - [item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)]; - [appMenu addItem:item]; - item = [[[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""] autorelease]; - [appMenu addItem:item]; - - [appMenu addItem:[NSMenuItem separatorItem]]; - - // and finally Quit - // DON'T use @selector(terminate:) as the action; we handle termination ourselves - title = [@"Quit " stringByAppendingString:appName]; - item = [[[NSMenuItem alloc] initWithTitle:title action:@selector(onQuitClicked:) keyEquivalent:@"q"] autorelease]; - [item setTarget:self]; - [appMenu addItem:item]; - self.quitItem = item; -} - -- (NSMenu *)makeMenubar -{ - NSMenu *menubar; - - menubar = [[[NSMenu alloc] initWithTitle:@""] autorelease]; - [self buildApplicationMenu:menubar]; - return menubar; -} - -@end - -static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data) -{ - // do nothing -} - -void uiMenuItemEnable(uiMenuItem *item) -{ - item->disabled = NO; - // we don't need to explicitly update the menus here; they'll be updated the next time they're opened (thanks mikeash in irc.freenode.net/#macdev) -} - -void uiMenuItemDisable(uiMenuItem *item) -{ - item->disabled = YES; -} - -void uiMenuItemOnClicked(uiMenuItem *item, void (*f)(uiMenuItem *, uiWindow *, void *), void *data) -{ - if (item->type == typeQuit) - userbug("You can't call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead."); - item->onClicked = f; - item->onClickedData = data; -} - -int uiMenuItemChecked(uiMenuItem *item) -{ - return [item->item state] != NSOffState; -} - -void uiMenuItemSetChecked(uiMenuItem *item, int checked) -{ - NSInteger state; - - state = NSOffState; - if ([item->item state] == NSOffState) - state = NSOnState; - [item->item setState:state]; -} - -static uiMenuItem *newItem(uiMenu *m, int type, const char *name) -{ - @autoreleasepool { - - uiMenuItem *item; - - if (menusFinalized) - userbug("You can't create a new menu item after menus have been finalized."); - - item = uiNew(uiMenuItem); - - item->type = type; - switch (item->type) { - case typeQuit: - item->item = [appDelegate().menuManager.quitItem retain]; - break; - case typePreferences: - item->item = [appDelegate().menuManager.preferencesItem retain]; - break; - case typeAbout: - item->item = [appDelegate().menuManager.aboutItem retain]; - break; - case typeSeparator: - item->item = [[NSMenuItem separatorItem] retain]; - [m->menu addItem:item->item]; - break; - default: - item->item = [[NSMenuItem alloc] initWithTitle:toNSString(name) action:@selector(onClicked:) keyEquivalent:@""]; - [item->item setTarget:appDelegate().menuManager]; - [m->menu addItem:item->item]; - break; - } - - [appDelegate().menuManager register:item->item to:item]; - item->onClicked = defaultOnClicked; - - [m->items addObject:[NSValue valueWithPointer:item]]; - - return item; - - } // @autoreleasepool -} - -uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name) -{ - return newItem(m, typeRegular, name); -} - -uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name) -{ - return newItem(m, typeCheckbox, name); -} - -uiMenuItem *uiMenuAppendQuitItem(uiMenu *m) -{ - // duplicate check is in the register:to: selector - return newItem(m, typeQuit, NULL); -} - -uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m) -{ - // duplicate check is in the register:to: selector - return newItem(m, typePreferences, NULL); -} - -uiMenuItem *uiMenuAppendAboutItem(uiMenu *m) -{ - // duplicate check is in the register:to: selector - return newItem(m, typeAbout, NULL); -} - -void uiMenuAppendSeparator(uiMenu *m) -{ - newItem(m, typeSeparator, NULL); -} - -uiMenu *uiNewMenu(const char *name) -{ - @autoreleasepool { - - uiMenu *m; - - if (menusFinalized) - userbug("You can't create a new menu after menus have been finalized."); - if (menus == nil) - menus = [NSMutableArray new]; - - m = uiNew(uiMenu); - - m->menu = [[NSMenu alloc] initWithTitle:toNSString(name)]; - // use automatic menu item enabling for all menus for consistency's sake - - m->item = [[NSMenuItem alloc] initWithTitle:toNSString(name) action:NULL keyEquivalent:@""]; - [m->item setSubmenu:m->menu]; - - m->items = [NSMutableArray new]; - - [[realNSApp() mainMenu] addItem:m->item]; - - [menus addObject:[NSValue valueWithPointer:m]]; - - return m; - - } // @autoreleasepool -} - -void finalizeMenus(void) -{ - menusFinalized = YES; -} - -void uninitMenus(void) -{ - if (menus == NULL) - return; - [menus enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { - NSValue *v; - uiMenu *m; - - v = (NSValue *) obj; - m = (uiMenu *) [v pointerValue]; - [m->items enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { - NSValue *v; - uiMenuItem *mi; - - v = (NSValue *) obj; - mi = (uiMenuItem *) [v pointerValue]; - uiFree(mi); - }]; - [m->items release]; - uiFree(m); - }]; - [menus release]; -} |