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]; -} |