]>
Commit | Line | Data |
---|---|---|
ffecfa5a JS |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: menu.cpp | |
3 | // Purpose: wxMenu, wxMenuBar, wxMenuItem | |
4 | // Author: William Osborne | |
5 | // Modified by: | |
6 | // Created: 10/12/04 | |
4055ed82 | 7 | // RCS-ID: $Id: |
ffecfa5a JS |
8 | // Copyright: (c) William Osborne |
9 | // Licence: wxWindows licence | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // =========================================================================== | |
13 | // declarations | |
14 | // =========================================================================== | |
15 | ||
16 | // --------------------------------------------------------------------------- | |
17 | // headers | |
18 | // --------------------------------------------------------------------------- | |
19 | ||
20 | #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) | |
21 | #pragma implementation "menu.h" | |
22 | #endif | |
23 | ||
24 | // For compilers that support precompilation, includes "wx.h". | |
25 | #include "wx/wxprec.h" | |
26 | ||
27 | #ifdef __BORLANDC__ | |
28 | #pragma hdrstop | |
29 | #endif | |
30 | ||
31 | #if wxUSE_MENUS | |
32 | ||
33 | #ifndef WX_PRECOMP | |
34 | #include "wx/frame.h" | |
35 | #include "wx/menu.h" | |
36 | #include "wx/utils.h" | |
37 | #include "wx/intl.h" | |
38 | #include "wx/log.h" | |
39 | #endif | |
40 | ||
41 | #if wxUSE_OWNER_DRAWN | |
42 | #include "wx/ownerdrw.h" | |
43 | #endif | |
44 | ||
45 | // other standard headers | |
46 | #include <string.h> | |
47 | ||
4055ed82 | 48 | #include <Menu.h> |
ffecfa5a JS |
49 | |
50 | // ---------------------------------------------------------------------------- | |
51 | // global variables | |
52 | // ---------------------------------------------------------------------------- | |
53 | ||
54 | extern wxMenu *wxCurrentPopupMenu; | |
55 | ||
56 | // ---------------------------------------------------------------------------- | |
57 | // constants | |
58 | // ---------------------------------------------------------------------------- | |
59 | ||
60 | // the (popup) menu title has this special id | |
61 | static const int idMenuTitle = -3; | |
62 | ||
63 | // ---------------------------------------------------------------------------- | |
64 | // private functions | |
65 | // ---------------------------------------------------------------------------- | |
66 | ||
67 | // ============================================================================ | |
68 | // implementation | |
69 | // ============================================================================ | |
70 | ||
71 | #include <wx/listimpl.cpp> | |
72 | ||
73 | WX_DEFINE_LIST( wxMenuInfoList ) ; | |
74 | ||
75 | #if wxUSE_EXTENDED_RTTI | |
76 | ||
77 | WX_DEFINE_FLAGS( wxMenuStyle ) | |
78 | ||
79 | wxBEGIN_FLAGS( wxMenuStyle ) | |
80 | wxFLAGS_MEMBER(wxMENU_TEAROFF) | |
81 | wxEND_FLAGS( wxMenuStyle ) | |
82 | ||
83 | IMPLEMENT_DYNAMIC_CLASS_XTI(wxMenu, wxEvtHandler,"wx/menu.h") | |
84 | ||
85 | wxCOLLECTION_TYPE_INFO( wxMenuItem * , wxMenuItemList ) ; | |
86 | ||
87 | template<> void wxCollectionToVariantArray( wxMenuItemList const &theList, wxxVariantArray &value) | |
88 | { | |
89 | wxListCollectionToVariantArray<wxMenuItemList::compatibility_iterator>( theList , value ) ; | |
90 | } | |
91 | ||
92 | wxBEGIN_PROPERTIES_TABLE(wxMenu) | |
93 | wxEVENT_PROPERTY( Select , wxEVT_COMMAND_MENU_SELECTED , wxCommandEvent) | |
94 | wxPROPERTY( Title, wxString , SetTitle, GetTitle, wxString(), 0 /*flags*/ , wxT("Helpstring") , wxT("group") ) | |
95 | wxREADONLY_PROPERTY_FLAGS( MenuStyle , wxMenuStyle , long , GetStyle , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style | |
96 | wxPROPERTY_COLLECTION( MenuItems , wxMenuItemList , wxMenuItem* , Append , GetMenuItems , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) | |
97 | wxEND_PROPERTIES_TABLE() | |
98 | ||
99 | wxBEGIN_HANDLERS_TABLE(wxMenu) | |
100 | wxEND_HANDLERS_TABLE() | |
101 | ||
102 | wxDIRECT_CONSTRUCTOR_2( wxMenu , wxString , Title , long , MenuStyle ) | |
103 | ||
104 | WX_DEFINE_FLAGS( wxMenuBarStyle ) | |
105 | ||
106 | wxBEGIN_FLAGS( wxMenuBarStyle ) | |
107 | wxFLAGS_MEMBER(wxMB_DOCKABLE) | |
108 | wxEND_FLAGS( wxMenuBarStyle ) | |
109 | ||
110 | // the negative id would lead the window (its superclass !) to vetoe streaming out otherwise | |
111 | bool wxMenuBarStreamingCallback( const wxObject *WXUNUSED(object), wxWriter * , wxPersister * , wxxVariantArray & ) | |
112 | { | |
113 | return true ; | |
114 | } | |
115 | ||
116 | IMPLEMENT_DYNAMIC_CLASS_XTI_CALLBACK(wxMenuBar, wxWindow ,"wx/menu.h",wxMenuBarStreamingCallback) | |
117 | ||
118 | IMPLEMENT_DYNAMIC_CLASS_XTI(wxMenuInfo, wxObject , "wx/menu.h" ) | |
119 | ||
120 | wxBEGIN_PROPERTIES_TABLE(wxMenuInfo) | |
121 | wxREADONLY_PROPERTY( Menu , wxMenu* , GetMenu , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) | |
122 | wxREADONLY_PROPERTY( Title , wxString , GetTitle , wxString() , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) | |
123 | wxEND_PROPERTIES_TABLE() | |
124 | ||
125 | wxBEGIN_HANDLERS_TABLE(wxMenuInfo) | |
126 | wxEND_HANDLERS_TABLE() | |
127 | ||
4055ed82 | 128 | wxCONSTRUCTOR_2( wxMenuInfo , wxMenu* , Menu , wxString , Title ) |
ffecfa5a JS |
129 | |
130 | wxCOLLECTION_TYPE_INFO( wxMenuInfo * , wxMenuInfoList ) ; | |
131 | ||
132 | template<> void wxCollectionToVariantArray( wxMenuInfoList const &theList, wxxVariantArray &value) | |
133 | { | |
134 | wxListCollectionToVariantArray<wxMenuInfoList::compatibility_iterator>( theList , value ) ; | |
135 | } | |
136 | ||
137 | wxBEGIN_PROPERTIES_TABLE(wxMenuBar) | |
138 | wxPROPERTY_COLLECTION( MenuInfos , wxMenuInfoList , wxMenuInfo* , Append , GetMenuInfos , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) | |
139 | wxEND_PROPERTIES_TABLE() | |
140 | ||
141 | wxBEGIN_HANDLERS_TABLE(wxMenuBar) | |
142 | wxEND_HANDLERS_TABLE() | |
143 | ||
144 | wxCONSTRUCTOR_DUMMY( wxMenuBar ) | |
145 | ||
146 | #else | |
147 | IMPLEMENT_DYNAMIC_CLASS(wxMenu, wxEvtHandler) | |
148 | IMPLEMENT_DYNAMIC_CLASS(wxMenuBar, wxWindow) | |
149 | IMPLEMENT_DYNAMIC_CLASS(wxMenuInfo, wxObject) | |
150 | #endif | |
151 | ||
152 | const wxMenuInfoList& wxMenuBar::GetMenuInfos() const | |
153 | { | |
154 | wxMenuInfoList* list = const_cast< wxMenuInfoList* >( &m_menuInfos ) ; | |
155 | WX_CLEAR_LIST( wxMenuInfoList , *list ) ; | |
156 | for( size_t i = 0 ; i < GetMenuCount() ; ++i ) | |
157 | { | |
158 | wxMenuInfo* info = new wxMenuInfo() ; | |
159 | info->Create( const_cast<wxMenuBar*>(this)->GetMenu(i) , GetLabelTop(i) ) ; | |
160 | list->Append( info ) ; | |
161 | } | |
162 | return m_menuInfos ; | |
163 | } | |
164 | ||
165 | // --------------------------------------------------------------------------- | |
166 | // wxMenu construction, adding and removing menu items | |
167 | // --------------------------------------------------------------------------- | |
168 | ||
169 | // Construct a menu with optional title (then use append) | |
170 | void wxMenu::Init() | |
171 | { | |
172 | } | |
173 | ||
174 | // The wxWindow destructor will take care of deleting the submenus. | |
175 | wxMenu::~wxMenu() | |
176 | { | |
177 | } | |
178 | ||
179 | void wxMenu::Break() | |
180 | { | |
181 | } | |
182 | ||
183 | void wxMenu::Attach(wxMenuBarBase *menubar) | |
184 | { | |
185 | wxMenuBase::Attach(menubar); | |
186 | } | |
187 | ||
188 | #if wxUSE_ACCEL | |
189 | ||
190 | int wxMenu::FindAccel(int id) const | |
191 | { | |
192 | return wxNOT_FOUND; | |
193 | } | |
194 | ||
195 | void wxMenu::UpdateAccel(wxMenuItem *item) | |
196 | { | |
197 | } | |
198 | ||
199 | #endif // wxUSE_ACCEL | |
200 | ||
201 | // append a new item or submenu to the menu | |
202 | bool wxMenu::DoInsertOrAppend(wxMenuItem *pItem, size_t pos) | |
203 | { | |
204 | if ( IsAttached() && GetMenuBar()->IsAttached() ) | |
205 | { | |
4055ed82 | 206 | // Regenerate the menu resource |
ffecfa5a JS |
207 | GetMenuBar()->Refresh(); |
208 | } | |
4055ed82 WS |
209 | |
210 | return true; | |
ffecfa5a JS |
211 | } |
212 | ||
213 | void wxMenu::EndRadioGroup() | |
214 | { | |
215 | } | |
216 | ||
217 | wxMenuItem* wxMenu::DoAppend(wxMenuItem *item) | |
218 | { | |
219 | wxCHECK_MSG( item, NULL, _T("NULL item in wxMenu::DoAppend") ); | |
220 | ||
221 | if(!wxMenuBase::DoAppend(item) || !DoInsertOrAppend(item)) | |
222 | { | |
223 | return NULL; | |
224 | } | |
225 | else if(IsAttached() && GetMenuBar()->IsAttached()) | |
226 | { | |
4055ed82 | 227 | // Regenerate the menu resource |
ffecfa5a JS |
228 | GetMenuBar()->Refresh(); |
229 | } | |
4055ed82 WS |
230 | |
231 | return item; | |
ffecfa5a JS |
232 | } |
233 | ||
234 | wxMenuItem* wxMenu::DoInsert(size_t pos, wxMenuItem *item) | |
235 | { | |
236 | if (wxMenuBase::DoInsert(pos, item) && DoInsertOrAppend(item, pos)) | |
237 | return item; | |
238 | else | |
4055ed82 | 239 | return NULL; |
ffecfa5a JS |
240 | } |
241 | ||
242 | wxMenuItem *wxMenu::DoRemove(wxMenuItem *item) | |
243 | { | |
244 | // we need to find the items position in the child list | |
245 | size_t pos; | |
246 | wxMenuItemList::compatibility_iterator node = GetMenuItems().GetFirst(); | |
247 | for ( pos = 0; node; pos++ ) | |
248 | { | |
249 | if ( node->GetData() == item ) | |
250 | break; | |
251 | ||
252 | node = node->GetNext(); | |
253 | } | |
254 | ||
255 | // DoRemove() (unlike Remove) can only be called for existing item! | |
256 | wxCHECK_MSG( node, NULL, wxT("bug in wxMenu::Remove logic") ); | |
257 | ||
258 | // remove the item from the menu | |
259 | wxMenuItem *ret=wxMenuBase::DoRemove(item); | |
4055ed82 | 260 | |
ffecfa5a JS |
261 | if ( IsAttached() && GetMenuBar()->IsAttached() ) |
262 | { | |
4055ed82 | 263 | // Regenerate the menu resource |
ffecfa5a JS |
264 | GetMenuBar()->Refresh(); |
265 | } | |
4055ed82 | 266 | |
ffecfa5a JS |
267 | return ret; |
268 | } | |
269 | ||
270 | // --------------------------------------------------------------------------- | |
271 | // accelerator helpers | |
272 | // --------------------------------------------------------------------------- | |
273 | ||
274 | #if wxUSE_ACCEL | |
275 | ||
276 | // create the wxAcceleratorEntries for our accels and put them into provided | |
277 | // array - return the number of accels we have | |
278 | size_t wxMenu::CopyAccels(wxAcceleratorEntry *accels) const | |
279 | { | |
280 | size_t count = GetAccelCount(); | |
281 | for ( size_t n = 0; n < count; n++ ) | |
282 | { | |
283 | *accels++ = *m_accels[n]; | |
284 | } | |
285 | ||
286 | return count; | |
287 | } | |
288 | ||
289 | #endif // wxUSE_ACCEL | |
290 | ||
291 | // --------------------------------------------------------------------------- | |
292 | // set wxMenu title | |
293 | // --------------------------------------------------------------------------- | |
294 | ||
295 | void wxMenu::SetTitle(const wxString& label) | |
296 | { | |
297 | m_title = label; | |
298 | ||
299 | if ( IsAttached() && GetMenuBar()->IsAttached() ) | |
300 | { | |
4055ed82 | 301 | // Regenerate the menu resource |
ffecfa5a JS |
302 | GetMenuBar()->Refresh(); |
303 | } | |
304 | } | |
305 | ||
306 | // --------------------------------------------------------------------------- | |
307 | // event processing | |
308 | // --------------------------------------------------------------------------- | |
309 | ||
310 | bool wxMenu::PalmCommand(WXUINT WXUNUSED(param), WXWORD id) | |
311 | { | |
312 | return false; | |
313 | } | |
314 | ||
315 | // --------------------------------------------------------------------------- | |
316 | // other | |
317 | // --------------------------------------------------------------------------- | |
318 | ||
319 | wxWindow *wxMenu::GetWindow() const | |
320 | { | |
321 | return NULL; | |
322 | } | |
323 | ||
324 | // --------------------------------------------------------------------------- | |
325 | // Menu Bar | |
326 | // --------------------------------------------------------------------------- | |
327 | ||
328 | void wxMenuBar::Init() | |
329 | { | |
330 | } | |
331 | ||
332 | wxMenuBar::wxMenuBar() | |
333 | { | |
334 | } | |
335 | ||
336 | wxMenuBar::wxMenuBar( long WXUNUSED(style) ) | |
337 | { | |
338 | } | |
339 | ||
340 | wxMenuBar::wxMenuBar(int count, wxMenu *menus[], const wxString titles[]) | |
341 | { | |
342 | } | |
343 | ||
344 | wxMenuBar::~wxMenuBar() | |
345 | { | |
346 | } | |
347 | ||
348 | // --------------------------------------------------------------------------- | |
349 | // wxMenuBar helpers | |
350 | // --------------------------------------------------------------------------- | |
351 | ||
352 | void wxMenuBar::Refresh() | |
353 | { | |
354 | wxCHECK_RET( IsAttached(), wxT("can't refresh unattached menubar") ); | |
355 | ||
356 | // Regenerate the menu resource | |
357 | LoadMenu(); | |
358 | } | |
359 | ||
360 | WXHMENU wxMenuBar::Create() | |
361 | { | |
362 | return NULL; | |
363 | } | |
364 | ||
365 | int wxMenuBar::PalmPositionForWxMenu(wxMenu *menu, int wxpos) | |
366 | { | |
367 | return -1; | |
368 | } | |
369 | ||
370 | // --------------------------------------------------------------------------- | |
371 | // wxMenuBar functions to work with the top level submenus | |
372 | // --------------------------------------------------------------------------- | |
373 | ||
374 | void wxMenuBar::EnableTop(size_t pos, bool enable) | |
375 | { | |
376 | // Palm OS does not have support for grayed or disabled items | |
377 | } | |
378 | ||
379 | void wxMenuBar::SetLabelTop(size_t pos, const wxString& label) | |
380 | { | |
381 | wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") ); | |
382 | ||
383 | m_titles[pos]=wxStripMenuCodes(label); | |
384 | ||
385 | if ( !IsAttached() ) | |
386 | { | |
387 | return; | |
388 | } | |
389 | ||
390 | // Regenerate the menu resource | |
391 | Refresh(); | |
392 | } | |
393 | ||
394 | wxString wxMenuBar::GetLabelTop(size_t pos) const | |
395 | { | |
396 | wxCHECK_MSG( pos < GetMenuCount(), wxEmptyString, | |
397 | wxT("invalid menu index in wxMenuBar::GetLabelTop") ); | |
398 | ||
399 | return wxMenuItem::GetLabelFromText(m_titles[pos]); | |
400 | } | |
401 | ||
402 | // --------------------------------------------------------------------------- | |
403 | // wxMenuBar construction | |
404 | // --------------------------------------------------------------------------- | |
405 | ||
406 | wxMenu *wxMenuBar::Replace(size_t pos, wxMenu *menu, const wxString& title) | |
407 | { | |
408 | wxMenu *menuOld = wxMenuBarBase::Replace(pos, menu, title); | |
409 | if ( !menuOld ) | |
410 | return NULL; | |
411 | ||
412 | m_titles[pos]=wxStripMenuCodes(title); | |
413 | ||
414 | if ( IsAttached() ) | |
415 | { | |
416 | // Regenerate the menu resource | |
417 | Refresh(); | |
418 | } | |
419 | ||
420 | return menuOld; | |
421 | } | |
422 | ||
423 | bool wxMenuBar::Insert(size_t pos, wxMenu *menu, const wxString& title) | |
424 | { | |
425 | if ( !wxMenuBarBase::Insert(pos, menu, title) ) | |
4055ed82 | 426 | return false; |
ffecfa5a JS |
427 | |
428 | m_titles.Insert(wxStripMenuCodes(title), pos); | |
429 | ||
430 | if ( IsAttached() ) | |
431 | { | |
432 | // Regenerate the menu resource | |
433 | Refresh(); | |
434 | } | |
435 | ||
4055ed82 | 436 | return true; |
ffecfa5a JS |
437 | } |
438 | ||
439 | bool wxMenuBar::Append(wxMenu *menu, const wxString& title) | |
440 | { | |
441 | if ( !wxMenuBarBase::Append(menu, title) ) | |
4055ed82 | 442 | return false; |
ffecfa5a JS |
443 | |
444 | m_titles.Add(wxStripMenuCodes(title)); | |
445 | ||
446 | if(IsAttached()) | |
447 | { | |
448 | // Regenerate the menu resource | |
449 | Refresh(); | |
450 | } | |
451 | ||
4055ed82 | 452 | return true; |
ffecfa5a JS |
453 | } |
454 | ||
455 | wxMenu *wxMenuBar::Remove(size_t pos) | |
456 | { | |
457 | wxMenu *menu = wxMenuBarBase::Remove(pos); | |
458 | if ( !menu ) | |
459 | return NULL; | |
460 | ||
461 | m_titles.RemoveAt(pos); | |
462 | ||
463 | if (IsAttached()) | |
464 | { | |
465 | // Regenerate the menu resource | |
466 | Refresh(); | |
467 | } | |
468 | ||
469 | return menu; | |
470 | } | |
471 | ||
472 | #if wxUSE_ACCEL | |
473 | ||
474 | void wxMenuBar::RebuildAccelTable() | |
475 | { | |
476 | } | |
477 | ||
478 | #endif // wxUSE_ACCEL | |
479 | ||
480 | int wxMenuBar::ProcessCommand(int ItemID) | |
481 | { | |
482 | if(!IsAttached()) | |
483 | return -1; | |
4055ed82 | 484 | |
ffecfa5a JS |
485 | int MenuNum=(ItemID/1000)-1; |
486 | int ItemNum=(ItemID-(1000*(MenuNum+1))); | |
4055ed82 | 487 | |
ffecfa5a JS |
488 | // Should never happen, but it doesn't hurt to check anyway. |
489 | if(MenuNum>GetMenuCount()) | |
490 | return -1; | |
491 | ||
492 | // Get the menu | |
493 | wxMenu *ActiveMenu=GetMenu(MenuNum); | |
4055ed82 | 494 | |
ffecfa5a JS |
495 | // Make sure this is a valid item. |
496 | if(ItemNum>ActiveMenu->GetMenuItemCount()) | |
497 | return -1; | |
498 | ||
499 | // Get the item | |
500 | wxMenuItem *ActiveItem=ActiveMenu->FindItemByPosition(ItemNum); | |
501 | int ActiveID=ActiveItem->GetId(); | |
502 | ||
503 | return ActiveID; | |
504 | } | |
505 | ||
4055ed82 WS |
506 | /* Palm OS does not have good dynamic menu support. About all you can do with |
507 | * the standard API calls is to add new items to an existing drop-down menu and | |
508 | * hide/show items in a drop-down menu. It is impossible to add, hide, or | |
509 | * change the label on a drop-down menu. | |
510 | * | |
511 | * The easiest and simplest way around this limitation is to modify the Palm OS | |
512 | * MenuBarType structure directly. This gives limited ability to change the | |
513 | * label on a drop-down menu. I have not been able to find a safe way to add, | |
ffecfa5a | 514 | * delete, or resize drop-down menus in OS 6. |
4055ed82 | 515 | * |
ffecfa5a | 516 | * The following routine attempt to work around these limitations present in the |
4055ed82 | 517 | * Palm OS API to provide limited dynamic menu support. This solution is far |
ffecfa5a JS |
518 | * from perfect, but the only other option is to wait for PalmSource to add full |
519 | * dynamic menu support, or to recreate the Palm OS menu system from scratch. | |
4055ed82 | 520 | * |
ffecfa5a JS |
521 | * This system is limited in that no more than 4 drop-down menus are allowed per |
522 | * menu bar, and the label for each drop-down menu is limited to 8 characters of | |
523 | * text. However, this menu system should work for most applications. | |
4055ed82 WS |
524 | * |
525 | * Basically the menu routines select one of four menu bars, depending on | |
526 | * whether or not the requested menu bar has one, two, three, or four drop-down | |
ffecfa5a | 527 | * menus. |
4055ed82 WS |
528 | * |
529 | * These four "template" menu bars contain one, two, three, or four drop-down | |
530 | * menus. Each menu has a dummy menu item attached to it to allow the Palm OS | |
ffecfa5a | 531 | * MenuAddItem function to add the real items. |
4055ed82 WS |
532 | * |
533 | * The labels on the drop-down menus are then replaced with the labels of the | |
ffecfa5a | 534 | * real menus. |
4055ed82 WS |
535 | * |
536 | * The menu is then attached to the active window and the MenuAddItem API | |
537 | * function is called to add the items to each drop-down menu. Finally, | |
ffecfa5a JS |
538 | * MenuHideItem is called to remove the dummy items from each drop-down menu. |
539 | */ | |
540 | void wxMenuBar::LoadMenu() | |
541 | { | |
542 | int i=0; | |
543 | int j=0; | |
4055ed82 | 544 | |
ffecfa5a JS |
545 | // Handle to the currently running application database |
546 | DmOpenRef AppDB; | |
547 | ||
548 | // Get app database reference - needed for some Palm OS Menu API calls. | |
549 | SysGetModuleDatabase(SysGetRefNum(), NULL, &AppDB); | |
550 | ||
551 | // Get the number of menus | |
552 | int NumMenus=GetMenuCount(); | |
553 | ||
554 | // Set up the pointers and handles | |
4055ed82 | 555 | char *PalmOSMenuBarPtr; |
ffecfa5a | 556 | MemHandle PalmOSMenuBar; |
4055ed82 | 557 | |
ffecfa5a JS |
558 | // Load the menu template and set up the menu pointers |
559 | if(NumMenus==1) | |
560 | { | |
561 | PalmOSMenuBar=DmGetResource(AppDB,'MBAR',1000); | |
562 | PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar); | |
563 | ||
4055ed82 | 564 | PalmOSMenuBarPtr+=74; |
ffecfa5a JS |
565 | } |
566 | else if(NumMenus==2) | |
567 | { | |
568 | PalmOSMenuBar=DmGetResource(AppDB,'MBAR',2000); | |
569 | PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar); | |
570 | ||
571 | PalmOSMenuBarPtr+=116; | |
572 | } | |
573 | else if(NumMenus==3) | |
574 | { | |
575 | PalmOSMenuBar=DmGetResource(AppDB,'MBAR',3000); | |
576 | PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar); | |
577 | ||
578 | PalmOSMenuBarPtr+=158; | |
579 | } | |
580 | else | |
581 | { | |
4055ed82 | 582 | // We support a maximum of 4 menus, so make sure that do not create |
ffecfa5a JS |
583 | // more than we can handle. |
584 | NumMenus=4; | |
585 | ||
586 | PalmOSMenuBar=DmGetResource(AppDB,'MBAR',4000); | |
587 | PalmOSMenuBarPtr=(char *)MemHandleLock(PalmOSMenuBar); | |
588 | ||
589 | PalmOSMenuBarPtr+=200; | |
590 | } | |
4055ed82 | 591 | |
ffecfa5a JS |
592 | // Set the proper names for the drop-down triggers. |
593 | for(i=0;i<NumMenus;i++) | |
594 | { | |
595 | // Clear out the old label | |
596 | char buffer[8]={' ',' ',' ',' ',' ',' ',' ',' '}; | |
597 | MemMove(PalmOSMenuBarPtr,buffer,8); | |
4055ed82 | 598 | |
ffecfa5a JS |
599 | wxString MenuTitle=m_titles.Item(i); |
600 | ||
601 | // Make sure we don't copy more than 8 bytes for the label | |
602 | int LengthToCopy=MenuTitle.length(); | |
603 | if(LengthToCopy>8) | |
604 | LengthToCopy=8; | |
605 | ||
606 | MemMove(PalmOSMenuBarPtr,MenuTitle,LengthToCopy); | |
607 | PalmOSMenuBarPtr+=11; | |
608 | } | |
609 | ||
610 | // We are done with the menu pointer. | |
4055ed82 | 611 | MemHandleUnlock(PalmOSMenuBar); |
ffecfa5a JS |
612 | DmReleaseResource(PalmOSMenuBar); |
613 | ||
4055ed82 | 614 | // We must make the menu active before we can add items to the drop-down |
ffecfa5a JS |
615 | // triggers. |
616 | FrmSetMenu(FrmGetActiveForm(),AppDB,NumMenus*1000); | |
617 | ||
4055ed82 WS |
618 | /* Add the menu items to the drop-down triggers. This must be done after |
619 | * setting the triggers, because setting the names of drop-down triggers | |
620 | * that have a variable number of items requires carefull calculation of | |
ffecfa5a JS |
621 | * the offsets in the MenuBarType structure. Setting the triggers first |
622 | * avoids this. | |
623 | */ | |
624 | for(i=0;i<NumMenus;i++) | |
625 | { | |
626 | wxMenu *CurrentMenu=GetMenu(i); | |
4055ed82 | 627 | |
ffecfa5a JS |
628 | for(j=0;j<CurrentMenu->GetMenuItemCount();j++) |
629 | { | |
630 | wxMenuItem *CurrentItem=CurrentMenu->FindItemByPosition(j); | |
631 | wxString ItemLabel=CurrentItem->GetLabel(); | |
4055ed82 | 632 | |
ffecfa5a JS |
633 | if(CurrentItem->IsSeparator()==true) |
634 | { | |
635 | char Separator=MenuSeparatorChar; | |
636 | if(j==0) | |
637 | MenuAddItem(9000+i,((i*1000)+1000)+j,0x00,&Separator); | |
638 | else | |
639 | MenuAddItem(((i*1000)+1000)+j-1,((i*1000)+1000)+j,0x00,&Separator); | |
640 | } | |
641 | else | |
642 | { | |
643 | if(j==0) | |
644 | MenuAddItem(9000+i,((i*1000)+1000)+j,0x00,ItemLabel); | |
645 | else | |
646 | MenuAddItem(((i*1000)+1000)+j-1,((i*1000)+1000)+j,0x00,ItemLabel); | |
647 | } | |
648 | } | |
4055ed82 | 649 | |
ffecfa5a JS |
650 | // Hide the dummy menu item, since we don't need it anymore. |
651 | MenuHideItem(9000+i); | |
652 | } | |
653 | } | |
654 | ||
655 | void wxMenuBar::Attach(wxFrame *frame) | |
656 | { | |
657 | wxMenuBarBase::Attach(frame); | |
ffecfa5a | 658 | |
4055ed82 | 659 | LoadMenu(); |
ffecfa5a | 660 | } |
ffecfa5a JS |
661 | |
662 | void wxMenuBar::Detach() | |
663 | { | |
664 | wxMenuBarBase::Detach(); | |
665 | } | |
666 | ||
667 | #endif // wxUSE_MENUS |