]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/menuitem.mm
Auto complete file names in the text controls of wx{File,Dir}PickerCtrl.
[wxWidgets.git] / src / osx / cocoa / menuitem.mm
CommitLineData
dbeddfb9
SC
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/osx/cocoa/menuitem.mm
3// Purpose: wxMenuItem implementation
4// Author: Stefan Csomor
5// Modified by:
6// Created: 1998-01-01
a9a4f229 7// RCS-ID: $Id$
dbeddfb9
SC
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"
70412bd4 19 #include "wx/log.h"
dbeddfb9
SC
20 #include "wx/menu.h"
21#endif // WX_PRECOMP
22
23#include "wx/osx/private.h"
24
fbbe829a
SC
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{
2daf63c4
SC
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 }
fbbe829a
SC
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
dbeddfb9
SC
73@implementation wxNSMenuItem
74
fbbe829a 75- (id) initWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)charCode
dbeddfb9 76{
a985b2c8
SC
77 self = [super initWithTitle:aString action:aSelector keyEquivalent:charCode];
78 return self;
dbeddfb9
SC
79}
80
81- (void) clickedAction: (id) sender
82{
d8207702 83 wxUnusedVar(sender);
dbeddfb9
SC
84 if ( impl )
85 {
c46d0503
SC
86 wxMenuItem* menuitem = impl->GetWXPeer();
87 if ( menuitem->GetMenu()->HandleCommandProcess(menuitem) == false )
88 {
89 }
dbeddfb9
SC
90 }
91}
92
fbbe829a
SC
93- (void) setEnabled:(BOOL) flag
94{
95 [super setEnabled:flag];
96}
97
dbeddfb9
SC
98- (BOOL)validateMenuItem:(NSMenuItem *) menuItem
99{
d8207702 100 wxUnusedVar(menuItem);
dbeddfb9
SC
101 if( impl )
102 {
40a35c1f
SC
103 wxMenuItem* wxmenuitem = impl->GetWXPeer();
104 if ( wxmenuitem )
105 {
106 wxmenuitem->GetMenu()->HandleCommandUpdateStatus(wxmenuitem);
107 return wxmenuitem->IsEnabled();
108 }
dbeddfb9
SC
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{
40a35c1f
SC
127 if ( entry == NULL )
128 {
129 [menuItem setKeyEquivalent:@""];
130 return;
131 }
132
dbeddfb9
SC
133 unsigned int modifiers = 0 ;
134 int key = entry->GetKeyCode() ;
135 if ( key )
136 {
fa6ff5f1 137 if (entry->GetFlags() & wxACCEL_CTRL)
dbeddfb9
SC
138 modifiers |= NSCommandKeyMask;
139
3c5f6264
SC
140 if (entry->GetFlags() & wxACCEL_RAW_CTRL)
141 modifiers |= NSControlKeyMask;
142
dbeddfb9
SC
143 if (entry->GetFlags() & wxACCEL_ALT)
144 modifiers |= NSAlternateKeyMask ;
145
146 // this may be ignored later for alpha chars
147
148 if (entry->GetFlags() & wxACCEL_SHIFT)
149 modifiers |= NSShiftKeyMask ;
150
151 unichar shortcut = 0;
152 if ( key >= WXK_F1 && key <= WXK_F15 )
153 {
154 modifiers |= NSFunctionKeyMask ;
155 shortcut = NSF1FunctionKey + ( key - WXK_F1 );
156 }
157 else
158 {
159 switch ( key )
160 {
dbeddfb9 161 case WXK_CLEAR :
9c894932
SC
162 modifiers |= NSFunctionKeyMask;
163 shortcut = NSDeleteCharacter ;
dbeddfb9
SC
164 break ;
165
166 case WXK_PAGEUP :
9c894932
SC
167 modifiers |= NSFunctionKeyMask;
168 shortcut = NSPageUpFunctionKey ;
dbeddfb9
SC
169 break ;
170
171 case WXK_PAGEDOWN :
9c894932
SC
172 modifiers |= NSFunctionKeyMask;
173 shortcut = NSPageDownFunctionKey ;
dbeddfb9
SC
174 break ;
175
176 case WXK_LEFT :
9c894932
SC
177 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
178 shortcut = NSLeftArrowFunctionKey ;
dbeddfb9
SC
179 break ;
180
181 case WXK_UP :
9c894932
SC
182 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
183 shortcut = NSUpArrowFunctionKey ;
dbeddfb9
SC
184 break ;
185
186 case WXK_RIGHT :
9c894932
SC
187 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
188 shortcut = NSRightArrowFunctionKey ;
dbeddfb9
SC
189 break ;
190
191 case WXK_DOWN :
9c894932
SC
192 modifiers |= NSNumericPadKeyMask | NSFunctionKeyMask;
193 shortcut = NSDownArrowFunctionKey ;
dbeddfb9
SC
194 break ;
195
196 case WXK_HOME :
9c894932
SC
197 modifiers |= NSFunctionKeyMask;
198 shortcut = NSHomeFunctionKey ;
dbeddfb9
SC
199 break ;
200
201 case WXK_END :
9c894932
SC
202 modifiers |= NSFunctionKeyMask;
203 shortcut = NSEndFunctionKey ;
dbeddfb9 204 break ;
9c894932
SC
205
206 case WXK_NUMPAD_ENTER :
207 shortcut = NSEnterCharacter;
208 break;
209
210 case WXK_BACK :
211 case WXK_RETURN :
212 case WXK_TAB :
213 case WXK_ESCAPE :
dbeddfb9
SC
214 default :
215 if(entry->GetFlags() & wxACCEL_SHIFT)
216 shortcut = toupper(key);
217 else
218 shortcut = tolower(key);
219 break ;
220 }
221 }
222
223 [menuItem setKeyEquivalent:[NSString stringWithCharacters:&shortcut length:1]];
224 [menuItem setKeyEquivalentModifierMask:modifiers];
225 }
226}
227
9c894932
SC
228@interface NSMenuItem(PossibleMethods)
229- (void)setHidden:(BOOL)hidden;
230@end
231
03647350 232class wxMenuItemCocoaImpl : public wxMenuItemImpl
dbeddfb9
SC
233{
234public :
235 wxMenuItemCocoaImpl( wxMenuItem* peer, NSMenuItem* item ) : wxMenuItemImpl(peer), m_osxMenuItem(item)
236 {
be136f07
SC
237 if ( ![m_osxMenuItem isSeparatorItem] )
238 [(wxNSMenuItem*)m_osxMenuItem setImplementation:this];
dbeddfb9 239 }
03647350 240
dbeddfb9 241 ~wxMenuItemCocoaImpl();
03647350
VZ
242
243 void SetBitmap( const wxBitmap& bitmap )
dbeddfb9
SC
244 {
245 [m_osxMenuItem setImage:bitmap.GetNSImage()];
246 }
03647350
VZ
247
248 void Enable( bool enable )
dbeddfb9
SC
249 {
250 [m_osxMenuItem setEnabled:enable];
251 }
03647350
VZ
252
253 void Check( bool check )
dbeddfb9
SC
254 {
255 [m_osxMenuItem setState:( check ? NSOnState : NSOffState) ];
256 }
03647350 257
dbeddfb9
SC
258 void Hide( bool hide )
259 {
70412bd4
KO
260 // NB: setHidden is new as of 10.5 so we should not call it below there
261 if ([m_osxMenuItem respondsToSelector:@selector(setHidden:)])
262 [m_osxMenuItem setHidden:hide ];
263 else
264 wxLogDebug("wxMenuItemCocoaImpl::Hide not yet supported under OS X < 10.5");
dbeddfb9 265 }
03647350
VZ
266
267 void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
dbeddfb9
SC
268 {
269 wxCFStringRef cfText(text);
270 [m_osxMenuItem setTitle:cfText.AsNSString()];
03647350 271
40a35c1f 272 wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
dbeddfb9 273 }
c46d0503
SC
274
275 bool DoDefault();
03647350 276
dbeddfb9
SC
277 void * GetHMenuItem() { return m_osxMenuItem; }
278
279protected :
280 NSMenuItem* m_osxMenuItem ;
281} ;
282
283wxMenuItemCocoaImpl::~wxMenuItemCocoaImpl()
284{
be136f07
SC
285 if ( ![m_osxMenuItem isSeparatorItem] )
286 [(wxNSMenuItem*)m_osxMenuItem setImplementation:nil];
3c9413b7 287 [m_osxMenuItem release];
dbeddfb9
SC
288}
289
c46d0503
SC
290bool wxMenuItemCocoaImpl::DoDefault()
291{
292 bool handled=false;
293 int menuid = m_peer->GetId();
294
295 NSApplication *theNSApplication = [NSApplication sharedApplication];
296 if (menuid == wxID_OSX_HIDE)
297 {
298 [theNSApplication hide:nil];
299 handled=true;
300 }
301 else if (menuid == wxID_OSX_HIDEOTHERS)
302 {
303 [theNSApplication hideOtherApplications:nil];
304 handled=true;
305 }
306 else if (menuid == wxID_OSX_SHOWALL)
307 {
308 [theNSApplication unhideAllApplications:nil];
309 handled=true;
310 }
311 return handled;
312}
dbeddfb9
SC
313
314wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
fbbe829a 315 int menuid,
dbeddfb9
SC
316 const wxString& text,
317 wxAcceleratorEntry *entry,
d8207702 318 const wxString& WXUNUSED(strHelp),
dbeddfb9
SC
319 wxItemKind kind,
320 wxMenu *pSubMenu )
321{
322 wxMenuItemImpl* c = NULL;
323 NSMenuItem* item = nil;
03647350 324
dbeddfb9
SC
325 if ( kind == wxITEM_SEPARATOR )
326 {
327 item = [[NSMenuItem separatorItem] retain];
328 }
329 else
330 {
331 wxCFStringRef cfText(text);
fbbe829a
SC
332 SEL selector = nil;
333 bool targetSelf = false;
e3288469 334 if ( (pParentMenu == NULL || !pParentMenu->GetNoEventsMode()) && pSubMenu == NULL )
dbeddfb9 335 {
fbbe829a
SC
336 selector = wxOSXGetSelectorFromID(menuid);
337
338 if ( selector == nil )
339 {
340 selector = @selector(clickedAction:);
341 targetSelf = true;
342 }
dbeddfb9 343 }
fbbe829a
SC
344
345 wxNSMenuItem* menuitem = [ [ wxNSMenuItem alloc ] initWithTitle:cfText.AsNSString() action:selector keyEquivalent:@""];
346 if ( targetSelf )
347 [menuitem setTarget:menuitem];
348
dbeddfb9
SC
349 if ( pSubMenu )
350 {
351 pSubMenu->GetPeer()->SetTitle( text );
fbbe829a 352 [menuitem setSubmenu:pSubMenu->GetHMenu()];
dbeddfb9
SC
353 }
354 else
355 {
40a35c1f 356 wxMacCocoaMenuItemSetAccelerator( menuitem, entry );
dbeddfb9 357 }
fbbe829a 358 item = menuitem;
dbeddfb9
SC
359 }
360 c = new wxMenuItemCocoaImpl( peer, item );
dbeddfb9
SC
361 return c;
362}