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