]> git.saurik.com Git - wxWidgets.git/commitdiff
allow passing -1 range to SetScrollbar() to indicate the the scrollbar should be...
authorVadim Zeitlin <vadim@wxwidgets.org>
Wed, 24 Dec 2008 21:58:05 +0000 (21:58 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Wed, 24 Dec 2008 21:58:05 +0000 (21:58 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57535 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/generic/scrolwin.h
interface/wx/window.h
samples/scroll/scroll.cpp
src/generic/scrlwing.cpp
src/msw/window.cpp

index 9b734990757dea84b161b6fb12e4ef2c061ced46..5ffb3caac0c72bbcc180f1a2b4871f2f4ba519de 100644 (file)
@@ -35,9 +35,10 @@ private:
     void DoAdjustScrollbar(int orient,
                            int clientSize,
                            int virtSize,
     void DoAdjustScrollbar(int orient,
                            int clientSize,
                            int virtSize,
-                           int& pixelsPerUnit,
+                           int pixelsPerUnit,
                            int& scrollUnits,
                            int& scrollPosition,
                            int& scrollUnits,
                            int& scrollPosition,
+                           int& scrollLinesPerPage,
                            wxScrollbarVisibility visibility);
 
 
                            wxScrollbarVisibility visibility);
 
 
index 8f8a9d8364b5c7632fd39e93ca1a263bcac2f9cb..8d8bec2cf1c784698fb4686a0e12872313b6914c 100644 (file)
@@ -2368,7 +2368,10 @@ public:
         @param thumbSize
             The size of the thumb, or visible portion of the scrollbar, in scroll units.
         @param range
         @param thumbSize
             The size of the thumb, or visible portion of the scrollbar, in scroll units.
         @param range
-            The maximum position of the scrollbar.
+            The maximum position of the scrollbar. Value of -1 can be used to
+            ask for the scrollbar to be shown but in the disabled state: this
+            can be used to avoid removing the scrollbar even when it is not
+            needed (currently this is only implemented in wxMSW port).
         @param refresh
             @true to redraw the scrollbar, @false otherwise.
 
         @param refresh
             @true to redraw the scrollbar, @false otherwise.
 
index efbfb37479600cb51f590956b09dbd4b90a055d4..98a9d01dad25e9bf0f366cae86159c9d7b12c22c 100644 (file)
@@ -452,7 +452,7 @@ public:
                            wxDefaultPosition, wxDefaultSize,
                            wxBORDER_SUNKEN)
     {
                            wxDefaultPosition, wxDefaultSize,
                            wxBORDER_SUNKEN)
     {
-        m_nLines = 100;
+        m_nLines = 50;
         m_winSync = NULL;
         m_inDoSync = false;
 
         m_winSync = NULL;
         m_inDoSync = false;
 
@@ -621,7 +621,7 @@ private:
     void OnTestAuto(wxCommandEvent& WXUNUSED(event)) { new MyAutoFrame(this); }
 
     void OnToggleSync(wxCommandEvent& event);
     void OnTestAuto(wxCommandEvent& WXUNUSED(event)) { new MyAutoFrame(this); }
 
     void OnToggleSync(wxCommandEvent& event);
-    void OnToggleScrollbar(wxCommandEvent& event);
+    void OnScrollbarVisibility(wxCommandEvent& event);
 
     MyScrolledWindowBase *m_win1,
                          *m_win2;
 
     MyScrolledWindowBase *m_win1,
                          *m_win2;
@@ -835,7 +835,7 @@ const wxWindowID Scroll_Test_Sub    = wxWindow::NewControlId();
 const wxWindowID Scroll_Test_Auto   = wxWindow::NewControlId();
 
 const wxWindowID Scroll_TglBtn_Sync = wxWindow::NewControlId();
 const wxWindowID Scroll_Test_Auto   = wxWindow::NewControlId();
 
 const wxWindowID Scroll_TglBtn_Sync = wxWindow::NewControlId();
-const wxWindowID Scroll_TglBtn_Scrollbar = wxWindow::NewControlId();
+const wxWindowID Scroll_Radio_ShowScrollbar = wxWindow::NewControlId();
 
 BEGIN_EVENT_TABLE(MyFrame,wxFrame)
     EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
 
 BEGIN_EVENT_TABLE(MyFrame,wxFrame)
     EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
@@ -848,7 +848,7 @@ BEGIN_EVENT_TABLE(MyFrame,wxFrame)
     EVT_MENU(Scroll_Test_Auto, MyFrame::OnTestAuto)
 
     EVT_TOGGLEBUTTON(Scroll_TglBtn_Sync, MyFrame::OnToggleSync)
     EVT_MENU(Scroll_Test_Auto, MyFrame::OnTestAuto)
 
     EVT_TOGGLEBUTTON(Scroll_TglBtn_Sync, MyFrame::OnToggleSync)
-    EVT_TOGGLEBUTTON(Scroll_TglBtn_Scrollbar, MyFrame::OnToggleScrollbar)
+    EVT_RADIOBOX(Scroll_Radio_ShowScrollbar, MyFrame::OnScrollbarVisibility)
 END_EVENT_TABLE()
 
 MyFrame::MyFrame()
 END_EVENT_TABLE()
 
 MyFrame::MyFrame()
@@ -879,10 +879,12 @@ MyFrame::MyFrame()
     SetMenuBar( mbar );
 
 
     SetMenuBar( mbar );
 
 
+    wxPanel *panel = new wxPanel(this);
+
     const wxSizerFlags flagsExpand(wxSizerFlags(1).Expand());
 
     wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
     const wxSizerFlags flagsExpand(wxSizerFlags(1).Expand());
 
     wxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
-    topsizer->Add(new wxStaticText(this, wxID_ANY,
+    topsizer->Add(new wxStaticText(panel, wxID_ANY,
         "The windows below should behave in the same way, even though\n"
         "they're implemented quite differently, see the code for details.\n"
         "\n"
         "The windows below should behave in the same way, even though\n"
         "they're implemented quite differently, see the code for details.\n"
         "\n"
@@ -891,28 +893,39 @@ MyFrame::MyFrame()
         "don't be surprised by this."),
         wxSizerFlags().Centre().Border());
 
         "don't be surprised by this."),
         wxSizerFlags().Centre().Border());
 
-    m_win1 = new MyScrolledWindowDumb(this);
-    m_win2 = new MyScrolledWindowSmart(this);
+    m_win1 = new MyScrolledWindowDumb(panel);
+    m_win2 = new MyScrolledWindowSmart(panel);
 
     wxSizer *sizerScrollWin = new wxBoxSizer(wxHORIZONTAL);
     sizerScrollWin->Add(m_win1, flagsExpand);
     sizerScrollWin->Add(m_win2, flagsExpand);
     topsizer->Add(sizerScrollWin, flagsExpand);
 
 
     wxSizer *sizerScrollWin = new wxBoxSizer(wxHORIZONTAL);
     sizerScrollWin->Add(m_win1, flagsExpand);
     sizerScrollWin->Add(m_win2, flagsExpand);
     topsizer->Add(sizerScrollWin, flagsExpand);
 
-    const wxSizerFlags flagsHBorder(wxSizerFlags().Border(wxLEFT | wxRIGHT));
+    const wxSizerFlags
+        flagsHBorder(wxSizerFlags().Centre().Border(wxLEFT | wxRIGHT));
 
     wxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
 
     wxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
-    sizerBtns->Add(new wxToggleButton(this, Scroll_TglBtn_Sync, "S&ynchronize"),
+
+    // the radio buttons are in the same order as wxSHOW_SB_XXX values but
+    // offset by 1
+    const wxString visibilities[] = { "&never", "&default", "&always" };
+    wxRadioBox *radio = new wxRadioBox(panel, Scroll_Radio_ShowScrollbar,
+                                       "Left &scrollbar visibility: ",
+                                       wxDefaultPosition, wxDefaultSize,
+                                       WXSIZEOF(visibilities), visibilities);
+    radio->SetSelection(wxSHOW_SB_DEFAULT + 1);
+    sizerBtns->Add(radio, flagsHBorder);
+
+    sizerBtns->Add(new wxToggleButton(panel, Scroll_TglBtn_Sync, "S&ynchronize"),
                    flagsHBorder);
 
                    flagsHBorder);
 
-    wxToggleButton *btn =new wxToggleButton(this, Scroll_TglBtn_Scrollbar,
-                                            "&Show scrollbar");
-    btn->SetValue(true);
-    sizerBtns->Add(btn, flagsHBorder);
     topsizer->Add(sizerBtns, wxSizerFlags().Centre().Border());
 
     topsizer->Add(sizerBtns, wxSizerFlags().Centre().Border());
 
-    SetSizer(topsizer);
+    panel->SetSizer(topsizer);
 
 
+    wxSize size = panel->GetBestSize();
+    SetSizeHints(size);
+    SetClientSize(2*size);
 
     Show();
 }
 
     Show();
 }
