]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix wxScrollHelperEvtHandler broken by recent changes to event processing.
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 20 May 2010 17:33:26 +0000 (17:33 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 20 May 2010 17:33:26 +0000 (17:33 +0000)
Use ProcessEventLocally() added in r64261 (which was probably the one to break
this) to forward event to the window itself instead of ProcessEvent() in
wxScrollHelperEvtHandler::ProcessEvent() implementation. Calling ProcessEvent()
didn't work any more in a case when another event handler was pushed on a
wxScrolledWindow: in this case the EVT_SIZE and EVT_PAINT handlers defined in
the window itself were not called at all any more.

Add a unit test checking for the even more tortuous than usual event
processing path in this particular case.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64358 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/generic/scrlwing.cpp
tests/events/propagation.cpp

index 6e0cca186f6688e32be6f89bfa726bc4fec230d3..bc1d5cdbde502775016d864e75fe98e52225f78b 100644 (file)
@@ -204,7 +204,7 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
     m_hasDrawnWindow = true;
 
     // pass it on to the real handler
     m_hasDrawnWindow = true;
 
     // pass it on to the real handler
-    bool processed = wxEvtHandler::ProcessEvent(event);
+    bool processed = m_nextHandler->ProcessEventLocally(event);
 
     // always process the size events ourselves, even if the user code handles
     // them as well, as we need to AdjustScrollbars()
 
     // always process the size events ourselves, even if the user code handles
     // them as well, as we need to AdjustScrollbars()
index e240dd6e17736d9b2459fbc4de307320ac73d215..f27395f1a5bac02f6ee64bef7c30bf58293c4d23 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef WX_PRECOMP
     #include "wx/app.h"
     #include "wx/event.h"
 #ifndef WX_PRECOMP
     #include "wx/app.h"
     #include "wx/event.h"
+    #include "wx/scrolwin.h"
     #include "wx/window.h"
 #endif // WX_PRECOMP
 
     #include "wx/window.h"
 #endif // WX_PRECOMP
 
@@ -34,37 +35,58 @@ wxString g_str;
 // a custom event
 wxDEFINE_EVENT(TEST_EVT, wxCommandEvent);
 
 // a custom event
 wxDEFINE_EVENT(TEST_EVT, wxCommandEvent);
 
-// a custom event handler
-class TestEvtHandler : public wxEvtHandler
+// a custom event handler tracing the propagation of the events of the
+// specified types
+template <class Event>
+class TestEvtHandlerBase : public wxEvtHandler
 {
 public:
 {
 public:
-    TestEvtHandler(char tag)
-        : m_tag(tag)
+    TestEvtHandlerBase(wxEventType evtType, char tag)
+        : m_evtType(evtType),
+          m_tag(tag)
     {
     {
-        Connect(TEST_EVT, wxCommandEventHandler(TestEvtHandler::OnTest));
+        Connect(evtType,
+                static_cast<wxEventFunction>(&TestEvtHandlerBase::OnTest));
     }
 
     // override ProcessEvent() to confirm that it is called for all event
     // handlers in the chain
     virtual bool ProcessEvent(wxEvent& event)
     {
     }
 
     // override ProcessEvent() to confirm that it is called for all event
     // handlers in the chain
     virtual bool ProcessEvent(wxEvent& event)
     {
-        if ( event.GetEventType() == TEST_EVT )
+        if ( event.GetEventType() == m_evtType )
             g_str += 'o'; // "o" == "overridden"
 
         return wxEvtHandler::ProcessEvent(event);
     }
 
 private:
             g_str += 'o'; // "o" == "overridden"
 
         return wxEvtHandler::ProcessEvent(event);
     }
 
 private:
-    void OnTest(wxCommandEvent& event)
+    void OnTest(wxEvent& event)
     {
         g_str += m_tag;
 
         event.Skip();
     }
 
     {
         g_str += m_tag;
 
         event.Skip();
     }
 
+    const wxEventType m_evtType;
     const char m_tag;
 
     const char m_tag;
 
-    DECLARE_NO_COPY_CLASS(TestEvtHandler)
+    wxDECLARE_NO_COPY_TEMPLATE_CLASS(TestEvtHandlerBase, Event);
+};
+
+struct TestEvtHandler : TestEvtHandlerBase<wxCommandEvent>
+{
+    TestEvtHandler(char tag)
+        : TestEvtHandlerBase<wxCommandEvent>(TEST_EVT, tag)
+    {
+    }
+};
+
+struct TestPaintEvtHandler : TestEvtHandlerBase<wxPaintEvent>
+{
+    TestPaintEvtHandler(char tag)
+        : TestEvtHandlerBase<wxPaintEvent>(wxEVT_PAINT, tag)
+    {
+    }
 };
 
 // a window handling the test event
 };
 
 // a window handling the test event
@@ -91,6 +113,35 @@ private:
     DECLARE_NO_COPY_CLASS(TestWindow)
 };
 
     DECLARE_NO_COPY_CLASS(TestWindow)
 };
 
