]> git.saurik.com Git - wxWidgets.git/blame - tests/events/keyboard.cpp
Fix event handling order in doc/view framework.
[wxWidgets.git] / tests / events / keyboard.cpp
CommitLineData
042ddf5d
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/events/keyboard.cpp
3// Purpose: Test keyboard events
4// Author: Vadim Zeitlin
5// Created: 2010-09-05
6// RCS-ID: $Id$
7// Copyright: (c) 2010 Vadim Zeitlin <vadim@wxwidgets.org>
8///////////////////////////////////////////////////////////////////////////////
9
10// ----------------------------------------------------------------------------
11// headers
12// ----------------------------------------------------------------------------
13
14#include "testprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
4a695c46
VZ
20// FIXME: As all the other tests involving wxUIActionSimulator, this one is
21// broken under OS X, the test window siply never gets any events.
22#if wxUSE_UIACTIONSIMULATOR && !defined(__WXOSX__)
042ddf5d
VZ
23
24#ifndef WX_PRECOMP
25 #include "wx/app.h"
26 #include "wx/event.h"
27 #include "wx/window.h"
28#endif // WX_PRECOMP
29
30#include "wx/uiaction.h"
31#include "wx/vector.h"
32
33namespace
34{
35
36// ----------------------------------------------------------------------------
37// test window verifying the event generation
38// ----------------------------------------------------------------------------
39
40class KeyboardTestWindow : public wxWindow
41{
42public:
43 KeyboardTestWindow(wxWindow *parent)
4a695c46 44 : wxWindow(parent, wxID_ANY, wxPoint(0, 0), parent->GetClientSize())
042ddf5d
VZ
45 {
46 Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(KeyboardTestWindow::OnKeyDown));
47 Connect(wxEVT_CHAR, wxKeyEventHandler(KeyboardTestWindow::OnChar));
48 Connect(wxEVT_KEY_UP, wxKeyEventHandler(KeyboardTestWindow::OnKeyUp));
49 }
50
51 unsigned GetKeyDownCount() const { return m_keyDownEvents.size(); }
52 unsigned GetCharCount() const { return m_charEvents.size(); }
53 unsigned GetKeyUpCount() const { return m_keyUpEvents.size(); }
54
55 const wxKeyEvent& GetKeyDownEvent(unsigned n = 0) const
56 {
57 return m_keyDownEvents[n];
58 }
59 const wxKeyEvent& GetCharEvent(unsigned n = 0) const
60 {
61 return m_charEvents[n];
62 }
63 const wxKeyEvent& GetKeyUpEvent(unsigned n = 0) const
64 {
65 return m_keyUpEvents[n];
66 }
67
68 void ClearEvents()
69 {
70 m_keyDownEvents =
71 m_charEvents =
72 m_keyUpEvents = wxVector<wxKeyEvent>();
73 }
74
75private:
76 void OnKeyDown(wxKeyEvent& event)
77 {
78 m_keyDownEvents.push_back(event);
79 event.Skip();
80 }
81
82 void OnChar(wxKeyEvent& event)
83 {
84 m_charEvents.push_back(event);
85 event.Skip();
86 }
87
88 void OnKeyUp(wxKeyEvent& event)
89 {
90 m_keyUpEvents.push_back(event);
91 event.Skip();
92 }
93
94 wxVector<wxKeyEvent> m_keyDownEvents,
95 m_charEvents,
96 m_keyUpEvents;
97
98
99 wxDECLARE_NO_COPY_CLASS(KeyboardTestWindow);
100};
101
102// Object describing the (main fields of) keyboard event.
103struct KeyDesc
104{
105 KeyDesc(int keycode, int mods = 0)
106 : m_keycode(keycode),
107 m_mods(mods)
108 {
109 }
110
111 int m_keycode;
112 int m_mods;
113};
114
d0fb62a6 115// Helper for ModKeyDown().
042ddf5d
VZ
116int GetModForKey(int keycode)
117{
118 switch ( keycode )
119 {
120 case WXK_CONTROL: return wxMOD_CONTROL;
121 case WXK_SHIFT: return wxMOD_SHIFT;
122 case WXK_ALT: return wxMOD_ALT;
123 default:
124 wxFAIL_MSG( "Unknown modifier key" );
125 }
126
127 return wxMOD_NONE;
128}
129
d0fb62a6
VZ
130// Helper function to allow writing just ModKeyDown(WXK_CONTROL) instead of
131// more verbose KeyDesc(WXK_CONTROL, wxMOD_CONTROL).
042ddf5d
VZ
132KeyDesc ModKeyDown(int keycode)
133{
134 return KeyDesc(keycode, GetModForKey(keycode));
135}
136
d0fb62a6 137// Another helper provided for symmetry with ModKeyDown() only.
042ddf5d
VZ
138KeyDesc ModKeyUp(int keycode)
139{
140 return KeyDesc(keycode);
141}
142
042ddf5d
VZ
143// Verify that the event object corresponds to our idea of what it should be.
144void TestEvent(int line, const wxKeyEvent& ev, const KeyDesc& desc)
145{
146 // Construct the message we'll display if an assert fails.
147 std::string msg;
148 const wxEventType t = ev.GetEventType();
149 if ( t == wxEVT_KEY_DOWN )
150 msg = "key down";
151 else if ( t == wxEVT_CHAR )
152 msg = "char";
153 else if ( t == wxEVT_KEY_UP )
154 msg = "key up";
155 else
156 CPPUNIT_FAIL( "unknown event type" );
157
158 msg += " event at line ";
159 msg += wxString::Format("%d", line).mb_str();
160
161
162 CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong key code in " + msg,
163 desc.m_keycode,
164 ev.GetKeyCode() );
165
166#if wxUSE_UNICODE
7333c0ef 167 if ( desc.m_keycode < WXK_START )
042ddf5d 168 {
7333c0ef
VZ
169 // For Latin-1 our key code is the same as Unicode character value.
170 CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong Unicode key in " + msg,
171 (char)desc.m_keycode,
172 (char)ev.GetUnicodeKey() );
042ddf5d 173 }
7333c0ef 174 else // Special key
042ddf5d 175 {
7333c0ef 176 // Key codes above WXK_START don't correspond to printable characters.
042ddf5d
VZ
177 CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong non-zero Unicode key in " + msg,
178 0,
179 (int)ev.GetUnicodeKey() );
180 }
181#endif // wxUSE_UNICODE
182
183 CPPUNIT_ASSERT_EQUAL_MESSAGE( "wrong modifiers in " + msg,
184 desc.m_mods,
185 ev.GetModifiers() );
186}
187
188// Call TestEvent() passing it the line number from where it was called: this
189// is useful for interpreting the assert failure messages.
190#define ASSERT_KEY_EVENT_IS( ev, desc ) TestEvent(__LINE__, ev, desc)
191
192} // anonymous namespace
193
194// --------------------------------------------------------------------------
195// test class
196// --------------------------------------------------------------------------
197
198class KeyboardEventTestCase : public CppUnit::TestCase
199{
200public:
201 KeyboardEventTestCase() {}
202
203 virtual void setUp();
204 virtual void tearDown();
205
206private:
207 CPPUNIT_TEST_SUITE( KeyboardEventTestCase );
208 CPPUNIT_TEST( NormalLetter );
209 CPPUNIT_TEST( NormalSpecial );
210 CPPUNIT_TEST( CtrlLetter );
211 CPPUNIT_TEST( CtrlSpecial );
212 CPPUNIT_TEST( ShiftLetter );
213 CPPUNIT_TEST( ShiftSpecial );
214 CPPUNIT_TEST_SUITE_END();
215
216 void NormalLetter();
217 void NormalSpecial();
218 void CtrlLetter();
219 void CtrlSpecial();
220 void ShiftLetter();
221 void ShiftSpecial();
222
223 KeyboardTestWindow *m_win;
224
225 wxDECLARE_NO_COPY_CLASS(KeyboardEventTestCase);
226};
227
228wxREGISTER_UNIT_TEST(KeyboardEvent);
229
230void KeyboardEventTestCase::setUp()
231{
232 m_win = new KeyboardTestWindow(wxTheApp->GetTopWindow());
233 m_win->SetFocus();
234 wxYield(); // needed to show the new window
235
236 // The window might get some key up events when it's being shown if the key
237 // was pressed when the program was started and released after the window
238 // was shown, e.g. this does happen in practice when launching the test
239 // from command line. Simply discard all the spurious events so far.
240 m_win->ClearEvents();
241}
242
243void KeyboardEventTestCase::tearDown()
244{
245 m_win->Destroy();
246}
247
248void KeyboardEventTestCase::NormalLetter()
249{
250 wxUIActionSimulator sim;
251 sim.Char('a');
252 wxYield();
253
254 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetKeyDownCount() );
255 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(), 'A' );
256
257 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetCharCount() );
258 ASSERT_KEY_EVENT_IS( m_win->GetCharEvent(), 'a' );
259
260 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetKeyUpCount() );
261 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(), 'A' );
262}
263
264void KeyboardEventTestCase::NormalSpecial()
265{
266 wxUIActionSimulator sim;
267 sim.Char(WXK_END);
268 wxYield();
269
270 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetKeyDownCount() );
271 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(), WXK_END );
272
273 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetCharCount() );
274 ASSERT_KEY_EVENT_IS( m_win->GetCharEvent(), WXK_END );
275
276 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetKeyUpCount() );
277 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(), WXK_END );
278}
279
280void KeyboardEventTestCase::CtrlLetter()
281{
282 wxUIActionSimulator sim;
283 sim.Char('z', wxMOD_CONTROL);
284 wxYield();
285
286 CPPUNIT_ASSERT_EQUAL( 2, m_win->GetKeyDownCount() );
287 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(0),
288 ModKeyDown(WXK_CONTROL) );
289 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(1),
290 KeyDesc('Z', wxMOD_CONTROL) );
291
292 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetCharCount() );
293 ASSERT_KEY_EVENT_IS( m_win->GetCharEvent(),
294 KeyDesc('\x1a', wxMOD_CONTROL) );
295
296 CPPUNIT_ASSERT_EQUAL( 2, m_win->GetKeyUpCount() );
297 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(0),
298 KeyDesc('Z', wxMOD_CONTROL) );
299 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(1),
300 ModKeyUp(WXK_CONTROL) );
301}
302
303void KeyboardEventTestCase::CtrlSpecial()
304{
305 wxUIActionSimulator sim;
306 sim.Char(WXK_PAGEUP, wxMOD_CONTROL);
307 wxYield();
308
309 CPPUNIT_ASSERT_EQUAL( 2, m_win->GetKeyDownCount() );
310 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(0),
311 ModKeyDown(WXK_CONTROL) );
312 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(1),
313 KeyDesc(WXK_PAGEUP, wxMOD_CONTROL) );
314
315 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetCharCount() );
316 ASSERT_KEY_EVENT_IS( m_win->GetCharEvent(),
317 KeyDesc(WXK_PAGEUP, wxMOD_CONTROL) );
318
319 CPPUNIT_ASSERT_EQUAL( 2, m_win->GetKeyUpCount() );
320 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(0),
321 KeyDesc(WXK_PAGEUP, wxMOD_CONTROL) );
322 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(1),
323 ModKeyUp(WXK_CONTROL) );
324}
325
326void KeyboardEventTestCase::ShiftLetter()
327{
328 wxUIActionSimulator sim;
329 sim.Char('Q', wxMOD_SHIFT);
330 wxYield();
331
332 CPPUNIT_ASSERT_EQUAL( 2, m_win->GetKeyDownCount() );
333 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(0),
334 ModKeyDown(WXK_SHIFT) );
335 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(1),
336 KeyDesc('Q', wxMOD_SHIFT) );
337
338 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetCharCount() );
339 ASSERT_KEY_EVENT_IS( m_win->GetCharEvent(),
340 KeyDesc('Q', wxMOD_SHIFT) );
341
342 CPPUNIT_ASSERT_EQUAL( 2, m_win->GetKeyUpCount() );
343 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(0),
344 KeyDesc('Q', wxMOD_SHIFT) );
345 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(1),
346 ModKeyUp(WXK_SHIFT) );
347}
348
349void KeyboardEventTestCase::ShiftSpecial()
350{
351 wxUIActionSimulator sim;
073d9e0f 352 sim.Char(WXK_F3, wxMOD_SHIFT);
042ddf5d
VZ
353 wxYield();
354
355 CPPUNIT_ASSERT_EQUAL( 2, m_win->GetKeyDownCount() );
356 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(0),
357 ModKeyDown(WXK_SHIFT) );
358 ASSERT_KEY_EVENT_IS( m_win->GetKeyDownEvent(1),
073d9e0f 359 KeyDesc(WXK_F3, wxMOD_SHIFT) );
042ddf5d
VZ
360
361 CPPUNIT_ASSERT_EQUAL( 1, m_win->GetCharCount() );
362 ASSERT_KEY_EVENT_IS( m_win->GetCharEvent(),
073d9e0f 363 KeyDesc(WXK_F3, wxMOD_SHIFT) );
042ddf5d
VZ
364
365 CPPUNIT_ASSERT_EQUAL( 2, m_win->GetKeyUpCount() );
366 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(0),
073d9e0f 367 KeyDesc(WXK_F3, wxMOD_SHIFT) );
042ddf5d
VZ
368 ASSERT_KEY_EVENT_IS( m_win->GetKeyUpEvent(1),
369 ModKeyUp(WXK_SHIFT) );
370}
371
372#endif // wxUSE_UIACTIONSIMULATOR