]>
Commit | Line | Data |
---|---|---|
dbeddfb9 SC |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: src/osx/cocoa/menu.mm | |
3 | // Purpose: wxMenu, wxMenuBar, wxMenuItem | |
4 | // Author: Stefan Csomor | |
5 | // Modified by: | |
6 | // Created: 1998-01-01 | |
7 | // RCS-ID: $Id: menu.cpp 54129 2008-06-11 19:30:52Z SC $ | |
8 | // Copyright: (c) Stefan Csomor | |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // ============================================================================ | |
13 | // headers & declarations | |
14 | // ============================================================================ | |
15 | ||
16 | // wxWidgets headers | |
17 | // ----------------- | |
18 | ||
19 | #include "wx/wxprec.h" | |
20 | ||
21 | #include "wx/menu.h" | |
22 | ||
23 | #ifndef WX_PRECOMP | |
24 | #include "wx/log.h" | |
25 | #include "wx/app.h" | |
26 | #include "wx/utils.h" | |
27 | #include "wx/frame.h" | |
28 | #include "wx/menuitem.h" | |
29 | #endif | |
30 | ||
31 | #include "wx/osx/private.h" | |
32 | ||
33 | // other standard headers | |
34 | // ---------------------- | |
35 | #include <string.h> | |
36 | ||
dbeddfb9 SC |
37 | @implementation wxNSMenu |
38 | ||
fbbe829a | 39 | - (id) initWithTitle:(NSString*) title |
dbeddfb9 | 40 | { |
fbbe829a | 41 | [super initWithTitle:title]; |
be136f07 | 42 | impl = NULL; |
dbeddfb9 SC |
43 | return self; |
44 | } | |
45 | ||
46 | - (void)setImplementation: (wxMenuImpl *) theImplementation | |
47 | { | |
48 | impl = theImplementation; | |
49 | } | |
50 | ||
51 | - (wxMenuImpl*) implementation | |
52 | { | |
53 | return impl; | |
54 | } | |
55 | ||
56 | @end | |
57 | ||
030495ec | 58 | @interface wxNSMenuController : NSObject wxOSX_10_6_AND_LATER(<NSMenuDelegate>) |
dbeddfb9 SC |
59 | { |
60 | } | |
61 | ||
62 | - (void)menuWillOpen:(NSMenu *)menu; | |
63 | - (void)menuDidClose:(NSMenu *)menu; | |
64 | - (void)menu:(NSMenu *)menu willHighlightItem:(NSMenuItem *)item; | |
65 | ||
66 | @end | |
67 | ||
68 | @implementation wxNSMenuController | |
69 | ||
70 | - (id) init | |
71 | { | |
72 | [super init]; | |
73 | return self; | |
74 | } | |
75 | ||
76 | - (void)menuWillOpen:(NSMenu *)smenu | |
77 | { | |
78 | wxNSMenu* menu = (wxNSMenu*) smenu; | |
79 | wxMenuImpl* menuimpl = [menu implementation]; | |
80 | if ( menuimpl ) | |
81 | { | |
82 | wxMenu* wxpeer = (wxMenu*) menuimpl->GetWXPeer(); | |
3fe48198 SC |
83 | if ( wxpeer ) |
84 | wxpeer->HandleMenuOpened(); | |
dbeddfb9 SC |
85 | } |
86 | } | |
87 | ||
88 | - (void)menuDidClose:(NSMenu *)smenu | |
89 | { | |
90 | wxNSMenu* menu = (wxNSMenu*) smenu; | |
91 | wxMenuImpl* menuimpl = [menu implementation]; | |
92 | if ( menuimpl ) | |
93 | { | |
94 | wxMenu* wxpeer = (wxMenu*) menuimpl->GetWXPeer(); | |
3fe48198 SC |
95 | if ( wxpeer ) |
96 | wxpeer->HandleMenuClosed(); | |
dbeddfb9 SC |
97 | } |
98 | } | |
99 | ||
100 | - (void)menu:(NSMenu *)smenu willHighlightItem:(NSMenuItem *)item | |
101 | { | |
102 | wxNSMenu* menu = (wxNSMenu*) smenu; | |
103 | wxMenuImpl* menuimpl = [menu implementation]; | |
104 | if ( menuimpl ) | |
105 | { | |
106 | wxMenu* wxpeer = (wxMenu*) menuimpl->GetWXPeer(); | |
107 | if ( [ item isKindOfClass:[wxNSMenuItem class] ] ) | |
108 | { | |
109 | wxMenuItemImpl* menuitemimpl = (wxMenuItemImpl*) [ (wxNSMenuItem*) item implementation ]; | |
110 | if ( wxpeer && menuitemimpl ) | |
111 | { | |
112 | wxpeer->HandleMenuItemHighlighted( menuitemimpl->GetWXPeer() ); | |
113 | } | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
118 | @end | |
119 | ||
03647350 VZ |
120 | @interface NSApplication(MissingAppleMenuCall) |
121 | - (void)setAppleMenu:(NSMenu *)menu; | |
122 | @end | |
ffad7b0d | 123 | |
03647350 | 124 | class wxMenuCocoaImpl : public wxMenuImpl |
dbeddfb9 SC |
125 | { |
126 | public : | |
be136f07 | 127 | wxMenuCocoaImpl( wxMenu* peer , wxNSMenu* menu) : wxMenuImpl(peer), m_osxMenu(menu) |
dbeddfb9 | 128 | { |
be136f07 SC |
129 | static wxNSMenuController* controller = NULL; |
130 | if ( controller == NULL ) | |
131 | { | |
132 | controller = [[wxNSMenuController alloc] init]; | |
133 | } | |
134 | [menu setDelegate:controller]; | |
135 | [m_osxMenu setImplementation:this]; | |
9a038ddc SC |
136 | // gc aware |
137 | if ( m_osxMenu ) | |
138 | CFRetain(m_osxMenu); | |
139 | [m_osxMenu release]; | |
dbeddfb9 | 140 | } |
03647350 | 141 | |
dbeddfb9 | 142 | virtual ~wxMenuCocoaImpl(); |
03647350 VZ |
143 | |
144 | virtual void InsertOrAppend(wxMenuItem *pItem, size_t pos) | |
dbeddfb9 | 145 | { |
b7a015cb SC |
146 | NSMenuItem* nsmenuitem = (NSMenuItem*) pItem->GetPeer()->GetHMenuItem(); |
147 | // make sure a call of SetSubMenu is also reflected (occuring after Create) | |
148 | // update the native menu item accordingly | |
149 | ||
150 | if ( pItem->IsSubMenu() ) | |
151 | { | |
152 | wxMenu* wxsubmenu = pItem->GetSubMenu(); | |
153 | WXHMENU nssubmenu = wxsubmenu->GetHMenu(); | |
154 | if ( [nsmenuitem submenu] != nssubmenu ) | |
155 | { | |
156 | wxsubmenu->GetPeer()->SetTitle( pItem->GetItemLabelText() ); | |
157 | [nsmenuitem setSubmenu:nssubmenu]; | |
158 | } | |
159 | } | |
160 | ||
dbeddfb9 | 161 | if ( pos == (size_t) -1 ) |
b7a015cb | 162 | [m_osxMenu addItem:nsmenuitem ]; |
dbeddfb9 | 163 | else |
b7a015cb | 164 | [m_osxMenu insertItem:nsmenuitem atIndex:pos]; |
dbeddfb9 | 165 | } |
03647350 VZ |
166 | |
167 | virtual void Remove( wxMenuItem *pItem ) | |
dbeddfb9 SC |
168 | { |
169 | [m_osxMenu removeItem:(NSMenuItem*) pItem->GetPeer()->GetHMenuItem()]; | |
170 | } | |
03647350 | 171 | |
dbeddfb9 SC |
172 | virtual void MakeRoot() |
173 | { | |
174 | [NSApp setMainMenu:m_osxMenu]; | |
175 | [NSApp setAppleMenu:[[m_osxMenu itemAtIndex:0] submenu]]; | |
176 | } | |
177 | ||
d8207702 | 178 | virtual void Enable( bool WXUNUSED(enable) ) |
dbeddfb9 SC |
179 | { |
180 | } | |
03647350 | 181 | |
dbeddfb9 SC |
182 | virtual void SetTitle( const wxString& text ) |
183 | { | |
184 | wxCFStringRef cfText(text); | |
185 | [m_osxMenu setTitle:cfText.AsNSString()]; | |
186 | } | |
187 | ||
2cb5d2d2 SC |
188 | virtual void PopUp( wxWindow *win, int x, int y ) |
189 | { | |
190 | win->ScreenToClient( &x , &y ) ; | |
191 | NSView *view = win->GetPeer()->GetWXWidget(); | |
192 | NSRect frame = [view frame]; | |
193 | frame.origin.x = x; | |
194 | frame.origin.y = y; | |
195 | frame.size.width = 1; | |
196 | frame.size.height = 1; | |
197 | NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]; | |
198 | [popUpButtonCell setAutoenablesItems:NO]; | |
199 | [popUpButtonCell setAltersStateOfSelectedItem:NO]; | |
200 | [popUpButtonCell setMenu:m_osxMenu]; | |
201 | [popUpButtonCell selectItem:nil]; | |
202 | [popUpButtonCell performClickWithFrame:frame inView:view]; | |
203 | [popUpButtonCell release]; | |
204 | } | |
205 | ||
dbeddfb9 SC |
206 | WXHMENU GetHMenu() { return m_osxMenu; } |
207 | ||
208 | static wxMenuImpl* Create( wxMenu* peer, const wxString& title ); | |
209 | static wxMenuImpl* CreateRootMenu( wxMenu* peer ); | |
210 | protected : | |
be136f07 | 211 | wxNSMenu* m_osxMenu; |
dbeddfb9 SC |
212 | } ; |
213 | ||
214 | wxMenuCocoaImpl::~wxMenuCocoaImpl() | |
215 | { | |
42c2b729 | 216 | [m_osxMenu setDelegate:nil]; |
be136f07 | 217 | [m_osxMenu setImplementation:nil]; |
9a038ddc SC |
218 | // gc aware |
219 | if ( m_osxMenu ) | |
220 | CFRelease(m_osxMenu); | |
dbeddfb9 SC |
221 | } |
222 | ||
223 | wxMenuImpl* wxMenuImpl::Create( wxMenu* peer, const wxString& title ) | |
224 | { | |
dbeddfb9 SC |
225 | wxCFStringRef cfText( title ); |
226 | wxNSMenu* menu = [[wxNSMenu alloc] initWithTitle:cfText.AsNSString()]; | |
227 | wxMenuImpl* c = new wxMenuCocoaImpl( peer, menu ); | |
dbeddfb9 SC |
228 | return c; |
229 | } |