]> git.saurik.com Git - wxWidgets.git/blame - samples/keyboard/keyboard.cpp
Always link with expat in monolithic build.
[wxWidgets.git] / samples / keyboard / keyboard.cpp
CommitLineData
7de7aed4
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: keyboard.cpp
be5a51fb 3// Purpose: Keyboard wxWidgets sample
7de7aed4 4// Author: Vadim Zeitlin
a96bab36 5// Modified by: Marcin Wojdyr
7de7aed4
VZ
6// Created: 07.04.02
7// RCS-ID: $Id$
8// Copyright: (c) 2002 Vadim Zeitlin
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
7de7aed4
VZ
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15 #pragma hdrstop
16#endif
7de7aed4
VZ
17#ifndef WX_PRECOMP
18 #include "wx/wx.h"
19#endif
20
41f02b9a
FM
21#ifndef __WXMSW__
22 #include "../sample.xpm"
23#endif
7de7aed4
VZ
24
25// Define a new frame type: this is going to be our main frame
26class MyFrame : public wxFrame
27{
28public:
a96bab36 29 MyFrame(const wxString& title);
7de7aed4
VZ
30
31private:
a96bab36
VZ
32 // event handlers
33 void OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); }
34 void OnAbout(wxCommandEvent& event);
a30305f8
VZ
35
36 void OnTestAccelA(wxCommandEvent& WXUNUSED(event))
37 { m_logText->AppendText("Test accelerator \"A\" used.\n"); }
38 void OnTestAccelCtrlA(wxCommandEvent& WXUNUSED(event))
39 { m_logText->AppendText("Test accelerator \"Ctrl-A\" used.\n"); }
40 void OnTestAccelEsc(wxCommandEvent& WXUNUSED(event))
41 { m_logText->AppendText("Test accelerator \"Esc\" used.\n"); }
42
a96bab36 43 void OnClear(wxCommandEvent& WXUNUSED(event)) { m_logText->Clear(); }
edf5822a
VZ
44 void OnSkipDown(wxCommandEvent& event) { m_skipDown = event.IsChecked(); }
45 void OnSkipHook(wxCommandEvent& event) { m_skipHook = event.IsChecked(); }
a30305f8 46
edf5822a
VZ
47 void OnKeyDown(wxKeyEvent& event)
48 {
49 LogEvent("KeyDown", event);
50 if ( m_skipDown )
51 event.Skip();
52 }
a96bab36
VZ
53 void OnKeyUp(wxKeyEvent& event) { LogEvent("KeyUp", event); }
54 void OnChar(wxKeyEvent& event) { LogEvent("Char", event); }
edf5822a
VZ
55 void OnCharHook(wxKeyEvent& event)
56 {
57 LogEvent("Hook", event);
58 if ( m_skipHook )
59 event.Skip();
60 }
61
a96bab36 62 void OnPaintInputWin(wxPaintEvent& event);
7de7aed4 63
a96bab36 64 void LogEvent(const wxString& name, wxKeyEvent& event);
7de7aed4 65
a96bab36
VZ
66 wxTextCtrl *m_logText;
67 wxWindow *m_inputWin;
edf5822a
VZ
68 bool m_skipHook,
69 m_skipDown;
7de7aed4
VZ
70};
71
7de7aed4 72
a96bab36
VZ
73// Define a new application type, each program should derive a class from wxApp
74class MyApp : public wxApp
7de7aed4
VZ
75{
76public:
a96bab36
VZ
77 // 'Main program' equivalent: the program execution "starts" here
78 virtual bool OnInit()
7de7aed4 79 {
a96bab36
VZ
80 // create the main application window
81 new MyFrame("Keyboard wxWidgets App");
7de7aed4 82
a96bab36
VZ
83 // If we returned false here, the application would exit immediately.
84 return true;
7de7aed4 85 }
7de7aed4
VZ
86};
87
be5a51fb 88// Create a new application object: this macro will allow wxWidgets to create
7de7aed4
VZ
89// the application object during program execution (it's better than using a
90// static object for many reasons) and also declares the accessor function
91// wxGetApp() which will return the reference of the right type (i.e. MyApp and
92// not wxApp)
93IMPLEMENT_APP(MyApp)
94
a96bab36 95
7de7aed4
VZ
96// ============================================================================
97// implementation
98// ============================================================================
99
7de7aed4 100// frame constructor
a96bab36
VZ
101MyFrame::MyFrame(const wxString& title)
102 : wxFrame(NULL, wxID_ANY, title),
103 m_inputWin(NULL),
edf5822a
VZ
104 m_skipHook(true),
105 m_skipDown(true)
7de7aed4 106{
41f02b9a
FM
107 SetIcon(wxICON(sample));
108
a96bab36
VZ
109 // IDs for menu items
110 enum
111 {
112 QuitID = wxID_EXIT,
113 ClearID = wxID_CLEAR,
edf5822a
VZ
114 SkipHook = 100,
115 SkipDown,
a30305f8
VZ
116 TestAccelA,
117 TestAccelCtrlA,
118 TestAccelEsc
a96bab36
VZ
119 };
120
7de7aed4
VZ
121 // create a menu bar
122 wxMenu *menuFile = new wxMenu;
a96bab36
VZ
123
124 menuFile->Append(ClearID, "&Clear log\tCtrl-L");
125 menuFile->AppendSeparator();
126
a30305f8
VZ
127 menuFile->Append(TestAccelA, "Test accelerator &1\tA");
128 menuFile->Append(TestAccelCtrlA, "Test accelerator &2\tCtrl-A");
129 menuFile->Append(TestAccelEsc, "Test accelerator &3\tEsc");
130 menuFile->AppendSeparator();
131
edf5822a
VZ
132 menuFile->AppendCheckItem(SkipHook, "Skip CHAR_HOOK event",
133 "Not skipping this event disables both KEY_DOWN and CHAR events"
134 );
135 menuFile->Check(SkipHook, true);
136 menuFile->AppendCheckItem(SkipDown, "Skip KEY_DOWN event",
137 "Not skipping this event disables CHAR event generation"
138 );
139 menuFile->Check(SkipDown, true);
7de7aed4 140 menuFile->AppendSeparator();
7de7aed4 141
a96bab36 142 menuFile->Append(QuitID, "E&xit\tAlt-X", "Quit this program");
7de7aed4
VZ
143
144 // the "About" item should be in the help menu
145 wxMenu *menuHelp = new wxMenu;
a96bab36 146 menuHelp->Append(wxID_ABOUT, "&About...\tF1", "Show about dialog");
7de7aed4
VZ
147
148 // now append the freshly created menu to the menu bar...
149 wxMenuBar *menuBar = new wxMenuBar();
a96bab36
VZ
150 menuBar->Append(menuFile, "&File");
151 menuBar->Append(menuHelp, "&Help");
7de7aed4
VZ
152
153 // ... and attach this menu bar to the frame
154 SetMenuBar(menuBar);
155
a96bab36 156 m_inputWin = new wxWindow(this, wxID_ANY, wxDefaultPosition, wxSize(-1, 50),
d7b3992a 157 wxRAISED_BORDER);
a96bab36
VZ
158 m_inputWin->SetBackgroundColour(*wxBLUE);
159
160 wxTextCtrl *headerText = new wxTextCtrl(this, wxID_ANY, "",
161 wxDefaultPosition, wxDefaultSize,
162 wxTE_READONLY);
163 headerText->SetValue(
164 " event key KeyCode mod UnicodeKey "
165 " RawKeyCode RawKeyFlags");
166
167
41f02b9a 168 m_logText = new wxTextCtrl(this, wxID_ANY, "",
a96bab36
VZ
169 wxDefaultPosition, wxDefaultSize,
170 wxTE_MULTILINE|wxTE_READONLY|wxHSCROLL);
171
172 // set monospace font to have output in nice columns
41f02b9a 173 wxFont font(10, wxFONTFAMILY_TELETYPE,
a96bab36
VZ
174 wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
175 headerText->SetFont(font);
176 m_logText->SetFont(font);
177
178 // layout
179 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
180 sizer->Add(m_inputWin, wxSizerFlags().Expand());
181 sizer->Add(headerText, wxSizerFlags().Expand());
182 sizer->Add(m_logText, wxSizerFlags(1).Expand());
183 SetSizerAndFit(sizer);
184
185 // set size and position on screen
186 SetSize(700, 340);
187 CentreOnScreen();
188
189 // connect menu event handlers
190
191 Connect(QuitID, wxEVT_COMMAND_MENU_SELECTED,
192 wxCommandEventHandler(MyFrame::OnQuit));
193
194 Connect(wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED,
195 wxCommandEventHandler(MyFrame::OnAbout));
196
197 Connect(ClearID, wxEVT_COMMAND_MENU_SELECTED,
198 wxCommandEventHandler(MyFrame::OnClear));
199
edf5822a
VZ
200 Connect(SkipHook, wxEVT_COMMAND_MENU_SELECTED,
201 wxCommandEventHandler(MyFrame::OnSkipHook));
202 Connect(SkipDown, wxEVT_COMMAND_MENU_SELECTED,
203 wxCommandEventHandler(MyFrame::OnSkipDown));
a96bab36 204
a30305f8
VZ
205 Connect(TestAccelA, wxEVT_COMMAND_MENU_SELECTED,
206 wxCommandEventHandler(MyFrame::OnTestAccelA));
207
208 Connect(TestAccelCtrlA, wxEVT_COMMAND_MENU_SELECTED,
209 wxCommandEventHandler(MyFrame::OnTestAccelCtrlA));
210
211 Connect(TestAccelEsc, wxEVT_COMMAND_MENU_SELECTED,
212 wxCommandEventHandler(MyFrame::OnTestAccelEsc));
213
41f02b9a 214 // connect event handlers for the blue input window
a96bab36
VZ
215 m_inputWin->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(MyFrame::OnKeyDown),
216 NULL, this);
217 m_inputWin->Connect(wxEVT_KEY_UP, wxKeyEventHandler(MyFrame::OnKeyUp),
218 NULL, this);
219 m_inputWin->Connect(wxEVT_CHAR, wxKeyEventHandler(MyFrame::OnChar),
220 NULL, this);
41f02b9a 221 m_inputWin->Connect(wxEVT_PAINT,
a96bab36
VZ
222 wxPaintEventHandler(MyFrame::OnPaintInputWin),
223 NULL, this);
224
edf5822a
VZ
225 // notice that we don't connect OnCharHook() to the input window, unlike
226 // the usual key events this one is propagated upwards
227 Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(MyFrame::OnCharHook));
228
229 // status bar is useful for showing the menu items help strings
230 CreateStatusBar();
231
a96bab36
VZ
232 // and show itself (the frames, unlike simple controls, are not shown when
233 // created initially)
234 Show(true);
7de7aed4
VZ
235}
236
237// event handlers
238
7de7aed4
VZ
239void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
240{
a96bab36
VZ
241 wxMessageBox("Demonstrates keyboard event processing in wxWidgets\n"
242 "(c) 2002 Vadim Zeitlin\n"
243 "(c) 2008 Marcin Wojdyr",
244 "About wxWidgets Keyboard Sample",
245 wxOK | wxICON_INFORMATION, this);
7de7aed4
VZ
246}
247
a96bab36 248void MyFrame::OnPaintInputWin(wxPaintEvent& WXUNUSED(event))
7de7aed4 249{
a96bab36
VZ
250 wxPaintDC dc(m_inputWin);
251 dc.SetTextForeground(*wxWHITE);
252 wxFont font(*wxSWISS_FONT);
253 font.SetWeight(wxFONTWEIGHT_BOLD);
254 font.SetPointSize(font.GetPointSize() + 2);
255 dc.SetFont(font);
256
41f02b9a 257 dc.DrawLabel("Press keys here",
a96bab36 258 m_inputWin->GetClientRect(), wxALIGN_CENTER);
7de7aed4
VZ
259}
260
62fa9712 261
a96bab36
VZ
262// helper function that returns textual description of wx virtual keycode
263const char* GetVirtualKeyCodeName(int keycode)
7de7aed4 264{
a96bab36 265 switch ( keycode )
7de7aed4 266 {
a96bab36 267#define WXK_(x) \
41f02b9a 268 case WXK_##x: return #x;
a96bab36
VZ
269
270 WXK_(BACK)
271 WXK_(TAB)
272 WXK_(RETURN)
273 WXK_(ESCAPE)
274 WXK_(SPACE)
275 WXK_(DELETE)
276 WXK_(START)
277 WXK_(LBUTTON)
278 WXK_(RBUTTON)
279 WXK_(CANCEL)
280 WXK_(MBUTTON)
281 WXK_(CLEAR)
282 WXK_(SHIFT)
283 WXK_(ALT)
284 WXK_(CONTROL)
285 WXK_(MENU)
286 WXK_(PAUSE)
287 WXK_(CAPITAL)
288 WXK_(END)
289 WXK_(HOME)
290 WXK_(LEFT)
291 WXK_(UP)
292 WXK_(RIGHT)
293 WXK_(DOWN)
294 WXK_(SELECT)
295 WXK_(PRINT)
296 WXK_(EXECUTE)
297 WXK_(SNAPSHOT)
298 WXK_(INSERT)
299 WXK_(HELP)
300 WXK_(NUMPAD0)
301 WXK_(NUMPAD1)
302 WXK_(NUMPAD2)
303 WXK_(NUMPAD3)
304 WXK_(NUMPAD4)
305 WXK_(NUMPAD5)
306 WXK_(NUMPAD6)
307 WXK_(NUMPAD7)
308 WXK_(NUMPAD8)
309 WXK_(NUMPAD9)
310 WXK_(MULTIPLY)
311 WXK_(ADD)
312 WXK_(SEPARATOR)
313 WXK_(SUBTRACT)
314 WXK_(DECIMAL)
315 WXK_(DIVIDE)
316 WXK_(F1)
317 WXK_(F2)
318 WXK_(F3)
319 WXK_(F4)
320 WXK_(F5)
321 WXK_(F6)
322 WXK_(F7)
323 WXK_(F8)
324 WXK_(F9)
325 WXK_(F10)
326 WXK_(F11)
327 WXK_(F12)
328 WXK_(F13)
329 WXK_(F14)
330 WXK_(F15)
331 WXK_(F16)
332 WXK_(F17)
333 WXK_(F18)
334 WXK_(F19)
335 WXK_(F20)
336 WXK_(F21)
337 WXK_(F22)
338 WXK_(F23)
339 WXK_(F24)
340 WXK_(NUMLOCK)
341 WXK_(SCROLL)
342 WXK_(PAGEUP)
343 WXK_(PAGEDOWN)
344 WXK_(NUMPAD_SPACE)
345 WXK_(NUMPAD_TAB)
346 WXK_(NUMPAD_ENTER)
347 WXK_(NUMPAD_F1)
348 WXK_(NUMPAD_F2)
349 WXK_(NUMPAD_F3)
350 WXK_(NUMPAD_F4)
351 WXK_(NUMPAD_HOME)
352 WXK_(NUMPAD_LEFT)
353 WXK_(NUMPAD_UP)
354 WXK_(NUMPAD_RIGHT)
355 WXK_(NUMPAD_DOWN)
356 WXK_(NUMPAD_PAGEUP)
357 WXK_(NUMPAD_PAGEDOWN)
358 WXK_(NUMPAD_END)
359 WXK_(NUMPAD_BEGIN)
360 WXK_(NUMPAD_INSERT)
361 WXK_(NUMPAD_DELETE)
362 WXK_(NUMPAD_EQUAL)
363 WXK_(NUMPAD_MULTIPLY)
364 WXK_(NUMPAD_ADD)
365 WXK_(NUMPAD_SEPARATOR)
366 WXK_(NUMPAD_SUBTRACT)
367 WXK_(NUMPAD_DECIMAL)
368 WXK_(NUMPAD_DIVIDE)
e7b12eec
VZ
369
370 WXK_(WINDOWS_LEFT)
371 WXK_(WINDOWS_RIGHT)
d3f81b85
SC
372#ifdef __WXOSX__
373 WXK_(RAW_CONTROL)
374#endif
a96bab36 375#undef WXK_
e7b12eec 376
41f02b9a
FM
377 default:
378 return NULL;
7de7aed4
VZ
379 }
380}
381
a96bab36
VZ
382// helper function that returns textual description of key in the event
383wxString GetKeyName(const wxKeyEvent &event)
7de7aed4 384{
a96bab36
VZ
385 int keycode = event.GetKeyCode();
386 const char* virt = GetVirtualKeyCodeName(keycode);
387 if ( virt )
388 return virt;
b6885972 389 if ( keycode > 0 && keycode < 32 )
a96bab36 390 return wxString::Format("Ctrl-%c", (unsigned char)('A' + keycode - 1));
b6885972 391 if ( keycode >= 32 && keycode < 128 )
a96bab36 392 return wxString::Format("'%c'", (unsigned char)keycode);
e7b12eec 393
52bbab36 394#if wxUSE_UNICODE
e7b12eec
VZ
395 int uc = event.GetUnicodeKey();
396 if ( uc != WXK_NONE )
397 return wxString::Format("'%c'", uc);
52bbab36 398#endif
e7b12eec
VZ
399
400 return "unknown";
a96bab36
VZ
401}
402
7de7aed4 403
a96bab36
VZ
404void MyFrame::LogEvent(const wxString& name, wxKeyEvent& event)
405{
62fa9712 406 wxString msg;
41f02b9a 407 // event key_name KeyCode modifiers Unicode raw_code raw_flags
a96bab36
VZ
408 msg.Printf("%7s %15s %5d %c%c%c%c"
409#if wxUSE_UNICODE
410 "%5d (U+%04x)"
411#else
412 " none "
413#endif
414#ifdef wxHAS_RAW_KEY_CODES
b6885972 415 " %7lu 0x%08lx"
a96bab36
VZ
416#else
417 " not-set not-set"
418#endif
419 "\n",
62fa9712 420 name,
a96bab36
VZ
421 GetKeyName(event),
422 event.GetKeyCode(),
423 event.ControlDown() ? 'C' : '-',
424 event.AltDown() ? 'A' : '-',
425 event.ShiftDown() ? 'S' : '-',
66ad7d6a 426 event.MetaDown() ? 'M' : '-'
a96bab36 427#if wxUSE_UNICODE
66ad7d6a
VZ
428 , event.GetUnicodeKey()
429 , event.GetUnicodeKey()
a96bab36
VZ
430#endif
431#ifdef wxHAS_RAW_KEY_CODES
66ad7d6a
VZ
432 , (unsigned long) event.GetRawKeyCode()
433 , (unsigned long) event.GetRawKeyFlags()
a96bab36
VZ
434#endif
435 );
62fa9712 436
a96bab36 437 m_logText->AppendText(msg);
7de7aed4 438}
a96bab36
VZ
439
440