]> git.saurik.com Git - wxWidgets.git/blob - samples/menu/menu.cpp
fix FindMenu broken by implementation of double ampersands in menu and menu
[wxWidgets.git] / samples / menu / menu.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/menu.cpp
3 // Purpose: wxMenu/wxMenuBar sample
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 01.11.99
7 // RCS-ID: $Id$
8 // Copyright: (c) 1999 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #ifndef WX_PRECOMP
28 #include "wx/app.h"
29 #include "wx/frame.h"
30 #include "wx/menu.h"
31 #include "wx/msgdlg.h"
32 #include "wx/log.h"
33 #include "wx/textctrl.h"
34 #include "wx/textdlg.h"
35 #endif
36
37 #if !wxUSE_MENUS
38 // nice try...
39 #error "menu sample requires wxUSE_MENUS=1"
40 #endif // wxUSE_MENUS
41
42 #include "copy.xpm"
43
44 // ----------------------------------------------------------------------------
45 // classes
46 // ----------------------------------------------------------------------------
47
48 // Define a new application
49 class MyApp: public wxApp
50 {
51 public:
52 bool OnInit();
53 };
54
55 // Define a new frame
56 class MyFrame: public wxFrame
57 {
58 public:
59 MyFrame();
60
61 virtual ~MyFrame();
62
63 void LogMenuEvent(const wxCommandEvent& event);
64
65 protected:
66 void OnQuit(wxCommandEvent& event);
67 void OnClearLog(wxCommandEvent& event);
68
69 void OnAbout(wxCommandEvent& event);
70
71 void OnDummy(wxCommandEvent& event);
72
73 void OnAppendMenuItem(wxCommandEvent& event);
74 void OnAppendSubMenu(wxCommandEvent& event);
75 void OnDeleteMenuItem(wxCommandEvent& event);
76 void OnInsertMenuItem(wxCommandEvent& event);
77 void OnCheckMenuItem(wxCommandEvent& event);
78 void OnEnableMenuItem(wxCommandEvent& event);
79 void OnGetLabelMenuItem(wxCommandEvent& event);
80 void OnSetLabelMenuItem(wxCommandEvent& event);
81 void OnGetMenuItemInfo(wxCommandEvent& event);
82 void OnFindMenuItem(wxCommandEvent& event);
83
84 void OnAppendMenu(wxCommandEvent& event);
85 void OnInsertMenu(wxCommandEvent& event);
86 void OnDeleteMenu(wxCommandEvent& event);
87 void OnToggleMenu(wxCommandEvent& event);
88 void OnEnableMenu(wxCommandEvent& event);
89 void OnGetLabelMenu(wxCommandEvent& event);
90 void OnSetLabelMenu(wxCommandEvent& event);
91 void OnFindMenu(wxCommandEvent& event);
92
93 void OnTestNormal(wxCommandEvent& event);
94 void OnTestCheck(wxCommandEvent& event);
95 void OnTestRadio(wxCommandEvent& event);
96
97 #ifdef __WXMSW__
98 void OnContextMenu(wxContextMenuEvent& event)
99 { ShowContextMenu(ScreenToClient(event.GetPosition())); }
100 #else
101 void OnRightUp(wxMouseEvent& event)
102 { ShowContextMenu(event.GetPosition()); }
103 #endif
104
105 void OnMenuOpen(wxMenuEvent& event)
106 { LogMenuOpenOrClose(event, _T("opened")); }
107 void OnMenuClose(wxMenuEvent& event)
108 { LogMenuOpenOrClose(event, _T("closed")); }
109
110 void OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event);
111
112 void OnSize(wxSizeEvent& event);
113
114 private:
115 void LogMenuOpenOrClose(const wxMenuEvent& event, const wxChar *what);
116 void ShowContextMenu(const wxPoint& pos);
117
118 wxMenu *CreateDummyMenu(wxString *title);
119
120 wxMenuItem *GetLastMenuItem() const;
121
122 // the menu previously detached from the menubar (may be NULL)
123 wxMenu *m_menu;
124
125 // the count of dummy menus already created
126 size_t m_countDummy;
127
128 // the control used for logging
129 wxTextCtrl *m_textctrl;
130
131 // the previous log target
132 wxLog *m_logOld;
133
134 DECLARE_EVENT_TABLE()
135 };
136
137 // A small helper class which intercepts all menu events and logs them
138 class MyEvtHandler : public wxEvtHandler
139 {
140 public:
141 MyEvtHandler(MyFrame *frame) { m_frame = frame; }
142
143 void OnMenuEvent(wxCommandEvent& event)
144 {
145 m_frame->LogMenuEvent(event);
146
147 event.Skip();
148 }
149
150 private:
151 MyFrame *m_frame;
152
153 DECLARE_EVENT_TABLE()
154 };
155
156 // ----------------------------------------------------------------------------
157 // constants
158 // ----------------------------------------------------------------------------
159
160 enum
161 {
162 Menu_File_Quit = 100,
163 Menu_File_ClearLog,
164
165 Menu_MenuBar_Toggle = 200,
166 Menu_MenuBar_Append,
167 Menu_MenuBar_Insert,
168 Menu_MenuBar_Delete,
169 Menu_MenuBar_Enable,
170 Menu_MenuBar_GetLabel,
171 Menu_MenuBar_SetLabel,
172 Menu_MenuBar_FindMenu,
173
174 Menu_Menu_Append = 300,
175 Menu_Menu_AppendSub,
176 Menu_Menu_Insert,
177 Menu_Menu_Delete,
178 Menu_Menu_Enable,
179 Menu_Menu_Check,
180 Menu_Menu_GetLabel,
181 Menu_Menu_SetLabel,
182 Menu_Menu_GetInfo,
183 Menu_Menu_FindItem,
184
185 Menu_Test_Normal = 400,
186 Menu_Test_Check,
187 Menu_Test_Radio1,
188 Menu_Test_Radio2,
189 Menu_Test_Radio3,
190
191 Menu_Dummy_First = 500,
192 Menu_Dummy_Second,
193 Menu_Dummy_Third,
194 Menu_Dummy_Fourth,
195 Menu_Dummy_Last,
196
197 Menu_Help_About = 1000,
198
199 Menu_Popup_ToBeDeleted = 2000,
200 Menu_Popup_ToBeGreyed,
201 Menu_Popup_ToBeChecked,
202 Menu_Popup_Submenu,
203
204 Menu_Max
205 };
206
207 // ----------------------------------------------------------------------------
208 // event tables
209 // ----------------------------------------------------------------------------
210
211 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
212 EVT_MENU(Menu_File_Quit, MyFrame::OnQuit)
213 EVT_MENU(Menu_File_ClearLog, MyFrame::OnClearLog)
214
215 EVT_MENU(Menu_Help_About, MyFrame::OnAbout)
216
217 EVT_MENU(Menu_MenuBar_Toggle, MyFrame::OnToggleMenu)
218 EVT_MENU(Menu_MenuBar_Append, MyFrame::OnAppendMenu)
219 EVT_MENU(Menu_MenuBar_Insert, MyFrame::OnInsertMenu)
220 EVT_MENU(Menu_MenuBar_Delete, MyFrame::OnDeleteMenu)
221 EVT_MENU(Menu_MenuBar_Enable, MyFrame::OnEnableMenu)
222 EVT_MENU(Menu_MenuBar_GetLabel, MyFrame::OnGetLabelMenu)
223 EVT_MENU(Menu_MenuBar_SetLabel, MyFrame::OnSetLabelMenu)
224 EVT_MENU(Menu_MenuBar_FindMenu, MyFrame::OnFindMenu)
225
226 EVT_MENU(Menu_Menu_Append, MyFrame::OnAppendMenuItem)
227 EVT_MENU(Menu_Menu_AppendSub, MyFrame::OnAppendSubMenu)
228 EVT_MENU(Menu_Menu_Insert, MyFrame::OnInsertMenuItem)
229 EVT_MENU(Menu_Menu_Delete, MyFrame::OnDeleteMenuItem)
230 EVT_MENU(Menu_Menu_Enable, MyFrame::OnEnableMenuItem)
231 EVT_MENU(Menu_Menu_Check, MyFrame::OnCheckMenuItem)
232 EVT_MENU(Menu_Menu_GetLabel, MyFrame::OnGetLabelMenuItem)
233 EVT_MENU(Menu_Menu_SetLabel, MyFrame::OnSetLabelMenuItem)
234 EVT_MENU(Menu_Menu_GetInfo, MyFrame::OnGetMenuItemInfo)
235 EVT_MENU(Menu_Menu_FindItem, MyFrame::OnFindMenuItem)
236
237 EVT_MENU(Menu_Test_Normal, MyFrame::OnTestNormal)
238 EVT_MENU(Menu_Test_Check, MyFrame::OnTestCheck)
239 EVT_MENU(Menu_Test_Radio1, MyFrame::OnTestRadio)
240 EVT_MENU(Menu_Test_Radio2, MyFrame::OnTestRadio)
241 EVT_MENU(Menu_Test_Radio3, MyFrame::OnTestRadio)
242
243 EVT_MENU_RANGE(Menu_Dummy_First, Menu_Dummy_Last, MyFrame::OnDummy)
244
245 EVT_UPDATE_UI(Menu_Menu_Check, MyFrame::OnUpdateCheckMenuItemUI)
246
247 #ifdef __WXMSW__
248 EVT_CONTEXT_MENU(MyFrame::OnContextMenu)
249 #else
250 EVT_RIGHT_UP(MyFrame::OnRightUp)
251 #endif
252
253 EVT_MENU_OPEN(MyFrame::OnMenuOpen)
254 EVT_MENU_CLOSE(MyFrame::OnMenuClose)
255
256 EVT_SIZE(MyFrame::OnSize)
257 END_EVENT_TABLE()
258
259 BEGIN_EVENT_TABLE(MyEvtHandler, wxEvtHandler)
260 EVT_MENU(-1, MyEvtHandler::OnMenuEvent)
261 END_EVENT_TABLE()
262
263 // ============================================================================
264 // implementation
265 // ============================================================================
266
267 // ----------------------------------------------------------------------------
268 // MyApp
269 // ----------------------------------------------------------------------------
270
271 IMPLEMENT_APP(MyApp)
272
273 // The `main program' equivalent, creating the windows and returning the
274 // main frame
275 bool MyApp::OnInit()
276 {
277 // Create the main frame window
278 MyFrame* frame = new MyFrame;
279
280 frame->Show(TRUE);
281
282 #if wxUSE_STATUSBAR
283 frame->SetStatusText("Welcome to wxWindows menu sample");
284 #endif // wxUSE_STATUSBAR
285
286 SetTopWindow(frame);
287
288 return TRUE;
289 }
290
291 // ----------------------------------------------------------------------------
292 // MyFrame
293 // ----------------------------------------------------------------------------
294
295 // Define my frame constructor
296 MyFrame::MyFrame()
297 : wxFrame((wxFrame *)NULL, -1, "wxWindows menu sample",
298 wxDefaultPosition, wxSize(400, 250))
299 {
300 m_textctrl = NULL;
301 m_menu = NULL;
302 m_countDummy = 0;
303 m_logOld = NULL;
304
305 #if wxUSE_STATUSBAR
306 CreateStatusBar();
307 #endif // wxUSE_STATUSBAR
308
309 // create the menubar
310 wxMenu *fileMenu = new wxMenu;
311
312 wxMenuItem *item = new wxMenuItem(fileMenu, Menu_File_ClearLog,
313 "Clear &log\tCtrl-L");
314 item->SetBitmap(copy_xpm);
315 fileMenu->Append(item);
316 fileMenu->AppendSeparator();
317 fileMenu->Append(Menu_File_Quit, "E&xit\tAlt-X", "Quit menu sample");
318
319 wxMenu *menubarMenu = new wxMenu;
320 menubarMenu->Append(Menu_MenuBar_Append, "&Append menu\tCtrl-A",
321 "Append a menu to the menubar");
322 menubarMenu->Append(Menu_MenuBar_Insert, "&Insert menu\tCtrl-I",
323 "Insert a menu into the menubar");
324 menubarMenu->Append(Menu_MenuBar_Delete, "&Delete menu\tCtrl-D",
325 "Delete the last menu from the menubar");
326 menubarMenu->Append(Menu_MenuBar_Toggle, "&Toggle menu\tCtrl-T",
327 "Toggle the first menu in the menubar", TRUE);
328 menubarMenu->AppendSeparator();
329 menubarMenu->Append(Menu_MenuBar_Enable, "&Enable menu\tCtrl-E",
330 "Enable or disable the last menu", TRUE);
331 menubarMenu->AppendSeparator();
332 menubarMenu->Append(Menu_MenuBar_GetLabel, "&Get menu label\tCtrl-G",
333 "Get the label of the last menu");
334 menubarMenu->Append(Menu_MenuBar_SetLabel, "&Set menu label\tCtrl-S",
335 "Change the label of the last menu");
336 menubarMenu->AppendSeparator();
337 menubarMenu->Append(Menu_MenuBar_FindMenu, "&Find menu from label\tCtrl-F",
338 "Find a menu by searching for its label");
339
340 wxMenu *menuMenu = new wxMenu;
341 menuMenu->Append(Menu_Menu_Append, "&Append menu item\tAlt-A",
342 "Append a menu item to the last menu");
343 menuMenu->Append(Menu_Menu_AppendSub, "&Append sub menu\tAlt-S",
344 "Append a sub menu to the last menu");
345 menuMenu->Append(Menu_Menu_Insert, "&Insert menu item\tAlt-I",
346 "Insert a menu item in head of the last menu");
347 menuMenu->Append(Menu_Menu_Delete, "&Delete menu item\tAlt-D",
348 "Delete the last menu item from the last menu");
349 menuMenu->AppendSeparator();
350 menuMenu->Append(Menu_Menu_Enable, "&Enable menu item\tAlt-E",
351 "Enable or disable the last menu item", TRUE);
352 menuMenu->Append(Menu_Menu_Check, "&Check menu item\tAlt-C",
353 "Check or uncheck the last menu item", TRUE);
354 menuMenu->AppendSeparator();
355 menuMenu->Append(Menu_Menu_GetLabel, "&Get menu item label\tAlt-G",
356 "Get the label of the last menu item");
357 menuMenu->Append(Menu_Menu_SetLabel, "&Set menu item label\tAlt-S",
358 "Change the label of the last menu item");
359 menuMenu->AppendSeparator();
360 menuMenu->Append(Menu_Menu_GetInfo, "Get menu item in&fo\tAlt-F",
361 "Show the state of the last menu item");
362 menuMenu->AppendSeparator();
363 menuMenu->Append(Menu_Menu_FindItem, "Find menu item from label",
364 "Find a menu item by searching for its label");
365
366 wxMenu *testMenu = new wxMenu;
367 testMenu->Append(Menu_Test_Normal, "&Normal item");
368 testMenu->AppendSeparator();
369 testMenu->AppendCheckItem(Menu_Test_Check, "&Check item");
370 testMenu->AppendSeparator();
371 testMenu->AppendRadioItem(Menu_Test_Radio1, "Radio item &1");
372 testMenu->AppendRadioItem(Menu_Test_Radio2, "Radio item &2");
373 testMenu->AppendRadioItem(Menu_Test_Radio3, "Radio item &3");
374
375 wxMenu *helpMenu = new wxMenu;
376 helpMenu->Append(Menu_Help_About, "&About\tF1", "About menu sample");
377
378 wxMenuBar* menuBar = new wxMenuBar( wxMB_DOCKABLE );
379
380 menuBar->Append(fileMenu, "&File");
381 menuBar->Append(menubarMenu, "Menu&bar");
382 menuBar->Append(menuMenu, "&Menu");
383 menuBar->Append(testMenu, "&Test");
384 menuBar->Append(helpMenu, "&Help");
385
386 // these items should be initially checked
387 menuBar->Check(Menu_MenuBar_Toggle, TRUE);
388 menuBar->Check(Menu_MenuBar_Enable, TRUE);
389 menuBar->Check(Menu_Menu_Enable, TRUE);
390 menuBar->Check(Menu_Menu_Check, FALSE);
391
392 // associate the menu bar with the frame
393 SetMenuBar(menuBar);
394
395 // intercept all menu events and log them in this custom event handler
396 PushEventHandler(new MyEvtHandler(this));
397
398 // create the log text window
399 m_textctrl = new wxTextCtrl(this, -1, _T(""),
400 wxDefaultPosition, wxDefaultSize,
401 wxTE_MULTILINE);
402 m_textctrl->SetEditable(FALSE);
403
404 wxLog::SetTimestamp(NULL);
405 m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_textctrl));
406
407 wxLogMessage(_T("Brief explanations: the commands or the \"Menu\" menu ")
408 _T("append/insert/delete items to/from the last menu.\n")
409 _T("The commands from \"Menubar\" menu work with the ")
410 _T("menubar itself.\n\n")
411 _T("Right click the band below to test popup menus.\n"));
412 }
413
414 MyFrame::~MyFrame()
415 {
416 delete m_menu;
417
418 // delete the event handler installed in ctor
419 PopEventHandler(TRUE);
420
421 // restore old logger
422 delete wxLog::SetActiveTarget(m_logOld);
423 }
424
425 wxMenu *MyFrame::CreateDummyMenu(wxString *title)
426 {
427 wxMenu *menu = new wxMenu;
428 menu->Append(Menu_Dummy_First, "&First item\tCtrl-F1");
429 menu->AppendSeparator();
430 menu->Append(Menu_Dummy_Second, "&Second item\tCtrl-F2", "", TRUE);
431
432 if ( title )
433 {
434 title->Printf(wxT("Dummy menu &%u"), (unsigned)++m_countDummy);
435 }
436
437 return menu;
438 }
439
440 wxMenuItem *MyFrame::GetLastMenuItem() const
441 {
442 wxMenuBar *menubar = GetMenuBar();
443 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
444
445 wxMenuItemList::Node *node = menu->GetMenuItems().GetLast();
446 if ( !node )
447 {
448 wxLogWarning(wxT("No last item in the last menu!"));
449
450 return NULL;
451 }
452 else
453 {
454 return node->GetData();
455 }
456 }
457
458 void MyFrame::LogMenuEvent(const wxCommandEvent& event)
459 {
460 int id = event.GetId();
461 if ( !GetMenuBar()->FindItem(id) )
462 return;
463
464 wxString msg = wxString::Format(wxT("Menu command %d"), id);
465 if ( GetMenuBar()->FindItem(id)->IsCheckable() )
466 {
467 msg += wxString::Format(wxT(" (the item is currently %schecked)"),
468 event.IsChecked() ? "" : "not ");
469 }
470
471 wxLogMessage(msg);
472 }
473
474 // ----------------------------------------------------------------------------
475 // menu callbacks
476 // ----------------------------------------------------------------------------
477
478 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
479 {
480 Close(TRUE);
481 }
482
483 void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
484 {
485 m_textctrl->Clear();
486 }
487
488 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
489 {
490 (void)wxMessageBox("wxWindows menu sample\n© 1999-2001 Vadim Zeitlin",
491 "About wxWindows menu sample",
492 wxICON_INFORMATION);
493 }
494
495 void MyFrame::OnDeleteMenu(wxCommandEvent& WXUNUSED(event))
496 {
497 wxMenuBar *mbar = GetMenuBar();
498
499 size_t count = mbar->GetMenuCount();
500 if ( count == 2 )
501 {
502 // don't let delete the first 2 menus
503 wxLogError(wxT("Can't delete any more menus"));
504 }
505 else
506 {
507 delete mbar->Remove(count - 1);
508 }
509 }
510
511 void MyFrame::OnInsertMenu(wxCommandEvent& WXUNUSED(event))
512 {
513 wxString title;
514 wxMenu *menu = CreateDummyMenu(&title);
515 GetMenuBar()->Insert(0, menu, title);
516 }
517
518 void MyFrame::OnAppendMenu(wxCommandEvent& WXUNUSED(event))
519 {
520 wxString title;
521 wxMenu *menu = CreateDummyMenu(&title);
522 GetMenuBar()->Append(menu, title);
523 }
524
525 void MyFrame::OnToggleMenu(wxCommandEvent& WXUNUSED(event))
526 {
527 wxMenuBar *mbar = GetMenuBar();
528 if ( !m_menu )
529 {
530 // hide the menu
531 m_menu = mbar->Remove(0);
532 }
533 else
534 {
535 // restore it
536 mbar->Insert(0, m_menu, "&File");
537 m_menu = NULL;
538 }
539 }
540
541 void MyFrame::OnEnableMenu(wxCommandEvent& event)
542 {
543 wxMenuBar *mbar = GetMenuBar();
544 size_t count = mbar->GetMenuCount();
545
546 mbar->EnableTop(count - 1, event.IsChecked());
547 }
548
549 void MyFrame::OnGetLabelMenu(wxCommandEvent& WXUNUSED(event))
550 {
551 wxMenuBar *mbar = GetMenuBar();
552 size_t count = mbar->GetMenuCount();
553
554 wxCHECK_RET( count, _T("no last menu?") );
555
556 wxLogMessage(wxT("The label of the last menu item is '%s'"),
557 mbar->GetLabelTop(count - 1).c_str());
558 }
559
560 void MyFrame::OnSetLabelMenu(wxCommandEvent& WXUNUSED(event))
561 {
562 wxMenuBar *mbar = GetMenuBar();
563 size_t count = mbar->GetMenuCount();
564
565 wxCHECK_RET( count, _T("no last menu?") );
566
567 wxString label = wxGetTextFromUser
568 (
569 _T("Enter new label: "),
570 _T("Change last menu text"),
571 mbar->GetLabelTop(count - 1),
572 this
573 );
574
575 if ( !label.empty() )
576 {
577 mbar->SetLabelTop(count - 1, label);
578 }
579 }
580
581 void MyFrame::OnFindMenu(wxCommandEvent& WXUNUSED(event))
582 {
583 wxMenuBar *mbar = GetMenuBar();
584 size_t count = mbar->GetMenuCount();
585
586 wxCHECK_RET( count, _T("no last menu?") );
587
588 wxString label = wxGetTextFromUser
589 (
590 _T("Enter label to search for: "),
591 _T("Find menu"),
592 "",
593 this
594 );
595
596 if ( !label.empty() )
597 {
598 int index = mbar->FindMenu(label);
599
600 if (index == wxNOT_FOUND)
601 {
602 wxLogWarning(wxT("No menu with label '%s'"), label.c_str());
603 }
604 else
605 {
606 wxLogMessage(wxT("Menu %d has label '%s'"), index, label.c_str());
607 }
608 }
609 }
610
611 void MyFrame::OnDummy(wxCommandEvent& event)
612 {
613 wxLogMessage(wxT("Dummy item #%d"), event.GetId() - Menu_Dummy_First + 1);
614 }
615
616 void MyFrame::OnAppendMenuItem(wxCommandEvent& WXUNUSED(event))
617 {
618 wxMenuBar *menubar = GetMenuBar();
619 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
620
621 menu->AppendSeparator();
622 menu->Append(Menu_Dummy_Third, "&Third dummy item\tCtrl-F3",
623 "Checkable item", TRUE);
624 }
625
626 void MyFrame::OnAppendSubMenu(wxCommandEvent& WXUNUSED(event))
627 {
628 wxMenuBar *menubar = GetMenuBar();
629
630 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
631
632 menu->Append(Menu_Dummy_Last, "&Dummy sub menu",
633 CreateDummyMenu(NULL), "Dummy sub menu help");
634 }
635
636 void MyFrame::OnDeleteMenuItem(wxCommandEvent& WXUNUSED(event))
637 {
638 wxMenuBar *menubar = GetMenuBar();
639 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
640
641 size_t count = menu->GetMenuItemCount();
642 if ( !count )
643 {
644 wxLogWarning(wxT("No items to delete!"));
645 }
646 else
647 {
648 menu->Destroy(menu->GetMenuItems().Item(count - 1)->GetData());
649 }
650 }
651
652 void MyFrame::OnInsertMenuItem(wxCommandEvent& WXUNUSED(event))
653 {
654 wxMenuBar *menubar = GetMenuBar();
655 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
656
657 menu->Insert(0, wxMenuItem::New(menu, Menu_Dummy_Fourth,
658 "Fourth dummy item\tCtrl-F4"));
659 menu->Insert(1, wxMenuItem::New(menu, wxID_SEPARATOR, ""));
660 }
661
662 void MyFrame::OnEnableMenuItem(wxCommandEvent& WXUNUSED(event))
663 {
664 wxMenuItem *item = GetLastMenuItem();
665
666 if ( item )
667 {
668 item->Enable(!item->IsEnabled());
669 }
670 }
671
672 void MyFrame::OnCheckMenuItem(wxCommandEvent& WXUNUSED(event))
673 {
674 wxMenuItem *item = GetLastMenuItem();
675
676 item->Toggle();
677 }
678
679 void MyFrame::OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event)
680 {
681 wxLogNull nolog;
682
683 wxMenuItem *item = GetLastMenuItem();
684
685 event.Enable(item && item->IsCheckable());
686 }
687
688 void MyFrame::OnGetLabelMenuItem(wxCommandEvent& WXUNUSED(event))
689 {
690 wxMenuItem *item = GetLastMenuItem();
691
692 if ( item )
693 {
694 wxLogMessage(wxT("The label of the last menu item is '%s'"),
695 item->GetLabel().c_str());
696 }
697 }
698
699 void MyFrame::OnSetLabelMenuItem(wxCommandEvent& WXUNUSED(event))
700 {
701 wxMenuItem *item = GetLastMenuItem();
702
703 if ( item )
704 {
705 wxString label = wxGetTextFromUser
706 (
707 _T("Enter new label: "),
708 _T("Change last menu item text"),
709 item->GetLabel(),
710 this
711 );
712
713 if ( !label.empty() )
714 {
715 item->SetText(label);
716 }
717 }
718 }
719
720 void MyFrame::OnGetMenuItemInfo(wxCommandEvent& WXUNUSED(event))
721 {
722 wxMenuItem *item = GetLastMenuItem();
723
724 if ( item )
725 {
726 wxString msg;
727 msg << "The item is " << (item->IsEnabled() ? "enabled"
728 : "disabled")
729 << '\n';
730
731 if ( item->IsCheckable() )
732 {
733 msg << "It is checkable and " << (item->IsChecked() ? "" : "un")
734 << "checked\n";
735 }
736
737 #if wxUSE_ACCEL
738 wxAcceleratorEntry *accel = item->GetAccel();
739 if ( accel )
740 {
741 msg << "Its accelerator is ";
742
743 int flags = accel->GetFlags();
744 if ( flags & wxACCEL_ALT )
745 msg << wxT("Alt-");
746 if ( flags & wxACCEL_CTRL )
747 msg << wxT("Ctrl-");
748 if ( flags & wxACCEL_SHIFT )
749 msg << wxT("Shift-");
750
751 int code = accel->GetKeyCode();
752 switch ( code )
753 {
754 case WXK_F1:
755 case WXK_F2:
756 case WXK_F3:
757 case WXK_F4:
758 case WXK_F5:
759 case WXK_F6:
760 case WXK_F7:
761 case WXK_F8:
762 case WXK_F9:
763 case WXK_F10:
764 case WXK_F11:
765 case WXK_F12:
766 msg << wxT('F') << code - WXK_F1 + 1;
767 break;
768
769 // if there are any other keys wxGetAccelFromString() may return,
770 // we should process them here
771
772 default:
773 if ( wxIsalnum(code) )
774 {
775 msg << (wxChar)code;
776
777 break;
778 }
779
780 wxFAIL_MSG( wxT("unknown keyboard accel") );
781 }
782
783 delete accel;
784 }
785 else
786 {
787 msg << "It doesn't have an accelerator";
788 }
789 #endif // wxUSE_ACCEL
790
791 wxLogMessage(msg);
792 }
793 }
794
795 void MyFrame::OnFindMenuItem(wxCommandEvent& WXUNUSED(event))
796 {
797 wxMenuBar *mbar = GetMenuBar();
798 size_t count = mbar->GetMenuCount();
799
800 wxCHECK_RET( count, _T("no last menu?") );
801
802 wxString label = wxGetTextFromUser
803 (
804 _T("Enter label to search for: "),
805 _T("Find menu item"),
806 "",
807 this
808 );
809
810 if ( !label.empty() )
811 {
812 size_t menuindex = 0;
813 int index = wxNOT_FOUND;
814
815 for (menuindex = 0; (menuindex < count) && (index == wxNOT_FOUND); ++menuindex)
816 {
817 index = mbar->FindMenuItem(mbar->GetMenu(menuindex)->GetTitle(), label);
818 }
819 if (index == wxNOT_FOUND)
820 {
821 wxLogWarning(wxT("No menu item with label '%s'"), label.c_str());
822 }
823 else
824 {
825 wxLogMessage(wxT("Menu item %d in menu %d has label '%s'"),
826 index, menuindex, label.c_str());
827 }
828 }
829 }
830
831 void MyFrame::ShowContextMenu(const wxPoint& pos)
832 {
833 wxMenu menu("Test popup");
834
835 menu.Append(Menu_Help_About, "&About");
836 menu.Append(Menu_Popup_Submenu, "&Submenu", CreateDummyMenu(NULL));
837 menu.Append(Menu_Popup_ToBeDeleted, "To be &deleted");
838 menu.Append(Menu_Popup_ToBeChecked, "To be &checked", "", TRUE);
839 menu.Append(Menu_Popup_ToBeGreyed, "To be &greyed");
840 menu.AppendSeparator();
841 menu.Append(Menu_File_Quit, "E&xit");
842
843 menu.Delete(Menu_Popup_ToBeDeleted);
844 menu.Check(Menu_Popup_ToBeChecked, TRUE);
845 menu.Enable(Menu_Popup_ToBeGreyed, FALSE);
846
847 PopupMenu(&menu, pos.x, pos.y);
848
849 // test for destroying items in popup menus
850 #if 0 // doesn't work in wxGTK!
851 menu.Destroy(Menu_Popup_Submenu);
852
853 PopupMenu( &menu, event.GetX(), event.GetY() );
854 #endif // 0
855 }
856
857 void MyFrame::OnTestNormal(wxCommandEvent& event)
858 {
859 wxLogMessage(_T("Normal item selected"));
860 }
861
862 void MyFrame::OnTestCheck(wxCommandEvent& event)
863 {
864 wxLogMessage(_T("Check item %schecked"),
865 event.IsChecked() ? _T("") : _T("un"));
866 }
867
868 void MyFrame::OnTestRadio(wxCommandEvent& event)
869 {
870 wxLogMessage(_T("Radio item %d selected"),
871 event.GetId() - Menu_Test_Radio1 + 1);
872 }
873
874 void MyFrame::LogMenuOpenOrClose(const wxMenuEvent& event, const wxChar *what)
875 {
876 wxLogStatus(this, _T("A %smenu has been %s."),
877 event.IsPopup() ? _T("popup ") : _T(""), what);
878 }
879
880 void MyFrame::OnSize(wxSizeEvent& event)
881 {
882 if ( !m_textctrl )
883 return;
884
885 // leave a band below for popup menu testing
886 wxSize size = GetClientSize();
887 m_textctrl->SetSize(0, 0, size.x, (3*size.y)/4);
888
889 // this is really ugly but we have to do it as we can't just call
890 // event.Skip() because wxFrameBase would make the text control fill the
891 // entire frame then
892 #ifdef __WXUNIVERSAL__
893 PositionMenuBar();
894 #endif // __WXUNIVERSAL__
895 }
896