1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/cocoa/menu.mm
3 // Purpose: wxMenu and wxMenuBar implementation
4 // Author: David Elliott
7 // Copyright: (c) 2002 David Elliott
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
27 #include "wx/cocoa/autorelease.h"
28 #include "wx/cocoa/string.h"
30 #import <Foundation/NSString.h>
31 #include "wx/cocoa/objc/NSMenu.h"
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 // ============================================================================
40 // wxMenu implementation
41 // ============================================================================
43 bool wxMenu::Create(const wxString& title, long style)
45 wxAutoNSAutoreleasePool pool;
46 m_cocoaNSMenu = [[WX_GET_OBJC_CLASS(WXNSMenu) alloc] initWithTitle: wxNSStringWithWxString(title)];
47 AssociateNSMenu(m_cocoaNSMenu);
53 DisassociateNSMenu(m_cocoaNSMenu);
55 [m_cocoaNSMenu release];
58 wxMenuItem* wxMenu::DoAppend(wxMenuItem *item)
60 wxAutoNSAutoreleasePool pool;
61 if(!wxMenuBase::DoAppend(item))
63 [m_cocoaNSMenu addItem: item->GetNSMenuItem()];
67 wxMenuItem* wxMenu::DoInsert(unsigned long pos, wxMenuItem *item)
69 wxAutoNSAutoreleasePool pool;
70 if(!wxMenuBase::DoInsert(pos,item))
72 [m_cocoaNSMenu insertItem:item->GetNSMenuItem() atIndex:pos];
76 wxMenuItem* wxMenu::DoRemove(wxMenuItem *item)
78 wxAutoNSAutoreleasePool pool;
79 wxMenuItem *retitem = wxMenuBase::DoRemove(item);
80 wxASSERT(retitem->GetNSMenuItem());
81 [m_cocoaNSMenu removeItem:retitem->GetNSMenuItem()];
85 // This autoreleases the menu on the assumption that something is
86 // going to retain it shortly (for instance, it is going to be returned from
87 // an overloaded [NSStatusItem menu] or from the applicationDockMenu:
88 // NSApplication delegate method.
90 // It then sets a bool flag m_cocoaDeletes. When the NSMenu is dealloc'd
91 // (dealloc is the Cocoa destructor) we delete ourselves. In this manner we
92 // can be available for Cocoa calls until Cocoa is finished with us.
94 // I can see very few reasons to undo this. Nevertheless, it is implemented.
95 void wxMenu::SetCocoaDeletes(bool cocoaDeletes)
97 if(m_cocoaDeletes==cocoaDeletes)
99 m_cocoaDeletes = cocoaDeletes;
101 [m_cocoaNSMenu autorelease];
103 [m_cocoaNSMenu retain];
106 void wxMenu::Cocoa_dealloc()
112 // ============================================================================
113 // wxMenuBar implementation
114 // ============================================================================
116 bool wxMenuBar::Create(long style)
118 wxAutoNSAutoreleasePool pool;
119 m_cocoaNSMenu = [[NSMenu alloc] initWithTitle: @"wxMenuBar"];
121 NSMenuItem *dummyItem = [[NSMenuItem alloc] initWithTitle:@"App menu"
122 /* Note: title gets clobbered by app name anyway */
123 action:nil keyEquivalent:@""];
124 [m_cocoaNSMenu addItem:dummyItem];
129 wxMenuBar::wxMenuBar(size_t n,
131 const wxString titles[],
136 for ( size_t i = 0; i < n; ++i )
137 Append(menus[i], titles[i]);
140 wxMenuBar::~wxMenuBar()
142 [m_cocoaNSMenu release];
145 bool wxMenuBar::Append( wxMenu *menu, const wxString &title )
147 wxAutoNSAutoreleasePool pool;
148 wxLogTrace(wxTRACE_COCOA,wxT("append menu=%p, title=%s"),menu,title.c_str());
149 if(!wxMenuBarBase::Append(menu,title))
152 wxASSERT(menu->GetNSMenu());
153 NSString *menuTitle = wxInitNSStringWithWxString([NSString alloc], wxStripMenuCodes(title));
154 NSMenuItem *newItem = [[NSMenuItem alloc] initWithTitle:menuTitle action:NULL keyEquivalent:@""];
155 [menu->GetNSMenu() setTitle:menuTitle];
156 [newItem setSubmenu:menu->GetNSMenu()];
158 [m_cocoaNSMenu addItem:newItem];
165 bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title)
167 wxAutoNSAutoreleasePool pool;
168 wxLogTrace(wxTRACE_COCOA,wxT("insert pos=%lu, menu=%p, title=%s"),pos,menu,title.c_str());
169 // Get the current menu at this position
170 wxMenu *nextmenu = GetMenu(pos);
171 if(!wxMenuBarBase::Insert(pos,menu,title))
174 wxASSERT(menu->GetNSMenu());
175 NSString *menuTitle = wxInitNSStringWithWxString([NSString alloc], title);
176 NSMenuItem *newItem = [[NSMenuItem alloc] initWithTitle:menuTitle action:NULL keyEquivalent:@""];
177 [menu->GetNSMenu() setTitle:menuTitle];
178 [newItem setSubmenu:menu->GetNSMenu()];
180 int itemindex = [m_cocoaNSMenu indexOfItemWithSubmenu:nextmenu->GetNSMenu()];
181 wxASSERT(itemindex>=0);
182 [m_cocoaNSMenu insertItem:newItem atIndex:itemindex];
189 wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title)
194 wxMenu *wxMenuBar::Remove(size_t pos)
196 wxMenu *menu = wxMenuBarBase::Remove(pos);
198 int itemindex = [GetNSMenu() indexOfItemWithSubmenu:menu->GetNSMenu()];
199 wxASSERT(itemindex>=0);
200 [m_cocoaNSMenu removeItemAtIndex:itemindex];
205 void wxMenuBar::EnableTop(size_t pos, bool enable)
209 bool wxMenuBar::IsEnabledTop(size_t pos) const
214 void wxMenuBar::SetMenuLabel(size_t pos, const wxString& label)
218 wxString wxMenuBar::GetMenuLabel(size_t pos) const
220 wxMenu *menu = GetMenu(pos);
221 int itemindex = [m_cocoaNSMenu indexOfItemWithSubmenu:menu->GetNSMenu()];
222 wxASSERT(itemindex>=0);
223 return wxStringWithNSString([[m_cocoaNSMenu itemAtIndex:itemindex] title]);
226 void wxMenuBar::Attach(wxFrame *frame)
228 wxMenuBarBase::Attach(frame);
231 void wxMenuBar::Detach()
233 wxMenuBarBase::Detach();
236 wxSize wxMenuBar::DoGetBestClientSize() const
238 return wxDefaultSize;
241 #endif // wxUSE_MENUS