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