]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/osx/cocoa/menuitem.mm
Add EnableHistory support to the OSX WebKit backend.
[wxWidgets.git] / src / osx / cocoa / menuitem.mm
... / ...
CommitLineData
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/cocoa/menuitem.mm
3// Purpose: wxMenuItem implementation
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
7// RCS-ID: $Id$
8// Copyright: (c) Stefan Csomor
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#include "wx/wxprec.h"
13
14#include "wx/menuitem.h"
15#include "wx/stockitem.h"
16
17#ifndef WX_PRECOMP
18 #include "wx/app.h"
19 #include "wx/log.h"
20 #include "wx/menu.h"
21#endif // WX_PRECOMP
22
23#include "wx/osx/private.h"
24
25// a mapping from wx ids to standard osx actions in order to support the native menu item handling
26// if a new mapping is added, make sure the wxNonOwnedWindowController has a handler for this action as well
27
28struct Mapping
29{
30 int menuid;
31 SEL action;
32};
33
34Mapping sActionToWXMapping[] =
35{
36 { wxID_UNDO, @selector(undo:) },
37 { wxID_REDO, @selector(redo:) },
38 { wxID_CUT, @selector(cut:) },
39 { wxID_COPY, @selector(copy:) },
40 { wxID_PASTE, @selector(paste:) },
41 { wxID_CLEAR, @selector(delete:) },
42 { wxID_SELECTALL, @selector(selectAll:) },
43 { 0, NULL }
44};
45
46int wxOSXGetIdFromSelector(SEL action )
47{
48 int i = 0 ;
49 while ( sActionToWXMapping[i].action != nil )
50 {
51 if ( sActionToWXMapping[i].action == action )
52 return sActionToWXMapping[i].menuid;
53 ++i;
54 }
55
56 return 0;
57}
58
59SEL wxOSXGetSelectorFromID(int menuId )
60{
61 int i = 0 ;
62 while ( sActionToWXMapping[i].action != nil )
63 {
64 if ( sActionToWXMapping[i].menuid == menuId )
65 return sActionToWXMapping[i].action;
66 ++i;
67 }
68
69 return nil;
70}
71
72
73@implementation wxNSMenuItem
74
75- (id) initWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)charCode
76{
77 self = [super initWithTitle:aString action:aSelector keyEquivalent:charCode];
78 return self;
79}
80
81- (void) clickedAction: (id) sender
82{
83 wxUnusedVar(sender);
84 if ( impl )
85 {
86 wxMenuItem* menuitem = impl->GetWXPeer();
87 if ( menuitem->GetMenu()->HandleCommandProcess(menuitem) == false )
88 {
89 }
90 }
91}
92
93- (void) setEnabled:(BOOL) flag
94{
95 [super setEnabled:flag];
96}
97
98- (BOOL)validateMenuItem:(NSMenuItem *) menuItem
99{
100 wxUnusedVar(menuItem);
101 if( impl )
102 {
103 wxMenuItem* wxmenuitem = impl->GetWXPeer();
104 if ( wxmenuitem )
105 {
106 wxmenuitem->GetMenu()->HandleCommandUpdateStatus(wxmenuitem);
107 return wxmenuitem->IsEnabled();
108 }
109 }
110 return YES ;
111}
112
113- (void)setImplementation: (wxMenuItemImpl *) theImplementation
114{
115 impl = theImplementation;
116}
117
118- (wxMenuItemImpl*) implementation
119{
120 return impl;
121}
122
123@end
124
125void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry* entry )
126{
127 if ( entry == NULL )
128 {
129 [menuItem setKeyEquivalent:@""];
130 return;
131 }
132
133 unsigned int modifiers = 0 ;
134 int key = entry->GetKeyCode() ;
135 if ( key )
136 {
137 if (entry->GetFlags() & wxACCEL_CTRL)
138 modifiers |= NSCommandKeyMask;
139
140 if (entry->GetFlags() & wxACCEL_ALT)
141 modifiers |= NSAlternateKeyMask ;
142
143 // this may be ignored later for alpha chars
144
145 if (entry->GetFlags() & wxACCEL_SHIFT)
146 modifiers |= NSShiftKeyMask ;
147
148 unichar shortcut = 0;
149 if ( key >= WXK_F1 && key <= WXK_F15 )
150 {
151 modifiers |= NSFunctionKeyMask ;
152 shortcut = NSF1FunctionKey + ( key - WXK_F1 );
153 }
154 else
155 {
156 switch ( key )
157 {
158 case WXK_CLEAR :
159 modifiers |= NSFunctionKeyMask;
160 shortcut = NSDeleteCharacter ;
161 break ;
162
163 case WXK_PAGEUP :
164 modifiers |= NSFunctionKeyMask;
165 shortcut = NSPageUpFunctionKey ;
166 break ;
167
168 case WXK_PAGEDOWN :
169 modifiers |= NSFunctionKeyMask;
170 shortcut = NSPageDownFunctionKey ;
171 break ;
172
173 case WXK_LEFT :
174 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
175 shortcut = NSLeftArrowFunctionKey ;
176 break ;
177
178 case WXK_UP :
179 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
180 shortcut = NSUpArrowFunctionKey ;
181 break ;
182
183 case WXK_RIGHT :
184 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
185 shortcut = NSRightArrowFunctionKey ;
186 break ;
187
188 case WXK_DOWN :
189 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
190 shortcut = NSDownArrowFunctionKey ;
191 break ;
192
193 case WXK_HOME :
194 modifiers |= NSFunctionKeyMask;
195 shortcut = NSHomeFunctionKey ;
196 break ;
197
198 case WXK_END :
199 modifiers |= NSFunctionKeyMask;
200 shortcut = NSEndFunctionKey ;
201 break ;
202
203 case WXK_NUMPAD_ENTER :
204 shortcut = NSEnterCharacter;
205 break;
206
207 case WXK_BACK :
208 case WXK_RETURN :
209 case WXK_TAB :
210 case WXK_ESCAPE :
211 default :
212 if(entry->GetFlags() & wxACCEL_SHIFT)
213 shortcut = toupper(key);
214 else
215 shortcut = tolower(key);
216 break ;
217 }
218 }
219
220 [menuItem setKeyEquivalent:[NSString stringWithCharacters:&shortcut length:1]];
221 [menuItem setKeyEquivalentModifierMask:modifiers];
222 }
223}
224
225@interface NSMenuItem(PossibleMethods)
226- (void)setHidden:(BOOL)hidden;
227@end
228
229class wxMenuItemCocoaImpl : public wxMenuItemImpl
230{
231public :
232 wxMenuItemCocoaImpl( wxMenuItem* peer, NSMenuItem* item ) : wxMenuItemImpl(peer), m_osxMenuItem(item)
233 {
234 if ( ![m_osxMenuItem isSeparatorItem] )
235 [(wxNSMenuItem*)m_osxMenuItem setImplementation:this];
236 }
237
238 ~wxMenuItemCocoaImpl();
239
240 void SetBitmap( const wxBitmap& bitmap )
241 {
242 [m_osxMenuItem setImage:bitmap.GetNSImage()];
243 }
244
245 void Enable( bool enable )
246 {
247 [m_osxMenuItem setEnabled:enable];
248 }
249
250 void Check( bool check )
251 {
252 [m_osxMenuItem setState:( check ? NSOnState : NSOffState) ];
253 }
254
255 void Hide( bool hide )
256 {
257 // NB: setHidden is new as of 10.5 so we should not call it below there
258 if ([m_osxMenuItem respondsToSelector:@selector(setHidden:)])
259 [m_osxMenuItem setHidden:hide ];
260 else
261 wxLogDebug("wxMenuItemCocoaImpl::Hide not yet supported under OS X < 10.5");
262 }
263
264 void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
265 {
266 wxCFStringRef cfText(text);
267 [m_osxMenuItem setTitle:cfText.AsNSString()];
268
269 wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
270 }
271
272 bool DoDefault();
273
274 void * GetHMenuItem() { return m_osxMenuItem; }
275
276protected :
277 NSMenuItem* m_osxMenuItem ;
278} ;
279
280wxMenuItemCocoaImpl::~wxMenuItemCocoaImpl()
281{
282 if ( ![m_osxMenuItem isSeparatorItem] )
283 [(wxNSMenuItem*)m_osxMenuItem setImplementation:nil];
284 [m_osxMenuItem release];
285}
286
287bool wxMenuItemCocoaImpl::DoDefault()
288{
289 bool handled=false;
290 int menuid = m_peer->GetId();
291
292 NSApplication *theNSApplication = [NSApplication sharedApplication];
293 if (menuid == wxID_OSX_HIDE)
294 {
295 [theNSApplication hide:nil];
296 handled=true;
297 }
298 else if (menuid == wxID_OSX_HIDEOTHERS)
299 {
300 [theNSApplication hideOtherApplications:nil];
301 handled=true;
302 }
303 else if (menuid == wxID_OSX_SHOWALL)
304 {
305 [theNSApplication unhideAllApplications:nil];
306 handled=true;
307 }
308 return handled;
309}
310
311wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
312 int menuid,
313 const wxString& text,
314 wxAcceleratorEntry *entry,
315 const wxString& WXUNUSED(strHelp),
316 wxItemKind kind,
317 wxMenu *pSubMenu )
318{
319 wxMenuItemImpl* c = NULL;
320 NSMenuItem* item = nil;
321
322 if ( kind == wxITEM_SEPARATOR )
323 {
324 item = [[NSMenuItem separatorItem] retain];
325 }
326 else
327 {
328 wxCFStringRef cfText(text);
329 SEL selector = nil;
330 bool targetSelf = false;
331 if ( (pParentMenu == NULL || !pParentMenu->GetNoEventsMode()) && pSubMenu == NULL )
332 {
333 selector = wxOSXGetSelectorFromID(menuid);
334
335 if ( selector == nil )
336 {
337 selector = @selector(clickedAction:);
338 targetSelf = true;
339 }
340 }
341
342 wxNSMenuItem* menuitem = [ [ wxNSMenuItem alloc ] initWithTitle:cfText.AsNSString() action:selector keyEquivalent:@""];
343 if ( targetSelf )
344 [menuitem setTarget:menuitem];
345
346 if ( pSubMenu )
347 {
348 pSubMenu->GetPeer()->SetTitle( text );
349 [menuitem setSubmenu:pSubMenu->GetHMenu()];
350 }
351 else
352 {
353 wxMacCocoaMenuItemSetAccelerator( menuitem, entry );
354 }
355 item = menuitem;
356 }
357 c = new wxMenuItemCocoaImpl( peer, item );
358 return c;
359}