]> git.saurik.com Git - wxWidgets.git/blame - tests/events/evthandler.cpp
add wxAppConsoleBase::OnEventLoopEnter/Exit callbacks; add wxEventLoopBase::IsMain...
[wxWidgets.git] / tests / events / evthandler.cpp
CommitLineData
b2238cc3
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/events/evthandler.cpp
3// Purpose: Test the new event types and wxEvtHandler-methods
4// Author: Peter Most
5// Created: 2009-01-24
6// RCS-ID: $Id$
7// Copyright: (c) 2009 Peter Most
8///////////////////////////////////////////////////////////////////////////////
9
10// ----------------------------------------------------------------------------
11// headers
12// ----------------------------------------------------------------------------
13
14#include "testprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
b2238cc3
VZ
20#include "wx/event.h"
21
f3ff831f
VZ
22// ----------------------------------------------------------------------------
23// test events and their handlers
24// ----------------------------------------------------------------------------
b2238cc3 25
a01ada05 26const wxEventType LegacyEventType = wxNewEventType();
b2238cc3 27
9b3ff3c0 28class MyEvent;
16be58c1 29wxDEFINE_EVENT(MyEventType, MyEvent);
9b3ff3c0 30
b2238cc3
VZ
31class MyEvent : public wxEvent
32{
9b3ff3c0 33public:
a01ada05 34 MyEvent() : wxEvent(0, MyEventType) { }
9b3ff3c0
VZ
35
36 virtual wxEvent *Clone() const { return new MyEvent; }
b2238cc3
VZ
37};
38
bb87b19b
VZ
39typedef void (wxEvtHandler::*MyEventFunction)(MyEvent&);
40#define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func)
41#define EVT_MYEVENT(func) \
42 wx__DECLARE_EVT0(MyEventType, MyEventHandler(func))
a01ada05 43
9b3ff3c0
VZ
44class AnotherEvent : public wxEvent
45{
46};
b2238cc3 47
9b3ff3c0
VZ
48namespace
49{
50
51struct Called
52{
53 Called() { Reset(); }
54
55 void Reset()
56 {
57 function =
58 functor =
59 method =
60 smethod = false;
61 }
62
63 bool function,
64 functor,
65 method,
66 smethod;
67} g_called;
68
69void GlobalOnMyEvent(MyEvent&)
70{
71 g_called.function = true;
72}
b2238cc3 73
f3ff831f
VZ
74void GlobalOnAnotherEvent(AnotherEvent&);
75
76void GlobalOnIdle(wxIdleEvent&)
77{
78 g_called.function = true;
79}
80
81struct MyFunctor
b2238cc3 82{
9b3ff3c0 83 void operator()(MyEvent &) { g_called.functor = true; }
f3ff831f 84};
b2238cc3 85
f3ff831f
VZ
86struct IdleFunctor
87{
88 void operator()(wxIdleEvent &) { g_called.functor = true; }
b2238cc3
VZ
89};
90
b2238cc3
VZ
91class MyHandler : public wxEvtHandler
92{
9b3ff3c0 93public:
f3ff831f
VZ
94 static void StaticOnMyEvent(MyEvent &) { g_called.smethod = true; }
95 static void StaticOnAnotherEvent(AnotherEvent &);
96 static void StaticOnIdle(wxIdleEvent&) { g_called.smethod = true; }
97
9b3ff3c0 98 void OnMyEvent(MyEvent&) { g_called.method = true; }
f3ff831f
VZ
99 void OnEvent(wxEvent&) { g_called.method = true; }
100 void OnAnotherEvent(AnotherEvent&);
101 void OnIdle(wxIdleEvent&) { g_called.method = true; }
102};
b2238cc3 103
f3ff831f
VZ
104// we can also handle events in classes not deriving from wxEvtHandler
105struct MySink
106{
107 void OnMyEvent(MyEvent&) { g_called.method = true; }
a01ada05 108 void OnEvent(wxEvent&) { g_called.method = true; }
f3ff831f
VZ
109 void OnIdle(wxIdleEvent&) { g_called.method = true; }
110};
b2238cc3 111
f3ff831f
VZ
112// also test event table compilation
113class MyClassWithEventTable : public wxEvtHandler
114{
115public:
116 void OnMyEvent(MyEvent&) { g_called.method = true; }
117 void OnEvent(wxEvent&) { g_called.method = true; }
118 void OnAnotherEvent(AnotherEvent&);
119 void OnIdle(wxIdleEvent&) { g_called.method = true; }
120
121private:
122 DECLARE_EVENT_TABLE()
b2238cc3
VZ
123};
124
f3ff831f
VZ
125BEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler)
126 EVT_IDLE(MyClassWithEventTable::OnIdle)
127
a01ada05 128 EVT_MYEVENT(MyClassWithEventTable::OnMyEvent)
bb87b19b 129#if !wxEVENTS_COMPATIBILITY_2_8
a01ada05 130 EVT_MYEVENT(MyClassWithEventTable::OnEvent)
bb87b19b 131#endif
a01ada05 132
f3ff831f 133 // this shouldn't compile:
a01ada05 134 //EVT_MYEVENT(MyClassWithEventTable::OnIdle)
f3ff831f
VZ
135 //EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)
136END_EVENT_TABLE()
137
9b3ff3c0
VZ
138} // anonymous namespace
139
f3ff831f
VZ
140
141// --------------------------------------------------------------------------
142// test class
143// --------------------------------------------------------------------------
144
145class EvtHandlerTestCase : public CppUnit::TestCase
b2238cc3 146{
f3ff831f
VZ
147public:
148 EvtHandlerTestCase() {}
149
150private:
151 CPPUNIT_TEST_SUITE( EvtHandlerTestCase );
152 CPPUNIT_TEST( BuiltinConnect );
153 CPPUNIT_TEST( LegacyConnect );
154#if !wxEVENTS_COMPATIBILITY_2_8
155 CPPUNIT_TEST( ConnectFunction );
156 CPPUNIT_TEST( ConnectStaticMethod );
157 CPPUNIT_TEST( ConnectFunctor );
158 CPPUNIT_TEST( ConnectMethod );
a01ada05 159 CPPUNIT_TEST( ConnectMethodUsingBaseEvent );
f3ff831f
VZ
160 CPPUNIT_TEST( ConnectMethodWithSink );
161 CPPUNIT_TEST( ConnectNonHandler );
162 CPPUNIT_TEST( StaticConnect );
163 CPPUNIT_TEST( InvalidConnect );
164#endif // !wxEVENTS_COMPATIBILITY_2_8
165 CPPUNIT_TEST_SUITE_END();
166
167 void BuiltinConnect();
168 void LegacyConnect();
169#if !wxEVENTS_COMPATIBILITY_2_8
170 void ConnectFunction();
171 void ConnectStaticMethod();
172 void ConnectFunctor();
173 void ConnectMethod();
a01ada05 174 void ConnectMethodUsingBaseEvent();
f3ff831f
VZ
175 void ConnectMethodWithSink();
176 void ConnectNonHandler();
177 void StaticConnect();
178 void InvalidConnect();
179#endif // !wxEVENTS_COMPATIBILITY_2_8
180
b2238cc3 181
f3ff831f
VZ
182 // these member variables exceptionally don't use "m_" prefix because
183 // they're used so many times
b2238cc3 184 MyHandler handler;
9b3ff3c0 185 MyEvent e;
b2238cc3 186
f3ff831f
VZ
187 DECLARE_NO_COPY_CLASS(EvtHandlerTestCase)
188};
b2238cc3 189
f3ff831f
VZ
190// register in the unnamed registry so that these tests are run by default
191CPPUNIT_TEST_SUITE_REGISTRATION( EvtHandlerTestCase );
192
193// also include in it's own registry so that these tests can be run alone
194CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EvtHandlerTestCase, "EvtHandlerTestCase" );
195
196void EvtHandlerTestCase::BuiltinConnect()
197{
198 handler.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle));
199 handler.Disconnect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle));
200
201 handler.Connect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &handler);
202 handler.Disconnect(wxEVT_IDLE, wxIdleEventHandler(MyHandler::OnIdle), NULL, &handler);
b2238cc3 203
a01ada05
VZ
204 // using casts like this is even uglier than using wxIdleEventHandler but
205 // it should still continue to work for compatibility
206 handler.Connect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
207 handler.Disconnect(wxEVT_IDLE, (wxObjectEventFunction)(wxEventFunction)&MyHandler::OnIdle);
208
f3ff831f
VZ
209#if !wxEVENTS_COMPATIBILITY_2_8
210 handler.Connect(wxEVT_IDLE, GlobalOnIdle);
211 handler.Disconnect(wxEVT_IDLE, GlobalOnIdle);
b2238cc3 212
f3ff831f
VZ
213 IdleFunctor f;
214 handler.Connect(wxEVT_IDLE, f);
215 handler.Disconnect(wxEVT_IDLE, f);
b2238cc3 216
f3ff831f
VZ
217 handler.Connect(wxEVT_IDLE, &MyHandler::OnIdle);
218 handler.Disconnect(wxEVT_IDLE, &MyHandler::OnIdle);
219
220 handler.Connect(wxEVT_IDLE, &MyHandler::StaticOnIdle);
221 handler.Disconnect(wxEVT_IDLE, &MyHandler::StaticOnIdle);
222#endif // !wxEVENTS_COMPATIBILITY_2_8
223}
224
225void EvtHandlerTestCase::LegacyConnect()
226{
a01ada05
VZ
227 handler.Connect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
228 handler.Connect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
229 handler.Connect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
b2238cc3 230
a01ada05
VZ
231 handler.Disconnect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
232 handler.Disconnect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
233 handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent );
b2238cc3 234
f3ff831f 235
a01ada05
VZ
236 handler.Connect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
237 handler.Connect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
238 handler.Connect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
f3ff831f 239
a01ada05
VZ
240 handler.Disconnect( LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
241 handler.Disconnect( 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
242 handler.Disconnect( 0, 0, LegacyEventType, (wxObjectEventFunction)&MyHandler::OnEvent, NULL, &handler );
f3ff831f 243}
b2238cc3
VZ
244
245#if !wxEVENTS_COMPATIBILITY_2_8
f3ff831f
VZ
246
247void EvtHandlerTestCase::ConnectFunction()
248{
249 // function tests
a01ada05 250 handler.Connect( MyEventType, GlobalOnMyEvent );
f3ff831f
VZ
251 g_called.Reset();
252 handler.ProcessEvent(e);
253 CPPUNIT_ASSERT( g_called.function );
a01ada05 254 handler.Disconnect( MyEventType, GlobalOnMyEvent );
f3ff831f
VZ
255 g_called.Reset();
256 handler.ProcessEvent(e);
257 CPPUNIT_ASSERT( !g_called.function ); // check that it was disconnected
258
a01ada05
VZ
259 handler.Connect( 0, MyEventType, GlobalOnMyEvent );
260 handler.Disconnect( 0, MyEventType, GlobalOnMyEvent );
f3ff831f 261
a01ada05
VZ
262 handler.Connect( 0, 0, MyEventType, GlobalOnMyEvent );
263 handler.Disconnect( 0, 0, MyEventType, GlobalOnMyEvent );
f3ff831f
VZ
264}
265
266void EvtHandlerTestCase::ConnectStaticMethod()
267{
268 // static method tests (this is same as functions but still test it just in
269 // case we hit some strange compiler bugs)
a01ada05 270 handler.Connect( MyEventType, &MyHandler::StaticOnMyEvent );
9b3ff3c0
VZ
271 g_called.Reset();
272 handler.ProcessEvent(e);
273 CPPUNIT_ASSERT( g_called.smethod );
a01ada05 274 handler.Disconnect( MyEventType, &MyHandler::StaticOnMyEvent );
9b3ff3c0
VZ
275 g_called.Reset();
276 handler.ProcessEvent(e);
f3ff831f 277 CPPUNIT_ASSERT( !g_called.smethod );
b2238cc3 278
a01ada05
VZ
279 handler.Connect( 0, MyEventType, &MyHandler::StaticOnMyEvent );
280 handler.Disconnect( 0, MyEventType, &MyHandler::StaticOnMyEvent );
b2238cc3 281
a01ada05
VZ
282 handler.Connect( 0, 0, MyEventType, &MyHandler::StaticOnMyEvent );
283 handler.Disconnect( 0, 0, MyEventType, &MyHandler::StaticOnMyEvent );
f3ff831f 284}
b2238cc3 285
f3ff831f
VZ
286void EvtHandlerTestCase::ConnectFunctor()
287{
288 // generalized functor tests
289 MyFunctor functor;
b2238cc3 290
a01ada05 291 handler.Connect( MyEventType, functor );
f3ff831f
VZ
292 g_called.Reset();
293 handler.ProcessEvent(e);
294 CPPUNIT_ASSERT( g_called.functor );
a01ada05 295 handler.Disconnect( MyEventType, functor );
f3ff831f
VZ
296 g_called.Reset();
297 handler.ProcessEvent(e);
298 CPPUNIT_ASSERT( !g_called.functor );
b2238cc3 299
a01ada05
VZ
300 handler.Connect( 0, MyEventType, functor );
301 handler.Disconnect( 0, MyEventType, functor );
f3ff831f 302
a01ada05
VZ
303 handler.Connect( 0, 0, MyEventType, functor );
304 handler.Disconnect( 0, 0, MyEventType, functor );
f3ff831f 305}
b2238cc3 306
f3ff831f
VZ
307void EvtHandlerTestCase::ConnectMethod()
308{
309 // class method tests
a01ada05
VZ
310 handler.Connect( MyEventType, &MyHandler::OnMyEvent );
311 g_called.Reset();
312 handler.ProcessEvent(e);
313 CPPUNIT_ASSERT( g_called.method );
314 handler.Disconnect( MyEventType, &MyHandler::OnMyEvent );
315 g_called.Reset();
316 handler.ProcessEvent(e);
317 CPPUNIT_ASSERT( !g_called.method );
318
319 handler.Connect( 0, MyEventType, &MyHandler::OnMyEvent );
320 handler.Disconnect( 0, MyEventType, &MyHandler::OnMyEvent );
321
322 handler.Connect( 0, 0, MyEventType, &MyHandler::OnMyEvent );
323 handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnMyEvent );
324}
325
326void EvtHandlerTestCase::ConnectMethodUsingBaseEvent()
327{
328 // test connecting a method taking just wxEvent and not MyEvent: this
329 // should work too if we don't need any MyEvent-specific information in the
330 // handler
331 handler.Connect( MyEventType, &MyHandler::OnEvent );
f3ff831f
VZ
332 g_called.Reset();
333 handler.ProcessEvent(e);
334 CPPUNIT_ASSERT( g_called.method );
a01ada05 335 handler.Disconnect( MyEventType, &MyHandler::OnEvent );
f3ff831f
VZ
336 g_called.Reset();
337 handler.ProcessEvent(e);
338 CPPUNIT_ASSERT( !g_called.method );
b2238cc3 339
a01ada05
VZ
340 handler.Connect( 0, MyEventType, &MyHandler::OnEvent );
341 handler.Disconnect( 0, MyEventType, &MyHandler::OnEvent );
b2238cc3 342
a01ada05
VZ
343 handler.Connect( 0, 0, MyEventType, &MyHandler::OnEvent );
344 handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnEvent );
f3ff831f 345}
b2238cc3 346
f3ff831f
VZ
347void EvtHandlerTestCase::ConnectMethodWithSink()
348{
a01ada05
VZ
349 handler.Connect( MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
350 handler.Connect( 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
351 handler.Connect( 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
b2238cc3 352
a01ada05
VZ
353 handler.Disconnect( MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
354 handler.Disconnect( 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
355 handler.Disconnect( 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
f3ff831f
VZ
356}
357
358void EvtHandlerTestCase::ConnectNonHandler()
359{
360 // class method tests for class not derived from wxEvtHandler
361 MySink sink;
b2238cc3 362
a01ada05 363 handler.Connect( MyEventType, &MySink::OnMyEvent, NULL, &sink );
f3ff831f
VZ
364 g_called.Reset();
365 handler.ProcessEvent(e);
366 CPPUNIT_ASSERT( g_called.method );
a01ada05 367 handler.Disconnect( MyEventType, &MySink::OnMyEvent, NULL, &sink );
f3ff831f
VZ
368 g_called.Reset();
369 handler.ProcessEvent(e);
370 CPPUNIT_ASSERT( !g_called.method );
371}
b2238cc3 372
f3ff831f
VZ
373void EvtHandlerTestCase::StaticConnect()
374{
a01ada05
VZ
375 wxEvtHandler::Connect( &handler, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
376 wxEvtHandler::Connect( &handler, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
377 wxEvtHandler::Connect( &handler, 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
b2238cc3 378
a01ada05
VZ
379 wxEvtHandler::Disconnect( &handler, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
380 wxEvtHandler::Disconnect( &handler, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
381 wxEvtHandler::Disconnect( &handler, 0, 0, MyEventType, &MyHandler::OnMyEvent, NULL, &handler );
f3ff831f 382}
b2238cc3 383
f3ff831f
VZ
384void EvtHandlerTestCase::InvalidConnect()
385{
9b3ff3c0
VZ
386 // these calls shouldn't compile but we unfortunately can't check this
387 // automatically, you need to uncomment them manually and test that
388 // compilation does indeed fail
a01ada05
VZ
389 //handler.Connect(MyEventType, GlobalOnAnotherEvent);
390 //IdleFunctor f; handler.Connect(MyEventType, f);
391 //handler.Connect(MyEventType, &MyHandler::StaticOnAnotherEvent);
392 //handler.Connect(MyEventType, &MyHandler::OnAnotherEvent);
b2238cc3
VZ
393}
394
f3ff831f 395#endif // !wxEVENTS_COMPATIBILITY_2_8