X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9845ffceccfd024109a88fd1d959ebd64a209782..8a28cd66a63ce30c75173e10948e9d49d366d218:/src/generic/vscroll.cpp diff --git a/src/generic/vscroll.cpp b/src/generic/vscroll.cpp index de9cf1fa61..589451775c 100644 --- a/src/generic/vscroll.cpp +++ b/src/generic/vscroll.cpp @@ -31,6 +31,8 @@ #include "wx/vscroll.h" +#include "wx/utils.h" // For wxMin/wxMax(). + // ============================================================================ // wxVarScrollHelperEvtHandler declaration // ============================================================================ @@ -53,7 +55,7 @@ public: private: wxVarScrollHelperBase *m_scrollHelper; - DECLARE_NO_COPY_CLASS(wxVarScrollHelperEvtHandler) + wxDECLARE_NO_COPY_CLASS(wxVarScrollHelperEvtHandler); }; // ============================================================================ @@ -97,10 +99,6 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event) if ( wasSkipped ) event.Skip(false); - // reset the skipped flag to false as it might have been set to true in - // ProcessEvent() above - event.Skip(false); - if ( evType == wxEVT_SCROLLWIN_TOP || evType == wxEVT_SCROLLWIN_BOTTOM || evType == wxEVT_SCROLLWIN_LINEUP || @@ -127,8 +125,7 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event) } #endif // wxUSE_MOUSEWHEEL - if ( processed ) - event.Skip(wasSkipped); + event.Skip(wasSkipped); return processed; } @@ -144,7 +141,7 @@ bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event) wxVarScrollHelperBase::wxVarScrollHelperBase(wxWindow *win) { - wxASSERT_MSG( win, _T("associated window can't be NULL in wxVarScrollHelperBase") ); + wxASSERT_MSG( win, wxT("associated window can't be NULL in wxVarScrollHelperBase") ); #if wxUSE_MOUSEWHEEL m_sumWheelRotation = 0; @@ -155,7 +152,7 @@ wxVarScrollHelperBase::wxVarScrollHelperBase(wxWindow *win) m_unitFirst = 0; m_win = - m_targetWindow = (wxWindow *)NULL; + m_targetWindow = NULL; m_physicalScrolling = true; m_handler = NULL; @@ -313,14 +310,17 @@ size_t wxVarScrollHelperBase::GetNewScrollPosition(wxScrollWinEvent& event) cons } else if ( evtType == wxEVT_SCROLLWIN_PAGEUP ) { - return FindFirstVisibleFromLast(m_unitFirst); + // Page up should do at least as much as line up. + return wxMin(FindFirstVisibleFromLast(m_unitFirst), + m_unitFirst ? m_unitFirst - 1 : 0); } else if ( evtType == wxEVT_SCROLLWIN_PAGEDOWN ) { + // And page down should do at least as much as line down. if ( GetVisibleEnd() ) - return GetVisibleEnd() - 1; + return wxMax(GetVisibleEnd() - 1, m_unitFirst + 1); else - return GetVisibleEnd(); + return wxMax(GetVisibleEnd(), m_unitFirst + 1); } else if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE ) { @@ -332,7 +332,7 @@ size_t wxVarScrollHelperBase::GetNewScrollPosition(wxScrollWinEvent& event) cons } // unknown scroll event? - wxFAIL_MSG( _T("unknown scroll event type?") ); + wxFAIL_MSG( wxT("unknown scroll event type?") ); return 0; } @@ -476,7 +476,7 @@ void wxVarScrollHelperBase::RefreshUnit(size_t unit) void wxVarScrollHelperBase::RefreshUnits(size_t from, size_t to) { - wxASSERT_MSG( from <= to, _T("RefreshUnits(): empty range") ); + wxASSERT_MSG( from <= to, wxT("RefreshUnits(): empty range") ); // clump the range to just the visible units -- it is useless to refresh // the other ones @@ -487,10 +487,10 @@ void wxVarScrollHelperBase::RefreshUnits(size_t from, size_t to) to = GetVisibleEnd(); // calculate the rect occupied by these units on screen - int orient_size, nonorient_size, orient_pos; - orient_size = nonorient_size = orient_pos = 0; + int orient_size = 0, + orient_pos = 0; - nonorient_size = GetNonOrientationTargetSize(); + int nonorient_size = GetNonOrientationTargetSize(); for ( size_t nBefore = GetVisibleBegin(); nBefore < from; @@ -593,7 +593,7 @@ bool wxVarScrollHelperBase::DoScrollToUnit(size_t unit) // to avoid flicker. We can't do this if we have children because they // won't be scrolled if ( m_targetWindow->GetChildren().empty() && - GetVisibleBegin() >= unitLastOld || GetVisibleEnd() <= unitFirstOld ) + (GetVisibleBegin() >= unitLastOld || GetVisibleEnd() <= unitFirstOld) ) { // the simplest case: we don't have any old units left, just redraw // everything @@ -601,7 +601,12 @@ bool wxVarScrollHelperBase::DoScrollToUnit(size_t unit) } else // scroll the window { + // Avoid scrolling visible parts of the screen on Mac +#ifdef __WXMAC__ + if (m_physicalScrolling && m_targetWindow->IsShownOnScreen()) +#else if ( m_physicalScrolling ) +#endif { wxCoord dx = 0, dy = GetUnitsSize(GetVisibleBegin(), unitFirstOld); @@ -669,6 +674,39 @@ bool wxVarScrollHelperBase::DoScrollPages(int pages) void wxVarScrollHelperBase::HandleOnSize(wxSizeEvent& event) { + if ( m_unitMax ) + { + // sometimes change in varscrollable window's size can result in + // unused empty space after the last item. Fix it by decrementing + // first visible item position according to the available space. + + // determine free space + const wxCoord sWindow = GetOrientationTargetSize(); + wxCoord s = 0; + size_t unit; + for ( unit = m_unitFirst; unit < m_unitMax; ++unit ) + { + if ( s > sWindow ) + break; + + s += OnGetUnitSize(unit); + } + wxCoord freeSpace = sWindow - s; + + // decrement first visible item index as long as there is free space + size_t idealUnitFirst; + for ( idealUnitFirst = m_unitFirst; + idealUnitFirst > 0; + idealUnitFirst-- ) + { + wxCoord us = OnGetUnitSize(idealUnitFirst-1); + if ( freeSpace < us ) + break; + freeSpace -= us; + } + m_unitFirst = idealUnitFirst; + } + UpdateScrollbar(); event.Skip(); @@ -789,7 +827,7 @@ void wxVarHVScrollHelper::RefreshRowColumn(size_t row, size_t column) h_rect.x += OnGetColumnWidth(n); } - // refresh but specialize the behavior if we have a single target window + // refresh but specialize the behaviour if we have a single target window if ( wxVarVScrollHelper::GetTargetWindow() == wxVarHScrollHelper::GetTargetWindow() ) { v_rect.x = h_rect.x; @@ -812,7 +850,7 @@ void wxVarHVScrollHelper::RefreshRowsColumns(size_t fromRow, size_t toRow, size_t fromColumn, size_t toColumn) { wxASSERT_MSG( fromRow <= toRow || fromColumn <= toColumn, - _T("RefreshRowsColumns(): empty range") ); + wxT("RefreshRowsColumns(): empty range") ); // clump the range to just the visible units -- it is useless to refresh // the other ones @@ -856,7 +894,7 @@ void wxVarHVScrollHelper::RefreshRowsColumns(size_t fromRow, size_t toRow, h_rect.width += OnGetColumnWidth(nBetween); } - // refresh but specialize the behavior if we have a single target window + // refresh but specialize the behaviour if we have a single target window if ( wxVarVScrollHelper::GetTargetWindow() == wxVarHScrollHelper::GetTargetWindow() ) { v_rect.x = h_rect.x; @@ -931,7 +969,7 @@ IMPLEMENT_ABSTRACT_CLASS(wxHVScrolledWindow, wxPanel) // wxVarVScrollLegacyAdaptor // =========================================================================== -size_t wxVarVScrollLegacyAdaptor::GetFirstVisibleLine() const +size_t wxVarVScrollLegacyAdaptor::GetFirstVisibleLine() const { return GetVisibleRowsBegin(); } size_t wxVarVScrollLegacyAdaptor::GetLastVisibleLine() const @@ -948,19 +986,19 @@ void wxVarVScrollLegacyAdaptor::RefreshLine(size_t line) void wxVarVScrollLegacyAdaptor::RefreshLines(size_t from, size_t to) { RefreshRows(from, to); } - + bool wxVarVScrollLegacyAdaptor::ScrollToLine(size_t line) { return ScrollToRow(line); } bool wxVarVScrollLegacyAdaptor::ScrollLines(int lines) { return ScrollRows(lines); } - + bool wxVarVScrollLegacyAdaptor::ScrollPages(int pages) { return ScrollRowPages(pages); } wxCoord wxVarVScrollLegacyAdaptor::OnGetLineHeight(size_t WXUNUSED(n)) const { - wxFAIL_MSG( _T("OnGetLineHeight() must be overridden if OnGetRowHeight() isn't!") ); + wxFAIL_MSG( wxT("OnGetLineHeight() must be overridden if OnGetRowHeight() isn't!") ); return -1; }