]> git.saurik.com Git - wxWidgets.git/blame - samples/menu/menu.cpp
don't try to remove -g flag from CFLAGS, it is not necessary and doesn't work correct...
[wxWidgets.git] / samples / menu / menu.cpp
CommitLineData
717a57c2
VZ
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".
92a19c2e 21#include "wx/wxprec.h"
717a57c2
VZ
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#ifndef WX_PRECOMP
f91bf72f
GD
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"
5c7766de 34 #include "wx/textdlg.h"
717a57c2
VZ
35#endif
36
6d5b2a57
VZ
37#if !wxUSE_MENUS
38 // nice try...
39 #error "menu sample requires wxUSE_MENUS=1"
40#endif // wxUSE_MENUS
41
fcaf9e70
RR
42#include "copy.xpm"
43
717a57c2
VZ
44// ----------------------------------------------------------------------------
45// classes
46// ----------------------------------------------------------------------------
47
48// Define a new application
49class MyApp: public wxApp
50{
51public:
52 bool OnInit();
53};
54
55// Define a new frame
56class MyFrame: public wxFrame
57{
58public:
59 MyFrame();
60
3ca6a5f0
BP
61 virtual ~MyFrame();
62
63 void LogMenuEvent(const wxCommandEvent& event);
717a57c2 64
e421922f 65protected:
717a57c2 66 void OnQuit(wxCommandEvent& event);
e421922f
VZ
67 void OnClearLog(wxCommandEvent& event);
68
717a57c2
VZ
69 void OnAbout(wxCommandEvent& event);
70
71 void OnDummy(wxCommandEvent& event);
72
73 void OnAppendMenuItem(wxCommandEvent& event);
74 void OnAppendSubMenu(wxCommandEvent& event);
75 void OnDeleteMenuItem(wxCommandEvent& event);
76 void OnInsertMenuItem(wxCommandEvent& event);
77 void OnCheckMenuItem(wxCommandEvent& event);
78 void OnEnableMenuItem(wxCommandEvent& event);
79 void OnGetLabelMenuItem(wxCommandEvent& event);
80 void OnSetLabelMenuItem(wxCommandEvent& event);
a80c322c 81 void OnGetMenuItemInfo(wxCommandEvent& event);
717a57c2
VZ
82
83 void OnAppendMenu(wxCommandEvent& event);
f03ec224 84 void OnInsertMenu(wxCommandEvent& event);
717a57c2
VZ
85 void OnDeleteMenu(wxCommandEvent& event);
86 void OnToggleMenu(wxCommandEvent& event);
87 void OnEnableMenu(wxCommandEvent& event);
88 void OnGetLabelMenu(wxCommandEvent& event);
89 void OnSetLabelMenu(wxCommandEvent& event);
90
d65c269b
VZ
91 void OnTestNormal(wxCommandEvent& event);
92 void OnTestCheck(wxCommandEvent& event);
93 void OnTestRadio(wxCommandEvent& event);
94
ccef86c7
VZ
95#ifdef __WXMSW__
96 void OnContextMenu(wxContextMenuEvent& event)
97 { ShowContextMenu(ScreenToClient(event.GetPosition())); }
98#else
99 void OnRightUp(wxMouseEvent& event)
100 { ShowContextMenu(event.GetPosition()); }
101#endif
102
103 void OnMenuOpen(wxMenuEvent& event)
104 { LogMenuOpenOrClose(event, _T("opened")); }
105 void OnMenuClose(wxMenuEvent& event)
106 { LogMenuOpenOrClose(event, _T("closed")); }
717a57c2
VZ
107
108 void OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event);
109
e421922f
VZ
110 void OnSize(wxSizeEvent& event);
111
717a57c2 112private:
ccef86c7
VZ
113 void LogMenuOpenOrClose(const wxMenuEvent& event, const wxChar *what);
114 void ShowContextMenu(const wxPoint& pos);
115
f03ec224 116 wxMenu *CreateDummyMenu(wxString *title);
717a57c2
VZ
117
118 wxMenuItem *GetLastMenuItem() const;
119
e421922f
VZ
120 // the menu previously detached from the menubar (may be NULL)
121 wxMenu *m_menu;
717a57c2 122
e421922f 123 // the count of dummy menus already created
f03ec224
VZ
124 size_t m_countDummy;
125
e421922f
VZ
126 // the control used for logging
127 wxTextCtrl *m_textctrl;
128
129 // the previous log target
130 wxLog *m_logOld;
131
717a57c2
VZ
132 DECLARE_EVENT_TABLE()
133};
134
3ca6a5f0
BP
135// A small helper class which intercepts all menu events and logs them
136class MyEvtHandler : public wxEvtHandler
137{
138public:
139 MyEvtHandler(MyFrame *frame) { m_frame = frame; }
140
141 void OnMenuEvent(wxCommandEvent& event)
142 {
143 m_frame->LogMenuEvent(event);
144
145 event.Skip();
146 }
147
148private:
149 MyFrame *m_frame;
150
151 DECLARE_EVENT_TABLE()
152};
153
717a57c2
VZ
154// ----------------------------------------------------------------------------
155// constants
156// ----------------------------------------------------------------------------
157
158enum
159{
160 Menu_File_Quit = 100,
e421922f 161 Menu_File_ClearLog,
717a57c2
VZ
162
163 Menu_MenuBar_Toggle = 200,
164 Menu_MenuBar_Append,
f03ec224 165 Menu_MenuBar_Insert,
717a57c2
VZ
166 Menu_MenuBar_Delete,
167 Menu_MenuBar_Enable,
168 Menu_MenuBar_GetLabel,
169 Menu_MenuBar_SetLabel,
170
171 Menu_Menu_Append = 300,
172 Menu_Menu_AppendSub,
173 Menu_Menu_Insert,
174 Menu_Menu_Delete,
175 Menu_Menu_Enable,
176 Menu_Menu_Check,
177 Menu_Menu_GetLabel,
178 Menu_Menu_SetLabel,
a80c322c 179 Menu_Menu_GetInfo,
717a57c2 180
d65c269b
VZ
181 Menu_Test_Normal = 400,
182 Menu_Test_Check,
183 Menu_Test_Radio1,
184 Menu_Test_Radio2,
185 Menu_Test_Radio3,
186
187 Menu_Dummy_First = 500,
717a57c2
VZ
188 Menu_Dummy_Second,
189 Menu_Dummy_Third,
190 Menu_Dummy_Fourth,
191 Menu_Dummy_Last,
192
193 Menu_Help_About = 1000,
194
195 Menu_Popup_ToBeDeleted = 2000,
196 Menu_Popup_ToBeGreyed,
197 Menu_Popup_ToBeChecked,
198 Menu_Popup_Submenu,
199
200 Menu_Max
201};
202
203// ----------------------------------------------------------------------------
204// event tables
205// ----------------------------------------------------------------------------
206
207BEGIN_EVENT_TABLE(MyFrame, wxFrame)
e421922f
VZ
208 EVT_MENU(Menu_File_Quit, MyFrame::OnQuit)
209 EVT_MENU(Menu_File_ClearLog, MyFrame::OnClearLog)
717a57c2
VZ
210
211 EVT_MENU(Menu_Help_About, MyFrame::OnAbout)
212
213 EVT_MENU(Menu_MenuBar_Toggle, MyFrame::OnToggleMenu)
214 EVT_MENU(Menu_MenuBar_Append, MyFrame::OnAppendMenu)
f03ec224 215 EVT_MENU(Menu_MenuBar_Insert, MyFrame::OnInsertMenu)
717a57c2
VZ
216 EVT_MENU(Menu_MenuBar_Delete, MyFrame::OnDeleteMenu)
217 EVT_MENU(Menu_MenuBar_Enable, MyFrame::OnEnableMenu)
218 EVT_MENU(Menu_MenuBar_GetLabel, MyFrame::OnGetLabelMenu)
219 EVT_MENU(Menu_MenuBar_SetLabel, MyFrame::OnSetLabelMenu)
220
221 EVT_MENU(Menu_Menu_Append, MyFrame::OnAppendMenuItem)
222 EVT_MENU(Menu_Menu_AppendSub, MyFrame::OnAppendSubMenu)
223 EVT_MENU(Menu_Menu_Insert, MyFrame::OnInsertMenuItem)
224 EVT_MENU(Menu_Menu_Delete, MyFrame::OnDeleteMenuItem)
225 EVT_MENU(Menu_Menu_Enable, MyFrame::OnEnableMenuItem)
a80c322c 226 EVT_MENU(Menu_Menu_Check, MyFrame::OnCheckMenuItem)
717a57c2
VZ
227 EVT_MENU(Menu_Menu_GetLabel, MyFrame::OnGetLabelMenuItem)
228 EVT_MENU(Menu_Menu_SetLabel, MyFrame::OnSetLabelMenuItem)
a80c322c 229 EVT_MENU(Menu_Menu_GetInfo, MyFrame::OnGetMenuItemInfo)
717a57c2 230
d65c269b
VZ
231 EVT_MENU(Menu_Test_Normal, MyFrame::OnTestNormal)
232 EVT_MENU(Menu_Test_Check, MyFrame::OnTestCheck)
233 EVT_MENU(Menu_Test_Radio1, MyFrame::OnTestRadio)
234 EVT_MENU(Menu_Test_Radio2, MyFrame::OnTestRadio)
235 EVT_MENU(Menu_Test_Radio3, MyFrame::OnTestRadio)
236
717a57c2
VZ
237 EVT_MENU_RANGE(Menu_Dummy_First, Menu_Dummy_Last, MyFrame::OnDummy)
238
239 EVT_UPDATE_UI(Menu_Menu_Check, MyFrame::OnUpdateCheckMenuItemUI)
240
ccef86c7
VZ
241#ifdef __WXMSW__
242 EVT_CONTEXT_MENU(MyFrame::OnContextMenu)
243#else
e421922f 244 EVT_RIGHT_UP(MyFrame::OnRightUp)
ccef86c7
VZ
245#endif
246
247 EVT_MENU_OPEN(MyFrame::OnMenuOpen)
248 EVT_MENU_CLOSE(MyFrame::OnMenuClose)
e421922f
VZ
249
250 EVT_SIZE(MyFrame::OnSize)
717a57c2
VZ
251END_EVENT_TABLE()
252
3ca6a5f0
BP
253BEGIN_EVENT_TABLE(MyEvtHandler, wxEvtHandler)
254 EVT_MENU(-1, MyEvtHandler::OnMenuEvent)
255END_EVENT_TABLE()
256
717a57c2
VZ
257// ============================================================================
258// implementation
259// ============================================================================
260
261// ----------------------------------------------------------------------------
262// MyApp
263// ----------------------------------------------------------------------------
264
265IMPLEMENT_APP(MyApp)
266
267// The `main program' equivalent, creating the windows and returning the
268// main frame
269bool MyApp::OnInit()
270{
271 // Create the main frame window
272 MyFrame* frame = new MyFrame;
273
274 frame->Show(TRUE);
275
6d5b2a57 276#if wxUSE_STATUSBAR
e421922f 277 frame->SetStatusText("Welcome to wxWindows menu sample");
6d5b2a57 278#endif // wxUSE_STATUSBAR
717a57c2
VZ
279
280 SetTopWindow(frame);
281
282 return TRUE;
283}
284
285// ----------------------------------------------------------------------------
286// MyFrame
287// ----------------------------------------------------------------------------
288
289// Define my frame constructor
290MyFrame::MyFrame()
291 : wxFrame((wxFrame *)NULL, -1, "wxWindows menu sample",
5c7766de 292 wxDefaultPosition, wxSize(400, 250))
717a57c2 293{
268766dd 294 m_textctrl = NULL;
717a57c2 295 m_menu = NULL;
f03ec224 296 m_countDummy = 0;
e421922f 297 m_logOld = NULL;
717a57c2 298
6d5b2a57 299#if wxUSE_STATUSBAR
e421922f 300 CreateStatusBar();
6d5b2a57 301#endif // wxUSE_STATUSBAR
717a57c2
VZ
302
303 // create the menubar
304 wxMenu *fileMenu = new wxMenu;
6d5b2a57 305
e421922f
VZ
306 wxMenuItem *item = new wxMenuItem(fileMenu, Menu_File_ClearLog,
307 "Clear &log\tCtrl-L");
308 item->SetBitmap(copy_xpm);
309 fileMenu->Append(item);
310 fileMenu->AppendSeparator();
311 fileMenu->Append(Menu_File_Quit, "E&xit\tAlt-X", "Quit menu sample");
717a57c2
VZ
312
313 wxMenu *menubarMenu = new wxMenu;
314 menubarMenu->Append(Menu_MenuBar_Append, "&Append menu\tCtrl-A",
315 "Append a menu to the menubar");
f03ec224
VZ
316 menubarMenu->Append(Menu_MenuBar_Insert, "&Insert menu\tCtrl-I",
317 "Insert a menu into the menubar");
717a57c2
VZ
318 menubarMenu->Append(Menu_MenuBar_Delete, "&Delete menu\tCtrl-D",
319 "Delete the last menu from the menubar");
320 menubarMenu->Append(Menu_MenuBar_Toggle, "&Toggle menu\tCtrl-T",
321 "Toggle the first menu in the menubar", TRUE);
322 menubarMenu->AppendSeparator();
323 menubarMenu->Append(Menu_MenuBar_Enable, "&Enable menu\tCtrl-E",
324 "Enable or disable the last menu", TRUE);
325 menubarMenu->AppendSeparator();
326 menubarMenu->Append(Menu_MenuBar_GetLabel, "&Get menu label\tCtrl-G",
327 "Get the label of the last menu");
328 menubarMenu->Append(Menu_MenuBar_SetLabel, "&Set menu label\tCtrl-S",
329 "Change the label of the last menu");
330
331 wxMenu *menuMenu = new wxMenu;
332 menuMenu->Append(Menu_Menu_Append, "&Append menu item\tAlt-A",
333 "Append a menu item to the last menu");
334 menuMenu->Append(Menu_Menu_AppendSub, "&Append sub menu\tAlt-S",
335 "Append a sub menu to the last menu");
336 menuMenu->Append(Menu_Menu_Insert, "&Insert menu item\tAlt-I",
337 "Insert a menu item in head of the last menu");
338 menuMenu->Append(Menu_Menu_Delete, "&Delete menu item\tAlt-D",
339 "Delete the last menu item from the last menu");
340 menuMenu->AppendSeparator();
341 menuMenu->Append(Menu_Menu_Enable, "&Enable menu item\tAlt-E",
342 "Enable or disable the last menu item", TRUE);
343 menuMenu->Append(Menu_Menu_Check, "&Check menu item\tAlt-C",
344 "Check or uncheck the last menu item", TRUE);
345 menuMenu->AppendSeparator();
346 menuMenu->Append(Menu_Menu_GetLabel, "&Get menu item label\tAlt-G",
347 "Get the label of the last menu item");
348 menuMenu->Append(Menu_Menu_SetLabel, "&Set menu item label\tAlt-S",
349 "Change the label of the last menu item");
a80c322c
VZ
350 menuMenu->AppendSeparator();
351 menuMenu->Append(Menu_Menu_GetInfo, "Get menu item in&fo\tAlt-F",
352 "Show the state of the last menu item");
717a57c2 353
d65c269b
VZ
354 wxMenu *testMenu = new wxMenu;
355 testMenu->Append(Menu_Test_Normal, "&Normal item");
356 testMenu->AppendSeparator();
357 testMenu->AppendCheckItem(Menu_Test_Check, "&Check item");
358 testMenu->AppendSeparator();
359 testMenu->AppendRadioItem(Menu_Test_Radio1, "Radio item &1");
360 testMenu->AppendRadioItem(Menu_Test_Radio2, "Radio item &2");
361 testMenu->AppendRadioItem(Menu_Test_Radio3, "Radio item &3");
362
717a57c2
VZ
363 wxMenu *helpMenu = new wxMenu;
364 helpMenu->Append(Menu_Help_About, "&About\tF1", "About menu sample");
365
366 wxMenuBar* menuBar = new wxMenuBar( wxMB_DOCKABLE );
367
368 menuBar->Append(fileMenu, "&File");
369 menuBar->Append(menubarMenu, "Menu&bar");
370 menuBar->Append(menuMenu, "&Menu");
d65c269b 371 menuBar->Append(testMenu, "&Test");
717a57c2
VZ
372 menuBar->Append(helpMenu, "&Help");
373
374 // these items should be initially checked
375 menuBar->Check(Menu_MenuBar_Toggle, TRUE);
376 menuBar->Check(Menu_MenuBar_Enable, TRUE);
377 menuBar->Check(Menu_Menu_Enable, TRUE);
378 menuBar->Check(Menu_Menu_Check, FALSE);
379
380 // associate the menu bar with the frame
381 SetMenuBar(menuBar);
3ca6a5f0
BP
382
383 // intercept all menu events and log them in this custom event handler
384 PushEventHandler(new MyEvtHandler(this));
e421922f
VZ
385
386 // create the log text window
387 m_textctrl = new wxTextCtrl(this, -1, _T(""),
388 wxDefaultPosition, wxDefaultSize,
389 wxTE_MULTILINE);
390 m_textctrl->SetEditable(FALSE);
5c7766de
VZ
391
392 wxLog::SetTimestamp(NULL);
e421922f
VZ
393 m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_textctrl));
394
5c7766de 395 wxLogMessage(_T("Brief explanations: the commands or the \"Menu\" menu ")
e421922f 396 _T("append/insert/delete items to/from the last menu.\n")
5c7766de
VZ
397 _T("The commands from \"Menubar\" menu work with the ")
398 _T("menubar itself.\n\n")
e421922f 399 _T("Right click the band below to test popup menus.\n"));
3ca6a5f0
BP
400}
401
402MyFrame::~MyFrame()
403{
404 delete m_menu;
405
406 // delete the event handler installed in ctor
407 PopEventHandler(TRUE);
e421922f
VZ
408
409 // restore old logger
410 delete wxLog::SetActiveTarget(m_logOld);
717a57c2
VZ
411}
412
f03ec224 413wxMenu *MyFrame::CreateDummyMenu(wxString *title)
717a57c2
VZ
414{
415 wxMenu *menu = new wxMenu;
e421922f 416 menu->Append(Menu_Dummy_First, "&First item\tCtrl-F1");
717a57c2 417 menu->AppendSeparator();
e421922f 418 menu->Append(Menu_Dummy_Second, "&Second item\tCtrl-F2", "", TRUE);
717a57c2 419
f03ec224
VZ
420 if ( title )
421 {
4693b20c 422 title->Printf(wxT("Dummy menu &%d"), ++m_countDummy);
f03ec224
VZ
423 }
424
717a57c2
VZ
425 return menu;
426}
427
428wxMenuItem *MyFrame::GetLastMenuItem() const
429{
430 wxMenuBar *menubar = GetMenuBar();
431 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
432
433 wxMenuItemList::Node *node = menu->GetMenuItems().GetLast();
434 if ( !node )
435 {
4693b20c 436 wxLogWarning(wxT("No last item in the last menu!"));
717a57c2
VZ
437
438 return NULL;
439 }
440 else
441 {
442 return node->GetData();
443 }
444}
445
3ca6a5f0
BP
446void MyFrame::LogMenuEvent(const wxCommandEvent& event)
447{
448 int id = event.GetId();
e421922f 449 if ( !GetMenuBar()->FindItem(id) )
d3d69314 450 return;
e421922f 451
4693b20c 452 wxString msg = wxString::Format(wxT("Menu command %d"), id);
3ca6a5f0
BP
453 if ( GetMenuBar()->FindItem(id)->IsCheckable() )
454 {
4693b20c 455 msg += wxString::Format(wxT(" (the item is currently %schecked)"),
3ca6a5f0
BP
456 event.IsChecked() ? "" : "not ");
457 }
458
e421922f 459 wxLogMessage(msg);
3ca6a5f0
BP
460}
461
462// ----------------------------------------------------------------------------
463// menu callbacks
464// ----------------------------------------------------------------------------
465
717a57c2
VZ
466void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
467{
468 Close(TRUE);
469}
470
e421922f
VZ
471void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
472{
473 m_textctrl->Clear();
474}
475
717a57c2
VZ
476void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
477{
e421922f 478