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
This commit is contained in:
Vadim Zeitlin
2008-12-24 21:58:05 +00:00
parent 938161a6a4
commit 1ddb6d2857
5 changed files with 104 additions and 67 deletions

View File

@@ -35,9 +35,10 @@ private:
void DoAdjustScrollbar(int orient, void DoAdjustScrollbar(int orient,
int clientSize, int clientSize,
int virtSize, int virtSize,
int& pixelsPerUnit, int pixelsPerUnit,
int& scrollUnits, int& scrollUnits,
int& scrollPosition, int& scrollPosition,
int& scrollLinesPerPage,
wxScrollbarVisibility visibility); wxScrollbarVisibility visibility);

View File

@@ -2368,7 +2368,10 @@ public:
@param thumbSize @param thumbSize
The size of the thumb, or visible portion of the scrollbar, in scroll units. The size of the thumb, or visible portion of the scrollbar, in scroll units.
@param range @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 @param refresh
@true to redraw the scrollbar, @false otherwise. @true to redraw the scrollbar, @false otherwise.

View File

@@ -452,7 +452,7 @@ public:
wxDefaultPosition, wxDefaultSize, wxDefaultPosition, wxDefaultSize,
wxBORDER_SUNKEN) wxBORDER_SUNKEN)
{ {
m_nLines = 100; m_nLines = 50;
m_winSync = NULL; m_winSync = NULL;
m_inDoSync = false; m_inDoSync = false;
@@ -621,7 +621,7 @@ private:
void OnTestAuto(wxCommandEvent& WXUNUSED(event)) { new MyAutoFrame(this); } void OnTestAuto(wxCommandEvent& WXUNUSED(event)) { new MyAutoFrame(this); }
void OnToggleSync(wxCommandEvent& event); void OnToggleSync(wxCommandEvent& event);
void OnToggleScrollbar(wxCommandEvent& event); void OnScrollbarVisibility(wxCommandEvent& event);
MyScrolledWindowBase *m_win1, MyScrolledWindowBase *m_win1,
*m_win2; *m_win2;
@@ -835,7 +835,7 @@ const wxWindowID Scroll_Test_Sub = wxWindow::NewControlId();
const wxWindowID Scroll_Test_Auto = wxWindow::NewControlId(); const wxWindowID Scroll_Test_Auto = wxWindow::NewControlId();
const wxWindowID Scroll_TglBtn_Sync = 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) BEGIN_EVENT_TABLE(MyFrame,wxFrame)
EVT_MENU(wxID_ABOUT, MyFrame::OnAbout) EVT_MENU(wxID_ABOUT, MyFrame::OnAbout)
@@ -848,7 +848,7 @@ BEGIN_EVENT_TABLE(MyFrame,wxFrame)
EVT_MENU(Scroll_Test_Auto, MyFrame::OnTestAuto) EVT_MENU(Scroll_Test_Auto, MyFrame::OnTestAuto)
EVT_TOGGLEBUTTON(Scroll_TglBtn_Sync, MyFrame::OnToggleSync) EVT_TOGGLEBUTTON(Scroll_TglBtn_Sync, MyFrame::OnToggleSync)
EVT_TOGGLEBUTTON(Scroll_TglBtn_Scrollbar, MyFrame::OnToggleScrollbar) EVT_RADIOBOX(Scroll_Radio_ShowScrollbar, MyFrame::OnScrollbarVisibility)
END_EVENT_TABLE() END_EVENT_TABLE()
MyFrame::MyFrame() MyFrame::MyFrame()
@@ -879,10 +879,12 @@ MyFrame::MyFrame()
SetMenuBar( mbar ); SetMenuBar( mbar );
wxPanel *panel = new wxPanel(this);
const wxSizerFlags flagsExpand(wxSizerFlags(1).Expand()); const wxSizerFlags flagsExpand(wxSizerFlags(1).Expand());
wxSizer *topsizer = new wxBoxSizer(wxVERTICAL); 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" "The windows below should behave in the same way, even though\n"
"they're implemented quite differently, see the code for details.\n" "they're implemented quite differently, see the code for details.\n"
"\n" "\n"
@@ -891,28 +893,39 @@ MyFrame::MyFrame()
"don't be surprised by this."), "don't be surprised by this."),
wxSizerFlags().Centre().Border()); wxSizerFlags().Centre().Border());
m_win1 = new MyScrolledWindowDumb(this); m_win1 = new MyScrolledWindowDumb(panel);
m_win2 = new MyScrolledWindowSmart(this); m_win2 = new MyScrolledWindowSmart(panel);
wxSizer *sizerScrollWin = new wxBoxSizer(wxHORIZONTAL); wxSizer *sizerScrollWin = new wxBoxSizer(wxHORIZONTAL);
sizerScrollWin->Add(m_win1, flagsExpand); sizerScrollWin->Add(m_win1, flagsExpand);
sizerScrollWin->Add(m_win2, flagsExpand); sizerScrollWin->Add(m_win2, flagsExpand);
topsizer->Add(sizerScrollWin, 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 wxScrollbarVisibility(event.GetSelection() - 1));
: wxSHOW_SB_NEVER);
} }
void MyFrame::OnQuit(wxCommandEvent &WXUNUSED(event)) void MyFrame::OnQuit(wxCommandEvent &WXUNUSED(event))

View File

