]> git.saurik.com Git - wxWidgets.git/blame_incremental - samples/menu/menu.cpp
added workaround for GTK+ focus_out bug (and removed Vaclav's mouse capture stack...
[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_menu = NULL;
257 m_countDummy = 0;
258 m_logOld = NULL;
259
260#if wxUSE_STATUSBAR
261 CreateStatusBar();
262#endif // wxUSE_STATUSBAR
263
264 // create the menubar
265 wxMenu *fileMenu = new wxMenu;
266
267 wxMenuItem *item = new wxMenuItem(fileMenu, Menu_File_ClearLog,
268 "Clear &log\tCtrl-L");
269 item->SetBitmap(copy_xpm);
270 fileMenu->Append(item);
271 fileMenu->AppendSeparator();
272 fileMenu->Append(Menu_File_Quit, "E&xit\tAlt-X", "Quit menu sample");
273
274 wxMenu *menubarMenu = new wxMenu;
275 menubarMenu->Append(Menu_MenuBar_Append, "&Append menu\tCtrl-A",
276 "Append a menu to the menubar");
277 menubarMenu->Append(Menu_MenuBar_Insert, "&Insert menu\tCtrl-I",
278 "Insert a menu into the menubar");
279 menubarMenu->Append(Menu_MenuBar_Delete, "&Delete menu\tCtrl-D",
280 "Delete the last menu from the menubar");
281 menubarMenu->Append(Menu_MenuBar_Toggle, "&Toggle menu\tCtrl-T",
282 "Toggle the first menu in the menubar", TRUE);
283 menubarMenu->AppendSeparator();
284 menubarMenu->Append(Menu_MenuBar_Enable, "&Enable menu\tCtrl-E",
285 "Enable or disable the last menu", TRUE);
286 menubarMenu->AppendSeparator();
287 menubarMenu->Append(Menu_MenuBar_GetLabel, "&Get menu label\tCtrl-G",
288 "Get the label of the last menu");
289 menubarMenu->Append(Menu_MenuBar_SetLabel, "&Set menu label\tCtrl-S",
290 "Change the label of the last menu");
291
292 wxMenu *menuMenu = new wxMenu;
293 menuMenu->Append(Menu_Menu_Append, "&Append menu item\tAlt-A",
294 "Append a menu item to the last menu");
295 menuMenu->Append(Menu_Menu_AppendSub, "&Append sub menu\tAlt-S",
296 "Append a sub menu to the last menu");
297 menuMenu->Append(Menu_Menu_Insert, "&Insert menu item\tAlt-I",
298 "Insert a menu item in head of the last menu");
299 menuMenu->Append(Menu_Menu_Delete, "&Delete menu item\tAlt-D",
300 "Delete the last menu item from the last menu");
301 menuMenu->AppendSeparator();
302 menuMenu->Append(Menu_Menu_Enable, "&Enable menu item\tAlt-E",
303 "Enable or disable the last menu item", TRUE);
304 menuMenu->Append(Menu_Menu_Check, "&Check menu item\tAlt-C",
305 "Check or uncheck the last menu item", TRUE);
306 menuMenu->AppendSeparator();
307 menuMenu->Append(Menu_Menu_GetLabel, "&Get menu item label\tAlt-G",
308 "Get the label of the last menu item");
309 menuMenu->Append(Menu_Menu_SetLabel, "&Set menu item label\tAlt-S",
310 "Change the label of the last menu item");
311 menuMenu->AppendSeparator();
312 menuMenu->Append(Menu_Menu_GetInfo, "Get menu item in&fo\tAlt-F",
313 "Show the state of the last menu item");
314
315 wxMenu *helpMenu = new wxMenu;
316 helpMenu->Append(Menu_Help_About, "&About\tF1", "About menu sample");
317
318 wxMenuBar* menuBar = new wxMenuBar( wxMB_DOCKABLE );
319
320 menuBar->Append(fileMenu, "&File");
321 menuBar->Append(menubarMenu, "Menu&bar");
322 menuBar->Append(menuMenu, "&Menu");
323 menuBar->Append(helpMenu, "&Help");
324
325 // these items should be initially checked
326 menuBar->Check(Menu_MenuBar_Toggle, TRUE);
327 menuBar->Check(Menu_MenuBar_Enable, TRUE);
328 menuBar->Check(Menu_Menu_Enable, TRUE);
329 menuBar->Check(Menu_Menu_Check, FALSE);
330
331 // associate the menu bar with the frame
332 SetMenuBar(menuBar);
333
334 // intercept all menu events and log them in this custom event handler
335 PushEventHandler(new MyEvtHandler(this));
336
337 // create the log text window
338 m_textctrl = new wxTextCtrl(this, -1, _T(""),
339 wxDefaultPosition, wxDefaultSize,
340 wxTE_MULTILINE);
341 m_textctrl->SetEditable(FALSE);
342 m_logOld = wxLog::SetActiveTarget(new wxLogTextCtrl(m_textctrl));
343
344 wxLogMessage(_T("Brief explanations: the commands or the \"Menu\" menu\n")
345 _T("append/insert/delete items to/from the last menu.\n")
346 _T("The commands from \"Menubar\" menu work with the\n")
347 _T("menubar itself.\n")
348 _T("Right click the band below to test popup menus.\n"));
349}
350
351MyFrame::~MyFrame()
352{
353 delete m_menu;
354
355 // delete the event handler installed in ctor
356 PopEventHandler(TRUE);
357
358 // restore old logger
359 delete wxLog::SetActiveTarget(m_logOld);
360}
361
362wxMenu *MyFrame::CreateDummyMenu(wxString *title)
363{
364 wxMenu *menu = new wxMenu;
365 menu->Append(Menu_Dummy_First, "&First item\tCtrl-F1");
366 menu->AppendSeparator();
367 menu->Append(Menu_Dummy_Second, "&Second item\tCtrl-F2", "", TRUE);
368
369 if ( title )
370 {
371 title->Printf(wxT("Dummy menu &%d"), ++m_countDummy);
372 }
373
374 return menu;
375}
376
377wxMenuItem *MyFrame::GetLastMenuItem() const
378{
379 wxMenuBar *menubar = GetMenuBar();
380 wxMenu *menu = menubar->GetMenu(menubar->GetMenuCount() - 1);
381
382 wxMenuItemList::Node *node = menu->GetMenuItems().GetLast();
383 if ( !node )
384 {
385 wxLogWarning(wxT("No last item in the last menu!"));
386
387 return NULL;
388 }
389 else
390 {
391 return node->GetData();
392 }
393}
394
395void MyFrame::LogMenuEvent(const wxCommandEvent& event)
396{
397 int id = event.GetId();
398 if ( !GetMenuBar()->FindItem(id) )
399 return;
400
401 wxString msg = wxString::Format(wxT("Menu command %d"), id);
402 if ( GetMenuBar()->FindItem(id)->IsCheckable() )
403 {
404 msg += wxString::Format(wxT(" (the item is currently %schecked)"),
405 event.IsChecked() ? "" : "not ");
406 }
407
408 wxLogMessage(msg);
409}
410
411// ----------------------------------------------------------------------------
412// menu callbacks
413// ----------------------------------------------------------------------------
414
415void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
416{
417 Close(TRUE);
418}
419
420void MyFrame::OnClearLog(wxCommandEvent& WXUNUSED(event))
421{
422 m_textctrl->Clear();
423}
424
425void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
426{
427