+// a scroll window handling paint event: we want to have a special test case
+// for this because the event propagation is complicated even further than
+// usual here by the presence of wxScrollHelperEvtHandler in the event handlers
+// chain and the fact that OnDraw() virtual method must be called if EVT_PAINT
+// is not handled
+class TestScrollWindow : public wxScrolledWindow
+{
+public:
+    TestScrollWindow(wxWindow *parent)
+        : wxScrolledWindow(parent, wxID_ANY)
+    {
+        Connect(wxEVT_PAINT, wxPaintEventHandler(TestScrollWindow::OnPaint));
+    }
+
+    virtual void OnDraw(wxDC& WXUNUSED(dc))
+    {
+        g_str += 'D';   // draw
+    }
+
+private:
+    void OnPaint(wxPaintEvent& event)
+    {
+        g_str += 'P';   // paint
+        event.Skip();
+    }
+
+    wxDECLARE_NO_COPY_CLASS(TestScrollWindow);
+};
+
 int DoFilterEvent(wxEvent& event)
 {
     if ( event.GetEventType() == TEST_EVT )
 int DoFilterEvent(wxEvent& event)
 {
     if ( event.GetEventType() == TEST_EVT )
@@ -127,12 +178,16 @@ private:
         CPPUNIT_TEST( TwoHandlers );
         CPPUNIT_TEST( WindowWithoutHandler );
         CPPUNIT_TEST( WindowWithHandler );
         CPPUNIT_TEST( TwoHandlers );
         CPPUNIT_TEST( WindowWithoutHandler );
         CPPUNIT_TEST( WindowWithHandler );
+        CPPUNIT_TEST( ScrollWindowWithoutHandler );
+        CPPUNIT_TEST( ScrollWindowWithHandler );
     CPPUNIT_TEST_SUITE_END();
 
     void OneHandler();
     void TwoHandlers();
     void WindowWithoutHandler();
     void WindowWithHandler();
     CPPUNIT_TEST_SUITE_END();
 
     void OneHandler();
     void TwoHandlers();
     void WindowWithoutHandler();
     void WindowWithHandler();
+    void ScrollWindowWithoutHandler();
+    void ScrollWindowWithHandler();
 
     DECLARE_NO_COPY_CLASS(EventPropagationTestCase)
 };
 
     DECLARE_NO_COPY_CLASS(EventPropagationTestCase)
 };
@@ -207,3 +262,29 @@ void EventPropagationTestCase::WindowWithHandler()
     CPPUNIT_ASSERT_EQUAL( "oa2o1cpA", g_str );
 }
 
     CPPUNIT_ASSERT_EQUAL( "oa2o1cpA", g_str );
 }
 
+void EventPropagationTestCase::ScrollWindowWithoutHandler()
+{
+    TestScrollWindow * const
+        win = new TestScrollWindow(wxTheApp->GetTopWindow());
+    wxON_BLOCK_EXIT_OBJ0( *win, wxWindow::Destroy );
+
+    wxPaintEvent event(win->GetId());
+    win->ProcessWindowEvent(event);
+    CPPUNIT_ASSERT_EQUAL( "PD", g_str );
+}
+
+void EventPropagationTestCase::ScrollWindowWithHandler()
+{
+    TestScrollWindow * const
+        win = new TestScrollWindow(wxTheApp->GetTopWindow());
+    wxON_BLOCK_EXIT_OBJ0( *win, wxWindow::Destroy );
+
+    TestPaintEvtHandler h('h');
+    win->PushEventHandler(&h);
+    wxON_BLOCK_EXIT_OBJ1( *win, wxWindow::PopEventHandler, false );
+
+    wxPaintEvent event(win->GetId());
+    win->ProcessWindowEvent(event);
+    CPPUNIT_ASSERT_EQUAL( "ohPD", g_str );
+}
+