]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/scrlwing.cpp
Optimized sizers to not call CalcMin more often than neccessary
[wxWidgets.git] / src / generic / scrlwing.cpp
index ffff7d7509502736e4801210271bfac3fdf1adf5..2eaa60e6cede63565e60306e458688ea73a22788 100644 (file)
@@ -6,7 +6,7 @@
 //              Ron Lee on 10.4.02:  virtual size / auto scrollbars et al.
 // Created:     01/02/97
 // RCS-ID:      $Id$
-// Copyright:   (c) wxWindows team
+// Copyright:   (c) wxWidgets team
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
@@ -18,7 +18,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "genscrolwin.h"
 #endif
 
 
 #include "wx/scrolwin.h"
 #include "wx/panel.h"
+#if wxUSE_TIMER
 #include "wx/timer.h"
+#endif
 #include "wx/sizer.h"
+#include "wx/recguard.h"
 
 #ifdef __WXMSW__
     #include <windows.h> // for DLGC_WANTARROWS
 
 IMPLEMENT_CLASS(wxScrolledWindow, wxGenericScrolledWindow)
 
+/*
+    TODO PROPERTIES
+        style wxHSCROLL | wxVSCROLL
+*/
+
 // ----------------------------------------------------------------------------
 // wxScrollHelperEvtHandler: intercept the events from the window and forward
 // them to wxScrollHelper
@@ -76,7 +84,7 @@ public:
 
     virtual bool ProcessEvent(wxEvent& event);
 
-    void ResetDrawnFlag() { m_hasDrawnWindow = FALSE; }
+    void ResetDrawnFlag() { m_hasDrawnWindow = false; }
 
 private:
     wxScrollHelper *m_scrollHelper;
@@ -86,6 +94,7 @@ private:
     DECLARE_NO_COPY_CLASS(wxScrollHelperEvtHandler)
 };
 
+#if wxUSE_TIMER
 // ----------------------------------------------------------------------------
 // wxAutoScrollTimer: the timer used to generate a stream of scroll events when
 // a captured mouse is held outside the window
@@ -170,6 +179,7 @@ void wxAutoScrollTimer::Notify()
         }
     }
 }
+#endif
 
 // ----------------------------------------------------------------------------
 // wxScrollHelperEvtHandler
@@ -195,7 +205,7 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
     // 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;
+    m_hasDrawnWindow = true;
 
     // pass it on to the real handler
     bool processed = wxEvtHandler::ProcessEvent(event);
@@ -211,7 +221,7 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
     {
         m_scrollHelper->HandleOnSize((wxSizeEvent &)event);
 
-        return TRUE;
+        return true;
     }
 
     if ( processed )
@@ -221,18 +231,18 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
         // OnDraw() below (from HandleOnPaint)
         if ( m_hasDrawnWindow )
         {
-            return TRUE;
+            return true;
         }
     }
 
-    // reset the skipped flag to FALSE as it might have been set to TRUE in
+    // reset the skipped flag to false as it might have been set to true in
     // ProcessEvent() above
-    event.Skip(FALSE);
+    event.Skip(false);
 
     if ( evType == wxEVT_PAINT )
     {
         m_scrollHelper->HandleOnPaint((wxPaintEvent &)event);
-        return TRUE;
+        return true;
     }
 
     if ( evType == wxEVT_SCROLLWIN_TOP ||
@@ -268,7 +278,7 @@ bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
         return !event.GetSkipped();
     }
 
-    return FALSE;
+    return false;
 }
 
 // ----------------------------------------------------------------------------
@@ -287,7 +297,7 @@ wxScrollHelper::wxScrollHelper(wxWindow *win)
     m_yScrollLinesPerPage = 0;
 
     m_xScrollingEnabled =
-    m_yScrollingEnabled = TRUE;
+    m_yScrollingEnabled = true;
 
     m_scaleX =
     m_scaleY = 1.0;
@@ -358,17 +368,23 @@ void wxScrollHelper::SetScrollbars(int pixelsPerUnitX,
     m_targetWindow->SetVirtualSize( w, h );
 
     if (do_refresh && !noRefresh)
-        m_targetWindow->Refresh(TRUE, GetScrollRect());
-
-    // TODO: check if we can use AdjustScrollbars always.
-#ifdef __WXUNIVERSAL__
-    AdjustScrollbars();
-#else    
-    // This is also done by AdjustScrollbars, above
-#ifdef __WXMAC__
-    m_targetWindow->MacUpdateImmediately() ;
-#endif
-#endif
+        m_targetWindow->Refresh(true, GetScrollRect());
+
+#ifndef __WXUNIVERSAL__
+    // If the target is not the same as the window with the scrollbars,
+    // then we need to update the scrollbars here, since they won't have
+    // been updated by SetVirtualSize().
+    if ( m_targetWindow != m_win )
+#endif // !__WXUNIVERSAL__
+    {
+        AdjustScrollbars();
+    }
+#ifndef __WXUNIVERSAL__
+    else
+    {
+        // otherwise this has been done by AdjustScrollbars, above
+    }
+#endif // !__WXUNIVERSAL__
 }
 
 // ----------------------------------------------------------------------------