@@ -931,11 +944,10 @@ void MyFrame::OnToggleSync(wxCommandEvent& event)
     }
 }
 
     }
 }
 
-void MyFrame::OnToggleScrollbar(wxCommandEvent& event)
+void MyFrame::OnScrollbarVisibility(wxCommandEvent& event)
 {
     m_win1->ShowScrollbars(wxSHOW_SB_NEVER,
 {
     m_win1->ShowScrollbars(wxSHOW_SB_NEVER,
-                           event.IsChecked() ? wxSHOW_SB_ALWAYS
-                                             : wxSHOW_SB_NEVER);
+                           wxScrollbarVisibility(event.GetSelection() - 1));
 }
 
 void MyFrame::OnQuit(wxCommandEvent &WXUNUSED(event))
 }
 
 void MyFrame::OnQuit(wxCommandEvent &WXUNUSED(event))
index 278ae610c0335b082d11268f5e19b8e3150881e3..49b8673eb434270b512ac16dc5155cf752492a48 100644 (file)
@@ -1232,28 +1232,20 @@ void
 wxScrollHelper::DoAdjustScrollbar(int orient,
                                   int clientSize,
                                   int virtSize,
 wxScrollHelper::DoAdjustScrollbar(int orient,
                                   int clientSize,
                                   int virtSize,
-                                  int& pixelsPerUnit,
+                                  int pixelsPerUnit,
                                   int& scrollUnits,
                                   int& scrollPosition,
                                   int& scrollUnits,
                                   int& scrollPosition,
+                                  int& scrollLinesPerPage,
                                   wxScrollbarVisibility visibility)
 {
                                   wxScrollbarVisibility visibility)
 {
-    if ( visibility == wxSHOW_SB_NEVER )
-    {
-        m_win->SetScrollbar(orient, 0, 0, 0);
-        return;
-    }
-
     // scroll lines per page: if 0, no scrolling is needed
     // scroll lines per page: if 0, no scrolling is needed
-    int unitsPerPage;
-
     // check if we need scrollbar in this direction at all
     // check if we need scrollbar in this direction at all
-    if ( pixelsPerUnit == 0 ||
-            (clientSize >= virtSize && visibility != wxSHOW_SB_ALWAYS) )
+    if ( pixelsPerUnit == 0 || clientSize >= virtSize )
     {
         // scrolling is disabled or unnecessary
         scrollUnits =
         scrollPosition = 0;
     {
         // scrolling is disabled or unnecessary
         scrollUnits =
         scrollPosition = 0;
-        unitsPerPage = 0;
+        scrollLinesPerPage = 0;
     }
     else // might need scrolling
     {
     }
     else // might need scrolling
     {
@@ -1261,23 +1253,23 @@ wxScrollHelper::DoAdjustScrollbar(int orient,
         scrollUnits = (virtSize + pixelsPerUnit - 1) / pixelsPerUnit;
 
         // Calculate the number of fully scroll units
         scrollUnits = (virtSize + pixelsPerUnit - 1) / pixelsPerUnit;
 
         // Calculate the number of fully scroll units
-        unitsPerPage = clientSize / pixelsPerUnit;
+        scrollLinesPerPage = clientSize / pixelsPerUnit;
 
 
-        if (unitsPerPage >= scrollUnits)
+        if ( scrollLinesPerPage >= scrollUnits )
         {
             // we're big enough to not need scrolling
             scrollUnits =
             scrollPosition = 0;
         {
             // we're big enough to not need scrolling
             scrollUnits =
             scrollPosition = 0;
-            unitsPerPage = 0;
+            scrollLinesPerPage = 0;
         }
         else // we do need a scrollbar
         {
         }
         else // we do need a scrollbar
         {
-            if ( unitsPerPage < 1 )
-                unitsPerPage = 1;
+            if ( scrollLinesPerPage < 1 )
+                scrollLinesPerPage = 1;
 
             // Correct position if greater than extent of canvas minus
             // the visible portion of it or if below zero
 
             // Correct position if greater than extent of canvas minus
             // the visible portion of it or if below zero
-            const int posMax = scrollUnits - unitsPerPage;
+            const int posMax = scrollUnits - scrollLinesPerPage;
             if ( scrollPosition > posMax )
                 scrollPosition = posMax;
             else if ( scrollPosition < 0 )
             if ( scrollPosition > posMax )
                 scrollPosition = posMax;
             else if ( scrollPosition < 0 )
@@ -1285,10 +1277,26 @@ wxScrollHelper::DoAdjustScrollbar(int orient,
         }
     }
 
         }
     }
 
-    m_win->SetScrollbar(orient, scrollPosition, unitsPerPage, scrollUnits);
+    // in wxSHOW_SB_NEVER case don't show the scrollbar even if it's needed, in
+    // wxSHOW_SB_ALWAYS case show the scrollbar even if it's not needed by
+    // passing a special range value to SetScrollbar()
+    int range wxDUMMY_INITIALIZE(0);
+    switch ( visibility )
+    {
+        case wxSHOW_SB_NEVER:
+            range = 0;
+            break;
+
+        case wxSHOW_SB_DEFAULT:
+            range = scrollUnits;
+            break;
+
+        case wxSHOW_SB_ALWAYS:
+            range = scrollUnits ? scrollUnits : -1;
+            break;
+    }
 
 
-    // The amount by which we scroll when paging
-    SetScrollPageSize(orient, unitsPerPage);
+    m_win->SetScrollbar(orient, scrollPosition, scrollLinesPerPage, range);
 }
 
 void wxScrollHelper::AdjustScrollbars()
 }
 
 void wxScrollHelper::AdjustScrollbars()
@@ -1348,6 +1356,7 @@ void wxScrollHelper::AdjustScrollbars()
                           m_xScrollPixelsPerLine,
                           m_xScrollLines,
                           m_xScrollPosition,
                           m_xScrollPixelsPerLine,
                           m_xScrollLines,
                           m_xScrollPosition,
+                          m_xScrollLinesPerPage,
                           m_xVisibility);
 
         DoAdjustScrollbar(wxVERTICAL,
                           m_xVisibility);
 
         DoAdjustScrollbar(wxVERTICAL,
@@ -1356,6 +1365,7 @@ void wxScrollHelper::AdjustScrollbars()
                           m_yScrollPixelsPerLine,
                           m_yScrollLines,
                           m_yScrollPosition,
                           m_yScrollPixelsPerLine,
                           m_yScrollLines,
                           m_yScrollPosition,
+                          m_yScrollLinesPerPage,
                           m_yVisibility);
 
 
                           m_yVisibility);
 
 
