// Author: Vadim Zeitlin
// Modified by: Brad Anderson, David Warkentin
// Created: 30.05.03
-// RCS-ID: $Id$
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#include "wx/vscroll.h"
+#include "wx/utils.h" // For wxMin/wxMax().
+
// ============================================================================
// wxVarScrollHelperEvtHandler declaration
// ============================================================================
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 ||
}
#endif // wxUSE_MOUSEWHEEL
- if ( processed )
- event.Skip(wasSkipped);
+ event.Skip(wasSkipped);
return processed;
}
}
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 )
{
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;
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();
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;
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;