summaryrefslogtreecommitdiffstats
path: root/tk8.6/macosx/tkMacOSXMenus.c
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2017-09-22 18:57:36 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2017-09-22 18:57:36 (GMT)
commit04d4f0f83ae01daebf6001f40d1261464d185809 (patch)
treed1e4a8b1c22c47d70a369143d3406c524b5c1834 /tk8.6/macosx/tkMacOSXMenus.c
parent2aff4a96fa0286d875bddec0019648e2c6431cbc (diff)
parent1005c7e630baa54e58ac331f48bf876011deb6b3 (diff)
downloadblt-04d4f0f83ae01daebf6001f40d1261464d185809.zip
blt-04d4f0f83ae01daebf6001f40d1261464d185809.tar.gz
blt-04d4f0f83ae01daebf6001f40d1261464d185809.tar.bz2
Merge commit '1005c7e630baa54e58ac331f48bf876011deb6b3' as 'tk8.6'
Diffstat (limited to 'tk8.6/macosx/tkMacOSXMenus.c')
-rw-r--r--tk8.6/macosx/tkMacOSXMenus.c544
1 files changed, 544 insertions, 0 deletions
diff --git a/tk8.6/macosx/tkMacOSXMenus.c b/tk8.6/macosx/tkMacOSXMenus.c
new file mode 100644
index 0000000..68b2c00
--- /dev/null
+++ b/tk8.6/macosx/tkMacOSXMenus.c
@@ -0,0 +1,544 @@
+/*
+ * tkMacOSXMenus.c --
+ *
+ * These calls set up the default menus for Tk.
+ *
+ * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ * Copyright 2001-2009, Apple Inc.
+ * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tkMacOSXPrivate.h"
+#include "tkMenu.h"
+
+static void GenerateEditEvent(const char *name);
+static Tcl_Obj * GetWidgetDemoPath(Tcl_Interp *interp);
+
+#pragma mark TKApplication(TKMenus)
+
+@implementation TKApplication(TKMenus)
+- (void) _setupMenus
+{
+ if (_defaultMainMenu) {
+ return;
+ }
+ TkMenuInit();
+
+ NSString *applicationName = [[NSBundle mainBundle]
+ objectForInfoDictionaryKey:@"CFBundleName"];
+
+ if (!applicationName) {
+ applicationName = [[NSProcessInfo processInfo] processName];
+ }
+
+ NSString *aboutName = (applicationName &&
+ ![applicationName isEqualToString:@"Wish"] &&
+ ![applicationName hasPrefix:@"tclsh"]) ?
+ applicationName : @"Tcl & Tk";
+
+ _servicesMenu = [NSMenu menuWithTitle:@"Services"];
+ _defaultApplicationMenuItems = [[NSArray arrayWithObjects:
+ [NSMenuItem separatorItem],
+ [NSMenuItem itemWithTitle:
+ [NSString stringWithFormat:@"Preferences%C", 0x2026]
+ action:@selector(preferences:) keyEquivalent:@","],
+ [NSMenuItem separatorItem],
+ [NSMenuItem itemWithTitle:@"Services" submenu:_servicesMenu],
+ [NSMenuItem separatorItem],
+ [NSMenuItem itemWithTitle:
+ [NSString stringWithFormat:@"Hide %@", applicationName]
+ action:@selector(hide:) keyEquivalent:@"h"],
+ [NSMenuItem itemWithTitle:@"Hide Others"
+ action:@selector(hideOtherApplications:) keyEquivalent:@"h"
+ keyEquivalentModifierMask:
+ NSCommandKeyMask|NSAlternateKeyMask],
+ [NSMenuItem itemWithTitle:@"Show All"
+ action:@selector(unhideAllApplications:)],
+ [NSMenuItem separatorItem],
+ [NSMenuItem itemWithTitle:
+ [NSString stringWithFormat:@"Quit %@", applicationName]
+ action: @selector(terminate:) keyEquivalent:@"q"],
+ nil] retain];
+ _defaultApplicationMenu = [TKMenu menuWithTitle:applicationName
+ menuItems:_defaultApplicationMenuItems];
+ [_defaultApplicationMenu insertItem:
+ [NSMenuItem itemWithTitle:
+ [NSString stringWithFormat:@"About %@", aboutName]
+ action:@selector(orderFrontStandardAboutPanel:)] atIndex:0];
+
+ TKMenu *fileMenu = [TKMenu menuWithTitle:@"File" menuItems:
+ [NSArray arrayWithObjects:
+ [NSMenuItem itemWithTitle:
+ [NSString stringWithFormat:@"Source%C", 0x2026]
+ action:@selector(tkSource:)],
+ [NSMenuItem itemWithTitle:@"Run Widget Demo"
+ action:@selector(tkDemo:)],
+ [NSMenuItem itemWithTitle:@"Close" action:@selector(performClose:)
+ target:nil keyEquivalent:@"w"],
+ nil]];
+ TKMenu *editMenu = [TKMenu menuWithTitle:@"Edit" menuItems:
+ [NSArray arrayWithObjects:
+ [NSMenuItem itemWithTitle:@"Undo" action:@selector(undo:)
+ target:nil keyEquivalent:@"z"],
+ [NSMenuItem itemWithTitle:@"Redo" action:@selector(redo:)
+ target:nil keyEquivalent:@"y"],
+ [NSMenuItem separatorItem],
+ [NSMenuItem itemWithTitle:@"Cut" action:@selector(cut:)
+ target:nil keyEquivalent:@"x"],
+ [NSMenuItem itemWithTitle:@"Copy" action:@selector(copy:)
+ target:nil keyEquivalent:@"c"],
+ [NSMenuItem itemWithTitle:@"Paste" action:@selector(paste:)
+ target:nil keyEquivalent:@"v"],
+ [NSMenuItem itemWithTitle:@"Delete" action:@selector(delete:)
+ target:nil],
+ nil]];
+
+ _defaultWindowsMenuItems = [[NSArray arrayWithObjects:
+ [NSMenuItem itemWithTitle:@"Minimize"
+ action:@selector(performMiniaturize:) target:nil
+ keyEquivalent:@"m"],
+ [NSMenuItem itemWithTitle:@"Zoom" action:@selector(performZoom:)
+ target:nil],
+ [NSMenuItem separatorItem],
+ [NSMenuItem itemWithTitle:@"Bring All to Front"
+ action:@selector(arrangeInFront:)],
+ nil] retain];
+
+ TKMenu *windowsMenu = [TKMenu menuWithTitle:@"Window" menuItems:
+ _defaultWindowsMenuItems];
+
+ _defaultHelpMenuItems = [[NSArray arrayWithObjects:
+ [NSMenuItem itemWithTitle:
+ [NSString stringWithFormat:@"%@ Help", applicationName]
+ action:@selector(showHelp:) keyEquivalent:@"?"],
+ nil] retain];
+
+ TKMenu *helpMenu = [TKMenu menuWithTitle:@"Help" menuItems:
+ _defaultHelpMenuItems];
+
+ [self setServicesMenu:_servicesMenu];
+ [self setWindowsMenu:windowsMenu];
+ _defaultMainMenu = [[TKMenu menuWithTitle:@"" submenus:[NSArray
+ arrayWithObjects:_defaultApplicationMenu, fileMenu, editMenu,
+ windowsMenu, helpMenu, nil]] retain];
+ [_defaultMainMenu setSpecial:tkMainMenu];
+ [_defaultApplicationMenu setSpecial:tkApplicationMenu];
+ [windowsMenu setSpecial:tkWindowsMenu];
+ [helpMenu setSpecial:tkHelpMenu];
+ [self tkSetMainMenu:nil];
+}
+
+- (void) dealloc
+{
+ [_defaultMainMenu release];
+ [_defaultHelpMenuItems release];
+ [_defaultWindowsMenuItems release];
+ [_defaultApplicationMenuItems release];
+ [super dealloc];
+}
+
+- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>) anItem
+{
+ SEL action = [anItem action];
+
+ if (sel_isEqual(action, @selector(preferences:))) {
+
+ return (_eventInterp && Tcl_FindCommand(_eventInterp,
+ "::tk::mac::ShowPreferences", NULL, 0));
+ } else if (sel_isEqual(action, @selector(tkDemo:))) {
+ BOOL haveDemo = NO;
+
+ if (_eventInterp) {
+ Tcl_Obj *path = GetWidgetDemoPath(_eventInterp);
+
+ if (path) {
+ Tcl_IncrRefCount(path);
+ haveDemo = (Tcl_FSAccess(path, R_OK) == 0);
+ Tcl_DecrRefCount(path);
+ }
+ }
+ return haveDemo;
+ } else {
+ return [super validateUserInterfaceItem:anItem];
+ }
+}
+
+- (void) orderFrontStandardAboutPanel: (id) sender
+{
+ if (!_eventInterp || !Tcl_FindCommand(_eventInterp, "tkAboutDialog",
+ NULL, 0) || (GetCurrentEventKeyModifiers() & optionKey)) {
+ TkAboutDlg();
+ } else {
+ int code = Tcl_EvalEx(_eventInterp, "tkAboutDialog", -1,
+ TCL_EVAL_GLOBAL);
+
+ if (code != TCL_OK) {
+ Tcl_BackgroundException(_eventInterp, code);
+ }
+ Tcl_ResetResult(_eventInterp);
+ }
+}
+
+- (void) showHelp: (id) sender
+{
+ if (!_eventInterp || !Tcl_FindCommand(_eventInterp,
+ "::tk::mac::ShowHelp", NULL, 0)) {
+ [super showHelp:sender];
+ } else {
+ int code = Tcl_EvalEx(_eventInterp, "::tk::mac::ShowHelp", -1,
+ TCL_EVAL_GLOBAL);
+
+ if (code != TCL_OK) {
+ Tcl_BackgroundException(_eventInterp, code);
+ }
+ Tcl_ResetResult(_eventInterp);
+ }
+}
+
+- (void) tkSource: (id) sender
+{
+ if (_eventInterp) {
+ if (Tcl_EvalEx(_eventInterp, "tk_getOpenFile -filetypes {"
+ "{{TCL Scripts} {.tcl} TEXT} {{Text Files} {} TEXT}}",
+ -1, TCL_EVAL_GLOBAL) == TCL_OK) {
+ Tcl_Obj *path = Tcl_GetObjResult(_eventInterp);
+ int len;
+
+ Tcl_GetStringFromObj(path, &len);
+ if (len) {
+ Tcl_IncrRefCount(path);
+
+ int code = Tcl_FSEvalFileEx(_eventInterp, path, NULL);
+
+ if (code != TCL_OK) {
+ Tcl_BackgroundException(_eventInterp, code);
+ }
+ Tcl_DecrRefCount(path);
+ }
+ }
+ Tcl_ResetResult(_eventInterp);
+ }
+}
+
+- (void) tkDemo: (id) sender
+{
+ if (_eventInterp) {
+ Tcl_Obj *path = GetWidgetDemoPath(_eventInterp);
+
+ if (path) {
+ Tcl_IncrRefCount(path);
+
+ int code = Tcl_FSEvalFileEx(_eventInterp, path, NULL);
+
+ if (code != TCL_OK) {
+ Tcl_BackgroundException(_eventInterp, code);
+ }
+ Tcl_DecrRefCount(path);
+ Tcl_ResetResult(_eventInterp);
+ }
+ }
+}
+@end
+
+#pragma mark TKContentView(TKMenus)
+
+@implementation TKContentView(TKMenus)
+
+- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>) anItem
+{
+ return YES;
+}
+
+#define EDIT_ACTION(a, e) \
+ - (void) a: (id) sender \
+ { \
+ if ([sender isKindOfClass:[NSMenuItem class]]) { \
+ GenerateEditEvent(#e); \
+ } \
+ }
+EDIT_ACTION(cut, Cut)
+EDIT_ACTION(copy, Copy)
+EDIT_ACTION(paste, Paste)
+EDIT_ACTION(delete, Clear)
+EDIT_ACTION(undo, Undo)
+EDIT_ACTION(redo, Redo)
+#undef EDIT_ACTION
+@end
+
+#pragma mark -
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetWidgetDemoPath --
+ *
+ * Get path to the widget demo.
+ *
+ * Results:
+ * pathObj with ref count 0.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+GetWidgetDemoPath(
+ Tcl_Interp *interp)
+{
+ Tcl_Obj *libpath, *result = NULL;
+
+ libpath = Tcl_GetVar2Ex(interp, "tk_library", NULL, TCL_GLOBAL_ONLY);
+ if (libpath) {
+ Tcl_Obj *demo[2] = { Tcl_NewStringObj("demos", 5),
+ Tcl_NewStringObj("widget", 6) };
+
+ Tcl_IncrRefCount(libpath);
+ result = Tcl_FSJoinToPath(libpath, 2, demo);
+ Tcl_DecrRefCount(libpath);
+ } else {
+ Tcl_ResetResult(interp);
+ }
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXHandleMenuSelect --
+ *
+ * Handles events that occur in the Menu bar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXHandleMenuSelect(
+ short theMenu,
+ unsigned short theItem,
+ int optionKeyPressed)
+{
+ Tcl_Panic("TkMacOSXHandleMenuSelect: Obsolete, no more Carbon!");
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInitMenus --
+ *
+ * This procedure initializes the Macintosh menu bar.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXInitMenus(
+ Tcl_Interp *interp)
+{
+ [NSApp _setupMenus];
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateEditEvent --
+ *
+ * Takes an edit menu item and posts the corasponding a virtual event to
+ * Tk's event queue.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May place events of queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GenerateEditEvent(
+ const char *name)
+{
+ XVirtualEvent event;
+ int x, y;
+ TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
+ Tk_Window tkwin = (Tk_Window) winPtr;
+
+ if (tkwin == NULL) {
+ return;
+ }
+ tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
+ if (tkwin == NULL) {
+ return;
+ }
+ bzero(&event, sizeof(XVirtualEvent));
+ event.type = VirtualEvent;
+ event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
+ event.send_event = false;
+ event.display = Tk_Display(tkwin);
+ event.event = Tk_WindowId(tkwin);
+ event.root = XRootWindow(Tk_Display(tkwin), 0);
+ event.subwindow = None;
+ event.time = TkpGetMS();
+ XQueryPointer(NULL, winPtr->window, NULL, NULL,
+ &event.x_root, &event.y_root, &x, &y, &event.state);
+ Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y);
+ event.same_screen = true;
+ event.name = Tk_GetUid(name);
+ Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
+}
+
+#pragma mark -
+
+#pragma mark NSMenu & NSMenuItem Utilities
+
+@implementation NSMenu(TKUtils)
+
++ (id) menuWithTitle: (NSString *) title
+{
+ NSMenu *m = [[self alloc] initWithTitle:title];
+
+ return [m autorelease];
+}
+
++ (id) menuWithTitle: (NSString *) title menuItems: (NSArray *) items
+{
+ NSMenu *m = [[self alloc] initWithTitle:title];
+
+ for (NSMenuItem *i in items) {
+ [m addItem:i];
+ }
+ return [m autorelease];
+}
+
++ (id) menuWithTitle: (NSString *) title submenus: (NSArray *) submenus
+{
+ NSMenu *m = [[self alloc] initWithTitle:title];
+
+ for (NSMenu *i in submenus) {
+ [m addItem:[NSMenuItem itemWithSubmenu:i]];
+ }
+ return [m autorelease];
+}
+
+- (NSMenuItem *) itemWithSubmenu: (NSMenu *) submenu
+{
+ return [self itemAtIndex:[self indexOfItemWithSubmenu:submenu]];
+}
+
+- (NSMenuItem *) itemInSupermenu
+{
+ NSMenu *supermenu = [self supermenu];
+
+ return (supermenu ? [supermenu itemWithSubmenu:self] : nil);
+}
+@end
+
+@implementation NSMenuItem(TKUtils)
+
++ (id) itemWithSubmenu: (NSMenu *) submenu
+{
+ NSMenuItem *i = [[self alloc] initWithTitle:[submenu title] action:NULL
+ keyEquivalent:@""];
+
+ [i setSubmenu:submenu];
+ return [i autorelease];
+}
+
++ (id) itemWithTitle: (NSString *) title submenu: (NSMenu *) submenu
+{
+ NSMenuItem *i = [[self alloc] initWithTitle:title action:NULL
+ keyEquivalent:@""];
+
+ [i setSubmenu:submenu];
+ return [i autorelease];
+}
+
++ (id) itemWithTitle: (NSString *) title action: (SEL) action
+{
+ NSMenuItem *i = [[self alloc] initWithTitle:title action:action
+ keyEquivalent:@""];
+
+ [i setTarget:NSApp];
+ return [i autorelease];
+}
+
++ (id) itemWithTitle: (NSString *) title action: (SEL) action
+ target: (id) target
+{
+ NSMenuItem *i = [[self alloc] initWithTitle:title action:action
+ keyEquivalent:@""];
+
+ [i setTarget:target];
+ return [i autorelease];
+}
+
++ (id) itemWithTitle: (NSString *) title action: (SEL) action
+ keyEquivalent: (NSString *) keyEquivalent
+{
+ NSMenuItem *i = [[self alloc] initWithTitle:title action:action
+ keyEquivalent:keyEquivalent];
+
+ [i setTarget:NSApp];
+ return [i autorelease];
+}
+
++ (id) itemWithTitle: (NSString *) title action: (SEL) action
+ target: (id) target keyEquivalent: (NSString *) keyEquivalent
+{
+ NSMenuItem *i = [[self alloc] initWithTitle:title action:action
+ keyEquivalent:keyEquivalent];
+
+ [i setTarget:target];
+ return [i autorelease];
+}
+
++ (id) itemWithTitle: (NSString *) title action: (SEL) action
+ keyEquivalent: (NSString *) keyEquivalent
+ keyEquivalentModifierMask: (NSUInteger) keyEquivalentModifierMask
+{
+ NSMenuItem *i = [[self alloc] initWithTitle:title action:action
+ keyEquivalent:keyEquivalent];
+
+ [i setTarget:NSApp];
+ [i setKeyEquivalentModifierMask:keyEquivalentModifierMask];
+ return [i autorelease];
+}
+
++ (id) itemWithTitle: (NSString *) title action: (SEL) action
+ target: (id) target keyEquivalent: (NSString *) keyEquivalent
+ keyEquivalentModifierMask: (NSUInteger) keyEquivalentModifierMask
+{
+ NSMenuItem *i = [[self alloc] initWithTitle:title action:action
+ keyEquivalent:keyEquivalent];
+
+ [i setTarget:target];
+ [i setKeyEquivalentModifierMask:keyEquivalentModifierMask];
+ return [i autorelease];
+}
+@end
+
+/*
+ * Local Variables:
+ * mode: objc
+ * c-basic-offset: 4
+ * fill-column: 79
+ * coding: utf-8
+ * End:
+ */