Fix wxScrollHelperEvtHandler broken by recent changes to event processing.
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
This commit is contained in:
parent
55a0f1e303
commit
ce45133ee7
@ -204,7 +204,7 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
|
||||
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()
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/app.h"
|
||||
#include "wx/event.h"
|
||||
#include "wx/scrolwin.h"
|
||||
#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 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:
|
||||
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)
|
||||
{
|
||||
if ( event.GetEventType() == TEST_EVT )
|
||||
if ( event.GetEventType() == m_evtType )
|
||||
g_str += 'o'; // "o" == "overridden"
|
||||
|
||||
return wxEvtHandler::ProcessEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
void OnTest(wxCommandEvent& event)
|
||||
void OnTest(wxEvent& event)
|
||||
{
|
||||
g_str += m_tag;
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
||||
const wxEventType m_evtType;
|
||||
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
|
||||
@ -91,6 +113,35 @@ private:
|
||||
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 )
|
||||
@ -127,12 +178,16 @@ private:
|
||||
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();
|
||||
void ScrollWindowWithoutHandler();
|
||||
void ScrollWindowWithHandler();
|
||||
|
||||
DECLARE_NO_COPY_CLASS(EventPropagationTestCase)
|
||||
};
|
||||
@ -207,3 +262,29 @@ void EventPropagationTestCase::WindowWithHandler()
|
||||
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 );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user