index 85acab831e8568ca6af40c4d6c4f11a74c57f2c4..199c04357eebdeb962411f35346a7408d5091ba4 100644 (file)
@@ -963,6 +963,9 @@ void wxWindowMSW::MSWUpdateUIState(int action, int state)
 // scrolling stuff
 // ---------------------------------------------------------------------------
 
 // scrolling stuff
 // ---------------------------------------------------------------------------
 
+namespace
+{
+
 inline int GetScrollPosition(HWND hWnd, int wOrient)
 {
 #ifdef __WXMICROWIN__
 inline int GetScrollPosition(HWND hWnd, int wOrient)
 {
 #ifdef __WXMICROWIN__
@@ -978,12 +981,19 @@ inline int GetScrollPosition(HWND hWnd, int wOrient)
 #endif
 }
 
 #endif
 }
 
+inline UINT WXOrientToSB(int orient)
+{
+    return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
+}
+
+} // anonymous namespace
+
 int wxWindowMSW::GetScrollPos(int orient) const
 {
     HWND hWnd = GetHwnd();
     wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") );
 
 int wxWindowMSW::GetScrollPos(int orient) const
 {
     HWND hWnd = GetHwnd();
     wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") );
 
-    return GetScrollPosition(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT);
+    return GetScrollPosition(hWnd, WXOrientToSB(orient));
 }
 
 // This now returns the whole range, not just the number
 }
 
 // This now returns the whole range, not just the number
