]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/vscroll.cpp
Somehow, setting a tint color makes gauge work :/.
[wxWidgets.git] / src / generic / vscroll.cpp
index 809ae48576edf1e2676329b89c77e6223d2b2fd3..efbef67e3344e8953c598ea2e733dbdd28e4c1a4 100644 (file)
@@ -4,7 +4,6 @@
 // Author:      Vadim Zeitlin
 // Modified by: Brad Anderson, David Warkentin
 // Created:     30.05.03
-// RCS-ID:      $Id$
 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -31,6 +30,8 @@
 
 #include "wx/vscroll.h"
 
+#include "wx/utils.h"   // For wxMin/wxMax().
+
 // ============================================================================
 // wxVarScrollHelperEvtHandler declaration
 // ============================================================================
@@ -60,12 +61,20 @@ private:
 // 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();
 
-    // 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()
@@ -77,18 +86,28 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& 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
@@ -97,10 +116,6 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
     if ( wasSkipped )
         event.Skip(false);
 
-    // reset the skipped flag to false as it might have been set to true in
-    // ProcessEvent() above
-    event.Skip(false);
-
     if ( evType == wxEVT_SCROLLWIN_TOP ||
          evType == wxEVT_SCROLLWIN_BOTTOM ||
          evType == wxEVT_SCROLLWIN_LINEUP ||
@@ -115,20 +130,44 @@ 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
-            // 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;
         }
     }
 #if wxUSE_MOUSEWHEEL
+    // Use GTK's own scroll wheel handling in GtkScrolledWindow
+#ifndef __WXGTK20__
     else if ( evType == wxEVT_MOUSEWHEEL )
     {
         m_scrollHelper->HandleOnMouseWheel((wxMouseEvent &)event);
     }
+#endif
 #endif // wxUSE_MOUSEWHEEL
+    else if ( evType == wxEVT_CHAR &&
+                (m_scrollHelper->GetOrientation() == wxVERTICAL) )
+    {
+        m_scrollHelper->HandleOnChar((wxKeyEvent &)event);
+        if ( !event.GetSkipped() )
+        {
+            processed = true;
+            wasSkipped = false;
+        }
+    }
 
-    if ( processed )
-        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;
 }
@@ -143,9 +182,8 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
 // ----------------------------------------------------------------------------
 
 wxVarScrollHelperBase::wxVarScrollHelperBase(wxWindow *win)
+    : wxAnyScrollHelperBase(win)
 {
-    wxASSERT_MSG( win, wxT("associated window can't be NULL in wxVarScrollHelperBase") );
-
 #if wxUSE_MOUSEWHEEL
     m_sumWheelRotation = 0;
 #endif
@@ -154,17 +192,11 @@ wxVarScrollHelperBase::wxVarScrollHelperBase(wxWindow *win)
     m_sizeTotal = 0;
     m_unitFirst = 0;
 
-    m_win =
-    m_targetWindow = NULL;
-
     m_physicalScrolling = true;
     m_handler = NULL;
 
-    m_win = win;
-
     // by default, the associated window is also the target window
     DoSetTargetWindow(win);
-
 }
 
 wxVarScrollHelperBase::~wxVarScrollHelperBase()
@@ -313,14 +345,17 @@ size_t wxVarScrollHelperBase::GetNewScrollPosition(wxScrollWinEvent& event) cons
     }
     else if ( evtType == wxEVT_SCROLLWIN_PAGEUP )
     {
-        return FindFirstVisibleFromLast(m_unitFirst);
+        // Page up should do at least as much as line up.
+        return wxMin(FindFirstVisibleFromLast(m_unitFirst),
+                    m_unitFirst ? m_unitFirst - 1 : 0);
     }
     else if ( evtType == wxEVT_SCROLLWIN_PAGEDOWN )
     {
+        // And page down should do at least as much as line down.
         if ( GetVisibleEnd() )
-            return GetVisibleEnd() - 1;
+            return wxMax(GetVisibleEnd() - 1, m_unitFirst + 1);
         else
-            return GetVisibleEnd();
+            return wxMax(GetVisibleEnd(), m_unitFirst + 1);
     }
     else if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE )
     {
@@ -487,10 +522,10 @@ void wxVarScrollHelperBase::RefreshUnits(size_t from, size_t to)
         to = GetVisibleEnd();
 
     // calculate the rect occupied by these units on screen
-    int orient_size, nonorient_size, orient_pos;
-    orient_size = nonorient_size = orient_pos = 0;
+    int orient_size = 0,
+        orient_pos = 0;
 
-    nonorient_size = GetNonOrientationTargetSize();
+    int nonorient_size = GetNonOrientationTargetSize();
 
     for ( size_t nBefore = GetVisibleBegin();
           nBefore < from;
@@ -827,7 +862,7 @@ void wxVarHVScrollHelper::RefreshRowColumn(size_t row, size_t column)
         h_rect.x += OnGetColumnWidth(n);
     }
 
-    // refresh but specialize the behavior if we have a single target window
+    // refresh but specialize the behaviour if we have a single target window
     if ( wxVarVScrollHelper::GetTargetWindow() == wxVarHScrollHelper::GetTargetWindow() )
     {
         v_rect.x = h_rect.x;
@@ -894,7 +929,7 @@ void wxVarHVScrollHelper::RefreshRowsColumns(size_t fromRow, size_t toRow,
         h_rect.width += OnGetColumnWidth(nBetween);
     }
 
-    // refresh but specialize the behavior if we have a single target window
+    // refresh but specialize the behaviour if we have a single target window
     if ( wxVarVScrollHelper::GetTargetWindow() == wxVarHScrollHelper::GetTargetWindow() )
     {
         v_rect.x = h_rect.x;