]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/scrarrow.cpp
destroy the old clipping region before setting the new one (part of patch 1716763)
[wxWidgets.git] / src / univ / scrarrow.cpp
index c3db2abdf8298e1ea24ffd7b9bad1e0dc71498ad..312bdeee1f1047afc4c573b2c721bfd4fde5be3e 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "univscrarrow.h"
-#endif
-
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
@@ -28,6 +24,7 @@
 #endif
 
 #ifndef WX_PRECOMP
 #endif
 
 #ifndef WX_PRECOMP
+    #include "wx/window.h"
 #endif
 
 #include "wx/univ/scrtimer.h"
 #endif
 
 #include "wx/univ/scrtimer.h"
@@ -49,7 +46,9 @@ struct wxScrollArrowCaptureData
         m_arrowPressed = wxScrollArrows::Arrow_None;
         m_window = NULL;
         m_btnCapture = -1;
         m_arrowPressed = wxScrollArrows::Arrow_None;
         m_window = NULL;
         m_btnCapture = -1;
+#if wxUSE_TIMER
         m_timerScroll = NULL;
         m_timerScroll = NULL;
+#endif // wxUSE_TIMER
     }
 
     ~wxScrollArrowCaptureData()
     }
 
     ~wxScrollArrowCaptureData()
@@ -57,7 +56,9 @@ struct wxScrollArrowCaptureData
         if ( m_window )
             m_window->ReleaseMouse();
 
         if ( m_window )
             m_window->ReleaseMouse();
 
+#if wxUSE_TIMER
         delete m_timerScroll;
         delete m_timerScroll;
+#endif // wxUSE_TIMER
     }
 
     // the arrow being held pressed (may be Arrow_None)
     }
 
     // the arrow being held pressed (may be Arrow_None)
@@ -69,14 +70,18 @@ struct wxScrollArrowCaptureData
     // the window which has captured the mouse
     wxWindow *m_window;
 
     // the window which has captured the mouse
     wxWindow *m_window;
 
+#if wxUSE_TIMER
     // the timer for generating the scroll events
     wxScrollTimer *m_timerScroll;
     // the timer for generating the scroll events
     wxScrollTimer *m_timerScroll;
+#endif
 };
 
 // ----------------------------------------------------------------------------
 // wxScrollArrowTimer: a wxScrollTimer which calls OnArrow()
 // ----------------------------------------------------------------------------
 
 };
 
 // ----------------------------------------------------------------------------
 // wxScrollArrowTimer: a wxScrollTimer which calls OnArrow()
 // ----------------------------------------------------------------------------
 
+#if wxUSE_TIMER
+
 class wxScrollArrowTimer : public wxScrollTimer
 {
 public:
 class wxScrollArrowTimer : public wxScrollTimer
 {
 public:
@@ -99,6 +104,8 @@ protected:
     wxScrollArrows::Arrow m_arrow;
 };
 
     wxScrollArrows::Arrow m_arrow;
 };
 
+#endif // wxUSE_TIMER
+
 // ============================================================================
 // implementation of wxScrollArrows
 // ============================================================================
 // ============================================================================
 // implementation of wxScrollArrows
 // ============================================================================
@@ -134,17 +141,18 @@ void wxScrollArrows::DrawArrow(Arrow arrow,
         { wxUP,   wxDOWN  }
     };
 
         { wxUP,   wxDOWN  }
     };
 
-    void (wxRenderer::*pfn)(wxDC&, wxDirection, const wxRect&, int) =
-        scrollbarLike ? wxRenderer::DrawScrollbarArrow
-                      : wxRenderer::DrawArrow;
-
-    (m_control->GetRenderer()->*pfn)
-    (
-        dc,
-        arrowDirs[m_control->IsVertical()][arrow],
-        rect,
-        m_control->GetArrowState(arrow)
-    );
+    if ( scrollbarLike )
+        m_control->GetRenderer()->DrawScrollbarArrow(
+            dc,
+            arrowDirs[m_control->IsVertical()][arrow],
+            rect,
+            m_control->GetArrowState(arrow));
+    else
+        m_control->GetRenderer()->DrawArrow(
+            dc,
+            arrowDirs[m_control->IsVertical()][arrow],
+            rect,
+            m_control->GetArrowState(arrow));
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -166,10 +174,11 @@ bool wxScrollArrows::HandleMouseMove(const wxMouseEvent& event) const
     }
     else // Moving() or Entering(), treat them the same here
     {
     }
     else // Moving() or Entering(), treat them the same here
     {
-        arrow = m_control->HitTest(event.GetPosition());
+        arrow = m_control->HitTestArrow(event.GetPosition());
     }
 
     }
 
-    if ( m_captureData )
+#if wxUSE_TIMER
+    if ( m_captureData && m_captureData->m_timerScroll)
     {
         // the mouse is captured, we may want to pause scrolling if it goes
         // outside the arrow or to resume it if we had paused it before
     {
         // the mouse is captured, we may want to pause scrolling if it goes
         // outside the arrow or to resume it if we had paused it before
@@ -180,35 +189,36 @@ bool wxScrollArrows::HandleMouseMove(const wxMouseEvent& event) const
             if ( arrow == m_captureData->m_arrowPressed )
             {
                 // resume now
             if ( arrow == m_captureData->m_arrowPressed )
             {
                 // resume now
-                m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, TRUE);
+                m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, true);
                 timer->Start();
 
                 timer->Start();
 
-                return TRUE;
+                return true;
             }
         }
             }
         }
