1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/osx/carbon/uma.cpp
3 // Purpose:     UMA support
4 // Author:      Stefan Csomor
5 // Modified by:
6 // Created:     04/01/98
7 // Copyright:   (c) Stefan Csomor
8 // Licence:     The wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10 
11 #include "wx/wxprec.h"
12 
13 #include "wx/osx/uma.h"
14 
15 #if wxUSE_GUI
16 
17 #include "wx/toplevel.h"
18 #include "wx/dc.h"
19 
20 #include "wx/osx/uma.h"
21 
22 // menu manager
23 
24 #if wxOSX_USE_CARBON
25 
UMANewMenu(SInt16 id,const wxString & title,wxFontEncoding encoding)26 MenuRef UMANewMenu( SInt16 id , const wxString& title , wxFontEncoding encoding )
27 {
28     wxString str = wxStripMenuCodes( title ) ;
29     MenuRef menu ;
30 
31     CreateNewMenu( id , 0 , &menu ) ;
32     SetMenuTitleWithCFString( menu , wxCFStringRef(str , encoding ) ) ;
33 
34     return menu ;
35 }
36 
UMASetMenuTitle(MenuRef menu,const wxString & title,wxFontEncoding encoding)37 void UMASetMenuTitle( MenuRef menu , const wxString& title , wxFontEncoding encoding )
38 {
39     wxString str = wxStripMenuCodes( title ) ;
40 
41     SetMenuTitleWithCFString( menu , wxCFStringRef(str , encoding) ) ;
42 }
43 
UMASetMenuItemText(MenuRef menu,MenuItemIndex item,const wxString & title,wxFontEncoding encoding)44 void UMASetMenuItemText( MenuRef menu,  MenuItemIndex item, const wxString& title, wxFontEncoding encoding )
45 {
46     // we don't strip the accels here anymore, must be done before
47     wxString str = title ;
48 
49     SetMenuItemTextWithCFString( menu , item , wxCFStringRef(str , encoding) ) ;
50 }
51 
UMAEnableMenuItem(MenuRef inMenu,MenuItemIndex inItem,bool enable)52 void UMAEnableMenuItem( MenuRef inMenu , MenuItemIndex inItem , bool enable)
53 {
54     if ( enable )
55         EnableMenuItem( inMenu , inItem ) ;
56     else
57         DisableMenuItem( inMenu , inItem ) ;
58 }
59 
UMAAppendSubMenuItem(MenuRef menu,const wxString & title,wxFontEncoding encoding,MenuRef submenu)60 void UMAAppendSubMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuRef submenu )
61 {
62     AppendMenuItemTextWithCFString( menu,
63                                 CFSTR("A"), 0, 0,NULL);
64     UMASetMenuItemText( menu, (SInt16) ::CountMenuItems(menu), title , encoding );
65     SetMenuItemHierarchicalMenu( menu , CountMenuItems( menu ) , submenu ) ;
66     SetMenuTitleWithCFString(submenu , wxCFStringRef(title , encoding) );
67 }
68 
UMAInsertSubMenuItem(MenuRef menu,const wxString & title,wxFontEncoding encoding,MenuItemIndex item,SInt16 id)69 void UMAInsertSubMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuItemIndex item , SInt16 id  )
70 {
71     InsertMenuItemTextWithCFString( menu,
72                 CFSTR("A"), item, 0, 0);
73 
74     UMASetMenuItemText( menu, item+1, title , encoding );
75     SetMenuItemHierarchicalID( menu , item+1 , id ) ;
76 }
77 
UMASetMenuItemShortcut(MenuRef menu,MenuItemIndex item,wxAcceleratorEntry * entry)78 void UMASetMenuItemShortcut( MenuRef menu , MenuItemIndex item , wxAcceleratorEntry *entry )
79 {
80     if ( !entry )
81     {
82         SetMenuItemCommandKey(menu, item, false, 0);
83         return ;
84     }
85 
86     UInt8 modifiers = 0 ;
87     SInt16 key = entry->GetKeyCode() ;
88     if ( key )
89     {
90         bool explicitCommandKey = (entry->GetFlags() & wxACCEL_CTRL);
91 
92         if (entry->GetFlags() & wxACCEL_ALT)
93             modifiers |= kMenuOptionModifier ;
94 
95         if (entry->GetFlags() & wxACCEL_SHIFT)
96             modifiers |= kMenuShiftModifier ;
97 
98         if (entry->GetFlags() & wxACCEL_RAW_CTRL)
99             modifiers |= kMenuControlModifier ;
100 
101         SInt16 glyph = 0 ;
102         SInt16 macKey = key ;
103         if ( key >= WXK_F1 && key <= WXK_F15 )
104         {
105             if ( !explicitCommandKey )
106                 modifiers |= kMenuNoCommandModifier ;
107 
108             // for some reasons this must be 0 right now
109             // everything else leads to just the first function key item
110             // to be selected. Thanks to Ryan Wilcox for finding out.
111             macKey = 0 ;
112             glyph = kMenuF1Glyph + ( key - WXK_F1 ) ;
113             if ( key >= WXK_F13 )
114                 glyph += 12 ;
115         }
116         else
117         {
118             switch ( key )
119             {
120                 case WXK_BACK :
121                     macKey = kBackspaceCharCode ;
122                     glyph = kMenuDeleteLeftGlyph ;
123                     break ;
124 
125                 case WXK_TAB :
126                     macKey = kTabCharCode ;
127                     glyph = kMenuTabRightGlyph ;
128                     break ;
129 
130                 case kEnterCharCode :
131                     macKey = kEnterCharCode ;
132                     glyph = kMenuEnterGlyph ;
133                     break ;
134 
135                 case WXK_RETURN :
136                     macKey = kReturnCharCode ;
137                     glyph = kMenuReturnGlyph ;
138                     break ;
139 
140                 case WXK_ESCAPE :
141                     macKey = kEscapeCharCode ;
142                     glyph = kMenuEscapeGlyph ;
143                     break ;
144 
145                 case WXK_SPACE :
146                     macKey = ' ' ;
147                     glyph = kMenuSpaceGlyph ;
148                     break ;
149 
150                 case WXK_DELETE :
151                     macKey = kDeleteCharCode ;
152                     glyph = kMenuDeleteRightGlyph ;
153                     break ;
154 
155                 case WXK_CLEAR :
156                     macKey = kClearCharCode ;
157                     glyph = kMenuClearGlyph ;
158                     break ;
159 
160                 case WXK_PAGEUP :
161                     macKey = kPageUpCharCode ;
162                     glyph = kMenuPageUpGlyph ;
163                     break ;
164 
165                 case WXK_PAGEDOWN :
166                     macKey = kPageDownCharCode ;
167                     glyph = kMenuPageDownGlyph ;
168                     break ;
169 
170                 case WXK_LEFT :
171                     macKey = kLeftArrowCharCode ;
172                     glyph = kMenuLeftArrowGlyph ;
173                     break ;
174 
175                 case WXK_UP :
176                     macKey = kUpArrowCharCode ;
177                     glyph = kMenuUpArrowGlyph ;
178                     break ;
179 
180                 case WXK_RIGHT :
181                     macKey = kRightArrowCharCode ;
182                     glyph = kMenuRightArrowGlyph ;
183                     break ;
184 
185                 case WXK_DOWN :
186                     macKey = kDownArrowCharCode ;
187                     glyph = kMenuDownArrowGlyph ;
188                     break ;
189 
190                 case WXK_HOME :
191                     macKey = kHomeCharCode ;
192                     glyph = kMenuNorthwestArrowGlyph ;
193                     break ;
194 
195                 case WXK_END :
196                     macKey = kEndCharCode ;
197                     glyph = kMenuSoutheastArrowGlyph ;
198                     break ;
199                 default :
200                     macKey = toupper( key ) ;
201                     break ;
202             }
203 
204             // we now allow non command key shortcuts
205             // remove in case this gives problems
206             if ( !explicitCommandKey )
207                 modifiers |= kMenuNoCommandModifier ;
208         }
209 
210         // 1d and 1e have special meaning to SetItemCmd, so
211         // do not use for these character codes.
212         if (key != WXK_UP && key != WXK_RIGHT && key != WXK_DOWN && key != WXK_LEFT)
213             SetItemCmd( menu, item , macKey );
214 
215         SetMenuItemModifiers( menu, item , modifiers ) ;
216 
217         if ( glyph )
218             SetMenuItemKeyGlyph( menu, item , glyph ) ;
219     }
220 }
221 
UMAAppendMenuItem(MenuRef menu,const wxString & title,wxFontEncoding encoding,wxAcceleratorEntry * entry)222 void UMAAppendMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , wxAcceleratorEntry *entry )
223 {
224     AppendMenuItemTextWithCFString( menu,
225                                 CFSTR("A"), 0, 0,NULL);
226     // don't attempt to interpret metacharacters like a '-' at the beginning (would become a separator otherwise)
227     ChangeMenuItemAttributes( menu , ::CountMenuItems(menu), kMenuItemAttrIgnoreMeta , 0 ) ;
228     UMASetMenuItemText(menu, (SInt16) ::CountMenuItems(menu), title , encoding );
229     UMASetMenuItemShortcut( menu , (SInt16) ::CountMenuItems(menu), entry ) ;
230 }
231 
UMAInsertMenuItem(MenuRef menu,const wxString & title,wxFontEncoding encoding,MenuItemIndex item,wxAcceleratorEntry * entry)232 void UMAInsertMenuItem( MenuRef menu , const wxString& title, wxFontEncoding encoding , MenuItemIndex item , wxAcceleratorEntry *entry )
233 {
234     InsertMenuItemTextWithCFString( menu,
235                 CFSTR("A"), item, 0, 0);
236 
237     // don't attempt to interpret metacharacters like a '-' at the beginning (would become a separator otherwise)
238     ChangeMenuItemAttributes( menu , item+1, kMenuItemAttrIgnoreMeta , 0 ) ;
239     UMASetMenuItemText(menu, item+1 , title , encoding );
240     UMASetMenuItemShortcut( menu , item+1 , entry ) ;
241 }
242 
243 static OSStatus UMAGetHelpMenu(
244                                MenuRef *        outHelpMenu,
245                                MenuItemIndex *  outFirstCustomItemIndex,
246                                bool             allowHelpMenuCreation);
247 
UMAGetHelpMenu(MenuRef * outHelpMenu,MenuItemIndex * outFirstCustomItemIndex,bool allowHelpMenuCreation)248 static OSStatus UMAGetHelpMenu(
249                                MenuRef *        outHelpMenu,
250                                MenuItemIndex *  outFirstCustomItemIndex,
251                                bool             allowHelpMenuCreation)
252 {
253     static bool s_createdHelpMenu = false ;
254 
255     if ( !s_createdHelpMenu && !allowHelpMenuCreation )
256     {
257         return paramErr ;
258     }
259 
260     OSStatus status = HMGetHelpMenu( outHelpMenu , outFirstCustomItemIndex ) ;
261     s_createdHelpMenu = ( status == noErr ) ;
262     return status ;
263 }
264 
UMAGetHelpMenu(MenuRef * outHelpMenu,MenuItemIndex * outFirstCustomItemIndex)265 OSStatus UMAGetHelpMenu(
266                         MenuRef *        outHelpMenu,
267                         MenuItemIndex *  outFirstCustomItemIndex)
268 {
269     return UMAGetHelpMenu( outHelpMenu , outFirstCustomItemIndex , true );
270 }
271 
UMAGetHelpMenuDontCreate(MenuRef * outHelpMenu,MenuItemIndex * outFirstCustomItemIndex)272 OSStatus UMAGetHelpMenuDontCreate(
273                                   MenuRef *        outHelpMenu,
274                                   MenuItemIndex *  outFirstCustomItemIndex)
275 {
276     return UMAGetHelpMenu( outHelpMenu , outFirstCustomItemIndex , false );
277 }
278 
279 #endif
280 
281 #endif  // wxUSE_GUI
282