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