]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/scrlwing.cpp
wxRTC: fixed guidelines overwriting adjacent cell borders; corrected capitalisation...
[wxWidgets.git] / src / generic / scrlwing.cpp
index 6e0cca186f6688e32be6f89bfa726bc4fec230d3..62918152093df6ec1027255f761b19d36135e76e 100644 (file)
@@ -5,7 +5,6 @@
 // Modified by: Vadim Zeitlin on 31.08.00: wxScrollHelper allows to implement.
 //              Ron Lee on 10.4.02:  virtual size / auto scrollbars et al.
 // Created:     01/02/97
-// RCS-ID:      $Id$
 // Copyright:   (c) wxWidgets team
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -79,13 +78,9 @@ public:
 
     virtual bool ProcessEvent(wxEvent& event);
 
-    void ResetDrawnFlag() { m_hasDrawnWindow = false; }
-
 private:
     wxScrollHelperBase *m_scrollHelper;
 
-    bool m_hasDrawnWindow;
-
     wxDECLARE_NO_COPY_CLASS(wxScrollHelperEvtHandler);
 };
 
@@ -147,6 +142,7 @@ void wxAutoScrollTimer::Notify()
         // first scroll the window if we are allowed to do it
         wxScrollWinEvent event1(m_eventType, m_pos, m_orient);
         event1.SetEventObject(m_win);
+        event1.SetId(m_win->GetId());
         if ( m_scrollHelper->SendAutoScrollEvents(event1) &&
                 m_win->GetEventHandler()->ProcessEvent(event1) )
         {
@@ -165,7 +161,16 @@ void wxAutoScrollTimer::Notify()
 
             event2.SetEventObject(m_win);
 
-            // FIXME: we don't fill in the other members - ok?
+            wxMouseState mouseState = wxGetMouseState();
+
+            event2.m_leftDown = mouseState.LeftIsDown();
+            event2.m_middleDown = mouseState.MiddleIsDown();
+            event2.m_rightDown = mouseState.RightIsDown();
+
+            event2.m_shiftDown = mouseState.ShiftDown();
+            event2.m_controlDown = mouseState.ControlDown();
+            event2.m_altDown = mouseState.AltDown();
+            event2.m_metaDown = mouseState.MetaDown();
 
             m_win->GetEventHandler()->ProcessEvent(event2);
         }
@@ -181,30 +186,20 @@ void wxAutoScrollTimer::Notify()
 // 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();
 
-    // the explanation of wxEVT_PAINT processing hack: for historic reasons
-    // there are 2 ways to process this event in classes deriving from
-    // wxScrolledWindow. The user code may
-    //
-    //  1. override wxScrolledWindow::OnDraw(dc)
-    //  2. define its own OnPaint() handler
-    //
-    // In addition, in wxUniversal wxWindow defines OnPaint() itself and
-    // always processes the draw event, so we can't just try the window
-    // OnPaint() first and call our HandleOnPaint() if it doesn't process it
-    // (the latter would never be called in wxUniversal).
-    //
-    // So the solution is to have a flag telling us whether the user code drew
-    // anything in the window. We set it to true here but reset it to false in
-    // wxScrolledWindow::OnPaint() handler (which wouldn't be called if the
-    // user code defined OnPaint() in the derived class)
-    m_hasDrawnWindow = true;
-
-    // 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()
@@ -216,22 +211,25 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
     if ( evType == wxEVT_SIZE )
     {
         m_scrollHelper->HandleOnSize((wxSizeEvent &)event);
-
         return true;
     }
 
-    if ( processed )
-    {
-        // normally, nothing more to do here - except if it was a paint event
-        // which wasn't really processed, then we'll try to call our
-        // OnDraw() below (from HandleOnPaint)
-        if ( m_hasDrawnWindow || event.IsCommandEvent() )
-        {
-            return true;
-        }
-    }
+    if ( processed && event.IsCommandEvent())
+        return true;
 
-    if ( evType == wxEVT_PAINT )
+    // 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 )
     {
         m_scrollHelper->HandleOnPaint((wxPaintEvent &)event);
         return true;
@@ -300,21 +298,45 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
 
     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;
 }
 
 // ============================================================================
-// wxScrollHelperBase implementation
+// wxAnyScrollHelperBase and wxScrollHelperBase implementation
 // ============================================================================
 
 // ----------------------------------------------------------------------------
-// wxScrollHelperBase construction
+// wxAnyScrollHelperBase
 // ----------------------------------------------------------------------------
 
