1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/events/propagation.cpp
3 // Purpose: Test events propagation
4 // Author: Vadim Zeitlin
7 // Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
23 #include "wx/scrolwin.h"
24 #include "wx/window.h"
27 #include "wx/scopeguard.h"
32 // this string will record the execution of all handlers
36 wxDEFINE_EVENT(TEST_EVT
, wxCommandEvent
);
38 // a custom event handler tracing the propagation of the events of the
40 template <class Event
>
41 class TestEvtHandlerBase
: public wxEvtHandler
44 TestEvtHandlerBase(wxEventType evtType
, char tag
)
49 static_cast<wxEventFunction
>(&TestEvtHandlerBase::OnTest
));
52 // override ProcessEvent() to confirm that it is called for all event
53 // handlers in the chain
54 virtual bool ProcessEvent(wxEvent
& event
)
56 if ( event
.GetEventType() == m_evtType
)
57 g_str
+= 'o'; // "o" == "overridden"
59 return wxEvtHandler::ProcessEvent(event
);
63 void OnTest(wxEvent
& event
)
70 const wxEventType m_evtType
;
73 wxDECLARE_NO_COPY_TEMPLATE_CLASS(TestEvtHandlerBase
, Event
);
76 struct TestEvtHandler
: TestEvtHandlerBase
<wxCommandEvent
>
78 TestEvtHandler(char tag
)
79 : TestEvtHandlerBase
<wxCommandEvent
>(TEST_EVT
, tag
)
84 struct TestPaintEvtHandler
: TestEvtHandlerBase
<wxPaintEvent
>
86 TestPaintEvtHandler(char tag
)
87 : TestEvtHandlerBase
<wxPaintEvent
>(wxEVT_PAINT
, tag
)
92 // a window handling the test event
93 class TestWindow
: public wxWindow
96 TestWindow(wxWindow
*parent
, char tag
)
97 : wxWindow(parent
, wxID_ANY
),
100 Connect(TEST_EVT
, wxCommandEventHandler(TestWindow::OnTest
));
104 void OnTest(wxCommandEvent
& event
)
113 DECLARE_NO_COPY_CLASS(TestWindow
)
116 // a scroll window handling paint event: we want to have a special test case
117 // for this because the event propagation is complicated even further than
118 // usual here by the presence of wxScrollHelperEvtHandler in the event handlers
119 // chain and the fact that OnDraw() virtual method must be called if EVT_PAINT
121 class TestScrollWindow
: public wxScrolledWindow
124 TestScrollWindow(wxWindow
*parent
)
125 : wxScrolledWindow(parent
, wxID_ANY
)
127 Connect(wxEVT_PAINT
, wxPaintEventHandler(TestScrollWindow::OnPaint
));
130 virtual void OnDraw(wxDC
& WXUNUSED(dc
))
132 g_str
+= 'D'; // draw
136 void OnPaint(wxPaintEvent
& event
)
138 g_str
+= 'P'; // paint
142 wxDECLARE_NO_COPY_CLASS(TestScrollWindow
);
145 int DoFilterEvent(wxEvent
& event
)
147 if ( event
.GetEventType() == TEST_EVT
)
153 bool DoProcessEvent(wxEvent
& event
)
155 if ( event
.GetEventType() == TEST_EVT
)
161 } // anonymous namespace
163 // --------------------------------------------------------------------------
165 // --------------------------------------------------------------------------
167 class EventPropagationTestCase
: public CppUnit::TestCase
170 EventPropagationTestCase() {}
172 virtual void setUp();
173 virtual void tearDown();
176 CPPUNIT_TEST_SUITE( EventPropagationTestCase
);
177 CPPUNIT_TEST( OneHandler
);
178 CPPUNIT_TEST( TwoHandlers
);
179 CPPUNIT_TEST( WindowWithoutHandler
);
180 CPPUNIT_TEST( WindowWithHandler
);
181 CPPUNIT_TEST( ScrollWindowWithoutHandler
);
182 CPPUNIT_TEST( ScrollWindowWithHandler
);
183 CPPUNIT_TEST_SUITE_END();
187 void WindowWithoutHandler();
188 void WindowWithHandler();
189 void ScrollWindowWithoutHandler();
190 void ScrollWindowWithHandler();
192 DECLARE_NO_COPY_CLASS(EventPropagationTestCase
)
195 // register in the unnamed registry so that these tests are run by default
196 CPPUNIT_TEST_SUITE_REGISTRATION( EventPropagationTestCase
);
198 // also include in it's own registry so that these tests can be run alone
199 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EventPropagationTestCase
, "EventPropagationTestCase" );
201 void EventPropagationTestCase::setUp()
203 SetFilterEventFunc(DoFilterEvent
);
204 SetProcessEventFunc(DoProcessEvent
);
209 void EventPropagationTestCase::tearDown()
211 SetFilterEventFunc(NULL
);
212 SetProcessEventFunc(NULL
);
215 void EventPropagationTestCase::OneHandler()
217 wxCommandEvent
event(TEST_EVT
);
218 TestEvtHandler
h1('1');
219 h1
.ProcessEvent(event
);
220 CPPUNIT_ASSERT_EQUAL( "oa1A", g_str
);
223 void EventPropagationTestCase::TwoHandlers()
225 wxCommandEvent
event(TEST_EVT
);
226 TestEvtHandler
h1('1');
227 TestEvtHandler
h2('2');
228 h1
.SetNextHandler(&h2
);
229 h2
.SetPreviousHandler(&h1
);
230 h1
.ProcessEvent(event
);
231 CPPUNIT_ASSERT_EQUAL( "oa1o2A", g_str
);
234 void EventPropagationTestCase::WindowWithoutHandler()
236 wxCommandEvent
event(TEST_EVT
);
237 TestWindow
* const parent
= new TestWindow(wxTheApp
->GetTopWindow(), 'p');
238 wxON_BLOCK_EXIT_OBJ0( *parent
, wxWindow::Destroy
);
240 TestWindow
* const child
= new TestWindow(parent
, 'c');
242 child
->GetEventHandler()->ProcessEvent(event
);
243 CPPUNIT_ASSERT_EQUAL( "acpA", g_str
);
246 void EventPropagationTestCase::WindowWithHandler()
248 wxCommandEvent
event(TEST_EVT
);
249 TestWindow
* const parent
= new TestWindow(wxTheApp
->GetTopWindow(), 'p');
250 wxON_BLOCK_EXIT_OBJ0( *parent
, wxWindow::Destroy
);
252 TestWindow
* const child
= new TestWindow(parent
, 'c');
254 TestEvtHandler
h1('1');
255 child
->PushEventHandler(&h1
);
256 wxON_BLOCK_EXIT_OBJ1( *child
, wxWindow::PopEventHandler
, false );
257 TestEvtHandler
h2('2');
258 child
->PushEventHandler(&h2
);
259 wxON_BLOCK_EXIT_OBJ1( *child
, wxWindow::PopEventHandler
, false );
261 child
->HandleWindowEvent(event
);
262 CPPUNIT_ASSERT_EQUAL( "oa2o1cpA", g_str
);
265 void EventPropagationTestCase::ScrollWindowWithoutHandler()
267 TestScrollWindow
* const
268 win
= new TestScrollWindow(wxTheApp
->GetTopWindow());
269 wxON_BLOCK_EXIT_OBJ0( *win
, wxWindow::Destroy
);
271 wxPaintEvent
event(win
->GetId());
272 win
->ProcessWindowEvent(event
);
273 CPPUNIT_ASSERT_EQUAL( "PD", g_str
);
276 void EventPropagationTestCase::ScrollWindowWithHandler()
278 TestScrollWindow
* const
279 win
= new TestScrollWindow(wxTheApp
->GetTopWindow());
280 wxON_BLOCK_EXIT_OBJ0( *win
, wxWindow::Destroy
);
282 TestPaintEvtHandler
h('h');
283 win
->PushEventHandler(&h
);
284 wxON_BLOCK_EXIT_OBJ1( *win
, wxWindow::PopEventHandler
, false );
286 wxPaintEvent
event(win
->GetId());
287 win
->ProcessWindowEvent(event
);
288 CPPUNIT_ASSERT_EQUAL( "ohPD", g_str
);