@@ -994,15 +1004,9 @@ int wxWindowMSW::GetScrollRange(int orient) const
     HWND hWnd = GetHwnd();
     if ( !hWnd )
         return 0;
     HWND hWnd = GetHwnd();
     if ( !hWnd )
         return 0;
-#if 0
-    ::GetScrollRange(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                     &minPos, &maxPos);
-#endif
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.fMask = SIF_RANGE;
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.fMask = SIF_RANGE;
-    if ( !::GetScrollInfo(hWnd,
-                          orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                          &scrollInfo) )
+    if ( !::GetScrollInfo(hWnd, WXOrientToSB(orient), &scrollInfo) )
     {
         // Most of the time this is not really an error, since the return
         // value can also be zero when there is no scrollbar yet.
     {
         // Most of the time this is not really an error, since the return
         // value can also be zero when there is no scrollbar yet.
@@ -1035,8 +1039,7 @@ void wxWindowMSW::SetScrollPos(int orient, int pos, bool refresh)
         info.fMask |= SIF_DISABLENOSCROLL;
     }
 
         info.fMask |= SIF_DISABLENOSCROLL;
     }
 
-    ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                    &info, refresh);
+    ::SetScrollInfo(hWnd, WXOrientToSB(orient), &info, refresh);
 }
 
 // New function that will replace some of the above.
 }
 
 // New function that will replace some of the above.
