1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/menuitem.mm
3 // Purpose: wxMenuItem implementation
4 // Author: Stefan Csomor
7 // RCS-ID: $Id: menuitem.cpp 54129 2008-06-11 19:30:52Z SC $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #include "wx/menuitem.h"
15 #include "wx/stockitem.h"
23 #include "wx/osx/private.h"
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
34 Mapping sActionToWXMapping[] =
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:) },
46 int wxOSXGetIdFromSelector(SEL action )
49 while ( sActionToWXMapping[i].action != nil )
51 if ( sActionToWXMapping[i].action == action )
52 return sActionToWXMapping[i].menuid;
59 SEL wxOSXGetSelectorFromID(int menuId )
62 while ( sActionToWXMapping[i].action != nil )
64 if ( sActionToWXMapping[i].menuid == menuId )
65 return sActionToWXMapping[i].action;
73 @implementation wxNSMenuItem
75 - (id) initWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)charCode
77 [super initWithTitle:aString action:aSelector keyEquivalent:charCode];
81 - (void) clickedAction: (id) sender
86 wxMenuItem* menuitem = impl->GetWXPeer();
87 if ( menuitem->GetMenu()->HandleCommandProcess(menuitem) == false )
93 - (void) setEnabled:(BOOL) flag
95 [super setEnabled:flag];
98 - (BOOL)validateMenuItem:(NSMenuItem *) menuItem
100 wxUnusedVar(menuItem);
103 if ( impl->GetWXPeer()->GetMenu()->HandleCommandUpdateStatus(impl->GetWXPeer()) )
104 return impl->GetWXPeer()->IsEnabled();
109 - (void)setImplementation: (wxMenuItemImpl *) theImplementation
111 impl = theImplementation;
114 - (wxMenuItemImpl*) implementation
121 void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry* entry )
123 unsigned int modifiers = 0 ;
124 int key = entry->GetKeyCode() ;
127 if (entry->GetFlags() & wxACCEL_CTRL)
128 modifiers |= NSCommandKeyMask;
130 if (entry->GetFlags() & wxACCEL_ALT)
131 modifiers |= NSAlternateKeyMask ;
133 // this may be ignored later for alpha chars
135 if (entry->GetFlags() & wxACCEL_SHIFT)
136 modifiers |= NSShiftKeyMask ;
138 unichar shortcut = 0;
139 if ( key >= WXK_F1 && key <= WXK_F15 )
141 modifiers |= NSFunctionKeyMask ;
142 shortcut = NSF1FunctionKey + ( key - WXK_F1 );
149 modifiers |= NSFunctionKeyMask;
150 shortcut = NSDeleteCharacter ;
154 modifiers |= NSFunctionKeyMask;
155 shortcut = NSPageUpFunctionKey ;
159 modifiers |= NSFunctionKeyMask;
160 shortcut = NSPageDownFunctionKey ;
164 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
165 shortcut = NSLeftArrowFunctionKey ;
169 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
170 shortcut = NSUpArrowFunctionKey ;
174 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
175 shortcut = NSRightArrowFunctionKey ;
179 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
180 shortcut = NSDownArrowFunctionKey ;
184 modifiers |= NSFunctionKeyMask;
185 shortcut = NSHomeFunctionKey ;
189 modifiers |= NSFunctionKeyMask;
190 shortcut = NSEndFunctionKey ;
193 case WXK_NUMPAD_ENTER :
194 shortcut = NSEnterCharacter;
202 if(entry->GetFlags() & wxACCEL_SHIFT)
203 shortcut = toupper(key);
205 shortcut = tolower(key);
210 [menuItem setKeyEquivalent:[NSString stringWithCharacters:&shortcut length:1]];
211 [menuItem setKeyEquivalentModifierMask:modifiers];
215 @interface NSMenuItem(PossibleMethods)
216 - (void)setHidden:(BOOL)hidden;
219 class wxMenuItemCocoaImpl : public wxMenuItemImpl
222 wxMenuItemCocoaImpl( wxMenuItem* peer, NSMenuItem* item ) : wxMenuItemImpl(peer), m_osxMenuItem(item)
224 if ( ![m_osxMenuItem isSeparatorItem] )
225 [(wxNSMenuItem*)m_osxMenuItem setImplementation:this];
228 ~wxMenuItemCocoaImpl();
230 void SetBitmap( const wxBitmap& bitmap )
232 [m_osxMenuItem setImage:bitmap.GetNSImage()];
235 void Enable( bool enable )
237 [m_osxMenuItem setEnabled:enable];
240 void Check( bool check )
242 [m_osxMenuItem setState:( check ? NSOnState : NSOffState) ];
245 void Hide( bool hide )
247 // NB: setHidden is new as of 10.5 so we should not call it below there
248 if ([m_osxMenuItem respondsToSelector:@selector(setHidden:)])
249 [m_osxMenuItem setHidden:hide ];
251 wxLogDebug("wxMenuItemCocoaImpl::Hide not yet supported under OS X < 10.5");
254 void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
256 wxCFStringRef cfText(text);
257 [m_osxMenuItem setTitle:cfText.AsNSString()];
260 wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
266 void * GetHMenuItem() { return m_osxMenuItem; }
269 NSMenuItem* m_osxMenuItem ;
272 wxMenuItemCocoaImpl::~wxMenuItemCocoaImpl()
274 if ( ![m_osxMenuItem isSeparatorItem] )
275 [(wxNSMenuItem*)m_osxMenuItem setImplementation:nil];
276 [m_osxMenuItem release];
279 bool wxMenuItemCocoaImpl::DoDefault()
282 int menuid = m_peer->GetId();
284 NSApplication *theNSApplication = [NSApplication sharedApplication];
285 if (menuid == wxID_OSX_HIDE)
287 [theNSApplication hide:nil];
290 else if (menuid == wxID_OSX_HIDEOTHERS)
292 [theNSApplication hideOtherApplications:nil];
295 else if (menuid == wxID_OSX_SHOWALL)
297 [theNSApplication unhideAllApplications:nil];
303 wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
305 const wxString& text,
306 wxAcceleratorEntry *entry,
307 const wxString& WXUNUSED(strHelp),
311 wxMenuItemImpl* c = NULL;
312 NSMenuItem* item = nil;
314 if ( kind == wxITEM_SEPARATOR )
316 item = [[NSMenuItem separatorItem] retain];
320 wxCFStringRef cfText(text);
322 bool targetSelf = false;
323 if ( ! pParentMenu->GetNoEventsMode() && pSubMenu == NULL )
325 selector = wxOSXGetSelectorFromID(menuid);
327 if ( selector == nil )
329 selector = @selector(clickedAction:);
334 wxNSMenuItem* menuitem = [ [ wxNSMenuItem alloc ] initWithTitle:cfText.AsNSString() action:selector keyEquivalent:@""];
336 [menuitem setTarget:menuitem];
340 pSubMenu->GetPeer()->SetTitle( text );
341 [menuitem setSubmenu:pSubMenu->GetHMenu()];
346 wxMacCocoaMenuItemSetAccelerator( menuitem, entry );
350 c = new wxMenuItemCocoaImpl( peer, item );