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,
int clientSize,
int virtSize,
int& pixelsPerUnit,
int pixelsPerUnit,
int& scrollUnits,
int& scrollPosition,
int& scrollLinesPerPage,
wxScrollbarVisibility visibility);

View File

@@ -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.

View File

@@ -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))

View File

@@ -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;
// The amount by which we scroll when paging
SetScrollPageSize(orient, unitsPerPage);
case wxSHOW_SB_DEFAULT:
range = scrollUnits;
break;
case wxSHOW_SB_ALWAYS:
range = scrollUnits ? scrollUnits : -1;
break;
}
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);

View File

@@ -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;
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<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;
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.