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