1 /////////////////////////////////////////////////////////////////////////////
2 // Name: cocoa/mbarman.cpp
3 // Purpose: wxMenuBarManager implementation
4 // Author: David Elliott
8 // Copyright: (c) 2003 David Elliott
9 // Licence: wxWidgets licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
18 #include "wx/toplevel.h"
21 #include "wx/cocoa/mbarman.h"
22 #include "wx/cocoa/autorelease.h"
23 #include "wx/cocoa/objc/objc_uniquifying.h"
25 #import <Foundation/NSString.h>
26 #import <Foundation/NSNotification.h>
27 #import <AppKit/NSMenu.h>
28 #import <AppKit/NSApplication.h>
29 #import <AppKit/NSWindow.h>
31 #define wxUSE_FSCRIPT 0
33 #import <FScript/FScriptMenuItem.h>
36 // Declare setAppleMenu: in an NSApplication category since Tiger and later
37 // releases support it but don't declare it as it's considered deprecated.
38 @interface NSApplication(wxDeprecatedMethodsWeWantToUse)
39 - (void)setAppleMenu:(NSMenu *)menu;
42 // ============================================================================
43 // wxMenuBarManagerObserver
44 // ============================================================================
45 @interface wxMenuBarManagerObserver : NSObject
47 wxMenuBarManager *m_mbarman;
51 - (id)initWithWxMenuBarManager: (wxMenuBarManager *)mbarman;
52 - (void)windowDidBecomeKey: (NSNotification *)notification;
54 - (void)windowDidResignKey: (NSNotification *)notification;
55 - (void)windowDidBecomeMain: (NSNotification *)notification;
56 - (void)windowDidResignMain: (NSNotification *)notification;
57 - (void)windowWillClose: (NSNotification *)notification;
59 @end // interface wxMenuBarManagerObserver : NSObject
60 WX_DECLARE_GET_OBJC_CLASS(wxMenuBarManagerObserver,NSObject)
62 @implementation wxMenuBarManagerObserver : NSObject
65 wxFAIL_MSG(wxT("[wxMenuBarManagerObserver -init] should never be called!"));
70 - (id)initWithWxMenuBarManager: (wxMenuBarManager *)mbarman
77 - (void)windowDidBecomeKey: (NSNotification *)notification
80 m_mbarman->WindowDidBecomeKey(notification);
84 - (void)windowDidResignKey: (NSNotification *)notification
87 m_mbarman->WindowDidResignKey(notification);
90 - (void)windowDidBecomeMain: (NSNotification *)notification
93 m_mbarman->WindowDidBecomeMain(notification);
96 - (void)windowDidResignMain: (NSNotification *)notification
99 m_mbarman->WindowDidResignMain(notification);
102 - (void)windowWillClose: (NSNotification *)notification
105 m_mbarman->WindowWillClose(notification);
109 @end // implementation wxMenuBarManagerObserver : NSObject
110 WX_IMPLEMENT_GET_OBJC_CLASS(wxMenuBarManagerObserver,NSObject)
112 // ============================================================================
114 // ============================================================================
115 wxMenuBarManager *wxMenuBarManager::sm_mbarmanInstance = NULL;
117 static void AddFScriptItem(NSMenu *menu)
120 NSMenuItem *item = [[FScriptMenuItem alloc] init];
121 [menu addItem: item];
128 wxMenuBarManager::wxMenuBarManager()
130 m_observer = [[WX_GET_OBJC_CLASS(wxMenuBarManagerObserver) alloc]
131 initWithWxMenuBarManager:this];
132 [[NSNotificationCenter defaultCenter] addObserver:m_observer
133 selector:@selector(windowDidBecomeKey:)
134 name:NSWindowDidBecomeKeyNotification object:nil];
136 [[NSNotificationCenter defaultCenter] addObserver:m_observer
137 selector:@selector(windowDidResignKey:)
138 name:NSWindowDidResignKeyNotification object:nil];
139 [[NSNotificationCenter defaultCenter] addObserver:m_observer
140 selector:@selector(windowDidBecomeMain:)
141 name:NSWindowDidBecomeMainNotification object:nil];
142 [[NSNotificationCenter defaultCenter] addObserver:m_observer
143 selector:@selector(windowDidResignMain:)
144 name:NSWindowDidResignMainNotification object:nil];
145 [[NSNotificationCenter defaultCenter] addObserver:m_observer
146 selector:@selector(windowWillClose:)
147 name:NSWindowWillCloseNotification object:nil];
150 m_menuServices = nil;
153 m_mainMenuBarInstalled = true;
154 m_mainMenuBar = NULL;
155 m_currentNSWindow = nil;
157 NSApplication *theNSApplication = wxTheApp->GetNSApplication();
158 // Create the services menu.
159 m_menuServices = [[NSMenu alloc] initWithTitle: @"Services"];
160 [theNSApplication setServicesMenu:m_menuServices];
162 NSMenuItem *menuitem;
163 // Create the application (Apple) menu.
164 m_menuApp = [[NSMenu alloc] initWithTitle: @"Apple Menu"];
166 /**/[m_menuApp addItemWithTitle:@"Preferences..." action:nil keyEquivalent:@""];
167 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
168 /**/AddFScriptItem(m_menuApp);
169 /**/menuitem = [[NSMenuItem alloc] initWithTitle: @"Services" action:nil keyEquivalent:@""];
170 [menuitem setSubmenu:m_menuServices];
171 [m_menuApp addItem: menuitem];
173 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
174 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide" action:@selector(hide:) keyEquivalent:@""];
175 [menuitem setTarget: theNSApplication];
176 [m_menuApp addItem: menuitem];
178 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@""];
179 [menuitem setTarget: theNSApplication];
180 [m_menuApp addItem: menuitem];
182 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
183 [menuitem setTarget: theNSApplication];
184 [m_menuApp addItem: menuitem];
186 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
187 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
188 [menuitem setTarget: theNSApplication];
189 [m_menuApp addItem: menuitem];
192 [theNSApplication setAppleMenu:m_menuApp];
194 // Create the Windows menu
195 m_menuWindows = [[NSMenu alloc] initWithTitle: @"Window"];
197 /**/[m_menuWindows addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@""];
198 /**/[m_menuWindows addItem: [NSMenuItem separatorItem]];
199 /**/[m_menuWindows addItemWithTitle:@"Bring All to Front" action:@selector(arrangeInFront:) keyEquivalent:@""];
201 [theNSApplication setWindowsMenu:m_menuWindows];
203 // Create the main menubar
204 m_menuMain = [[NSMenu alloc] initWithTitle: @"wxApp Menu"];
205 /**/NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@"App menu"
206 /* Note: title gets clobbered by app name anyway */
207 action:nil keyEquivalent:@""];
208 [dummyItem setSubmenu:m_menuApp];
209 [m_menuMain addItem:dummyItem];
211 /**/dummyItem = [[NSMenuItem alloc] initWithTitle:@"Window"
212 action:nil keyEquivalent:@""];
213 [dummyItem setSubmenu:m_menuWindows];
214 [m_menuMain addItem:dummyItem];
217 [theNSApplication setMainMenu: m_menuMain];
221 wxMenuBarManager::~wxMenuBarManager()
223 [m_observer release];
226 void wxMenuBarManager::CreateInstance()
228 sm_mbarmanInstance = new wxMenuBarManager;
231 void wxMenuBarManager::DestroyInstance()
233 delete sm_mbarmanInstance;
234 sm_mbarmanInstance = NULL;
237 void wxMenuBarManager::SetMenuBar(wxMenuBar* menubar)
239 m_mainMenuBarInstalled = false;
242 [[[wxTheApp->GetNSApplication() mainMenu] itemAtIndex:0] setSubmenu:nil];
243 [[menubar->GetNSMenu() itemAtIndex:0] setSubmenu:m_menuApp];
244 [wxTheApp->GetNSApplication() setMainMenu:menubar->GetNSMenu()];
250 void wxMenuBarManager::SetMainMenuBar(wxMenuBar* menubar)
252 m_mainMenuBar = menubar;
253 if(m_mainMenuBarInstalled)
257 void wxMenuBarManager::InstallMainMenu()
260 SetMenuBar(m_mainMenuBar);
263 m_mainMenuBarInstalled = true;
264 [[[wxTheApp->GetNSApplication() mainMenu] itemAtIndex:0] setSubmenu:nil];
265 [[m_menuMain itemAtIndex:0] setSubmenu:m_menuApp];
266 [wxTheApp->GetNSApplication() setMainMenu:m_menuMain];
270 void wxMenuBarManager::WindowDidBecomeKey(NSNotification *notification)
272 /* NOTE: m_currentNSWindow might be destroyed but we only ever use it
273 to look it up in the hash table. Do not send messages to it. */
274 m_currentNSWindow = [notification object];
275 wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa(m_currentNSWindow);
277 InstallMenuBarForWindow(win);
283 void wxMenuBarManager::WindowDidResignKey(NSNotification *notification)
287 void wxMenuBarManager::WindowDidBecomeMain(NSNotification *notification)
291 void wxMenuBarManager::WindowDidResignMain(NSNotification *notification)
295 void wxMenuBarManager::WindowWillClose(NSNotification *notification)
300 void wxMenuBarManager::InstallMenuBarForWindow(wxCocoaNSWindow *win)
303 wxMenuBar *menubar = win->GetAppMenuBar(win);
304 wxLogTrace(wxTRACE_COCOA,wxT("Found menubar=%p for window=%p."),menubar,win);
308 void wxMenuBarManager::UpdateMenuBar()
310 if(m_currentNSWindow)
312 wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa(m_currentNSWindow);
314 InstallMenuBarForWindow(win);
318 #endif // wxUSE_MENUS