]> git.saurik.com Git - wxWidgets.git/commitdiff
Propagate the event handling fixes to wxVarScrollHelperBase.
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 15 Sep 2013 00:15:12 +0000 (00:15 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 15 Sep 2013 00:15:12 +0000 (00:15 +0000)
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

include/wx/scrolwin.h
include/wx/vscroll.h
src/generic/scrlwing.cpp
src/generic/vscroll.cpp

index 3e22eb59c2775a02bd56a9f14d79c48d260e7228..3ea03fcc60ad18300129426e627af05b895f4232 100644 (file)
@@ -66,9 +66,19 @@ class WXDLLIMPEXP_CORE wxAnyScrollHelperBase
 public:
     wxEXPLICIT wxAnyScrollHelperBase(wxWindow* win);
 
 public:
     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.
     wxWindow *GetTargetWindow() const { return m_targetWindow; }
 
     // Simple accessor for the window that is really being scrolled.
     wxWindow *GetTargetWindow() const { return m_targetWindow; }
 
+
+    // The methods called from the window event handlers.
+    void HandleOnPaint(wxPaintEvent& event);
+
 protected:
     // the window that receives the scroll events and the window to actually
     // scroll, respectively
 protected:
     // the window that receives the scroll events and the window to actually
     // scroll, respectively
@@ -199,10 +209,6 @@ public:
     void SetTargetRect(const wxRect& rect) { m_rectToScroll = rect; }
     wxRect GetTargetRect() const { return m_rectToScroll; }
 
     void SetTargetRect(const wxRect& rect) { m_rectToScroll = rect; }
     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);
 
     // are we generating the autoscroll events?
     virtual void DoPrepareDC(wxDC& dc);
 
     // are we generating the autoscroll events?
@@ -222,7 +228,6 @@ public:
     // the methods to be called from the window event handlers
     void HandleOnScroll(wxScrollWinEvent& event);
     void HandleOnSize(wxSizeEvent& event);
     // the methods to be called from the window event handlers
     void HandleOnScroll(wxScrollWinEvent& event);
     void HandleOnSize(wxSizeEvent& event);
-    void HandleOnPaint(wxPaintEvent& event);
     void HandleOnChar(wxKeyEvent& event);
     void HandleOnMouseEnter(wxMouseEvent& event);
     void HandleOnMouseLeave(wxMouseEvent& event);
     void HandleOnChar(wxKeyEvent& event);
     void HandleOnMouseEnter(wxMouseEvent& event);
     void HandleOnMouseLeave(wxMouseEvent& event);
index 51e2b0b58c31412e1ac35004eb11b74a35545afd..2312d78f0bef6dcd1bc6900e8e21b0dd8a929e49 100644 (file)
@@ -121,9 +121,6 @@ public:
     // scrollbars (spreadsheet: only cell area will move).
     virtual void SetTargetWindow(wxWindow *target);
 
     // scrollbars (spreadsheet: only cell area will move).
     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
     // forward calls to wxWindow::Layout use WX_FORWARD_TO_SCROLL_HELPER()
     // derived class
     // change the DC origin according to the scroll position. To properly
     // forward calls to wxWindow::Layout use WX_FORWARD_TO_SCROLL_HELPER()
     // derived class
index 1323e450608d0cf251ec47852d13ab57ecfd685e..5fb622b242a51f7a60d324c75624ff4cd065406e 100644 (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)
 {
     wxEventType evType = event.GetEventType();
 bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
 {
     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
 // scroll position
 
 // This calls OnDraw, having adjusted the origin according to the current
 // 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
     wxPaintDC dc(m_win);
 {
     // don't use m_targetWindow here, this is always called for ourselves
     wxPaintDC dc(m_win);
index 905d7cc4d0048d92d559f295ed0abe0fcd0eb123..0048bd75b02b5faf8962e9168cde46e6698fca64 100644 (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)
 {
     wxEventType evType = event.GetEventType();
 
 bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
 {
     wxEventType evType = event.GetEventType();
 
-    // pass it on to the real handler
-    bool processed = wxEvtHandler::ProcessEvent(event);
+    // Pass it on to the real handler: notice that we must not call
+    // 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
     // 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()
@@ -78,18 +86,28 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
     if ( evType == wxEVT_SIZE )
     {
         m_scrollHelper->HandleOnSize((wxSizeEvent &)event);
     if ( evType == wxEVT_SIZE )
     {
         m_scrollHelper->HandleOnSize((wxSizeEvent &)event);
-
-        return !event.GetSkipped();
+        return true;
     }
 
     }
 
-    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
-        // event
-        if ( event.IsCommandEvent() )
-        {
-            return true;
-        }
+        m_scrollHelper->HandleOnPaint((wxPaintEvent &)event);
+        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
             // did scroll the window (and also notice that wxAutoScrollTimer
         {
             // it makes sense to indicate that we processed the message as we
             // 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;
             wasSkipped = false;
         }
             processed = true;
             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;
 }