]> git.saurik.com Git - wxWidgets.git/blob - samples/menu/menu.cpp
final (touch wood) tidy after things went pearshaped on line 666
[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/wx.h>
29
30 #include <wx/log.h>
31 #endif
32
33 // ----------------------------------------------------------------------------
34 // classes
35 // ----------------------------------------------------------------------------
36
37 // Define a new application
38 class MyApp: public wxApp
39 {
40 public:
41 bool OnInit();
42 };
43
44 // Define a new frame
45 class MyFrame: public wxFrame
46 {
47 public:
48 MyFrame();
49
50 virtual ~MyFrame() { delete m_menu; }
51
52 void OnQuit(wxCommandEvent& event);
53 void OnAbout(wxCommandEvent& event);
54
55 void OnDummy(wxCommandEvent& event);
56
57 void OnAppendMenuItem(wxCommandEvent& event);
58 void OnAppendSubMenu(wxCommandEvent& event);
59 void OnDeleteMenuItem(wxCommandEvent& event);
60 void OnInsertMenuItem(wxCommandEvent& event);
61 void OnCheckMenuItem(wxCommandEvent& event);
62 void OnEnableMenuItem(wxCommandEvent& event);
63 void OnGetLabelMenuItem(wxCommandEvent& event);
64 void OnSetLabelMenuItem(wxCommandEvent& event);
65 void OnGetMenuItemInfo(wxCommandEvent& event);
66
67 void OnAppendMenu(wxCommandEvent& event);
68 void OnInsertMenu(wxCommandEvent& event);
69 void OnDeleteMenu(wxCommandEvent& event);
70 void OnToggleMenu(wxCommandEvent& event);
71 void OnEnableMenu(wxCommandEvent& event);
72 void OnGetLabelMenu(wxCommandEvent& event);
73 void OnSetLabelMenu(wxCommandEvent& event);
74
75 void OnRightDown(wxMouseEvent& event);
76
77 void OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event);
78
79 private:
80 wxMenu *CreateDummyMenu(wxString *title);
81
82 wxMenuItem *GetLastMenuItem() const;
83
84 wxMenu *m_menu;
85
86 size_t m_countDummy;
87
88 DECLARE_EVENT_TABLE()
89 };
90
91 // ----------------------------------------------------------------------------
92 // constants
93 // ----------------------------------------------------------------------------
94
95 enum
96 {
97 Menu_File_Quit = 100,
98
99 Menu_MenuBar_Toggle = 200,
100 Menu_MenuBar_Append,
101 Menu_MenuBar_Insert,
102 Menu_MenuBar_Delete,
103 Menu_MenuBar_Enable,
104 Menu_MenuBar_GetLabel,
105 Menu_MenuBar_SetLabel,
106
107 Menu_Menu_Append = 300,
108 Menu_Menu_AppendSub,
109 Menu_Menu_Insert,
110 Menu_Menu_Delete,
111 Menu_Menu_Enable,
112 Menu_Menu_Check,
113 Menu_Menu_GetLabel,
114 Menu_Menu_SetLabel,
115 Menu_Menu_GetInfo,
116
117 Menu_Dummy_First = 400,
118 Menu_Dummy_Second,
119 Menu_Dummy_Third,
120 Menu_Dummy_Fourth,
121 Menu_Dummy_Last,
122
123 Menu_Help_About = 1000,
124
125 Menu_Popup_ToBeDeleted = 2000,
126 Menu_Popup_ToBeGreyed,
127 Menu_Popup_ToBeChecked,
128 Menu_Popup_Submenu,
129
130 Menu_Max
131 };
132
133 // ----------------------------------------------------------------------------
134 // event tables
135 // ----------------------------------------------------------------------------
136
137 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
138 EVT_MENU(Menu_File_Quit, MyFrame::OnQuit)
139
140 EVT_MENU(Menu_Help_About, MyFrame::OnAbout)
141
142 EVT_MENU(Menu_MenuBar_Toggle, MyFrame::OnToggleMenu)
143 EVT_MENU(Menu_MenuBar_Append, MyFrame::OnAppendMenu)
144 EVT_MENU(Menu_MenuBar_Insert, MyFrame::OnInsertMenu)
145 EVT_MENU(Menu_MenuBar_Delete, MyFrame::OnDeleteMenu)
146 EVT_MENU(Menu_MenuBar_Enable, MyFrame::OnEnableMenu)
147 EVT_MENU(Menu_MenuBar_GetLabel, MyFrame::OnGetLabelMenu)
148 EVT_MENU(Menu_MenuBar_SetLabel, MyFrame::OnSetLabelMenu)
149
150 EVT_MENU(Menu_Menu_Append, MyFrame::OnAppendMenuItem)
151 EVT_MENU(Menu_Menu_AppendSub, MyFrame::OnAppendSubMenu)
152 EVT_MENU(Menu_Menu_Insert, MyFrame::OnInsertMenuItem)
153 EVT_MENU(Menu_Menu_Delete, MyFrame::OnDeleteMenuItem)
154 EVT_MENU(Menu_Menu_Enable, MyFrame::OnEnableMenuItem)
155 EVT_MENU(Menu_Menu_Check, MyFrame::OnCheckMenuItem)
156 EVT_MENU(Menu_Menu_GetLabel, MyFrame::OnGetLabelMenuItem)
157 EVT_MENU(Menu_Menu_SetLabel, MyFrame::OnSetLabelMenuItem)
158 EVT_MENU(Menu_Menu_GetInfo, MyFrame::OnGetMenuItemInfo)
159
160 EVT_MENU_RANGE(Menu_Dummy_First, Menu_Dummy_Last, MyFrame::OnDummy)
161
162 EVT_UPDATE_UI(Menu_Menu_Check, MyFrame::OnUpdateCheckMenuItemUI)
163
164 EVT_RIGHT_DOWN(MyFrame::OnRightDown)
165 END_EVENT_TABLE()
166
167 // ============================================================================
168 // implementation
169 // ============================================================================
170
171 // ----------------------------------------------------------------------------
172 // MyApp
173 // ----------------------------------------------------------------------------
174
175 IMPLEMENT_APP(MyApp)
176
177 // The `main program' equivalent, creating the windows and returning the
178 // main frame
179 bool MyApp::OnInit()
180 {
181 // Create the main frame window
182 MyFrame* frame = new MyFrame;
183
184 frame->Show(TRUE);
185
186 frame->SetStatusText("Hello, wxWindows");
187
188 SetTopWindow(frame);
189
190 return TRUE;
191 }
192
193 // ----------------------------------------------------------------------------
194 // MyFrame
195 // ----------------------------------------------------------------------------
196
197 // Define my frame constructor
198 MyFrame::MyFrame()
199 : wxFrame((wxFrame *)NULL, -1, "wxWindows menu sample",
200 wxDefaultPosition, wxSize(300, 200))
201 {
202 m_menu = NULL;
203 m_countDummy = 0;
204
205 CreateStatusBar();
206
207 // create the menubar
208 wxMenu *fileMenu = new wxMenu;
209 fileMenu->Append(Menu_File_Quit, "E&xit\tAlt-X", "Quit toolbar sample" );
210
211 wxMenu *menubarMenu = new wxMenu;
212 menubarMenu->Append(Menu_MenuBar_Append, "&Append menu\tCtrl-A",
213 "Append a menu to the menubar");
214 menubarMenu->Append(Menu_MenuBar_Insert, "&Insert menu\tCtrl-I",
215 "Insert a menu into the menubar");
216 menubarMenu->Append(Menu_MenuBar_Delete, "&Delete menu\tCtrl-D",
217 "Delete the last menu from the menubar");
218 menubarMenu->Append(Menu_MenuBar_Toggle, "&Toggle menu\tCtrl-T",
219 "Toggle the first menu in the menubar", TRUE);
220 menubarMenu->AppendSeparator();
221 menubarMenu->Append(Menu_MenuBar_Enable, "&Enable menu\tCtrl-E",
222 "Enable or disable the last menu", TRUE);
223 menubarMenu->AppendSeparator();
224 menubarMenu->Append(Menu_MenuBar_GetLabel, "&Get menu label\tCtrl-G",
225 "Get the label of the last menu");
226 menubarMenu->Append(Menu_MenuBar_SetLabel, "&Set menu label\tCtrl-S",
227 "Change the label of the last menu");
228
229 wxMenu *menuMenu = new wxMenu;
230 menuMenu->Append(Menu_Menu_Append, "&Append menu item\tAlt-A",
231 "Append a menu item to the last menu");
232 menuMenu->Append(Menu_Menu_AppendSub, "&Append sub menu\tAlt-S",
233 "Append a sub menu to the last menu");
234 menuMenu->Append(Menu_Menu_Insert, "&Insert menu item\tAlt-I",
235 "Insert a menu item in head of the last menu");
236 menuMenu->Append(Menu_Menu_Delete, "&Delete menu item\tAlt-D",
237 "Delete the last menu item from the last menu");
238 menuMenu->AppendSeparator();
239 menuMenu->Append(Menu_Menu_Enable, "&Enable menu item\tAlt-E",
240 "Enable or disable the last menu item", TRUE);
241 menuMenu->Append(Menu_Menu_Check, "&Check menu item\tAlt-C",
242 "Check or uncheck the last menu item", TRUE);
243 menuMenu->AppendSeparator();
244 menuMenu->Append(Menu_Menu_GetLabel, "&Get menu item label\tAlt-G",
245 "Get the label of the last menu item");
246 menuMenu->Append(Menu_Menu_SetLabel, "&Set menu item label\tAlt-S",
247 "Change the label of the last menu item");
248 menuMenu->AppendSeparator();
249 menuMenu->Append(Menu_Menu_GetInfo, "Get menu item in&fo\tAlt-F",
250 "Show the state of the last menu item");
251
252 wxMenu *helpMenu = new wxMenu;
253 helpMenu->Append(Menu_Help_About, "&About\tF1", "About menu sample");
254
255 wxMenuBar* menuBar = new wxMenuBar( wxMB_DOCKABLE );
256
257 menuBar->Append(fileMenu, "&File");
258 menuBar->Append(menubarMenu, "Menu&bar");
259 menuBar->Append(menuMenu, "&Menu");
260 menuBar->Append(helpMenu, "&Help");
261
262 // these items should be initially checked
263 menuBar->Check(Menu_MenuBar_Toggle, TRUE);
264 menuBar->Check(Menu_MenuBar_Enable, TRUE);
265 menuBar->Check(Menu_Menu_Enable, TRUE);
266 menuBar->Check(Menu_Menu_Check, FALSE);
267
268 // associate the menu bar with the frame
269 SetMenuBar(menuBar);
270 }
271
272 wxMenu *MyFrame::CreateDummyMenu(wxString *title)
273 {
274 wxMenu *menu = new wxMenu;
275 menu->Append(Menu_Dummy_First, "First item\tCtrl-F1");
276 menu->AppendSeparator();
277 menu->Append(Menu_Dummy_Second, "Second item\tCtrl-F2", "", TRUE);
278
279 if ( title )
280 {
281 title->Printf("Dummy menu &%d", ++m_countDummy);
282 }
283
284 return menu;
285 }
286
287 wxMenuItem *MyFrame::GetLastMenuItem() const
288 {
289 wxMenuBar *menubar = GetMenuBar();
290 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
291
292 wxMenuItemList::Node *node = menu->GetMenuItems().GetLast();
293 if ( !node )
294 {
295 wxLogWarning("No last item in the last menu!");
296
297 return NULL;
298 }
299 else
300 {
301 return node->GetData();
302 }
303 }
304
305 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
306 {
307 Close(TRUE);
308 }
309
310 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
311 {
312 (void)wxMessageBox("wxWindows toolbar sample",
313 "About wxWindows menu sample",
314 wxICON_INFORMATION);
315 }
316
317 void MyFrame::OnDeleteMenu(wxCommandEvent& WXUNUSED(event))
318 {
319 wxMenuBar *mbar = GetMenuBar();
320
321 size_t count = mbar->GetMenuCount();
322 if ( count == 2 )
323 {
324 // don't let delete the first 2 menus
325 wxLogError("Can't delete any more menus");
326 }
327 else
328 {
329 delete mbar->Remove(count - 1);
330 }
331 }
332
333 void MyFrame::OnInsertMenu(wxCommandEvent& WXUNUSED(event))
334 {
335 wxString title;
336 wxMenu *menu = CreateDummyMenu(&title);
337 GetMenuBar()->Insert(0, menu, title);
338 }
339
340 void MyFrame::OnAppendMenu(wxCommandEvent& WXUNUSED(event))
341 {
342 wxString title;
343 wxMenu *menu = CreateDummyMenu(&title);
344 GetMenuBar()->Append(menu, title);
345 }
346
347 void MyFrame::OnToggleMenu(wxCommandEvent& WXUNUSED(event))
348 {
349 wxMenuBar *mbar = GetMenuBar();
350 if ( !m_menu )
351 {
352 // hide the menu
353 m_menu = mbar->Remove(0);
354 }
355 else
356 {
357 // restore it
358 mbar->Insert(0, m_menu, "&File");
359 m_menu = NULL;
360 }
361 }
362
363 void MyFrame::OnEnableMenu(wxCommandEvent& WXUNUSED(event))
364 {
365 wxMenuBar *mbar = GetMenuBar();
366 size_t count = mbar->GetMenuCount();
367
368 static bool s_enabled = TRUE;
369
370 s_enabled = !s_enabled;
371 mbar->EnableTop(count - 1, s_enabled);
372 }
373
374 void MyFrame::OnGetLabelMenu(wxCommandEvent& WXUNUSED(event))
375 {
376 wxMenuBar *mbar = GetMenuBar();
377 size_t count = mbar->GetMenuCount();
378
379 wxLogMessage("The label of the last menu item is '%s'",
380 mbar->GetLabelTop(count - 1).c_str());
381 }
382
383 void MyFrame::OnSetLabelMenu(wxCommandEvent& WXUNUSED(event))
384 {
385 wxMenuBar *mbar = GetMenuBar();
386 size_t count = mbar->GetMenuCount();
387
388 mbar->SetLabelTop(count - 1, "Dummy label &0");
389 }
390
391 void MyFrame::OnDummy(wxCommandEvent& event)
392 {
393 wxString s;
394 s.Printf("Dummy item #%d", event.GetId() - Menu_Dummy_First + 1);
395 wxMessageBox(s, "Menu sample", wxICON_INFORMATION);
396 }
397
398 void MyFrame::OnAppendMenuItem(wxCommandEvent& WXUNUSED(event))
399 {
400 wxMenuBar *menubar = GetMenuBar();
401 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
402
403 menu->AppendSeparator();
404 menu->Append(Menu_Dummy_Third, "Third dummy item\tCtrl-F3",
405 "Checkable item", TRUE);
406 }
407
408 void MyFrame::OnAppendSubMenu(wxCommandEvent& WXUNUSED(event))
409 {
410 wxMenuBar *menubar = GetMenuBar();
411
412 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
413
414 menu->Append(Menu_Dummy_Last, "Dummy sub menu\tCtrl-F2",
415 CreateDummyMenu(NULL));
416 }
417
418 void MyFrame::OnDeleteMenuItem(wxCommandEvent& WXUNUSED(event))
419 {
420 wxMenuBar *menubar = GetMenuBar();
421 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
422
423 size_t count = menu->GetMenuItemCount();
424 if ( !count )
425 {
426 wxLogWarning("No items to delete!");
427 }
428 else
429 {
430 menu->Destroy(menu->GetMenuItems().Item(count - 1)->GetData());
431 }
432 }
433
434 void MyFrame::OnInsertMenuItem(wxCommandEvent& WXUNUSED(event))
435 {
436 wxMenuBar *menubar = GetMenuBar();
437 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
438
439 menu->Insert(0, wxMenuItem::New(menu, Menu_Dummy_Fourth,
440 "Fourth dummy item\tCtrl-F4"));
441 menu->Insert(1, wxMenuItem::New(menu, wxID_SEPARATOR, ""));
442 }
443
444 void MyFrame::OnEnableMenuItem(wxCommandEvent& WXUNUSED(event))
445 {
446 wxMenuItem *item = GetLastMenuItem();
447
448 if ( item )
449 {
450 item->Enable(!item->IsEnabled());
451 }
452 }
453
454 void MyFrame::OnCheckMenuItem(wxCommandEvent& WXUNUSED(event))
455 {
456 wxMenuItem *item = GetLastMenuItem();
457
458 item->Toggle();
459 }
460
461 void MyFrame::OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event)
462 {
463 wxLogNull nolog;
464
465 wxMenuItem *item = GetLastMenuItem();
466
467 event.Enable(item && item->IsCheckable());
468 }
469
470 void MyFrame::OnGetLabelMenuItem(wxCommandEvent& WXUNUSED(event))
471 {
472 wxMenuItem *item = GetLastMenuItem();
473
474 if ( item )
475 {
476 wxLogMessage("The label of the last menu item is '%s'",
477 item->GetLabel().c_str());
478 }
479 }
480
481 void MyFrame::OnSetLabelMenuItem(wxCommandEvent& WXUNUSED(event))
482 {
483 wxMenuItem *item = GetLastMenuItem();
484
485 if ( item )
486 {
487 item->SetText("Dummy menu item text");
488 }
489 }
490
491 void MyFrame::OnGetMenuItemInfo(wxCommandEvent& WXUNUSED(event))
492 {
493 wxMenuItem *item = GetLastMenuItem();
494
495 if ( item )
496 {
497 wxString msg;
498 msg << "The item is " << (item->IsEnabled() ? "enabled"
499 : "disabled")
500 << '\n';
501
502 if ( item->IsCheckable() )
503 {
504 msg << "It is checkable and " << (item->IsChecked() ? "" : "un")
505 << "checked\n";
506 }
507
508 #if wxUSE_ACCEL
509 wxAcceleratorEntry *accel = item->GetAccel();
510 if ( accel )
511 {
512 msg << "Its accelerator is ";
513
514 int flags = accel->GetFlags();
515 if ( flags & wxACCEL_ALT )
516 msg << wxT("Alt-");
517 if ( flags & wxACCEL_CTRL )
518 msg << wxT("Ctrl-");
519 if ( flags & wxACCEL_SHIFT )
520 msg << wxT("Shift-");
521
522 int code = accel->GetKeyCode();
523 switch ( code )
524 {
525 case WXK_F1:
526 case WXK_F2:
527 case WXK_F3:
528 case WXK_F4:
529 case WXK_F5:
530 case WXK_F6:
531 case WXK_F7:
532 case WXK_F8:
533 case WXK_F9:
534 case WXK_F10:
535 case WXK_F11:
536 case WXK_F12:
537 msg << wxT('F') << code - WXK_F1 + 1;
538 break;
539
540 // if there are any other keys wxGetAccelFromString() may return,
541 // we should process them here
542
543 default:
544 if ( wxIsalnum(code) )
545 {
546 msg << (wxChar)code;
547
548 break;
549 }
550
551 wxFAIL_MSG( wxT("unknown keyboard accel") );
552 }
553
554 delete accel;
555 }
556 else
557 {
558 msg << "It doesn't have an accelerator";
559 }
560 #endif // wxUSE_ACCEL
561
562 wxLogMessage(msg);
563 }
564 }
565
566 void MyFrame::OnRightDown(wxMouseEvent &event )
567 {
568 wxMenu menu("Test popup");
569
570 menu.Append(Menu_Help_About, "&About");
571 menu.Append(Menu_Popup_Submenu, "Submenu", CreateDummyMenu(NULL));
572 menu.Append(Menu_Popup_ToBeDeleted, "To be deleted");
573 menu.Append(Menu_Popup_ToBeChecked, "To be checked", "", TRUE);
574 menu.Append(Menu_Popup_ToBeGreyed, "To be greyed");
575 menu.AppendSeparator();
576 menu.Append(Menu_File_Quit, "E&xit");
577
578 //menu.Delete(Menu_Popup_ToBeDeleted);
579 menu.Check(Menu_Popup_ToBeChecked, TRUE);
580 menu.Enable(Menu_Popup_ToBeGreyed, FALSE);
581
582 PopupMenu( &menu, event.GetX(), event.GetY() );
583 }