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 // Declare setAppleMenu: in an NSApplication category since Tiger and later
32 // releases support it but don't declare it as it's considered deprecated.
33 @interface NSApplication(wxDeprecatedMethodsWeWantToUse)
34 - (void)setAppleMenu:(NSMenu *)menu;
37 // ============================================================================
38 // wxMenuBarManagerObserver
39 // ============================================================================
40 @interface wxMenuBarManagerObserver : NSObject
42 wxMenuBarManager *m_mbarman;
46 - (id)initWithWxMenuBarManager: (wxMenuBarManager *)mbarman;
47 - (void)windowDidBecomeKey: (NSNotification *)notification;
49 - (void)windowDidResignKey: (NSNotification *)notification;
50 - (void)windowDidBecomeMain: (NSNotification *)notification;
51 - (void)windowDidResignMain: (NSNotification *)notification;
52 - (void)windowWillClose: (NSNotification *)notification;
54 @end // interface wxMenuBarManagerObserver : NSObject
55 WX_DECLARE_GET_OBJC_CLASS(wxMenuBarManagerObserver,NSObject)
57 @implementation wxMenuBarManagerObserver : NSObject
60 wxFAIL_MSG(wxT("[wxMenuBarManagerObserver -init] should never be called!"));
65 - (id)initWithWxMenuBarManager: (wxMenuBarManager *)mbarman
72 - (void)windowDidBecomeKey: (NSNotification *)notification
75 m_mbarman->WindowDidBecomeKey(notification);
79 - (void)windowDidResignKey: (NSNotification *)notification
82 m_mbarman->WindowDidResignKey(notification);
85 - (void)windowDidBecomeMain: (NSNotification *)notification
88 m_mbarman->WindowDidBecomeMain(notification);
91 - (void)windowDidResignMain: (NSNotification *)notification
94 m_mbarman->WindowDidResignMain(notification);
97 - (void)windowWillClose: (NSNotification *)notification
100 m_mbarman->WindowWillClose(notification);
104 @end // implementation wxMenuBarManagerObserver : NSObject
105 WX_IMPLEMENT_GET_OBJC_CLASS(wxMenuBarManagerObserver,NSObject)
107 // ============================================================================
109 // ============================================================================
110 wxMenuBarManager *wxMenuBarManager::sm_mbarmanInstance = NULL;
112 wxMenuBarManager::wxMenuBarManager()
114 m_observer = [[WX_GET_OBJC_CLASS(wxMenuBarManagerObserver) alloc]
115 initWithWxMenuBarManager:this];
116 [[NSNotificationCenter defaultCenter] addObserver:m_observer
117 selector:@selector(windowDidBecomeKey:)
118 name:NSWindowDidBecomeKeyNotification object:nil];
120 [[NSNotificationCenter defaultCenter] addObserver:m_observer
121 selector:@selector(windowDidResignKey:)
122 name:NSWindowDidResignKeyNotification object:nil];
123 [[NSNotificationCenter defaultCenter] addObserver:m_observer
124 selector:@selector(windowDidBecomeMain:)
125 name:NSWindowDidBecomeMainNotification object:nil];
126 [[NSNotificationCenter defaultCenter] addObserver:m_observer
127 selector:@selector(windowDidResignMain:)
128 name:NSWindowDidResignMainNotification object:nil];
129 [[NSNotificationCenter defaultCenter] addObserver:m_observer
130 selector:@selector(windowWillClose:)
131 name:NSWindowWillCloseNotification object:nil];
134 m_menuServices = nil;
137 m_mainMenuBarInstalled = true;
138 m_mainMenuBar = NULL;
139 m_currentNSWindow = nil;
141 NSApplication *theNSApplication = wxTheApp->GetNSApplication();
142 // Create the services menu.
143 m_menuServices = [[NSMenu alloc] initWithTitle: @"Services"];
144 [theNSApplication setServicesMenu:m_menuServices];
146 NSMenuItem *menuitem;
147 // Create the application (Apple) menu.
148 m_menuApp = [[NSMenu alloc] initWithTitle: @"Apple Menu"];
150 /**/[m_menuApp addItemWithTitle:@"Preferences..." action:nil keyEquivalent:@""];
151 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
152 /**/menuitem = [[NSMenuItem alloc] initWithTitle: @"Services" action:nil keyEquivalent:@""];
153 [menuitem setSubmenu:m_menuServices];
154 [m_menuApp addItem: menuitem];
156 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
157 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide" action:@selector(hide:) keyEquivalent:@""];
158 [menuitem setTarget: theNSApplication];
159 [m_menuApp addItem: menuitem];
161 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@""];
162 [menuitem setTarget: theNSApplication];
163 [m_menuApp addItem: menuitem];
165 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
166 [menuitem setTarget: theNSApplication];
167 [m_menuApp addItem: menuitem];
169 /**/[m_menuApp addItem: [NSMenuItem separatorItem]];
170 /**/menuitem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
171 [menuitem setTarget: theNSApplication];
172 [m_menuApp addItem: menuitem];
175 [theNSApplication setAppleMenu:m_menuApp];
177 // Create the Windows menu
178 m_menuWindows = [[NSMenu alloc] initWithTitle: @"Window"];
180 /**/[m_menuWindows addItemWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@""];
181 /**/[m_menuWindows addItem: [NSMenuItem separatorItem]];
182 /**/[m_menuWindows addItemWithTitle:@"Bring All to Front" action:@selector(arrangeInFront:) keyEquivalent:@""];
184 [theNSApplication setWindowsMenu:m_menuWindows];
186 // Create the main menubar
187 m_menuMain = [[NSMenu alloc] initWithTitle: @"wxApp Menu"];
188 /**/NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@"App menu"
189 /* Note: title gets clobbered by app name anyway */
190 action:nil keyEquivalent:@""];
191 [dummyItem setSubmenu:m_menuApp];
192 [m_menuMain addItem:dummyItem];
194 /**/dummyItem = [[NSMenuItem alloc] initWithTitle:@"Window"
195 action:nil keyEquivalent:@""];
196 [dummyItem setSubmenu:m_menuWindows];
197 [m_menuMain addItem:dummyItem];
200 [theNSApplication setMainMenu: m_menuMain];
204 wxMenuBarManager::~wxMenuBarManager()
206 [m_observer release];
209 void wxMenuBarManager::CreateInstance()
211 sm_mbarmanInstance = new wxMenuBarManager;
214 void wxMenuBarManager::DestroyInstance()
216 delete sm_mbarmanInstance;
217 sm_mbarmanInstance = NULL;
220 void wxMenuBarManager::SetMenuBar(wxMenuBar* menubar)
222 m_mainMenuBarInstalled = false;
225 [[[wxTheApp->GetNSApplication() mainMenu] itemAtIndex:0] setSubmenu:nil];
226 [[menubar->GetNSMenu() itemAtIndex:0] setSubmenu:m_menuApp];
227 [wxTheApp->GetNSApplication() setMainMenu:menubar->GetNSMenu()];
233 void wxMenuBarManager::SetMainMenuBar(wxMenuBar* menubar)
235 m_mainMenuBar = menubar;
236 if(m_mainMenuBarInstalled)
240 void wxMenuBarManager::InstallMainMenu()
243 SetMenuBar(m_mainMenuBar);
246 m_mainMenuBarInstalled = true;
247 [[[wxTheApp->GetNSApplication() mainMenu] itemAtIndex:0] setSubmenu:nil];
248 [[m_menuMain itemAtIndex:0] setSubmenu:m_menuApp];
249 [wxTheApp->GetNSApplication() setMainMenu:m_menuMain];
253 void wxMenuBarManager::WindowDidBecomeKey(NSNotification *notification)
255 /* NOTE: m_currentNSWindow might be destroyed but we only ever use it
256 to look it up in the hash table. Do not send messages to it. */
257 m_currentNSWindow = [notification object];
258 wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa(m_currentNSWindow);
260 InstallMenuBarForWindow(win);
266 void wxMenuBarManager::WindowDidResignKey(NSNotification *notification)
270 void wxMenuBarManager::WindowDidBecomeMain(NSNotification *notification)
274 void wxMenuBarManager::WindowDidResignMain(NSNotification *notification)
278 void wxMenuBarManager::WindowWillClose(NSNotification *notification)
283 void wxMenuBarManager::InstallMenuBarForWindow(wxCocoaNSWindow *win)
286 wxMenuBar *menubar = win->GetAppMenuBar(win);
287 wxLogTrace(wxTRACE_COCOA,wxT("Found menubar=%p for window=%p."),menubar,win);
291 void wxMenuBarManager::UpdateMenuBar()
293 if(m_currentNSWindow)
295 wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa(m_currentNSWindow);
297 InstallMenuBarForWindow(win);
301 #endif // wxUSE_MENUS