@@ -460,7 +476,7 @@ void wxScrollHelper::HandleOnScroll(wxScrollWinEvent& event)
         m_win->SetScrollPos(wxVERTICAL, m_yScrollPosition);
     }
 
-    bool needsRefresh = FALSE;
+    bool needsRefresh = false;
     int dx = 0,
         dy = 0;
     if (orient == wxHORIZONTAL)
@@ -471,7 +487,7 @@ void wxScrollHelper::HandleOnScroll(wxScrollWinEvent& event)
        }
        else
        {
-           needsRefresh = TRUE;
+           needsRefresh = true;
        }
     }
     else
@@ -482,22 +498,18 @@ void wxScrollHelper::HandleOnScroll(wxScrollWinEvent& event)
         }
         else
         {
-            needsRefresh = TRUE;
+            needsRefresh = true;
         }
     }
 
     if ( needsRefresh )
     {
-        m_targetWindow->Refresh(TRUE, GetScrollRect());
+        m_targetWindow->Refresh(true, GetScrollRect());
     }
     else
     {
         m_targetWindow->ScrollWindow(dx, dy, GetScrollRect());
     }
-
-#ifdef __WXMAC__
-    m_targetWindow->MacUpdateImmediately() ;
-#endif
 }
 
 int wxScrollHelper::CalcScrollInc(wxScrollWinEvent& event)
@@ -569,7 +581,7 @@ int wxScrollHelper::CalcScrollInc(wxScrollWinEvent& event)
                 nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go
         }
         else
-            m_targetWindow->Refresh(TRUE, GetScrollRect());
+            m_targetWindow->Refresh(true, GetScrollRect());
     }
     else
     {
@@ -593,7 +605,7 @@ int wxScrollHelper::CalcScrollInc(wxScrollWinEvent& event)
         else
         {
             // VZ: why do we do this? (FIXME)
-            m_targetWindow->Refresh(TRUE, GetScrollRect());
+            m_targetWindow->Refresh(true, GetScrollRect());
         }
     }
 
@@ -603,9 +615,18 @@ int wxScrollHelper::CalcScrollInc(wxScrollWinEvent& event)
 // Adjust the scrollbars - new version.
 void wxScrollHelper::AdjustScrollbars()
 {
-#ifdef __WXMAC__
-    m_targetWindow->MacUpdateImmediately();
-#endif
+    static wxRecursionGuardFlag s_flagReentrancy;
+    wxRecursionGuard guard(s_flagReentrancy);
+    if ( guard.IsInside() )
+    {
+        // don't reenter AdjustScrollbars() while another call to
+        // AdjustScrollbars() is in progress because this may lead to calling
+        // ScrollWindow() twice and this can really happen under MSW if
+        // SetScrollbar() call below adds or removes the scrollbar which
+        // changes the window size and hence results in another
+        // AdjustScrollbars() call
+        return;
+    }
 
     int w = 0, h = 0;
     int oldw, oldh;
@@ -627,7 +648,7 @@ void wxScrollHelper::AdjustScrollbars()
         {
             m_xScrollLines = 0;
             m_xScrollPosition = 0;
-            m_win->SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);
+            m_win->SetScrollbar (wxHORIZONTAL, 0, 0, 0, false);
         }
         else
         {
@@ -704,7 +725,7 @@ void wxScrollHelper::AdjustScrollbars()
         oldh = h;
 
         GetTargetSize( &w, &h );
-    } while ( w != oldw && h != oldh );
+    } while ( w != oldw || h != oldh );
 
 #ifdef __WXMOTIF__
     // Sorry, some Motif-specific code to implement a backing pixmap
@@ -745,7 +766,7 @@ void wxScrollHelper::AdjustScrollbars()
             m_targetWindow->ScrollWindow( m_xScrollPixelsPerLine * (oldXScroll - m_xScrollPosition), 0,
                                           GetScrollRect() );
        else
-            m_targetWindow->Refresh(TRUE, GetScrollRect());
+            m_targetWindow->Refresh(true, GetScrollRect());
     }
 
     if (oldYScroll != m_yScrollPosition)
