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"
24 #import <Foundation/NSString.h>
25 #import <Foundation/NSNotification.h>
26 #import <AppKit/NSMenu.h>
27 #import <AppKit/NSApplication.h>
28 #import <AppKit/NSWindow.h>
30 // Declare setAppleMenu: in an NSApplication category since Tiger and later
31 // releases support it but don't declare it as it's considered deprecated.
32 @interface NSApplication(wxDeprecatedMethodsWeWantToUse)
33 - (void)setAppleMenu:(NSMenu *)menu;
36 // ============================================================================
37 // wxMenuBarManagerObserver
38 // ============================================================================
39 @interface wxMenuBarManagerObserver : NSObject
41 wxMenuBarManager *m_mbarman;
45 - (id)initWithWxMenuBarManager: (wxMenuBarManager *)mbarman;
46 - (void)windowDidBecomeKey: (NSNotification *)notification;
48 - (void)windowDidResignKey: (NSNotification *)notification;
49 - (void)windowDidBecomeMain: (NSNotification *)notification;
50 - (void)windowDidResignMain: (NSNotification *)notification;
51 - (void)windowWillClose: (NSNotification *)notification;
53 @end // interface wxMenuBarManagerObserver : NSObject
55 @implementation wxMenuBarManagerObserver : NSObject
58 wxFAIL_MSG(wxT("[wxMenuBarManagerObserver -init] should never be called!"));
63 - (id)initWithWxMenuBarManager: (wxMenuBarManager *)mbarman
70 - (void)windowDidBecomeKey: (NSNotification *)notification
73 m_mbarman->WindowDidBecomeKey(notification);
77 - (void)windowDidResignKey: (NSNotification *)notification
80 m_mbarman->WindowDidResignKey(notification);
83 - (void)windowDidBecomeMain: (NSNotification *)notification
86 m_mbarman->WindowDidBecomeMain(notification);
89 - (void)windowDidResignMain: (NSNotification *)notification
92 m_mbarman->WindowDidResignMain(notification);
95 - (void)windowWillClose: (NSNotification *)notification
98 m_mbarman->WindowWillClose(notification);
102 @end // implementation wxMenuBarManagerObserver : NSObject
104 // ============================================================================
106 // ============================================================================
107 wxMenuBarManager *wxMenuBarManager::sm_mbarmanInstance = NULL;
109 wxMenuBarManager::wxMenuBarManager()
111 m_observer = [[wxMenuBarManagerObserver alloc]
112 initWithWxMenuBarManager:this];
113 [[NSNotificationCenter defaultCenter] addObserver:m_observer
114 selector:@selector(windowDidBecomeKey:)
115 name:NSWindowDidBecomeKeyNotification object:nil];
117 [[NSNotificationCenter defaultCenter] addObserver:m_observer
118 selector:@selector(windowDidResignKey:)
119 name:NSWindowDidResignKeyNotification object:nil];
120 [[NSNotificationCenter defaultCenter] addObserver:m_observer
121 selector:@selector(windowDidBecomeMain:)
122 name:NSWindowDidBecomeMainNotification object:nil];
123 [[NSNotificationCenter defaultCenter] addObserver:m_observer
124 selector:@selector(windowDidResignMain:)
125 name:NSWindowDidResignMainNotification object:nil];
126 [[NSNotificationCenter defaultCenter] addObserver:m_observer
127 selector:@selector(windowWillClose:)
128 name:NSWindowWillCloseNotification object:nil];
131 m_menuServices = nil;
134 m_mainMenuBarInstalled = true;
135 m_mainMenuBar = NULL;
136 m_currentNSWindow = nil;
138 NSApplication *theNSApplication = wxTheApp->GetNSApplication();
139 // Create the services menu.
140 m_menuServices = [[NSMenu alloc] initWithTitle: @"Services"];
141 [theNSApplication setServicesMenu:m_menuServices];
143 NSMenuItem *menuitem;
144 // Create the application (Apple) menu.
145 m_menuApp = [[NSMenu alloc] initWithTitle: @"Apple Menu"];
147 /**/[m_menuApp addItemWithTitle:@"Preferences..." action:nil keyEquivalent:@""];
148 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
149 /**/menuitem = [[NSMenuItem alloc] initWithTitle: @"Services" action:nil keyEquivalent:@""];
150 [menuitem setSubmenu:m_menuServices];
151 [m_menuApp addItem: menuitem];
153 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
154 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide" action:@selector(hide:) keyEquivalent:@""];
155 [menuitem setTarget: theNSApplication];
156 [m_menuApp addItem: menuitem];
158 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@""];
159 [menuitem setTarget: theNSApplication];
160 [m_menuApp addItem: menuitem];
162 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
163 [menuitem setTarget: theNSApplication];
164 [m_menuApp addItem: menuitem];
166 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
167 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
168 [menuitem setTarget: theNSApplication];
169 [m_menuApp addItem: menuitem];
172 [theNSApplication setAppleMenu:m_menuApp];
174 // Create the Windows menu
175 m_menuWindows = [[NSMenu alloc] initWithTitle: @"Window"];
177 /**/[m_menuWindows addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@""];
178 /**/[m_menuWindows addItem: [NSMenuItem separatorItem]];
179 /**/[m_menuWindows addItemWithTitle:@"Bring All to Front" action:@selector(arrangeInFront:) keyEquivalent:@""];
181 [theNSApplication setWindowsMenu:m_menuWindows];
183 // Create the main menubar
184 m_menuMain = [[NSMenu alloc] initWithTitle: @"wxApp Menu"];
185 /**/NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@"App menu"
186 /* Note: title gets clobbered by app name anyway */
187 action:nil keyEquivalent:@""];
188 [dummyItem setSubmenu:m_menuApp];
189 [m_menuMain addItem:dummyItem];
191 /**/dummyItem = [[NSMenuItem alloc] initWithTitle:@"Window"
192 action:nil keyEquivalent:@""];
193 [dummyItem setSubmenu:m_menuWindows];
194 [m_menuMain addItem:dummyItem];
197 [theNSApplication setMainMenu: m_menuMain];
201 wxMenuBarManager::~wxMenuBarManager()
203 [m_observer release];
206 void wxMenuBarManager::CreateInstance()
208 sm_mbarmanInstance = new wxMenuBarManager;
211 void wxMenuBarManager::DestroyInstance()
213 delete sm_mbarmanInstance;
214 sm_mbarmanInstance = NULL;
217 void wxMenuBarManager::SetMenuBar(wxMenuBar* menubar)
219 m_mainMenuBarInstalled = false;
222 [[[wxTheApp->GetNSApplication() mainMenu] itemAtIndex:0] setSubmenu:nil];
223 [[menubar->GetNSMenu() itemAtIndex:0] setSubmenu:m_menuApp];
224 [wxTheApp->GetNSApplication() setMainMenu:menubar->GetNSMenu()];
230 void wxMenuBarManager::SetMainMenuBar(wxMenuBar* menubar)
232 m_mainMenuBar = menubar;
233 if(m_mainMenuBarInstalled)
237 void wxMenuBarManager::InstallMainMenu()
240 SetMenuBar(m_mainMenuBar);
243 m_mainMenuBarInstalled = true;
244 [[[wxTheApp->GetNSApplication() mainMenu] itemAtIndex:0] setSubmenu:nil];
245 [[m_menuMain itemAtIndex:0] setSubmenu:m_menuApp];
246 [wxTheApp->GetNSApplication() setMainMenu:m_menuMain];
250 void wxMenuBarManager::WindowDidBecomeKey(NSNotification *notification)
252 /* NOTE: m_currentNSWindow might be destroyed but we only ever use it
253 to look it up in the hash table. Do not send messages to it. */
254 m_currentNSWindow = [notification object];
255 wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa(m_currentNSWindow);
257 InstallMenuBarForWindow(win);
263 void wxMenuBarManager::WindowDidResignKey(NSNotification *notification)
267 void wxMenuBarManager::WindowDidBecomeMain(NSNotification *notification)
271 void wxMenuBarManager::WindowDidResignMain(NSNotification *notification)
275 void wxMenuBarManager::WindowWillClose(NSNotification *notification)
280 void wxMenuBarManager::InstallMenuBarForWindow(wxCocoaNSWindow *win)
283 wxMenuBar *menubar = win->GetAppMenuBar(win);
284 wxLogTrace(wxTRACE_COCOA,wxT("Found menubar=%p for window=%p."),menubar,win);
288 void wxMenuBarManager::UpdateMenuBar()
290 if(m_currentNSWindow)
292 wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa(m_currentNSWindow);
294 InstallMenuBarForWindow(win);
298 #endif // wxUSE_MENUS