@@ -1232,28 +1232,20 @@ void
wxScrollHelper::DoAdjustScrollbar(int orient, wxScrollHelper::DoAdjustScrollbar(int orient,
int clientSize, int clientSize,
int virtSize, int virtSize,
int& pixelsPerUnit, int pixelsPerUnit,
int& scrollUnits, int& scrollUnits,
int& scrollPosition, 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 || if ( pixelsPerUnit == 0 || clientSize >= virtSize )
(clientSize >= virtSize && visibility != wxSHOW_SB_ALWAYS) )
{ {
// scrolling is disabled or unnecessary // scrolling is disabled or unnecessary
scrollUnits = scrollUnits =
scrollPosition = 0; 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; scrollUnits = (virtSize + pixelsPerUnit - 1) / pixelsPerUnit;
// Calculate the number of fully scroll units // 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 // we're big enough to not need scrolling
scrollUnits = scrollUnits =
scrollPosition = 0; scrollPosition = 0;
unitsPerPage = 0; scrollLinesPerPage = 0;
} }
else // we do need a scrollbar else // we do need a scrollbar
{ {
if ( unitsPerPage < 1 ) if ( scrollLinesPerPage < 1 )
unitsPerPage = 1; scrollLinesPerPage = 1;
// Correct position if greater than extent of canvas minus // Correct position if greater than extent of canvas minus
// the visible portion of it or if below zero // the visible portion of it or if below zero
const int posMax = scrollUnits - unitsPerPage; const int posMax = scrollUnits - scrollLinesPerPage;
if ( scrollPosition > posMax ) if ( scrollPosition > posMax )
scrollPosition = posMax; scrollPosition = posMax;
else if ( scrollPosition < 0 ) 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;
// The amount by which we scroll when paging case wxSHOW_SB_DEFAULT:
SetScrollPageSize(orient, unitsPerPage); range = scrollUnits;
break;
case wxSHOW_SB_ALWAYS:
range = scrollUnits ? scrollUnits : -1;
break;
}
m_win->SetScrollbar(orient, scrollPosition, scrollLinesPerPage, range);
} }
void wxScrollHelper::AdjustScrollbars() void wxScrollHelper::AdjustScrollbars()
@@ -1348,6 +1356,7 @@ void wxScrollHelper::AdjustScrollbars()
m_xScrollPixelsPerLine, m_xScrollPixelsPerLine,
m_xScrollLines, m_xScrollLines,
m_xScrollPosition, m_xScrollPosition,
m_xScrollLinesPerPage,
m_xVisibility); m_xVisibility);
DoAdjustScrollbar(wxVERTICAL, DoAdjustScrollbar(wxVERTICAL,
@@ -1356,6 +1365,7 @@ void wxScrollHelper::AdjustScrollbars()
m_yScrollPixelsPerLine, m_yScrollPixelsPerLine,
m_yScrollLines, m_yScrollLines,
m_yScrollPosition, m_yScrollPosition,
m_yScrollLinesPerPage,
m_yVisibility); m_yVisibility);

View File

@@ -963,6 +963,9 @@ void wxWindowMSW::MSWUpdateUIState(int action, int state)
// scrolling stuff // scrolling stuff
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
namespace
{
inline int GetScrollPosition(HWND hWnd, int wOrient) inline int GetScrollPosition(HWND hWnd, int wOrient)
{ {
#ifdef __WXMICROWIN__ #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 int wxWindowMSW::GetScrollPos(int orient) const
{ {
HWND hWnd = GetHwnd(); HWND hWnd = GetHwnd();
wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") ); 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(); HWND hWnd = GetHwnd();
if ( !hWnd ) if ( !hWnd )
return 0; return 0;
#if 0
::GetScrollRange(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
&minPos, &maxPos);
#endif
WinStruct<SCROLLINFO> scrollInfo; WinStruct<SCROLLINFO> scrollInfo;
scrollInfo.fMask = SIF_RANGE; scrollInfo.fMask = SIF_RANGE;
if ( !::GetScrollInfo(hWnd, if ( !::GetScrollInfo(hWnd, WXOrientToSB(orient), &scrollInfo) )
orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
&scrollInfo) )
{ {
// Most of the time this is not really an error, since the return // Most of the time this is not really an error, since the return
// value can also be zero when there is no scrollbar yet. // 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, ::SetScrollInfo(hWnd, WXOrientToSB(orient), &info, refresh);
&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, int range,
bool refresh) 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; if ( range != -1 )
info.nMin = 0; // range is nMax - nMin + 1 {
info.nMax = range - 1; // as both nMax and nMax are inclusive info.nPage = pageSize;
info.nPos = pos; 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 // disable scrollbar instead of removing it then
info.fMask |= SIF_DISABLENOSCROLL; info.fMask |= SIF_DISABLENOSCROLL;
} }
HWND hWnd = GetHwnd(); ::SetScrollInfo(hwnd, WXOrientToSB(orient), &info, refresh);
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);
}
} }
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; scrollInfo.fMask = SIF_TRACKPOS;
if ( !::GetScrollInfo(GetHwnd(), if ( !::GetScrollInfo(GetHwnd(),
orientation == wxHORIZONTAL ? SB_HORZ WXOrientToSB(orientation),
: SB_VERT,
&scrollInfo) ) &scrollInfo) )
{ {
// Not necessarily an error, if there are no scrollbars yet. // Not necessarily an error, if there are no scrollbars yet.