]> git.saurik.com Git - wxWidgets.git/blame - tests/events/evthandler.cpp
remember to users that env vars are hardly usable for IPC :)
[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 39typedef void (wxEvtHandler::*MyEventFunction)(MyEvent&);
5293e4b7
VZ
40#if wxEVENTS_COMPATIBILITY_2_8
41 #define MyEventHandler(func) wxEVENT_HANDLER_CAST(MyEventFunction, func)
42#else
43 #define MyEventHandler(func) &func
44#endif
bb87b19b
VZ
45#define EVT_MYEVENT(func) \
46 wx__DECLARE_EVT0(MyEventType, MyEventHandler(func))
a01ada05 47
9b3ff3c0
VZ
48class AnotherEvent : public wxEvent
49{
50};
b2238cc3 51
9b3ff3c0
VZ
52namespace
53{
54
55struct Called
56{
57 Called() { Reset(); }
58
59 void Reset()
60 {
61 function =
62 functor =
63 method =
64 smethod = false;
65 }
66
67 bool function,
68 functor,
69 method,
70 smethod;
71} g_called;
72
73void GlobalOnMyEvent(MyEvent&)
74{
75 g_called.function = true;
76}
b2238cc3 77
f3ff831f
VZ
78void GlobalOnAnotherEvent(AnotherEvent&);
79
80void GlobalOnIdle(wxIdleEvent&)
81{
82 g_called.function = true;
83}
84
85struct MyFunctor
b2238cc3 86{
9b3ff3c0 87 void operator()(MyEvent &) { g_called.functor = true; }
f3ff831f 88};
b2238cc3 89
f3ff831f
VZ
90struct IdleFunctor
91{
92 void operator()(wxIdleEvent &) { g_called.functor = true; }
b2238cc3
VZ
93};
94
b2238cc3
VZ
95class MyHandler : public wxEvtHandler
96{
9b3ff3c0 97public:
f3ff831f
VZ
98 static void StaticOnMyEvent(MyEvent &) { g_called.smethod = true; }
99 static void StaticOnAnotherEvent(AnotherEvent &);
100 static void StaticOnIdle(wxIdleEvent&) { g_called.smethod = true; }
101
9b3ff3c0 102 void OnMyEvent(MyEvent&) { g_called.method = true; }
f3ff831f
VZ
103 void OnEvent(wxEvent&) { g_called.method = true; }
104 void OnAnotherEvent(AnotherEvent&);
105 void OnIdle(wxIdleEvent&) { g_called.method = true; }
106};
b2238cc3 107
f3ff831f
VZ
108// we can also handle events in classes not deriving from wxEvtHandler
109struct MySink
110{
111 void OnMyEvent(MyEvent&) { g_called.method = true; }
a01ada05 112 void OnEvent(wxEvent&) { g_called.method = true; }
f3ff831f
VZ
113 void OnIdle(wxIdleEvent&) { g_called.method = true; }
114};
b2238cc3 115
f3ff831f
VZ
116// also test event table compilation
117class MyClassWithEventTable : public wxEvtHandler
118{
119public:
120 void OnMyEvent(MyEvent&) { g_called.method = true; }
121 void OnEvent(wxEvent&) { g_called.method = true; }
122 void OnAnotherEvent(AnotherEvent&);
123 void OnIdle(wxIdleEvent&) { g_called.method = true; }
124
125private:
126 DECLARE_EVENT_TABLE()
b2238cc3
VZ
127};
128
f3ff831f
VZ
129BEGIN_EVENT_TABLE(MyClassWithEventTable, wxEvtHandler)
130 EVT_IDLE(MyClassWithEventTable::OnIdle)
131
a01ada05 132 EVT_MYEVENT(MyClassWithEventTable::OnMyEvent)
bb87b19b 133#if !wxEVENTS_COMPATIBILITY_2_8
a01ada05 134 EVT_MYEVENT(MyClassWithEventTable::OnEvent)
bb87b19b 135#endif
a01ada05 136
f3ff831f 137 // this shouldn't compile:
a01ada05 138 //EVT_MYEVENT(MyClassWithEventTable::OnIdle)
f3ff831f
VZ
139 //EVT_IDLE(MyClassWithEventTable::OnAnotherEvent)
140END_EVENT_TABLE()
141
9b3ff3c0
VZ
142} // anonymous namespace
143
f3ff831f
VZ
144
145// --------------------------------------------------------------------------
146// test class
147// --------------------------------------------------------------------------
148
149class EvtHandlerTestCase : public CppUnit::TestCase
b2238cc3 150{
f3ff831f
VZ
151public:
152 EvtHandlerTestCase() {}
153
154private:
155 CPPUNIT_TEST_SUITE( EvtHandlerTestCase );
156 CPPUNIT_TEST( BuiltinConnect );
157 CPPUNIT_TEST( LegacyConnect );
158#if !wxEVENTS_COMPATIBILITY_2_8
5293e4b7
VZ
159 CPPUNIT_TEST( BindFunction );
160 CPPUNIT_TEST( BindStaticMethod );
161 CPPUNIT_TEST( BindFunctor );
162 CPPUNIT_TEST( BindMethod );
163 CPPUNIT_TEST( BindMethodUsingBaseEvent );
164 CPPUNIT_TEST( BindNonHandler );
165 CPPUNIT_TEST( InvalidBind );
f3ff831f
VZ
166#endif // !wxEVENTS_COMPATIBILITY_2_8
167 CPPUNIT_TEST_SUITE_END();
168
169 void BuiltinConnect();
170 void LegacyConnect();
171#if !wxEVENTS_COMPATIBILITY_2_8
5293e4b7
VZ
172 void BindFunction();
173 void BindStaticMethod();
174 void BindFunctor();
175 void BindMethod();
176 void BindMethodUsingBaseEvent();
177 void BindNonHandler();
178 void InvalidBind();
f3ff831f
VZ
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 209#if !wxEVENTS_COMPATIBILITY_2_8
5293e4b7
VZ
210 handler.Bind(wxEVT_IDLE, GlobalOnIdle);
211 handler.Unbind(wxEVT_IDLE, GlobalOnIdle);
b2238cc3 212
f3ff831f 213 IdleFunctor f;
5293e4b7
VZ
214 handler.Bind(wxEVT_IDLE, f);
215 handler.Unbind(wxEVT_IDLE, f);
b2238cc3 216
5293e4b7
VZ
217 handler.Bind(wxEVT_IDLE, &MyHandler::OnIdle, &handler);
218 handler.Unbind(wxEVT_IDLE, &MyHandler::OnIdle, &handler);
f3ff831f 219
5293e4b7
VZ
220 handler.Bind(wxEVT_IDLE, &MyHandler::StaticOnIdle);
221 handler.Unbind(wxEVT_IDLE, &MyHandler::StaticOnIdle);
f3ff831f
VZ
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 246
5293e4b7 247void EvtHandlerTestCase::BindFunction()
f3ff831f
VZ
248{
249 // function tests
5293e4b7 250 handler.Bind( MyEventType, GlobalOnMyEvent );
f3ff831f
VZ
251 g_called.Reset();
252 handler.ProcessEvent(e);
253 CPPUNIT_ASSERT( g_called.function );
5293e4b7 254 handler.Unbind( MyEventType, GlobalOnMyEvent );
f3ff831f
VZ
255 g_called.Reset();
256 handler.ProcessEvent(e);
257 CPPUNIT_ASSERT( !g_called.function ); // check that it was disconnected
258
5293e4b7
VZ
259 handler.Bind( MyEventType, GlobalOnMyEvent, 0 );
260 handler.Unbind( MyEventType, GlobalOnMyEvent, 0 );
f3ff831f 261
5293e4b7
VZ
262 handler.Bind( MyEventType, GlobalOnMyEvent, 0, 0 );
263 handler.Unbind( MyEventType, GlobalOnMyEvent, 0, 0 );
f3ff831f
VZ
264}
265
5293e4b7 266void EvtHandlerTestCase::BindStaticMethod()
f3ff831f
VZ
267{
268 // static method tests (this is same as functions but still test it just in
269 // case we hit some strange compiler bugs)
5293e4b7 270 handler.Bind( MyEventType, &MyHandler::StaticOnMyEvent );
9b3ff3c0
VZ
271 g_called.Reset();
272 handler.ProcessEvent(e);
273 CPPUNIT_ASSERT( g_called.smethod );
5293e4b7 274 handler.Unbind( MyEventType, &MyHandler::StaticOnMyEvent );
9b3ff3c0
VZ
275 g_called.Reset();
276 handler.ProcessEvent(e);
f3ff831f 277 CPPUNIT_ASSERT( !g_called.smethod );
b2238cc3 278
5293e4b7
VZ
279 handler.Bind( MyEventType, &MyHandler::StaticOnMyEvent, 0 );
280 handler.Unbind( MyEventType, &MyHandler::StaticOnMyEvent, 0 );
b2238cc3 281
5293e4b7
VZ
282 handler.Bind( MyEventType, &MyHandler::StaticOnMyEvent, 0, 0 );
283 handler.Unbind( MyEventType, &MyHandler::StaticOnMyEvent, 0, 0 );
f3ff831f 284}
b2238cc3 285
5293e4b7 286void EvtHandlerTestCase::BindFunctor()
f3ff831f
VZ
287{
288 // generalized functor tests
289 MyFunctor functor;
b2238cc3 290
5293e4b7 291 handler.Bind( MyEventType, functor );
f3ff831f
VZ
292 g_called.Reset();
293 handler.ProcessEvent(e);
294 CPPUNIT_ASSERT( g_called.functor );
5293e4b7 295 handler.Unbind( MyEventType, functor );
f3ff831f
VZ
296 g_called.Reset();
297 handler.ProcessEvent(e);
298 CPPUNIT_ASSERT( !g_called.functor );
b2238cc3 299
5293e4b7
VZ
300 handler.Bind( MyEventType, functor, 0 );
301 handler.Unbind( MyEventType, functor, 0 );
f3ff831f 302
5293e4b7
VZ
303 handler.Bind( MyEventType, functor, 0, 0 );
304 handler.Unbind( MyEventType, functor, 0, 0 );
f3ff831f 305}
b2238cc3 306
5293e4b7 307void EvtHandlerTestCase::BindMethod()
f3ff831f
VZ
308{
309 // class method tests
5293e4b7 310 handler.Bind( MyEventType, &MyHandler::OnMyEvent, &handler );
a01ada05
VZ
311 g_called.Reset();
312 handler.ProcessEvent(e);
313 CPPUNIT_ASSERT( g_called.method );
5293e4b7 314 handler.Unbind( MyEventType, &MyHandler::OnMyEvent, &handler );
a01ada05
VZ
315 g_called.Reset();
316 handler.ProcessEvent(e);
317 CPPUNIT_ASSERT( !g_called.method );
318
5293e4b7
VZ
319 handler.Bind( MyEventType, &MyHandler::OnMyEvent, &handler, 0 );
320 handler.Unbind( MyEventType, &MyHandler::OnMyEvent, &handler, 0 );
a01ada05 321
5293e4b7
VZ
322 handler.Bind( MyEventType, &MyHandler::OnMyEvent, &handler, 0, 0 );
323 handler.Unbind( MyEventType, &MyHandler::OnMyEvent, &handler, 0, 0 );
a01ada05
VZ
324}
325
5293e4b7 326void EvtHandlerTestCase::BindMethodUsingBaseEvent()
a01ada05
VZ
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
5293e4b7 331 handler.Bind( MyEventType, &MyHandler::OnEvent, &handler );
f3ff831f
VZ
332 g_called.Reset();
333 handler.ProcessEvent(e);
334 CPPUNIT_ASSERT( g_called.method );
5293e4b7 335 handler.Unbind( MyEventType, &MyHandler::OnEvent, &handler );
f3ff831f
VZ
336 g_called.Reset();
337 handler.ProcessEvent(e);
338 CPPUNIT_ASSERT( !g_called.method );
b2238cc3 339
5293e4b7
VZ
340 handler.Bind( MyEventType, &MyHandler::OnEvent, &handler, 0 );
341 handler.Unbind( MyEventType, &MyHandler::OnEvent, &handler, 0 );
b2238cc3 342
5293e4b7
VZ
343 handler.Bind( MyEventType, &MyHandler::OnEvent, &handler, 0, 0 );
344 handler.Unbind( MyEventType, &MyHandler::OnEvent, &handler, 0, 0 );
f3ff831f 345}
b2238cc3 346
f3ff831f 347
5293e4b7 348void EvtHandlerTestCase::BindNonHandler()
f3ff831f
VZ
349{
350 // class method tests for class not derived from wxEvtHandler
351 MySink sink;
b2238cc3 352
5293e4b7 353 handler.Bind( MyEventType, &MySink::OnMyEvent, &sink );
f3ff831f
VZ
354 g_called.Reset();
355 handler.ProcessEvent(e);
356 CPPUNIT_ASSERT( g_called.method );
5293e4b7 357 handler.Unbind( MyEventType, &MySink::OnMyEvent, &sink );
f3ff831f
VZ
358 g_called.Reset();
359 handler.ProcessEvent(e);
360 CPPUNIT_ASSERT( !g_called.method );
361}
b2238cc3 362
5293e4b7 363void EvtHandlerTestCase::InvalidBind()
f3ff831f 364{
9b3ff3c0
VZ
365 // these calls shouldn't compile but we unfortunately can't check this
366 // automatically, you need to uncomment them manually and test that
367 // compilation does indeed fail
5293e4b7
VZ
368
369 //handler.Bind(MyEventType, GlobalOnAnotherEvent);
370 //IdleFunctor f; handler.Bind(MyEventType, f);
371 //handler.Bind(MyEventType, &MyHandler::StaticOnAnotherEvent);
372 //handler.Bind(MyEventType, &MyHandler::OnAnotherEvent, &handler);
373
374 // Test that this sample (discussed on the mailing list) doesn't compile:
375 // >struct C1 : wxEvtHandler { };
376 // >struct C2 : wxEvtHandler { void OnWhatever(wxEvent&) };
377 // >C1 c1;
378 // >c1.Connect(&C2::OnWhatever); // BOOM
379
380 //MySink mySink;
381 //MyHandler myHandler;
382 //myHandler.Bind( MyEventType, &MyHandler::OnMyEvent, &mySink );
b2238cc3
VZ
383}
384
f3ff831f 385#endif // !wxEVENTS_COMPATIBILITY_2_8