From 1ddb6d28576c3ab21f80d8a3815fcccb1545961c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 24 Dec 2008 21:58:05 +0000 Subject: [PATCH] allow passing -1 range to SetScrollbar() to indicate the the scrollbar should be disabled and use this to implement wxSHOW_SB_ALWAYS in the generic wxScrollHelper git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@57535 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/scrolwin.h | 3 +- interface/wx/window.h | 5 ++- samples/scroll/scroll.cpp | 46 ++++++++++++++++--------- src/generic/scrlwing.cpp | 52 +++++++++++++++++----------- src/msw/window.cpp | 65 ++++++++++++++++++++--------------- 5 files changed, 104 insertions(+), 67 deletions(-) diff --git a/include/wx/generic/scrolwin.h b/include/wx/generic/scrolwin.h index 9b73499075..5ffb3caac0 100644 --- a/include/wx/generic/scrolwin.h +++ b/include/wx/generic/scrolwin.h @@ -35,9 +35,10 @@ private: void DoAdjustScrollbar(int orient, int clientSize, int virtSize, - int& pixelsPerUnit, + int pixelsPerUnit, int& scrollUnits, int& scrollPosition, + int& scrollLinesPerPage, wxScrollbarVisibility visibility); diff --git a/interface/wx/window.h b/interface/wx/window.h index 8f8a9d8364..8d8bec2cf1 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -2368,7 +2368,10 @@ public: @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. diff --git a/samples/scroll/scroll.cpp b/samples/scroll/scroll.cpp index efbfb37479..98a9d01dad 100644 --- a/samples/scroll/scroll.cpp +++ b/samples/scroll/scroll.cpp @@ -452,7 +452,7 @@ public: wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN) { - m_nLines = 100; + m_nLines = 50; m_winSync = NULL; m_inDoSync = false; @@ -621,7 +621,7 @@ private: 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; @@ -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_TglBtn_Scrollbar = wxWindow::NewControlId(); +const wxWindowID Scroll_Radio_ShowScrollbar = wxWindow::NewControlId(); 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_TOGGLEBUTTON(Scroll_TglBtn_Scrollbar, MyFrame::OnToggleScrollbar) + EVT_RADIOBOX(Scroll_Radio_ShowScrollbar, MyFrame::OnScrollbarVisibility) END_EVENT_TABLE() MyFrame::MyFrame() @@ -879,10 +879,12 @@ MyFrame::MyFrame() SetMenuBar( mbar ); + wxPanel *panel = new wxPanel(this); + 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" @@ -891,28 +893,39 @@ MyFrame::MyFrame() "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); - const wxSizerFlags flagsHBorder(wxSizerFlags().Border(wxLEFT | wxRIGHT)); + const wxSizerFlags + flagsHBorder(wxSizerFlags().Centre().Border(wxLEFT | wxRIGHT)); 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); - wxToggleButton *btn =new wxToggleButton(this, Scroll_TglBtn_Scrollbar, - "&Show scrollbar"); - btn->SetValue(true); - sizerBtns->Add(btn, flagsHBorder); topsizer->Add(sizerBtns, wxSizerFlags().Centre().Border()); - SetSizer(topsizer); + panel->SetSizer(topsizer); + wxSize size = panel->GetBestSize(); + SetSizeHints(size); + SetClientSize(2*size); 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, - event.IsChecked() ? wxSHOW_SB_ALWAYS - : wxSHOW_SB_NEVER); + wxScrollbarVisibility(event.GetSelection() - 1)); } void MyFrame::OnQuit(wxCommandEvent &WXUNUSED(event)) diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index 278ae610c0..49b8673eb4 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -1232,28 +1232,20 @@ void wxScrollHelper::DoAdjustScrollbar(int orient, int clientSize, int virtSize, - int& pixelsPerUnit, + int pixelsPerUnit, int& scrollUnits, int& scrollPosition, + int& scrollLinesPerPage, 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 - int unitsPerPage; - // 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; - unitsPerPage = 0; + scrollLinesPerPage = 0; } else // might need scrolling { @@ -1261,23 +1253,23 @@ wxScrollHelper::DoAdjustScrollbar(int orient, 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; - unitsPerPage = 0; + scrollLinesPerPage = 0; } 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 - const int posMax = scrollUnits - unitsPerPage; + const int posMax = scrollUnits - scrollLinesPerPage; 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() @@ -1348,6 +1356,7 @@ void wxScrollHelper::AdjustScrollbars() m_xScrollPixelsPerLine, m_xScrollLines, m_xScrollPosition, + m_xScrollLinesPerPage, m_xVisibility); DoAdjustScrollbar(wxVERTICAL, @@ -1356,6 +1365,7 @@ void wxScrollHelper::AdjustScrollbars() m_yScrollPixelsPerLine, m_yScrollLines, m_yScrollPosition, + m_yScrollLinesPerPage, m_yVisibility); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 85acab831e..199c04357e 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -963,6 +963,9 @@ void wxWindowMSW::MSWUpdateUIState(int action, int state) // scrolling stuff // --------------------------------------------------------------------------- +namespace +{ + inline int GetScrollPosition(HWND hWnd, int wOrient) { #ifdef __WXMICROWIN__ @@ -978,12 +981,19 @@ inline int GetScrollPosition(HWND hWnd, int wOrient) #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") ); - return GetScrollPosition(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT); + return GetScrollPosition(hWnd, WXOrientToSB(orient)); } // 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; -#if 0 - ::GetScrollRange(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT, - &minPos, &maxPos); -#endif WinStruct 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. @@ -1035,8 +1039,7 @@ void wxWindowMSW::SetScrollPos(int orient, int pos, bool refresh) 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. @@ -1046,28 +1049,37 @@ void wxWindowMSW::SetScrollbar(int orient, 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 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; - if ( HasFlag(wxALWAYS_SHOW_SB) ) + if ( HasFlag(wxALWAYS_SHOW_SB) || range == -1 ) { // 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) @@ -5783,8 +5795,7 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam, 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. -- 2.45.2