]>
git.saurik.com Git - wxWidgets.git/blob - samples/menu/menu.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/menu.cpp
3 // Purpose: wxMenu/wxMenuBar sample
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1999 Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include <wx/wxprec.h>
31 #include <wx/msgdlg.h>
33 #include <wx/textctrl.h>
38 #error "menu sample requires wxUSE_MENUS=1"
43 #ifdef __WXUNIVERSAL__
44 #include "wx/univ/theme.h"
48 #endif // __WXUNIVERSAL__
50 // ----------------------------------------------------------------------------
52 // ----------------------------------------------------------------------------
54 // Define a new application
55 class MyApp
: public wxApp
62 class MyFrame
: public wxFrame
69 void LogMenuEvent(const wxCommandEvent
& event
);
72 void OnQuit(wxCommandEvent
& event
);
73 void OnClearLog(wxCommandEvent
& event
);
75 void OnAbout(wxCommandEvent
& event
);
77 void OnDummy(wxCommandEvent
& event
);
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
);
89 void OnAppendMenu(wxCommandEvent
& event
);
90 void OnInsertMenu(wxCommandEvent
& event
);
91 void OnDeleteMenu(wxCommandEvent
& event
);
92 void OnToggleMenu(wxCommandEvent
& event
);
93 void OnEnableMenu(wxCommandEvent
& event
);
94 void OnGetLabelMenu(wxCommandEvent
& event
);
95 void OnSetLabelMenu(wxCommandEvent
& event
);
97 void OnRightUp(wxMouseEvent
& event
);
99 void OnUpdateCheckMenuItemUI(wxUpdateUIEvent
& event
);
101 void OnSize(wxSizeEvent
& event
);
104 wxMenu
*CreateDummyMenu(wxString
*title
);
106 wxMenuItem
*GetLastMenuItem() const;
108 // the menu previously detached from the menubar (may be NULL)
111 // the count of dummy menus already created
114 // the control used for logging
115 wxTextCtrl
*m_textctrl
;
117 // the previous log target
120 DECLARE_EVENT_TABLE()
123 // A small helper class which intercepts all menu events and logs them
124 class MyEvtHandler
: public wxEvtHandler
127 MyEvtHandler(MyFrame
*frame
) { m_frame
= frame
; }
129 void OnMenuEvent(wxCommandEvent
& event
)
131 m_frame
->LogMenuEvent(event
);
139 DECLARE_EVENT_TABLE()
142 // ----------------------------------------------------------------------------
144 // ----------------------------------------------------------------------------
148 Menu_File_Quit
= 100,
151 Menu_MenuBar_Toggle
= 200,
156 Menu_MenuBar_GetLabel
,
157 Menu_MenuBar_SetLabel
,
159 Menu_Menu_Append
= 300,
169 Menu_Dummy_First
= 400,
175 Menu_Help_About
= 1000,
177 Menu_Popup_ToBeDeleted
= 2000,
178 Menu_Popup_ToBeGreyed
,
179 Menu_Popup_ToBeChecked
,
185 // ----------------------------------------------------------------------------
187 // ----------------------------------------------------------------------------
189 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
190 EVT_MENU(Menu_File_Quit
, MyFrame::OnQuit
)
191 EVT_MENU(Menu_File_ClearLog
, MyFrame::OnClearLog
)
193 EVT_MENU(Menu_Help_About
, MyFrame::OnAbout
)
195 EVT_MENU(Menu_MenuBar_Toggle
, MyFrame::OnToggleMenu
)
196 EVT_MENU(Menu_MenuBar_Append
, MyFrame::OnAppendMenu
)
197 EVT_MENU(Menu_MenuBar_Insert
, MyFrame::OnInsertMenu
)
198 EVT_MENU(Menu_MenuBar_Delete
, MyFrame::OnDeleteMenu
)
199 EVT_MENU(Menu_MenuBar_Enable
, MyFrame::OnEnableMenu
)
200 EVT_MENU(Menu_MenuBar_GetLabel
, MyFrame::OnGetLabelMenu
)
201 EVT_MENU(Menu_MenuBar_SetLabel
, MyFrame::OnSetLabelMenu
)
203 EVT_MENU(Menu_Menu_Append
, MyFrame::OnAppendMenuItem
)
204 EVT_MENU(Menu_Menu_AppendSub
, MyFrame::OnAppendSubMenu
)
205 EVT_MENU(Menu_Menu_Insert
, MyFrame::OnInsertMenuItem
)
206 EVT_MENU(Menu_Menu_Delete
, MyFrame::OnDeleteMenuItem
)
207 EVT_MENU(Menu_Menu_Enable
, MyFrame::OnEnableMenuItem
)
208 EVT_MENU(Menu_Menu_Check
, MyFrame::OnCheckMenuItem
)
209 EVT_MENU(Menu_Menu_GetLabel
, MyFrame::OnGetLabelMenuItem
)
210 EVT_MENU(Menu_Menu_SetLabel
, MyFrame::OnSetLabelMenuItem
)
211 EVT_MENU(Menu_Menu_GetInfo
, MyFrame::OnGetMenuItemInfo
)
213 EVT_MENU_RANGE(Menu_Dummy_First
, Menu_Dummy_Last
, MyFrame::OnDummy
)
215 EVT_UPDATE_UI(Menu_Menu_Check
, MyFrame::OnUpdateCheckMenuItemUI
)
217 EVT_RIGHT_UP(MyFrame::OnRightUp
)
219 EVT_SIZE(MyFrame::OnSize
)
222 BEGIN_EVENT_TABLE(MyEvtHandler
, wxEvtHandler
)
223 EVT_MENU(-1, MyEvtHandler::OnMenuEvent
)
226 // ============================================================================
228 // ============================================================================
230 // ----------------------------------------------------------------------------
232 // ----------------------------------------------------------------------------
236 // The `main program' equivalent, creating the windows and returning the
240 // Create the main frame window
241 MyFrame
* frame
= new MyFrame
;
246 frame
->SetStatusText("Welcome to wxWindows menu sample");
247 #endif // wxUSE_STATUSBAR
254 // ----------------------------------------------------------------------------
256 // ----------------------------------------------------------------------------
258 // Define my frame constructor
260 : wxFrame((wxFrame
*)NULL
, -1, "wxWindows menu sample",
261 wxDefaultPosition
, wxSize(300, 200))
269 #endif // wxUSE_STATUSBAR
271 // create the menubar
272 wxMenu
*fileMenu
= new wxMenu
;
274 wxMenuItem
*item
= new wxMenuItem(fileMenu
, Menu_File_ClearLog
,
275 "Clear &log\tCtrl-L");
276 item
->SetBitmap(copy_xpm
);
277 fileMenu
->Append(item
);
278 fileMenu
->AppendSeparator();
279 fileMenu
->Append(Menu_File_Quit
, "E&xit\tAlt-X", "Quit menu sample");
281 wxMenu
*menubarMenu
= new wxMenu
;
282 menubarMenu
->Append(Menu_MenuBar_Append
, "&Append menu\tCtrl-A",
283 "Append a menu to the menubar");
284 menubarMenu
->Append(Menu_MenuBar_Insert
, "&Insert menu\tCtrl-I",
285 "Insert a menu into the menubar");
286 menubarMenu
->Append(Menu_MenuBar_Delete
, "&Delete menu\tCtrl-D",
287 "Delete the last menu from the menubar");
288 menubarMenu
->Append(Menu_MenuBar_Toggle
, "&Toggle menu\tCtrl-T",
289 "Toggle the first menu in the menubar", TRUE
);
290 menubarMenu
->AppendSeparator();
291 menubarMenu
->Append(Menu_MenuBar_Enable
, "&Enable menu\tCtrl-E",
292 "Enable or disable the last menu", TRUE
);
293 menubarMenu
->AppendSeparator();
294 menubarMenu
->Append(Menu_MenuBar_GetLabel
, "&Get menu label\tCtrl-G",
295 "Get the label of the last menu");
296 menubarMenu
->Append(Menu_MenuBar_SetLabel
, "&Set menu label\tCtrl-S",
297 "Change the label of the last menu");
299 wxMenu
*menuMenu
= new wxMenu
;
300 menuMenu
->Append(Menu_Menu_Append
, "&Append menu item\tAlt-A",
301 "Append a menu item to the last menu");
302 menuMenu
->Append(Menu_Menu_AppendSub
, "&Append sub menu\tAlt-S",
303 "Append a sub menu to the last menu");
304 menuMenu
->Append(Menu_Menu_Insert
, "&Insert menu item\tAlt-I",
305 "Insert a menu item in head of the last menu");
306 menuMenu
->Append(Menu_Menu_Delete
, "&Delete menu item\tAlt-D",
307 "Delete the last menu item from the last menu");
308 menuMenu
->AppendSeparator();
309 menuMenu
->Append(Menu_Menu_Enable
, "&Enable menu item\tAlt-E",
310 "Enable or disable the last menu item", TRUE
);
311 menuMenu
->Append(Menu_Menu_Check
, "&Check menu item\tAlt-C",
312 "Check or uncheck the last menu item", TRUE
);
313 menuMenu
->AppendSeparator();
314 menuMenu
->Append(Menu_Menu_GetLabel
, "&Get menu item label\tAlt-G",
315 "Get the label of the last menu item");
316 menuMenu
->Append(Menu_Menu_SetLabel
, "&Set menu item label\tAlt-S",
317 "Change the label of the last menu item");
318 menuMenu
->AppendSeparator();
319 menuMenu
->Append(Menu_Menu_GetInfo
, "Get menu item in&fo\tAlt-F",
320 "Show the state of the last menu item");
322 wxMenu
*helpMenu
= new wxMenu
;
323 helpMenu
->Append(Menu_Help_About
, "&About\tF1", "About menu sample");
325 wxMenuBar
* menuBar
= new wxMenuBar( wxMB_DOCKABLE
);
327 menuBar
->Append(fileMenu
, "&File");
328 menuBar
->Append(menubarMenu
, "Menu&bar");
329 menuBar
->Append(menuMenu
, "&Menu");
330 menuBar
->Append(helpMenu
, "&Help");
332 // these items should be initially checked
333 menuBar
->Check(Menu_MenuBar_Toggle
, TRUE
);
334 menuBar
->Check(Menu_MenuBar_Enable
, TRUE
);
335 menuBar
->Check(Menu_Menu_Enable
, TRUE
);
336 menuBar
->Check(Menu_Menu_Check
, FALSE
);
338 // associate the menu bar with the frame
341 // intercept all menu events and log them in this custom event handler
342 PushEventHandler(new MyEvtHandler(this));
344 // create the log text window
345 m_textctrl
= new wxTextCtrl(this, -1, _T(""),
346 wxDefaultPosition
, wxDefaultSize
,
348 m_textctrl
->SetEditable(FALSE
);
349 m_logOld
= wxLog::SetActiveTarget(new wxLogTextCtrl(m_textctrl
));
351 wxLogMessage(_T("Brief explanations: the commands or the \"Menu\" menu\n")
352 _T("append/insert/delete items to/from the last menu.\n")
353 _T("The commands from \"Menubar\" menu work with the\n")
354 _T("menubar itself.\n")
355 _T("Right click the band below to test popup menus.\n"));
362 // delete the event handler installed in ctor
363 PopEventHandler(TRUE
);
365 // restore old logger
366 delete wxLog::SetActiveTarget(m_logOld
);
369 wxMenu
*MyFrame::CreateDummyMenu(wxString
*title
)
371 wxMenu
*menu
= new wxMenu
;
372 menu
->Append(Menu_Dummy_First
, "&First item\tCtrl-F1");
373 menu
->AppendSeparator();
374 menu
->Append(Menu_Dummy_Second
, "&Second item\tCtrl-F2", "", TRUE
);
378 title
->Printf("Dummy menu &%d", ++m_countDummy
);
384 wxMenuItem
*MyFrame::GetLastMenuItem() const
386 wxMenuBar
*menubar
= GetMenuBar();
387 wxMenu
*menu
= menubar
->GetMenu(menubar
->GetMenuCount() - 1);
389 wxMenuItemList::Node
*node
= menu
->GetMenuItems().GetLast();
392 wxLogWarning("No last item in the last menu!");
398 return node
->GetData();
402 void MyFrame::LogMenuEvent(const wxCommandEvent
& event
)
404 int id
= event
.GetId();
405 if ( !GetMenuBar()->FindItem(id
) )
408 wxString msg
= wxString::Format("Menu command %d", id
);
409 if ( GetMenuBar()->FindItem(id
)->IsCheckable() )
411 msg
+= wxString::Format(" (the item is currently %schecked)",
412 event
.IsChecked() ? "" : "not ");
418 // ----------------------------------------------------------------------------
420 // ----------------------------------------------------------------------------
422 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
427 void MyFrame::OnClearLog(wxCommandEvent
& WXUNUSED(event
))
432 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
434 #ifdef __WXUNIVERSAL__
435 // wxMessageBox not implemented yet
436 wxLogMessage("wxWindows menu sample\n© 1999-2001 Vadim Zeitlin");
438 (void)wxMessageBox("wxWindows menu sample\n© 1999-2001 Vadim Zeitlin",
439 "About wxWindows menu sample",
444 void MyFrame::OnDeleteMenu(wxCommandEvent
& WXUNUSED(event
))
446 wxMenuBar
*mbar
= GetMenuBar();
448 size_t count
= mbar
->GetMenuCount();
451 // don't let delete the first 2 menus
452 wxLogError("Can't delete any more menus");
456 delete mbar
->Remove(count
- 1);
460 void MyFrame::OnInsertMenu(wxCommandEvent
& WXUNUSED(event
))
463 wxMenu
*menu
= CreateDummyMenu(&title
);
464 GetMenuBar()->Insert(0, menu
, title
);
467 void MyFrame::OnAppendMenu(wxCommandEvent
& WXUNUSED(event
))
470 wxMenu
*menu
= CreateDummyMenu(&title
);
471 GetMenuBar()->Append(menu
, title
);
474 void MyFrame::OnToggleMenu(wxCommandEvent
& WXUNUSED(event
))
476 wxMenuBar
*mbar
= GetMenuBar();
480 m_menu
= mbar
->Remove(0);
485 mbar
->Insert(0, m_menu
, "&File");
490 void MyFrame::OnEnableMenu(wxCommandEvent
& event
)
492 wxMenuBar
*mbar
= GetMenuBar();
493 size_t count
= mbar
->GetMenuCount();
495 mbar
->EnableTop(count
- 1, event
.IsChecked());
498 void MyFrame::OnGetLabelMenu(wxCommandEvent
& WXUNUSED(event
))
500 wxMenuBar
*mbar
= GetMenuBar();
501 size_t count
= mbar
->GetMenuCount();
503 wxLogMessage("The label of the last menu item is '%s'",
504 mbar
->GetLabelTop(count
- 1).c_str());
507 void MyFrame::OnSetLabelMenu(wxCommandEvent
& WXUNUSED(event
))
509 wxMenuBar
*mbar
= GetMenuBar();
510 size_t count
= mbar
->GetMenuCount();
512 mbar
->SetLabelTop(count
- 1, "Dummy label &0");
515 void MyFrame::OnDummy(wxCommandEvent
& event
)
517 wxLogMessage("Dummy item #%d", event
.GetId() - Menu_Dummy_First
+ 1);
520 void MyFrame::OnAppendMenuItem(wxCommandEvent
& WXUNUSED(event
))
522 wxMenuBar
*menubar
= GetMenuBar();
523 wxMenu
*menu
= menubar
->GetMenu(menubar
->GetMenuCount() - 1);
525 menu
->AppendSeparator();
526 menu
->Append(Menu_Dummy_Third
, "&Third dummy item\tCtrl-F3",
527 "Checkable item", TRUE
);
530 void MyFrame::OnAppendSubMenu(wxCommandEvent
& WXUNUSED(event
))
532 wxMenuBar
*menubar
= GetMenuBar();
534 wxMenu
*menu
= menubar
->GetMenu(menubar
->GetMenuCount() - 1);
536 menu
->Append(Menu_Dummy_Last
, "&Dummy sub menu",
537 CreateDummyMenu(NULL
), "Dummy sub menu help");
540 void MyFrame::OnDeleteMenuItem(wxCommandEvent
& WXUNUSED(event
))
542 wxMenuBar
*menubar
= GetMenuBar();
543 wxMenu
*menu
= menubar
->GetMenu(menubar
->GetMenuCount() - 1);
545 size_t count
= menu
->GetMenuItemCount();
548 wxLogWarning("No items to delete!");
552 menu
->Destroy(menu
->GetMenuItems().Item(count
- 1)->GetData());
556 void MyFrame::OnInsertMenuItem(wxCommandEvent
& WXUNUSED(event
))
558 wxMenuBar
*menubar
= GetMenuBar();
559 wxMenu
*menu
= menubar
->GetMenu(menubar
->GetMenuCount() - 1);
561 menu
->Insert(0, wxMenuItem::New(menu
, Menu_Dummy_Fourth
,
562 "Fourth dummy item\tCtrl-F4"));
563 menu
->Insert(1, wxMenuItem::New(menu
, wxID_SEPARATOR
, ""));
566 void MyFrame::OnEnableMenuItem(wxCommandEvent
& WXUNUSED(event
))
568 wxMenuItem
*item
= GetLastMenuItem();
572 item
->Enable(!item
->IsEnabled());
576 void MyFrame::OnCheckMenuItem(wxCommandEvent
& WXUNUSED(event
))
578 wxMenuItem
*item
= GetLastMenuItem();
583 void MyFrame::OnUpdateCheckMenuItemUI(wxUpdateUIEvent
& event
)
587 wxMenuItem
*item
= GetLastMenuItem();
589 event
.Enable(item
&& item
->IsCheckable());
592 void MyFrame::OnGetLabelMenuItem(wxCommandEvent
& WXUNUSED(event
))
594 wxMenuItem
*item
= GetLastMenuItem();
598 wxLogMessage("The label of the last menu item is '%s'",
599 item
->GetLabel().c_str());
603 void MyFrame::OnSetLabelMenuItem(wxCommandEvent
& WXUNUSED(event
))
605 wxMenuItem
*item
= GetLastMenuItem();
609 item
->SetText("Dummy menu item text");
613 void MyFrame::OnGetMenuItemInfo(wxCommandEvent
& WXUNUSED(event
))
615 wxMenuItem
*item
= GetLastMenuItem();
620 msg
<< "The item is " << (item
->IsEnabled() ? "enabled"
624 if ( item
->IsCheckable() )
626 msg
<< "It is checkable and " << (item
->IsChecked() ? "" : "un")
631 wxAcceleratorEntry
*accel
= item
->GetAccel();
634 msg
<< "Its accelerator is ";
636 int flags
= accel
->GetFlags();
637 if ( flags
& wxACCEL_ALT
)
639 if ( flags
& wxACCEL_CTRL
)
641 if ( flags
& wxACCEL_SHIFT
)
642 msg
<< wxT("Shift-");
644 int code
= accel
->GetKeyCode();
659 msg
<< wxT('F') << code
- WXK_F1
+ 1;
662 // if there are any other keys wxGetAccelFromString() may return,
663 // we should process them here
666 if ( wxIsalnum(code
) )
673 wxFAIL_MSG( wxT("unknown keyboard accel") );
680 msg
<< "It doesn't have an accelerator";
682 #endif // wxUSE_ACCEL
688 void MyFrame::OnRightUp(wxMouseEvent
&event
)
690 wxMenu
menu("Test popup");
692 menu
.Append(Menu_Help_About
, "&About");
693 menu
.Append(Menu_Popup_Submenu
, "&Submenu", CreateDummyMenu(NULL
));
694 menu
.Append(Menu_Popup_ToBeDeleted
, "To be &deleted");
695 menu
.Append(Menu_Popup_ToBeChecked
, "To be &checked", "", TRUE
);
696 menu
.Append(Menu_Popup_ToBeGreyed
, "To be &greyed");
697 menu
.AppendSeparator();
698 menu
.Append(Menu_File_Quit
, "E&xit");
700 menu
.Delete(Menu_Popup_ToBeDeleted
);
701 menu
.Check(Menu_Popup_ToBeChecked
, TRUE
);
702 menu
.Enable(Menu_Popup_ToBeGreyed
, FALSE
);
704 PopupMenu(&menu
, event
.GetX(), event
.GetY());
706 // test for destroying items in popup menus
707 #if 0 // doesn't work in wxGTK!
708 menu
.Destroy(Menu_Popup_Submenu
);
710 PopupMenu( &menu
, event
.GetX(), event
.GetY() );
714 void MyFrame::OnSize(wxSizeEvent
& event
)
716 // leave a band below for popup menu testing
717 wxSize size
= GetClientSize();
718 m_textctrl
->SetSize(0, 0, size
.x
, (3*size
.y
)/4);
720 // this is really ugly but we have to do it as we can't just call
721 // event.Skip() because wxFrameBase would make the text control fill the
723 #ifdef __WXUNIVERSAL__
725 #endif // __WXUNIVERSAL__