-        else if ( 1 ) //FIXME: m_control->ShouldPauseScrolling() )
+        else // if ( 1 ) FIXME: m_control->ShouldPauseScrolling() )
         {
             // we may want to stop it
             if ( arrow != m_captureData->m_arrowPressed )
             {
                 // stop as the mouse left the arrow
                 m_control->SetArrowFlag(m_captureData->m_arrowPressed,
         {
             // we may want to stop it
             if ( arrow != m_captureData->m_arrowPressed )
             {
                 // stop as the mouse left the arrow
                 m_control->SetArrowFlag(m_captureData->m_arrowPressed,
-                                        wxCONTROL_PRESSED, FALSE);
+                                        wxCONTROL_PRESSED, false);
                 timer->Stop();
 
                 timer->Stop();
 
-                return TRUE;
+                return true;
             }
         }
 
             }
         }
 
-        return FALSE;
+        return false;
     }
     }
+#endif // wxUSE_TIMER
 
     // reset the wxCONTROL_CURRENT flag for the arrows which don't have the
     // mouse and set it for the one which has
     UpdateCurrentFlag(Arrow_First, arrow);
     UpdateCurrentFlag(Arrow_Second, arrow);
 
 
     // reset the wxCONTROL_CURRENT flag for the arrows which don't have the
     // mouse and set it for the one which has
     UpdateCurrentFlag(Arrow_First, arrow);
     UpdateCurrentFlag(Arrow_Second, arrow);
 
-    // return TRUE if it was really an event for an arrow
+    // return true if it was really an event for an arrow
     return !event.Leaving() && arrow != Arrow_None;
 }
 
     return !event.Leaving() && arrow != Arrow_None;
 }
 
@@ -218,24 +228,24 @@ bool wxScrollArrows::HandleMouse(const wxMouseEvent& event) const
     if ( btn == -1 )
     {
         // we only care about button press/release events
     if ( btn == -1 )
     {
         // we only care about button press/release events
-        return FALSE;
+        return false;
     }
 
     if ( event.ButtonDown() || event.ButtonDClick() )
     {
         if ( !m_captureData )
         {
     }
 
     if ( event.ButtonDown() || event.ButtonDClick() )
     {
         if ( !m_captureData )
         {
-            Arrow arrow = m_control->HitTest(event.GetPosition());
+            Arrow arrow = m_control->HitTestArrow(event.GetPosition());
             if ( arrow == Arrow_None )
             {
                 // mouse pressed over something else
             if ( arrow == Arrow_None )
             {
                 // mouse pressed over something else
-                return FALSE;
+                return false;
             }
 
             if ( m_control->GetArrowState(arrow) & wxCONTROL_DISABLED )
             {
                 // don't allow to press disabled arrows
             }
 
             if ( m_control->GetArrowState(arrow) & wxCONTROL_DISABLED )
             {
                 // don't allow to press disabled arrows
-                return TRUE;
+                return true;
             }
 
             wxConstCast(this, wxScrollArrows)->m_captureData =
             }
 
             wxConstCast(this, wxScrollArrows)->m_captureData =
@@ -245,11 +255,29 @@ bool wxScrollArrows::HandleMouse(const wxMouseEvent& event) const
             m_captureData->m_window = m_control->GetWindow();
             m_captureData->m_window->CaptureMouse();
 
             m_captureData->m_window = m_control->GetWindow();
             m_captureData->m_window->CaptureMouse();
 
+#if wxUSE_TIMER
             // start scrolling
             // start scrolling
-            m_captureData->m_timerScroll =
+            wxScrollArrowTimer *tmpTimerScroll =
                 new wxScrollArrowTimer(m_control, arrow);
                 new wxScrollArrowTimer(m_control, arrow);
+#endif // wxUSE_TIMER
 
 
-            m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, TRUE);
+            // Because in some cases wxScrollArrowTimer can cause
+            // m_captureData to be destructed we need to test if it
+            // is still valid before using.
+            if (m_captureData)
+            {
+#if wxUSE_TIMER
+                m_captureData->m_timerScroll = tmpTimerScroll;
+#endif // wxUSE_TIMER
+
+                m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, true);
+            }
+            else
+            {
+#if wxUSE_TIMER
+                delete tmpTimerScroll;
+#endif // wxUSE_TIMER
+            }
         }
         //else: mouse already captured, nothing to do
     }
         }
         //else: mouse already captured, nothing to do
     }
@@ -261,14 +289,13 @@ bool wxScrollArrows::HandleMouse(const wxMouseEvent& event) const
         delete m_captureData;
         wxConstCast(this, wxScrollArrows)->m_captureData = NULL;
 
         delete m_captureData;
         wxConstCast(this, wxScrollArrows)->m_captureData = NULL;
 
-        m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, FALSE);
+        m_control->SetArrowFlag(arrow, wxCONTROL_PRESSED, false);
     }
     else
     {
         // we don't process this
     }
     else
     {
         // we don't process this
-        return FALSE;
+        return false;
     }
 
     }
 
-    return TRUE;
+    return true;
 }
 }
-