]> git.saurik.com Git - wxWidgets.git/blame_incremental - samples/menu/menu.cpp
fixed bug with the caret positioning after SetValue() introduced by the last commit
[wxWidgets.git] / samples / menu / menu.cpp
... / ...
CommitLineData
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/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"
34#endif
35
36#if !wxUSE_MENUS
37 // nice try...
38 #error "menu sample requires wxUSE_MENUS=1"
39#endif // wxUSE_MENUS
40
41#include "copy.xpm"
42
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
60 virtual ~MyFrame();
61
62 void LogMenuEvent(const wxCommandEvent& event);
63
64protected:
65 void OnQuit(wxCommandEvent& event);
66 void OnClearLog(wxCommandEvent& event);
67
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);
80 void OnGetMenuItemInfo(wxCommandEvent& event);
81
82 void OnAppendMenu(wxCommandEvent& event);
83 void OnInsertMenu(wxCommandEvent& event);
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
90 void OnRightUp(wxMouseEvent& event);
91
92 void OnUpdateCheckMenuItemUI(wxUpdateUIEvent& event);
93
94 void OnSize(wxSizeEvent& event);
95
96private:
97 wxMenu *CreateDummyMenu(wxString *title);
98
99 wxMenuItem *GetLastMenuItem() const;
100
101 // the menu previously detached from the menubar (may be NULL)
102 wxMenu *m_menu;
103
104 // the count of dummy menus already created
105 size_t m_countDummy;
106
107 // the control used for logging
108 wxTextCtrl *m_textctrl;
109
110 // the previous log target
111 wxLog *m_logOld;
112
113 DECLARE_EVENT_TABLE()
114};
115
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
135// ----------------------------------------------------------------------------
136// constants
137// ----------------------------------------------------------------------------
138
139enum
140{
141 Menu_File_Quit = 100,
142 Menu_File_ClearLog,
143
144 Menu_MenuBar_Toggle = 200,
145 Menu_MenuBar_Append,
146 Menu_MenuBar_Insert,
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,
160 Menu_Menu_GetInfo,
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)
183 EVT_MENU(Menu_File_Quit, MyFrame::OnQuit)
184 EVT_MENU(Menu_File_ClearLog, MyFrame::OnClearLog)
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)
190 EVT_MENU(Menu_MenuBar_Insert, MyFrame::OnInsertMenu)
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)
201 EVT_MENU(Menu_Menu_Check, MyFrame::OnCheckMenuItem)
202 EVT_MENU(Menu_Menu_GetLabel, MyFrame::OnGetLabelMenuItem)
203 EVT_MENU(Menu_Menu_SetLabel, MyFrame::OnSetLabelMenuItem)
204 EVT_MENU(Menu_Menu_GetInfo, MyFrame::OnGetMenuItemInfo)
205
206 EVT_MENU_RANGE(Menu_Dummy_First, Menu_Dummy_Last, MyFrame::OnDummy)
207
208 EVT_UPDATE_UI(Menu_Menu_Check, MyFrame::OnUpdateCheckMenuItemUI)
209
210 EVT_RIGHT_UP(MyFrame::OnRightUp)
211
212 EVT_SIZE(MyFrame::OnSize)
213END_EVENT_TABLE()
214
215BEGIN_EVENT_TABLE(MyEvtHandler, wxEvtHandler)
216 EVT_MENU(-1, MyEvtHandler::OnMenuEvent)
217END_EVENT_TABLE()
218
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
238#if wxUSE_STATUSBAR
239 frame->SetStatusText("Welcome to wxWindows menu sample");
240#endif // wxUSE_STATUSBAR
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{
256 m_textctrl = NULL;
257 m_menu = NULL;
258 m_countDummy = 0;
259 m_logOld = NULL;
260
261#if wxUSE_STATUSBAR
262 CreateStatusBar();
263#endif // wxUSE_STATUSBAR
264
265 // create the menubar
266 wxMenu *fileMenu = new wxMenu;
267
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");
274
275 wxMenu *menubarMenu = new wxMenu;
276 menubarMenu->Append(Menu_MenuBar_Append, "&Append menu\tCtrl-A",
277 "Append a menu to the menubar");
278 menubarMenu->Append(Menu_MenuBar_Insert, "&Insert menu\tCtrl-I",
279 "Insert a menu into the menubar");
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");
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");
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);
334
335 // intercept all menu events and log them in this custom event handler
336 PushEventHandler(new MyEvtHandler(this));
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"));
350}
351
352MyFrame::~MyFrame()
353{
354 delete m_menu;
355
356 // delete the event handler installed in ctor
357 PopEventHandler(TRUE);
358
359 // restore old logger
360 delete wxLog::SetActiveTarget(m_logOld);
361}
362
363wxMenu *MyFrame::CreateDummyMenu(wxString *title)
364{
365 wxMenu *menu = new wxMenu;
366 menu->Append(Menu_Dummy_First, "&First item\tCtrl-F1");
367 menu->AppendSeparator();
368 menu->Append(Menu_Dummy_Second, "&Second item\tCtrl-F2", "", TRUE);
369
370 if ( title )
371 {
372 title->Printf(wxT("Dummy menu &%d"), ++m_countDummy);
373 }
374
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 {
386 wxLogWarning(wxT("No last item in the last menu!"));
387
388 return NULL;
389 }
390 else
391 {
392 return node->GetData();
393 }
394}
395
396void MyFrame::LogMenuEvent(const wxCommandEvent& event)
397{
398 int id = event.GetId();
399 if ( !GetMenuBar()->FindItem(id) )
400 return;
401
402 wxString msg = wxString::Format(wxT("Menu command %d"), id);
403 if ( GetMenuBar()->FindItem(id)->IsCheckable() )
404 {
405 msg += wxString::Format(wxT(" (the item is currently %schecked)"),
406 event.IsChecked() ? "" : "not ");
407 }
408
409 wxLogMessage(msg);
410}
411
412// ----------------------------------------------------------------------------
413// menu callbacks
414// ----------------------------------------------------------------------------
415
416void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
417{
418 Close(TRUE);
419}
420
421void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
422{
423 m_textctrl->Clear();
424}
425
426void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
427{
428