Propagate the event handling fixes to wxVarScrollHelperBase.

Merge the fixes to wxScrollHelperBase::ProcessEvent() of r64358, r64370,
r64464, r72939 and possibly a few more in wxVarScrollHelperBase to fix its
behaviour too, as it wasn't generating the correct events any longer.

Unfortunately the fix right now is to physically copy the code from one class
to the other. This should be avoided, of course, and a more in depth
refactoring should be done to move the code common to both classes into
wxAnyScrollHelperBase after 3.0 release. But for now continuing to duplicate
code is better than not having a working wxVarScrollHelperBase.

See #15357.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74814 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2013-09-15 00:15:12 +00:00
parent 010d821b31
commit dc2513650d
4 changed files with 56 additions and 21 deletions

View File

@@ -66,9 +66,19 @@ class WXDLLIMPEXP_CORE wxAnyScrollHelperBase
public: public:
wxEXPLICIT wxAnyScrollHelperBase(wxWindow* win); wxEXPLICIT wxAnyScrollHelperBase(wxWindow* win);
// Override this function to draw the graphic (or just process EVT_PAINT)
virtual void OnDraw(wxDC& WXUNUSED(dc)) { }
// change the DC origin according to the scroll position.
virtual void DoPrepareDC(wxDC& dc) = 0;
// Simple accessor for the window that is really being scrolled. // Simple accessor for the window that is really being scrolled.
wxWindow *GetTargetWindow() const { return m_targetWindow; } wxWindow *GetTargetWindow() const { return m_targetWindow; }
// The methods called from the window event handlers.
void HandleOnPaint(wxPaintEvent& event);
protected: protected:
// the window that receives the scroll events and the window to actually // the window that receives the scroll events and the window to actually
// scroll, respectively // scroll, respectively
@@ -199,10 +209,6 @@ public:
void SetTargetRect(const wxRect& rect) { m_rectToScroll = rect; } void SetTargetRect(const wxRect& rect) { m_rectToScroll = rect; }
wxRect GetTargetRect() const { return m_rectToScroll; } wxRect GetTargetRect() const { return m_rectToScroll; }
// Override this function to draw the graphic (or just process EVT_PAINT)
virtual void OnDraw(wxDC& WXUNUSED(dc)) { }
// change the DC origin according to the scroll position.
virtual void DoPrepareDC(wxDC& dc); virtual void DoPrepareDC(wxDC& dc);
// are we generating the autoscroll events? // are we generating the autoscroll events?
@@ -222,7 +228,6 @@ public:
// the methods to be called from the window event handlers // the methods to be called from the window event handlers
void HandleOnScroll(wxScrollWinEvent& event); void HandleOnScroll(wxScrollWinEvent& event);
void HandleOnSize(wxSizeEvent& event); void HandleOnSize(wxSizeEvent& event);
void HandleOnPaint(wxPaintEvent& event);
void HandleOnChar(wxKeyEvent& event); void HandleOnChar(wxKeyEvent& event);
void HandleOnMouseEnter(wxMouseEvent& event); void HandleOnMouseEnter(wxMouseEvent& event);
void HandleOnMouseLeave(wxMouseEvent& event); void HandleOnMouseLeave(wxMouseEvent& event);

View File

@@ -121,9 +121,6 @@ public:
// scrollbars (spreadsheet: only cell area will move). // scrollbars (spreadsheet: only cell area will move).
virtual void SetTargetWindow(wxWindow *target); virtual void SetTargetWindow(wxWindow *target);
// Override this function to draw the graphic (or just process EVT_PAINT)
//virtual void OnDraw(wxDC& WXUNUSED(dc)) { }
// change the DC origin according to the scroll position. To properly // change the DC origin according to the scroll position. To properly
// forward calls to wxWindow::Layout use WX_FORWARD_TO_SCROLL_HELPER() // forward calls to wxWindow::Layout use WX_FORWARD_TO_SCROLL_HELPER()
// derived class // derived class

View File

