]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/menuitem.mm
Applied #10007: SetWindowGroupParent hangs in Mac Carbon dialog.cpp
[wxWidgets.git] / src / osx / cocoa / menuitem.mm
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: menuitem.cpp 54129 2008-06-11 19:30:52Z 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"
19 #include "wx/log.h"
20 #include "wx/menu.h"
21 #endif // WX_PRECOMP
22
23 #include "wx/osx/private.h"
24
25 @implementation wxNSMenuItem
26
27 - (id) init
28 {
29 [super init];
30 return self;
31 }
32
33 - (void) clickedAction: (id) sender
34 {
35 wxUnusedVar(sender);
36 if ( impl )
37 {
38 impl->GetWXPeer()->GetMenu()->HandleCommandProcess(impl->GetWXPeer());
39 }
40 }
41
42 - (BOOL)validateMenuItem:(NSMenuItem *) menuItem
43 {
44 wxUnusedVar(menuItem);
45 if( impl )
46 {
47 impl->GetWXPeer()->GetMenu()->HandleCommandUpdateStatus(impl->GetWXPeer());
48 return impl->GetWXPeer()->IsEnabled();
49 }
50 return YES ;
51 }
52
53 - (void)setImplementation: (wxMenuItemImpl *) theImplementation
54 {
55 impl = theImplementation;
56 }
57
58 - (wxMenuItemImpl*) implementation
59 {
60 return impl;
61 }
62
63 @end
64
65 void wxMacCocoaMenuItemSetAccelerator( NSMenuItem* menuItem, wxAcceleratorEntry* entry )
66 {
67 unsigned int modifiers = 0 ;
68 int key = entry->GetKeyCode() ;
69 if ( key )
70 {
71 if (entry->GetFlags() & wxACCEL_CTRL);
72 modifiers |= NSCommandKeyMask;
73
74 if (entry->GetFlags() & wxACCEL_ALT)
75 modifiers |= NSAlternateKeyMask ;
76
77 // this may be ignored later for alpha chars
78
79 if (entry->GetFlags() & wxACCEL_SHIFT)
80 modifiers |= NSShiftKeyMask ;
81
82 unichar shortcut = 0;
83 if ( key >= WXK_F1 && key <= WXK_F15 )
84 {
85 modifiers |= NSFunctionKeyMask ;
86 shortcut = NSF1FunctionKey + ( key - WXK_F1 );
87 }
88 else
89 {
90 switch ( key )
91 {
92 /*
93 // standard function keys from here
94 case WXK_TAB :
95 modifiers |= NSFunctionKeyMask ;
96 shortcut = NSTabCharacter ;
97 break ;
98
99 case kEnterCharCode :
100 modifiers |= NSFunctionKeyMask ;
101 cocoaKey = NSTabCharacter ;
102 break ;
103
104 case WXK_RETURN :
105 modifiers |= NSFunctionKeyMask ;
106 cocoaKey = NSTabCharacter ;
107 break ;
108
109 case WXK_ESCAPE :
110 modifiers |= NSFunctionKeyMask ;
111 cocoaKey = kEscapeCharCode ;
112 break ;
113
114 case WXK_SPACE :
115 shortcut = ' ' ;
116 break ;
117
118
119 case WXK_CLEAR :
120 cocoaKey = kClearCharCode ;
121 break ;
122
123 case WXK_PAGEUP :
124 cocoaKey = kPageUpCharCode ;
125 break ;
126
127 case WXK_PAGEDOWN :
128 cocoaKey = kPageDownCharCode ;
129 break ;
130
131 case WXK_LEFT :
132 cocoaKey = kLeftArrowCharCode ;
133 break ;
134
135 case WXK_UP :
136 cocoaKey = kUpArrowCharCode ;
137 break ;
138
139 case WXK_RIGHT :
140 cocoaKey = kRightArrowCharCode ;
141 break ;
142
143 case WXK_DOWN :
144 cocoaKey = kDownArrowCharCode ;
145 break ;
146
147 case WXK_HOME :
148 cocoaKey = kHomeCharCode ;
149 break ;
150
151 case WXK_END :
152 cocoaKey = kEndCharCode ;
153 break ;
154 */
155 // TODO Test all above with their function key equiv.
156 // from NSEvent.h
157 default :
158 if(entry->GetFlags() & wxACCEL_SHIFT)
159 shortcut = toupper(key);
160 else
161 shortcut = tolower(key);
162 break ;
163 }
164 }
165
166 [menuItem setKeyEquivalent:[NSString stringWithCharacters:&shortcut length:1]];
167 [menuItem setKeyEquivalentModifierMask:modifiers];
168 }
169 }
170
171 class wxMenuItemCocoaImpl : public wxMenuItemImpl
172 {
173 public :
174 wxMenuItemCocoaImpl( wxMenuItem* peer, NSMenuItem* item ) : wxMenuItemImpl(peer), m_osxMenuItem(item)
175 {
176 if ( ![m_osxMenuItem isSeparatorItem] )
177 [(wxNSMenuItem*)m_osxMenuItem setImplementation:this];
178 }
179
180 ~wxMenuItemCocoaImpl();
181
182 void SetBitmap( const wxBitmap& bitmap )
183 {
184 [m_osxMenuItem setImage:bitmap.GetNSImage()];
185 }
186
187 void Enable( bool enable )
188 {
189 [m_osxMenuItem setEnabled:enable];
190 }
191
192 void Check( bool check )
193 {
194 [m_osxMenuItem setState:( check ? NSOnState : NSOffState) ];
195 }
196
197 void Hide( bool hide )
198 {
199 // NB: setHidden is new as of 10.5 so we should not call it below there
200 if ([m_osxMenuItem respondsToSelector:@selector(setHidden:)])
201 [m_osxMenuItem setHidden:hide ];
202 else
203 wxLogDebug("wxMenuItemCocoaImpl::Hide not yet supported under OS X < 10.5");
204 }
205
206 void SetLabel( const wxString& text, wxAcceleratorEntry *entry )
207 {
208 wxCFStringRef cfText(text);
209 [m_osxMenuItem setTitle:cfText.AsNSString()];
210
211 if ( entry )
212 wxMacCocoaMenuItemSetAccelerator( m_osxMenuItem, entry );
213
214 }
215
216 void * GetHMenuItem() { return m_osxMenuItem; }
217
218 protected :
219 NSMenuItem* m_osxMenuItem ;
220 } ;
221
222 wxMenuItemCocoaImpl::~wxMenuItemCocoaImpl()
223 {
224 if ( ![m_osxMenuItem isSeparatorItem] )
225 [(wxNSMenuItem*)m_osxMenuItem setImplementation:nil];
226 }
227
228
229 wxMenuItemImpl* wxMenuItemImpl::Create( wxMenuItem* peer, wxMenu *pParentMenu,
230 int WXUNUSED(id),
231 const wxString& text,
232 wxAcceleratorEntry *entry,
233 const wxString& WXUNUSED(strHelp),
234 wxItemKind kind,
235 wxMenu *pSubMenu )
236 {
237 wxMenuItemImpl* c = NULL;
238 NSMenuItem* item = nil;
239
240 if ( kind == wxITEM_SEPARATOR )
241 {
242 item = [[NSMenuItem separatorItem] retain];
243 }
244 else
245 {
246 wxCFStringRef cfText(text);
247 wxNSMenuItem* temp = [ [ wxNSMenuItem alloc ] init ];
248 if ( ! pParentMenu->GetNoEventsMode() )
249 {
250 [temp setTarget: temp];
251 [temp setAction: @selector(clickedAction:)];
252 }
253 [temp setTitle:cfText.AsNSString()];
254 if ( pSubMenu )
255 {
256 pSubMenu->GetPeer()->SetTitle( text );
257 [temp setSubmenu:pSubMenu->GetHMenu()];
258 }
259 else
260 {
261 if ( entry )
262 wxMacCocoaMenuItemSetAccelerator( temp, entry );
263 }
264 item = temp;
265 }
266 c = new wxMenuItemCocoaImpl( peer, item );
267 return c;
268 }