]> git.saurik.com Git - wxWidgets.git/blob - tests/events/propagation.cpp
don't start menu IDs at 0 to avoid an assert under Mac
[wxWidgets.git] / tests / events / propagation.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/events/propagation.cpp
3 // Purpose: Test events propagation
4 // Author: Vadim Zeitlin
5 // Created: 2009-01-16
6 // RCS-ID: $Id$
7 // Copyright: (c) 2009 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
20 #ifndef WX_PRECOMP
21 #include "wx/app.h"
22 #include "wx/event.h"
23 #include "wx/window.h"
24 #endif // WX_PRECOMP
25
26 #include "wx/scopeguard.h"
27
28 namespace
29 {
30
31 // this string will record the execution of all handlers
32 wxString g_str;
33
34 // a custom event
35 wxDEFINE_EVENT(TEST_EVT, wxCommandEvent);
36
37 // a custom event handler
38 class TestEvtHandler : public wxEvtHandler
39 {
40 public:
41 TestEvtHandler(char tag)
42 : m_tag(tag)
43 {
44 Connect(TEST_EVT, wxCommandEventHandler(TestEvtHandler::OnTest));
45 }
46
47 // override ProcessEvent() to confirm that it is called for all event
48 // handlers in the chain
49 virtual bool ProcessEvent(wxEvent& event)
50 {
51 if ( event.GetEventType() == TEST_EVT )
52 g_str += 'o'; // "o" == "overridden"
53
54 return wxEvtHandler::ProcessEvent(event);
55 }
56
57 private:
58 void OnTest(wxCommandEvent& event)
59 {
60 g_str += m_tag;
61
62 event.Skip();
63 }
64
65 const char m_tag;
66
67 DECLARE_NO_COPY_CLASS(TestEvtHandler)
68 };
69
70 // a window handling the test event
71 class TestWindow : public wxWindow
72 {
73 public:
74 TestWindow(wxWindow *parent, char tag)
75 : wxWindow(parent, wxID_ANY),
76 m_tag(tag)
77 {
78 Connect(TEST_EVT, wxCommandEventHandler(TestWindow::OnTest));
79 }
80
81 private:
82 void OnTest(wxCommandEvent& event)
83 {
84 g_str += m_tag;
85
86 event.Skip();
87 }
88
89 const char m_tag;
90
91 DECLARE_NO_COPY_CLASS(TestWindow)
92 };
93
94 int DoFilterEvent(wxEvent& event)
95 {
96 if ( event.GetEventType() == TEST_EVT )
97 g_str += 'a';
98
99 return -1;
100 }
101
102 bool DoProcessEvent(wxEvent& event)
103 {
104 if ( event.GetEventType() == TEST_EVT )
105 g_str += 'A';
106
107 return false;
108 }
109
110 } // anonymous namespace
111
112 // --------------------------------------------------------------------------
113 // test class
114 // --------------------------------------------------------------------------
115
116 class EventPropagationTestCase : public CppUnit::TestCase
117 {
118 public:
119 EventPropagationTestCase() {}
120
121 virtual void setUp();
122 virtual void tearDown();
123
124 private:
125 CPPUNIT_TEST_SUITE( EventPropagationTestCase );
126 CPPUNIT_TEST( OneHandler );
127 CPPUNIT_TEST( TwoHandlers );
128 CPPUNIT_TEST( WindowWithoutHandler );
129 CPPUNIT_TEST( WindowWithHandler );
130 CPPUNIT_TEST_SUITE_END();
131
132 void OneHandler();
133 void TwoHandlers();
134 void WindowWithoutHandler();
135 void WindowWithHandler();
136
137 DECLARE_NO_COPY_CLASS(EventPropagationTestCase)
138 };
139
140 // register in the unnamed registry so that these tests are run by default
141 CPPUNIT_TEST_SUITE_REGISTRATION( EventPropagationTestCase );
142
143 // also include in it's own registry so that these tests can be run alone
144 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( EventPropagationTestCase, "EventPropagationTestCase" );
145
146 void EventPropagationTestCase::setUp()
147 {
148 SetFilterEventFunc(DoFilterEvent);
149 SetProcessEventFunc(DoProcessEvent);
150
151 g_str.clear();
152 }
153
154 void EventPropagationTestCase::tearDown()
155 {
156 SetFilterEventFunc(NULL);
157 SetProcessEventFunc(NULL);
158 }
159
160 void EventPropagationTestCase::OneHandler()
161 {
162 wxCommandEvent event(TEST_EVT);
163 TestEvtHandler h1('1');
164 h1.ProcessEvent(event);
165 CPPUNIT_ASSERT_EQUAL( "oa1A", g_str );
166 }
167
168 void EventPropagationTestCase::TwoHandlers()
169 {
170 wxCommandEvent event(TEST_EVT);
171 TestEvtHandler h1('1');
172 TestEvtHandler h2('2');
173 h1.SetNextHandler(&h2);
174 h2.SetPreviousHandler(&h1);
175 h1.ProcessEvent(event);
176 CPPUNIT_ASSERT_EQUAL( "oa1o2A", g_str );
177 }
178
179 void EventPropagationTestCase::WindowWithoutHandler()
180 {
181 wxCommandEvent event(TEST_EVT);
182 TestWindow * const parent = new TestWindow(wxTheApp->GetTopWindow(), 'p');
183 wxON_BLOCK_EXIT_OBJ0( *parent, wxWindow::Destroy );
184
185 TestWindow * const child = new TestWindow(parent, 'c');
186
187 child->GetEventHandler()->ProcessEvent(event);
188 CPPUNIT_ASSERT_EQUAL( "acpA", g_str );
189 }
190
191 void EventPropagationTestCase::WindowWithHandler()
192 {
193 wxCommandEvent event(TEST_EVT);
194 TestWindow * const parent = new TestWindow(wxTheApp->GetTopWindow(), 'p');
195 wxON_BLOCK_EXIT_OBJ0( *parent, wxWindow::Destroy );
196
197 TestWindow * const child = new TestWindow(parent, 'c');
198
199 TestEvtHandler h1('1');
200 child->PushEventHandler(&h1);
201 wxON_BLOCK_EXIT_OBJ1( *child, wxWindow::PopEventHandler, false );
202 TestEvtHandler h2('2');
203 child->PushEventHandler(&h2);
204 wxON_BLOCK_EXIT_OBJ1( *child, wxWindow::PopEventHandler, false );
205
206 child->HandleWindowEvent(event);
207 CPPUNIT_ASSERT_EQUAL( "oa2o1cpA", g_str );
208 }
209