@@ -186,6 +186,9 @@ void wxAutoScrollTimer::Notify()
// wxScrollHelperEvtHandler // wxScrollHelperEvtHandler
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Notice that this method is currently duplicated in the method with the same
// name in wxVarScrollHelperEvtHandler class, until this is fixed, the other
// copy of the method needs to be modified every time this version is.
bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event) bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
{ {
wxEventType evType = event.GetEventType(); wxEventType evType = event.GetEventType();
@@ -817,7 +820,7 @@ void wxScrollHelperBase::HandleOnSize(wxSizeEvent& WXUNUSED(event))
// This calls OnDraw, having adjusted the origin according to the current // This calls OnDraw, having adjusted the origin according to the current
// scroll position // scroll position
void wxScrollHelperBase::HandleOnPaint(wxPaintEvent& WXUNUSED(event)) void wxAnyScrollHelperBase::HandleOnPaint(wxPaintEvent& WXUNUSED(event))
{ {
// don't use m_targetWindow here, this is always called for ourselves // don't use m_targetWindow here, this is always called for ourselves
wxPaintDC dc(m_win); wxPaintDC dc(m_win);

View File

@@ -61,12 +61,20 @@ private:
// wxVarScrollHelperEvtHandler implementation // wxVarScrollHelperEvtHandler implementation
// ============================================================================ // ============================================================================
// FIXME: This method totally duplicates a method with the same name in
// wxScrollHelperEvtHandler, we really should merge them by reusing the
// common parts in wxAnyScrollHelperBase.
bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event) bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
{ {
wxEventType evType = event.GetEventType(); wxEventType evType = event.GetEventType();
// pass it on to the real handler // Pass it on to the real handler: notice that we must not call
bool processed = wxEvtHandler::ProcessEvent(event); // ProcessEvent() on this object itself as it wouldn't pass it to the next
// handler (i.e. the real window) if we're called from a previous handler
// (as indicated by "process here only" flag being set) and we do want to
// execute the handler defined in the window we're associated with right
// now, without waiting until TryAfter() is called from wxEvtHandler.
bool processed = m_nextHandler->ProcessEvent(event);
// always process the size events ourselves, even if the user code handles // always process the size events ourselves, even if the user code handles
// them as well, as we need to AdjustScrollbars() // them as well, as we need to AdjustScrollbars()
@@ -78,18 +86,28 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
if ( evType == wxEVT_SIZE ) if ( evType == wxEVT_SIZE )
{ {
m_scrollHelper->HandleOnSize((wxSizeEvent &)event); m_scrollHelper->HandleOnSize((wxSizeEvent &)event);
return true;
return !event.GetSkipped();
} }
if ( processed ) if ( processed && event.IsCommandEvent())
return true;
// For wxEVT_PAINT the user code can either handle this event as usual or
// override virtual OnDraw(), so if the event hasn't been handled we need
// to call this virtual function ourselves.
if (
#ifndef __WXUNIVERSAL__
// in wxUniversal "processed" will always be true, because
// all windows use the paint event to draw themselves.
// In this case we can't use this flag to determine if a custom
// paint event handler already drew our window and we just
// call OnDraw() anyway.
!processed &&
#endif // !__WXUNIVERSAL__
evType == wxEVT_PAINT )
{ {
// normally, nothing more to do here - except if we have a command m_scrollHelper->HandleOnPaint((wxPaintEvent &)event);
// event return true;
if ( event.IsCommandEvent() )
{
return true;
}
} }
// reset the skipped flag (which might have been set to true in // reset the skipped flag (which might have been set to true in
@@ -112,7 +130,8 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
{ {
// it makes sense to indicate that we processed the message as we // it makes sense to indicate that we processed the message as we
// did scroll the window (and also notice that wxAutoScrollTimer // did scroll the window (and also notice that wxAutoScrollTimer
// relies on our return value for continuous scrolling) // relies on our return value to stop scrolling when we are at top
// or bottom already)
processed = true; processed = true;
wasSkipped = false; wasSkipped = false;
} }
@@ -126,6 +145,17 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
event.Skip(wasSkipped); event.Skip(wasSkipped);
// We called ProcessEvent() on the next handler, meaning that we explicitly
// worked around the request to process the event in this handler only. As
// explained above, this is unfortunately really necessary but the trouble
// is that the event will continue to be post-processed by the previous
// handler resulting in duplicate calls to event handlers. Call the special
// function below to prevent this from happening, base class DoTryChain()
// will check for it and behave accordingly.
//
// And if we're not called from DoTryChain(), this won't do anything anyhow.
event.DidntHonourProcessOnlyIn();
return processed; return processed;
} }