void DoAdjustScrollbar(int orient,
int clientSize,
int virtSize,
- int& pixelsPerUnit,
+ int pixelsPerUnit,
int& scrollUnits,
int& scrollPosition,
+ int& scrollLinesPerPage,
wxScrollbarVisibility visibility);
@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.
wxDefaultPosition, wxDefaultSize,
wxBORDER_SUNKEN)
{
- m_nLines = 100;
+ m_nLines = 50;
m_winSync = NULL;
m_inDoSync = false;
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;
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)
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()
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"
"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();
}
}
}
-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))
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
{
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 )
}
}
- 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()
m_xScrollPixelsPerLine,
m_xScrollLines,
m_xScrollPosition,
+ m_xScrollLinesPerPage,
m_xVisibility);
DoAdjustScrollbar(wxVERTICAL,
m_yScrollPixelsPerLine,
m_yScrollLines,
m_yScrollPosition,
+ m_yScrollLinesPerPage,
m_yVisibility);
// scrolling stuff
// ---------------------------------------------------------------------------
+namespace
+{
+
inline int GetScrollPosition(HWND hWnd, int wOrient)
{
#ifdef __WXMICROWIN__
#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
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.
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.
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)
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.