-wxScrollHelperBase::wxScrollHelperBase(wxWindow *win)
+wxAnyScrollHelperBase::wxAnyScrollHelperBase(wxWindow* win)
 {
     wxASSERT_MSG( win, wxT("associated window can't be NULL in wxScrollHelper") );
 
+    m_win = win;
+    m_targetWindow = NULL;
+
+    m_kbdScrollingEnabled = true;
+}
+
+// ----------------------------------------------------------------------------
+// wxScrollHelperBase construction
+// ----------------------------------------------------------------------------
+
+wxScrollHelperBase::wxScrollHelperBase(wxWindow *win)
+    : wxAnyScrollHelperBase(win)
+{
     m_xScrollPixelsPerLine =
     m_yScrollPixelsPerLine =
     m_xScrollPosition =
@@ -333,15 +355,10 @@ wxScrollHelperBase::wxScrollHelperBase(wxWindow *win)
     m_wheelRotation = 0;
 #endif
 
-    m_win =
-    m_targetWindow = NULL;
-
     m_timerAutoScroll = NULL;
 
     m_handler = NULL;
 
-    m_win = win;
-
     m_win->SetScrollHelper(static_cast<wxScrollHelper *>(this));
 
     // by default, the associated window is also the target window
@@ -367,16 +384,17 @@ void wxScrollHelperBase::SetScrollbars(int pixelsPerUnitX,
                                        int yPos,
                                        bool noRefresh)
 {
-    int xpos, ypos;
+    // Convert positions expressed in scroll units to positions in pixels.
+    int xPosInPixels = (xPos + m_xScrollPosition)*m_xScrollPixelsPerLine,
+        yPosInPixels = (yPos + m_yScrollPosition)*m_yScrollPixelsPerLine;
 
-    CalcUnscrolledPosition(xPos, yPos, &xpos, &ypos);
     bool do_refresh =
     (
       (noUnitsX != 0 && m_xScrollLines == 0) ||
-      (noUnitsX < m_xScrollLines && xpos > pixelsPerUnitX * noUnitsX) ||
+      (noUnitsX < m_xScrollLines && xPosInPixels > pixelsPerUnitX * noUnitsX) ||
 
       (noUnitsY != 0 && m_yScrollLines == 0) ||
-      (noUnitsY < m_yScrollLines && ypos > pixelsPerUnitY * noUnitsY) ||
+      (noUnitsY < m_yScrollLines && yPosInPixels > pixelsPerUnitY * noUnitsY) ||
       (xPos != m_xScrollPosition) ||
       (yPos != m_yScrollPosition)
     );
@@ -442,12 +460,6 @@ void wxScrollHelperBase::DeleteEvtHandler()
     }
 }
 
-void wxScrollHelperBase::ResetDrawnFlag()
-{
-    wxCHECK_RET( m_handler, "invalid use of ResetDrawnFlag - no handler?" );
-    m_handler->ResetDrawnFlag();
-}
-
 void wxScrollHelperBase::DoSetTargetWindow(wxWindow *target)
 {
     m_targetWindow = target;
@@ -478,11 +490,6 @@ void wxScrollHelperBase::SetTargetWindow(wxWindow *target)
     DoSetTargetWindow(target);
 }
 
-wxWindow *wxScrollHelperBase::GetTargetWindow() const
-{
-    return m_targetWindow;
-}
-
 // ----------------------------------------------------------------------------
 // scrolling implementation itself
 // ----------------------------------------------------------------------------
@@ -813,7 +820,7 @@ void wxScrollHelperBase::HandleOnSize(wxSizeEvent& WXUNUSED(event))
 
 // 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);
@@ -826,13 +833,20 @@ void wxScrollHelperBase::HandleOnPaint(wxPaintEvent& WXUNUSED(event))
 // compatibility here - if we used OnKeyDown(), the programs which process
 // arrows themselves in their OnChar() would never get the message and like
 // this they always have the priority
-void wxScrollHelperBase::HandleOnChar(wxKeyEvent& event)
+void wxAnyScrollHelperBase::HandleOnChar(wxKeyEvent& event)
 {
+    if ( !m_kbdScrollingEnabled )
+    {
+        event.Skip();
+        return;
+    }
+
     // prepare the event this key press maps to
     wxScrollWinEvent newEvent;
 
     newEvent.SetPosition(0);
     newEvent.SetEventObject(m_win);
+    newEvent.SetId(m_win->GetId());
 
     // this is the default, it's changed to wxHORIZONTAL below if needed
     newEvent.SetOrientation(wxVERTICAL);
@@ -910,11 +924,7 @@ bool wxScrollHelperBase::SendAutoScrollEvents(wxScrollWinEvent& event) const
 void wxScrollHelperBase::StopAutoScrolling()
 {
 #if wxUSE_TIMER
-    if ( m_timerAutoScroll )
-    {
-        delete m_timerAutoScroll;
-        m_timerAutoScroll = NULL;
-    }
+    wxDELETE(m_timerAutoScroll);
 #endif
 }
 
@@ -1011,6 +1021,9 @@ void wxScrollHelperBase::HandleOnMouseWheel(wxMouseEvent& event)
         newEvent.SetOrientation( event.GetWheelAxis() == 0 ? wxVERTICAL : wxHORIZONTAL);
         newEvent.SetEventObject(m_win);
 
+        if ( event.GetWheelAxis() == wxMOUSE_WHEEL_HORIZONTAL )
+            lines = -lines;
+
         if (event.IsPageScroll())
         {
             if (lines > 0)
@@ -1091,7 +1104,7 @@ void wxScrollHelperBase::HandleOnChildFocus(wxChildFocusEvent& event)
     // part of a wxComboCtrl visible and the button would still be outside the
     // scrolled area.  But do so only if the parent fits *entirely* inside the
     // scrolled window. In other situations, such as nested wxPanel or
-    // wxScrolledWindows, the parent might be way to big to fit inside the
+    // wxScrolledWindows, the parent might be way too big to fit inside the
     // scrolled window. If that is the case, then make only the focused window
     // visible
     if ( win->GetParent() != m_targetWindow)
@@ -1192,6 +1205,14 @@ wxScrollHelper::wxScrollHelper(wxWindow *winToScroll)
     m_yVisibility = wxSHOW_SB_DEFAULT;
 }
 
+bool wxScrollHelper::IsScrollbarShown(int orient) const
+{
+    wxScrollbarVisibility visibility = orient == wxHORIZONTAL ? m_xVisibility
+                                                              : m_yVisibility;
+
+    return visibility != wxSHOW_SB_NEVER;
+}
+
 void wxScrollHelper::DoShowScrollbars(wxScrollbarVisibility horz,
                                       wxScrollbarVisibility vert)
 {