@@ -1046,28 +1049,37 @@ void wxWindowMSW::SetScrollbar(int orient,
                                int range,
                                bool refresh)
 {
                                int range,
                                bool refresh)
 {
+    // We have to set the variables here to make them valid in events
+    // triggered by ::SetScrollInfo()
+    *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
+
+    HWND hwnd = GetHwnd();
+    if ( !hwnd )
+        return;
+
     WinStruct<SCROLLINFO> info;
     WinStruct<SCROLLINFO> info;
-    info.nPage = pageSize;
-    info.nMin = 0;              // range is nMax - nMin + 1
-    info.nMax = range - 1;      //  as both nMax and nMax are inclusive
-    info.nPos = pos;
+    if ( range != -1 )
+    {
+        info.nPage = pageSize;
+        info.nMin = 0;              // range is nMax - nMin + 1
+        info.nMax = range - 1;      //  as both nMax and nMax are inclusive
+        info.nPos = pos;
+
+        // enable the scrollbar if it had been disabled before by specifying
+        // SIF_DISABLENOSCROLL below: as we can't know whether this had been
+        // done or not just do it always
+        ::EnableScrollBar(hwnd, WXOrientToSB(orient), ESB_ENABLE_BOTH);
+    }
+    //else: leave all the fields to be 0
+
     info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
     info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
-    if ( HasFlag(wxALWAYS_SHOW_SB) )
+    if ( HasFlag(wxALWAYS_SHOW_SB) || range == -1 )
     {
         // disable scrollbar instead of removing it then
         info.fMask |= SIF_DISABLENOSCROLL;
     }
 
     {
         // disable scrollbar instead of removing it then
         info.fMask |= SIF_DISABLENOSCROLL;
     }
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
-    {
-        // We have to set the variables here to make them valid in events
-        // triggered by ::SetScrollInfo()
-        *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
-
-        ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                        &info, refresh);
-    }
+    ::SetScrollInfo(hwnd, WXOrientToSB(orient), &info, refresh);
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
@@ -5783,8 +5795,7 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
             scrollInfo.fMask = SIF_TRACKPOS;
 
             if ( !::GetScrollInfo(GetHwnd(),
             scrollInfo.fMask = SIF_TRACKPOS;
 
             if ( !::GetScrollInfo(GetHwnd(),
-                                  orientation == wxHORIZONTAL ? SB_HORZ
-                                                              : SB_VERT,
+                                  WXOrientToSB(orientation),
                                   &scrollInfo) )
             {
                 // Not necessarily an error, if there are no scrollbars yet.
                                   &scrollInfo) )
             {
                 // Not necessarily an error, if there are no scrollbars yet.