// headers
// ----------------------------------------------------------------------------
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+#pragma implementation "vscroll.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
#include "wx/vscroll.h"
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxVScrolledWindow, wxPanel)
EVT_SIZE(wxVScrolledWindow::OnSize)
EVT_SCROLLWIN(wxVScrolledWindow::OnScroll)
+#if wxUSE_MOUSEWHEEL
+ EVT_MOUSEWHEEL(wxVScrolledWindow::OnMouseWheel)
+#endif
END_EVENT_TABLE()
// implementation
// ============================================================================
+IMPLEMENT_ABSTRACT_CLASS(wxVScrolledWindow, wxPanel)
+
// ----------------------------------------------------------------------------
// initialization
// ----------------------------------------------------------------------------
m_nVisible = 1;
m_heightTotal = 0;
+
+#if wxUSE_MOUSEWHEEL
+ m_sumWheelRotation = 0;
+#endif
}
// ----------------------------------------------------------------------------
// various helpers
// ----------------------------------------------------------------------------
+wxCoord wxVScrolledWindow::EstimateTotalHeight() const
+{
+ // estimate the total height: it is impossible to call
+ // OnGetLineHeight() for every line because there may be too many of
+ // them, so we just make a guess using some lines in the beginning,
+ // some in the end and some in the middle
+ static const size_t NUM_LINES_TO_SAMPLE = 10;
+
+ wxCoord heightTotal;
+ if ( m_lineMax < 3*NUM_LINES_TO_SAMPLE )
+ {
+ // in this case calculating exactly is faster and more correct than
+ // guessing
+ heightTotal = GetLinesHeight(0, m_lineMax);
+ }
+ else // too many lines to calculate exactly
+ {
+ // look at some lines in the beginning/middle/end
+ heightTotal =
+ GetLinesHeight(0, NUM_LINES_TO_SAMPLE) +
+ GetLinesHeight(m_lineMax - NUM_LINES_TO_SAMPLE, m_lineMax) +
+ GetLinesHeight(m_lineMax/2 - NUM_LINES_TO_SAMPLE/2,
+ m_lineMax/2 + NUM_LINES_TO_SAMPLE/2);
+
+ // use the height of the lines we looked as the average
+ heightTotal = (wxCoord)
+ (((float)heightTotal / (3*NUM_LINES_TO_SAMPLE)) * m_lineMax);
+ }
+
+ return heightTotal;
+}
+
wxCoord wxVScrolledWindow::GetLinesHeight(size_t lineMin, size_t lineMax) const
{
if ( lineMin == lineMax )
// save the number of lines
m_lineMax = count;
-
- // estimate the total height: it is impossible to call
- // OnGetLineHeight() for every line because there may be too many of
- // them, so we just make a guess using some lines in the beginning,
- // some in the end and some in the middle
- static const size_t NUM_LINES_TO_SAMPLE = 10;
-
- if ( count < 3*NUM_LINES_TO_SAMPLE )
- {
- // in this case calculating exactly is faster and more correct than
- // guessing
- m_heightTotal = GetLinesHeight(0, m_lineMax);
- }
- else // too many lines to calculate exactly
- {
- // look at some lines in the beginning/middle/end
- m_heightTotal =
- GetLinesHeight(0, NUM_LINES_TO_SAMPLE) +
- GetLinesHeight(count - NUM_LINES_TO_SAMPLE, count) +
- GetLinesHeight(count/2 - NUM_LINES_TO_SAMPLE/2,
- count/2 + NUM_LINES_TO_SAMPLE/2);
-
- // use the height of the lines we looked as the average
- m_heightTotal = (wxCoord)
- (((float)m_heightTotal / (3*NUM_LINES_TO_SAMPLE)) * m_lineMax);
- }
-
+ // and our estimate for their total height
+ m_heightTotal = EstimateTotalHeight();
// recalculate the scrollbars parameters
m_lineFirst = 1; // make sure it is != 0
RefreshRect(rect);
}
+void wxVScrolledWindow::RefreshLines(size_t from, size_t to)
+{
+ wxASSERT_MSG( from <= to, _T("RefreshLines(): empty range") );
+
+ // clump the range to just the visible lines -- it is useless to refresh
+ // the other ones
+ if ( from < GetFirstVisibleLine() )
+ from = GetFirstVisibleLine();
+
+ if ( to > GetLastVisibleLine() )
+ to = GetLastVisibleLine();
+
+ // calculate the rect occupied by these lines on screen
+ wxRect rect;
+ rect.width = GetClientSize().x;
+ for ( size_t nBefore = GetFirstVisibleLine(); nBefore < from; nBefore++ )
+ {
+ rect.y += OnGetLineHeight(nBefore);
+ }
+
+ for ( size_t nBetween = from; nBetween <= to; nBetween++ )
+ {
+ rect.height += OnGetLineHeight(nBetween);
+ }
+
+ // do refresh it
+ RefreshRect(rect);
+}
+
void wxVScrolledWindow::RefreshAll()
{
UpdateScrollbar();
size_t lineFirstNew;
const wxEventType evtType = event.GetEventType();
+
if ( evtType == wxEVT_SCROLLWIN_TOP )
{
lineFirstNew = 0;
{
lineFirstNew = GetLastVisibleLine();
}
- else // unknown scroll event?
+ else if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE )
{
- if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE )
- {
- lineFirstNew = event.GetPosition();
- }
- else
- {
- wxASSERT_MSG( evtType == wxEVT_SCROLLWIN_THUMBTRACK,
- _T("unknown scroll event type?") );
+ lineFirstNew = event.GetPosition();
+ }
+ else if ( evtType == wxEVT_SCROLLWIN_THUMBTRACK )
+ {
+ lineFirstNew = event.GetPosition();
+ }
- // don't do anything, otherwise dragging the thumb around would
- // be too slow
- return;
- }
+ else // unknown scroll event?
+ {
+ wxFAIL_MSG( _T("unknown scroll event type?") );
+ return;
}
ScrollToLine(lineFirstNew);
#endif // __WXMAC__
}
+#if wxUSE_MOUSEWHEEL
+
+void wxVScrolledWindow::OnMouseWheel(wxMouseEvent& event)
+{
+ m_sumWheelRotation += event.GetWheelRotation();
+ int delta = event.GetWheelDelta();
+
+ // how much to scroll this time
+ int units_to_scroll = -(m_sumWheelRotation/delta);
+ if ( !units_to_scroll )
+ return;
+
+ m_sumWheelRotation += units_to_scroll*delta;
+
+ if ( !event.IsPageScroll() )
+ ScrollLines( units_to_scroll*event.GetLinesPerAction() );
+ else
+ // scroll pages instead of lines
+ ScrollPages( units_to_scroll );
+}
+
+#endif