1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/menuitem.mm
3 // Purpose: wxMenuItem implementation
4 // Author: Stefan Csomor
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 // as we don't have NSUndoManager support we must not use the native actions
38 { wxID_UNDO, @selector(undo:) },
39 { wxID_REDO, @selector(redo:) },
41 { wxID_CUT, @selector(cut:) },
42 { wxID_COPY, @selector(copy:) },
43 { wxID_PASTE, @selector(paste:) },
44 { wxID_CLEAR, @selector(delete:) },
45 { wxID_SELECTALL, @selector(selectAll:) },
49 int wxOSXGetIdFromSelector(SEL action )
52 while ( sActionToWXMapping[i].action != nil )
54 if ( sActionToWXMapping[i].action == action )
55 return sActionToWXMapping[i].menuid;
62 SEL wxOSXGetSelectorFromID(int menuId )
65 while ( sActionToWXMapping[i].action != nil )
67 if ( sActionToWXMapping[i].menuid == menuId )
68 return sActionToWXMapping[i].action;
76 @implementation wxNSMenuItem
78 - (id) initWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)charCode
80 self = [super initWithTitle:aString action:aSelector keyEquivalent:charCode];
84 - (void) clickedAction: (id) sender
89 wxMenuItem* menuitem = impl->GetWXPeer();
90 if ( menuitem->GetMenu()->HandleCommandProcess(menuitem) == false )
96 - (void) setEnabled:(BOOL) flag
98 [super setEnabled:flag];
101 - (BOOL)validateMenuItem:(NSMenuItem *) menuItem
103 wxUnusedVar(menuItem);
106 wxMenuItem* wxmenuitem = impl->GetWXPeer();
109 wxmenuitem->GetMenu()->HandleCommandUpdateStatus(wxmenuitem);
110 return wxmenuitem->IsEnabled();
116 - (void)setImplementation: (wxMenuItemImpl *) theImplementation
118 impl = theImplementation;
121 - (wxMenuItemImpl*) implementation
128 void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry* entry )
132 [menuItem setKeyEquivalent:@""];
136 unsigned int modifiers = 0 ;
137 int key = entry->GetKeyCode() ;
140 if (entry->GetFlags() & wxACCEL_CTRL)
141 modifiers |= NSCommandKeyMask;
143 if (entry->GetFlags() & wxACCEL_RAW_CTRL)
144 modifiers |= NSControlKeyMask;
146 if (entry->GetFlags() & wxACCEL_ALT)
147 modifiers |= NSAlternateKeyMask ;
149 // this may be ignored later for alpha chars
151 if (entry->GetFlags() & wxACCEL_SHIFT)
152 modifiers |= NSShiftKeyMask ;
154 unichar shortcut = 0;
155 if ( key >= WXK_F1 && key <= WXK_F15 )
157 modifiers |= NSFunctionKeyMask ;
158 shortcut = NSF1FunctionKey + ( key - WXK_F1 );
165 modifiers |= NSFunctionKeyMask;
166 shortcut = NSDeleteCharacter ;
170 modifiers |= NSFunctionKeyMask;
171 shortcut = NSPageUpFunctionKey ;
175 modifiers |= NSFunctionKeyMask;
176 shortcut = NSPageDownFunctionKey ;
180 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
181 shortcut = NSLeftArrowFunctionKey ;
185 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
186 shortcut = NSUpArrowFunctionKey ;
190 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
191 shortcut = NSRightArrowFunctionKey ;
195 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
196 shortcut = NSDownArrowFunctionKey ;
200 modifiers |= NSFunctionKeyMask;
201 shortcut = NSHomeFunctionKey ;
205 modifiers |= NSFunctionKeyMask;
206 shortcut = NSEndFunctionKey ;
209 case WXK_NUMPAD_ENTER :
210 shortcut = NSEnterCharacter;
218 if(entry->GetFlags() & wxACCEL_SHIFT)
219 shortcut = toupper(key);
221 shortcut = tolower(key);
226 [menuItem setKeyEquivalent:[NSString stringWithCharacters:&shortcut length:1]];
227 [menuItem setKeyEquivalentModifierMask:modifiers];
231 @interface NSMenuItem(PossibleMethods)
232 - (void)setHidden:(BOOL)hidden;
235 class wxMenuItemCocoaImpl : public wxMenuItemImpl
238 wxMenuItemCocoaImpl( wxMenuItem* peer, NSMenuItem* item ) : wxMenuItemImpl(peer), m_osxMenuItem(item)
240 if ( ![m_osxMenuItem isSeparatorItem] )
241 [(wxNSMenuItem*)m_osxMenuItem setImplementation:this];
244 ~wxMenuItemCocoaImpl();
246 void SetBitmap( const wxBitmap& bitmap )
248 [m_osxMenuItem setImage:bitmap.GetNSImage()];
251 void Enable( bool enable )
253 [m_osxMenuItem setEnabled:enable];
256 void Check( bool check )
258 [m_osxMenuItem setState:( check ? NSOnState : NSOffState) ];
261 void Hide( bool hide )
263 // NB: setHidden is new as of 10.5 so we should not call it below there
264 if ([m_osxMenuItem respondsToSelector:@selector(setHidden:)])
265 [m_osxMenuItem setHidden:hide ];
267 wxLogDebug("wxMenuItemCocoaImpl::Hide not yet supported under OS X < 10.5");
270 void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
272 wxCFStringRef cfText(text);
273 [m_osxMenuItem setTitle:cfText.AsNSString()];
275 wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
280 void * GetHMenuItem() { return m_osxMenuItem; }
283 NSMenuItem* m_osxMenuItem ;
286 wxMenuItemCocoaImpl::~wxMenuItemCocoaImpl()
288 if ( ![m_osxMenuItem isSeparatorItem] )
289 [(wxNSMenuItem*)m_osxMenuItem setImplementation:nil];
290 [m_osxMenuItem release];
293 bool wxMenuItemCocoaImpl::DoDefault()
296 int menuid = m_peer->GetId();
298 NSApplication *theNSApplication = [NSApplication sharedApplication];
299 if (menuid == wxID_OSX_HIDE)
301 [theNSApplication hide:nil];
304 else if (menuid == wxID_OSX_HIDEOTHERS)
306 [theNSApplication hideOtherApplications:nil];
309 else if (menuid == wxID_OSX_SHOWALL)
311 [theNSApplication unhideAllApplications:nil];
314 else if (menuid == wxApp::s_macExitMenuItemId)
316 wxTheApp->ExitMainLoop();
321 wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
323 const wxString& text,
324 wxAcceleratorEntry *entry,
325 const wxString& WXUNUSED(strHelp),
329 wxMenuItemImpl* c = NULL;
330 NSMenuItem* item = nil;
332 if ( kind == wxITEM_SEPARATOR )
334 item = [[NSMenuItem separatorItem] retain];
338 wxCFStringRef cfText(text);
340 bool targetSelf = false;
341 if ( (pParentMenu == NULL || !pParentMenu->GetNoEventsMode()) && pSubMenu == NULL )
343 selector = wxOSXGetSelectorFromID(menuid);
345 if ( selector == nil )
347 selector = @selector(clickedAction:);
352 wxNSMenuItem* menuitem = [ [ wxNSMenuItem alloc ] initWithTitle:cfText.AsNSString() action:selector keyEquivalent:@""];
354 [menuitem setTarget:menuitem];
358 pSubMenu->GetPeer()->SetTitle( text );
359 [menuitem setSubmenu:pSubMenu->GetHMenu()];
363 wxMacCocoaMenuItemSetAccelerator( menuitem, entry );
367 c = new wxMenuItemCocoaImpl( peer, item );