ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

appmenu_osx.mm

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 // Disable symbol overrides so that we can use system headers.
00024 #define FORBIDDEN_SYMBOL_ALLOW_ALL
00025 
00026 #include "backends/platform/sdl/macosx/appmenu_osx.h"
00027 #include "common/translation.h"
00028 
00029 #include "backends/platform/sdl/macosx/macosx-compat.h"
00030 #include <Cocoa/Cocoa.h>
00031 #include <AppKit/NSWorkspace.h>
00032 
00033 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
00034 #define NSEventModifierFlagCommand NSCommandKeyMask
00035 #define NSEventModifierFlagOption  NSAlternateKeyMask
00036 #endif
00037 
00038 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10
00039 #define NSEventModifierFlags NSUInteger
00040 #endif
00041 
00042 #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
00043 typedef unsigned long NSUInteger;
00044 #endif
00045 
00046 // Apple added setAppleMenu in 10.5 and removed it in 10.6.
00047 // But as the method still exists we declare it ourselves here.
00048 // Yes, this works :)
00049 @interface NSApplication(MissingFunction)
00050 - (void)setAppleMenu:(NSMenu *)menu;
00051 @end
00052 // However maybe we should conditionally use it depending on the system on which we run ScummVM (and not
00053 // the one on which we compile) to only do it on OS X 10.5.
00054 // Here is the relevant bit from the release notes for 10.6:
00055 // In Leopard and earlier, apps that tried to construct a menu bar without a nib would get an undesirable
00056 // stubby application menu that could not be removed. To work around this problem on Leopard, you can call
00057 // the undocumented setAppleMenu: method and pass it the application menu, like so:
00058 //   [NSApp setAppleMenu:[[[NSApp mainMenu] itemAtIndex:0] submenu]];
00059 // In SnowLeopard, this workaround is unnecessary and should not be used. Under SnowLeopard, the first menu
00060 // is always identified as the application menu.
00061 
00062 static void openFromBundle(NSString *file) {
00063     NSString *path = [[NSBundle mainBundle] pathForResource:file ofType:@"rtf"];
00064     if (!path) {
00065         path = [[NSBundle mainBundle] pathForResource:file ofType:@"html"];
00066         if (!path) {
00067             path = [[NSBundle mainBundle] pathForResource:file ofType:@""];
00068             if (!path)
00069                 path = [[NSBundle mainBundle] pathForResource:file ofType:@"md"];
00070         }
00071     }
00072 
00073     if (path) {
00074         // RTF and HTML files are widely recognized and we can rely on the default
00075         // file association working for those. For the other ones this might not be
00076         // the case so we explicitely indicate they should be open with TextEdit.
00077         if ([path hasSuffix:@".html"] || [path hasSuffix:@".rtf"])
00078             [[NSWorkspace sharedWorkspace] openFile:path];
00079         else
00080             [[NSWorkspace sharedWorkspace] openFile:path withApplication:@"TextEdit"];
00081     }
00082 }
00083 
00084 @interface ScummVMMenuHandler : NSObject {
00085 }
00086 - (void) openReadme;
00087 - (void) openLicenseGPL;
00088 - (void) openLicenseLGPL;
00089 - (void) openLicenseFreefont;
00090 - (void) openLicenseOFL;
00091 - (void) openLicenseBSD;
00092 - (void) openNews;
00093 - (void) openUserManual;
00094 - (void) openCredits;
00095 @end
00096 
00097 @implementation ScummVMMenuHandler : NSObject
00098 - (void)openReadme {
00099     openFromBundle(@"README");
00100 }
00101 
00102 - (void)openLicenseGPL {
00103     openFromBundle(@"COPYING");
00104 }
00105 
00106 - (void)openLicenseLGPL {
00107     openFromBundle(@"COPYING-LGPL");
00108 }
00109 
00110 - (void)openLicenseFreefont {
00111     openFromBundle(@"COPYING-FREEFONT");
00112 }
00113 
00114 - (void)openLicenseOFL {
00115     openFromBundle(@"COPYING-OFL");
00116 }
00117 
00118 - (void)openLicenseBSD {
00119     openFromBundle(@"COPYING-BSD");
00120 }
00121 
00122 - (void)openNews {
00123     openFromBundle(@"NEWS");
00124 }
00125 
00126 - (void)openUserManual {
00127     [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.residualvm.org/documentation"]];
00128 }
00129 
00130 - (void)openCredits {
00131     openFromBundle(@"AUTHORS");
00132 }
00133 @end
00134 
00135 NSString *constructNSStringFromCString(const char *rawCString, CFStringEncoding stringEncoding) {
00136     return (NSString *)CFStringCreateWithCString(NULL, rawCString, stringEncoding);
00137 }
00138 
00139 static NSMenu *addMenu(const char *title, CFStringEncoding encoding, NSString *key, SEL setAs) {
00140     if (setAs && ![NSApp respondsToSelector:setAs]) {
00141         return nil;
00142     }
00143 
00144     NSString *str = constructNSStringFromCString(title, encoding);
00145     NSMenu *menu = [[NSMenu alloc] initWithTitle:str];
00146 
00147     NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:str action:nil keyEquivalent:key];
00148     [menuItem setSubmenu:menu];
00149     [[NSApp mainMenu] addItem:menuItem];
00150 
00151     if (setAs) {
00152         [NSApp performSelector:setAs withObject:menu];
00153     }
00154 
00155     [str release];
00156     [menuItem release];
00157 
00158     return menu;
00159 }
00160 
00161 static void addMenuItem(const char *title, CFStringEncoding encoding, id target, SEL selector, NSString *key, NSMenu *parent, NSEventModifierFlags flags = 0) {
00162     NSString *nsString = constructNSStringFromCString(title, encoding);
00163     NSMenuItem *menuItem = [[NSMenuItem alloc]
00164                             initWithTitle:nsString
00165                             action:selector
00166                             keyEquivalent:key];
00167     if (target) {
00168         [menuItem setTarget:target];
00169     }
00170     if (flags) {
00171         [menuItem setKeyEquivalentModifierMask:flags];
00172     }
00173     [parent addItem:menuItem];
00174     [nsString release];
00175 }
00176 
00177 static ScummVMMenuHandler *delegate = nullptr;
00178 
00179 void releaseMenu() {
00180     [delegate release];
00181     delegate = nullptr;
00182 }
00183 
00184 void replaceApplicationMenuItems() {
00185     // We cannot use [[NSApp mainMenu] removeAllItems] as removeAllItems was added in OS X 10.6
00186     // So remove the SDL generated menus one by one instead.
00187     while ([[NSApp mainMenu] numberOfItems] > 0) {
00188         [[NSApp mainMenu] removeItemAtIndex:0];
00189     }
00190 
00191     NSString *nsString = NULL;
00192 
00193     // Get current encoding
00194 #ifdef USE_TRANSLATION
00195     nsString = constructNSStringFromCString(TransMan.getCurrentCharset().c_str(), NSASCIIStringEncoding);
00196     CFStringEncoding stringEncoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)nsString);
00197     [nsString release];
00198 #else
00199     CFStringEncoding stringEncoding = kCFStringEncodingASCII;
00200 #endif
00201 
00202     NSMenu *appleMenu = addMenu("ResidualVM", kCFStringEncodingASCII, @"", @selector(setAppleMenu:));
00203     if (appleMenu) {
00204         addMenuItem(_("About ResidualVM"), stringEncoding, nil, @selector(orderFrontStandardAboutPanel:), @"", appleMenu);
00205         [appleMenu addItem:[NSMenuItem separatorItem]];
00206         addMenuItem(_("Hide ResidualVM"), stringEncoding, nil, @selector(hide:), @"h", appleMenu);
00207         addMenuItem(_("Hide Others"), stringEncoding, nil, @selector(hideOtherApplications:), @"h", appleMenu, (NSEventModifierFlagOption|NSEventModifierFlagCommand));
00208         addMenuItem(_("Show All"), stringEncoding, nil, @selector(unhideAllApplications:), @"", appleMenu);
00209         [appleMenu addItem:[NSMenuItem separatorItem]];
00210         addMenuItem(_("Quit ResidualVM"), stringEncoding, nil, @selector(terminate:), @"q", appleMenu);
00211     }
00212 
00213     NSMenu *windowMenu = addMenu(_("Window"), stringEncoding, @"", @selector(setWindowsMenu:));
00214     if (windowMenu) {
00215         addMenuItem(_("Minimize"), stringEncoding, nil, @selector(performMiniaturize:), @"m", windowMenu);
00216     }
00217 
00218     NSMenu *helpMenu = addMenu(_("Help"), stringEncoding, @"", @selector(setHelpMenu:));
00219     if (helpMenu) {
00220         if (!delegate) {
00221             delegate = [[ScummVMMenuHandler alloc] init];
00222         }
00223         addMenuItem(_("User Manual"), stringEncoding, delegate, @selector(openUserManual), @"", helpMenu);
00224         [helpMenu addItem:[NSMenuItem separatorItem]];
00225         addMenuItem(_("General Information"), stringEncoding, delegate, @selector(openReadme), @"", helpMenu);
00226         addMenuItem(_("What's New in ResidualVM"), stringEncoding, delegate, @selector(openNews), @"", helpMenu);
00227         [helpMenu addItem:[NSMenuItem separatorItem]];
00228         addMenuItem(_("Credits"), stringEncoding, delegate, @selector(openCredits), @"", helpMenu);
00229         addMenuItem(_("GPL License"), stringEncoding, delegate, @selector(openLicenseGPL), @"", helpMenu);
00230         addMenuItem(_("LGPL License"), stringEncoding, delegate, @selector(openLicenseLGPL), @"", helpMenu);
00231         addMenuItem(_("Freefont License"), stringEncoding, delegate, @selector(openLicenseFreefont), @"", helpMenu);
00232         addMenuItem(_("OFL License"), stringEncoding, delegate, @selector(openLicenseOFL), @"", helpMenu);
00233         addMenuItem(_("BSD License"), stringEncoding, delegate, @selector(openLicenseBSD), @"", helpMenu);
00234     }
00235 
00236     [appleMenu release];
00237     [windowMenu release];
00238     [helpMenu release];
00239 }


Generated on Sat Jun 27 2020 05:00:31 for ResidualVM by doxygen 1.7.1
curved edge   curved edge