@@ -754,12 +775,8 @@ void wxScrollHelper::AdjustScrollbars()
             m_targetWindow->ScrollWindow( 0, m_yScrollPixelsPerLine * (oldYScroll-m_yScrollPosition),
                                           GetScrollRect() );
         else
-            m_targetWindow->Refresh(TRUE, GetScrollRect());
+            m_targetWindow->Refresh(true, GetScrollRect());
     }
-
-#ifdef __WXMAC__
-    m_targetWindow->MacUpdateImmediately();
-#endif
 }
 
 void wxScrollHelper::DoPrepareDC(wxDC& dc)
@@ -823,10 +840,6 @@ void wxScrollHelper::Scroll( int x_pos, int y_pos )
     if (((x_pos == -1) || (x_pos == m_xScrollPosition)) &&
         ((y_pos == -1) || (y_pos == m_yScrollPosition))) return;
 
-#ifdef __WXMAC__
-    m_targetWindow->MacUpdateImmediately();
-#endif
-
     int w, h;
     GetTargetSize(&w, &h);
 
@@ -872,11 +885,6 @@ void wxScrollHelper::Scroll( int x_pos, int y_pos )
                                           GetScrollRect() );
         }
     }
-
-#ifdef __WXMAC__
-    m_targetWindow->MacUpdateImmediately();
-#endif
-
 }
 
 void wxScrollHelper::EnableScrolling (bool x_scroll, bool y_scroll)
@@ -1058,11 +1066,13 @@ bool wxScrollHelper::SendAutoScrollEvents(wxScrollWinEvent& event) const
 
 void wxScrollHelper::StopAutoScrolling()
 {
+#if wxUSE_TIMER
     if ( m_timerAutoScroll )
     {
         delete m_timerAutoScroll;
         m_timerAutoScroll = (wxTimer *)NULL;
     }
+#endif
 }
 
 void wxScrollHelper::HandleOnMouseEnter(wxMouseEvent& event)
@@ -1124,6 +1134,7 @@ void wxScrollHelper::HandleOnMouseLeave(wxMouseEvent& event)
         if ( !m_targetWindow->HasScrollbar(orient) )
             return;
 
+#if wxUSE_TIMER
         delete m_timerAutoScroll;
         m_timerAutoScroll = new wxAutoScrollTimer
                                 (
@@ -1134,6 +1145,7 @@ void wxScrollHelper::HandleOnMouseLeave(wxMouseEvent& event)
                                     orient
                                 );
         m_timerAutoScroll->Start(50); // FIXME: make configurable
+#endif
     }
 }
 
@@ -1219,7 +1231,7 @@ bool wxGenericScrolledWindow::Layout()
         CalcScrolledPosition(0,0, &x,&y);
         GetVirtualSize(&w, &h);
         GetSizer()->SetDimension(x, y, w, h);
-        return TRUE;
+        return true;
     }
 
     // fall back to default for LayoutConstraints
@@ -1231,10 +1243,8 @@ void wxGenericScrolledWindow::DoSetVirtualSize(int x, int y)
     wxPanel::DoSetVirtualSize( x, y );
     AdjustScrollbars();
 
-#if wxUSE_CONSTRAINTS
     if (GetAutoLayout())
         Layout();
-#endif
 }
 
 void wxGenericScrolledWindow::OnPaint(wxPaintEvent& event)
@@ -1247,42 +1257,26 @@ void wxGenericScrolledWindow::OnPaint(wxPaintEvent& event)
 }
 
 #ifdef __WXMSW__
-long
+WXLRESULT
 wxGenericScrolledWindow::MSWWindowProc(WXUINT nMsg,
                                        WXWPARAM wParam,
                                        WXLPARAM lParam)
 {
-    long rc = wxPanel::MSWWindowProc(nMsg, wParam, lParam);
+    WXLRESULT rc = wxPanel::MSWWindowProc(nMsg, wParam, lParam);
 
+#ifndef __WXWINCE__
     // we need to process arrows ourselves for scrolling
     if ( nMsg == WM_GETDLGCODE )
     {
         rc |= DLGC_WANTARROWS;
     }
+#endif
 
     return rc;
 }
 
 #endif // __WXMSW__
 
-#if WXWIN_COMPATIBILITY
-
-void wxGenericScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
-{
-      *x_page = GetScrollPageSize(wxHORIZONTAL);
-      *y_page = GetScrollPageSize(wxVERTICAL);
-}
-
-void wxGenericScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
-{
-    if ( xx )
-        *xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
-    if ( yy )
-        *yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
-}
-
-#endif // WXWIN_COMPATIBILITY
-
 #endif // !wxGTK
 
 // vi:sts=4:sw=4:et