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