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