From 1e0af0bcdaedd6cb7a0d49f7752905e8bc3415cd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 26 Jun 2003 15:39:24 +0000 Subject: [PATCH] added EstimateTotalHeight git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21426 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/vscroll.tex | 19 ++++++++++++ include/wx/vscroll.h | 10 +++++++ src/generic/vscroll.cpp | 61 ++++++++++++++++++++++----------------- 3 files changed, 63 insertions(+), 27 deletions(-) diff --git a/docs/latex/wx/vscroll.tex b/docs/latex/wx/vscroll.tex index 1a647fc704..83d151170f 100644 --- a/docs/latex/wx/vscroll.tex +++ b/docs/latex/wx/vscroll.tex @@ -90,6 +90,25 @@ Just as with the ctor above, {\tt wxVSCROLL} style is always used, there is no need to specify it explicitly. +\membersection{wxVScrolledWindow::EstimateTotalHeight}\label{wxvscrolledwindowestimatetotalheight} + +\constfunc{virtual wxCoord}{EstimateTotalHeight}{\void} + +This protected function is used internally by wxVScrolledWindow to estimate the +total height of the window when \helpref{SetLineCount}{wxvscrolledwindowsetlinecount} +is called. The default implementation uses the brute force approach if the +number of the items in the control is small enough. Otherwise, it tries to find +the average line height using some lines in the beginning, middle and the end. + +If it is undesirable to access all these lines (some of which might be never +shown) just for the total height calculation, you may override the function and +provide your own guess better and/or faster. + +Note that although returning a totally wrong value would still work, it risks +to result in very strange scrollbar behaviour so this function should really +try to make the best guess possible. + + \membersection{wxVScrolledWindow::GetFirstVisibleLine}\label{wxvscrolledwindowgetfirstvisibleline} \constfunc{size\_t}{GetFirstVisibleLine}{\void} diff --git a/include/wx/vscroll.h b/include/wx/vscroll.h index a48faef6e3..5f4f2cb0a6 100644 --- a/include/wx/vscroll.h +++ b/include/wx/vscroll.h @@ -144,6 +144,16 @@ protected: // usual virtual void OnGetLinesHint(size_t lineMin, size_t lineMax) const { } + // when the number of lines changes, we try to estimate the total height + // of all lines which is a rather expensive operation in terms of lines + // access, so if the user code may estimate the average height + // better/faster than we do, it should override this function to implement + // its own logic + // + // this function should return the best guess for the total height it may + // make + virtual wxCoord EstimateTotalHeight() const; + // the event handlers void OnSize(wxSizeEvent& event); diff --git a/src/generic/vscroll.cpp b/src/generic/vscroll.cpp index f0c58c61b8..87d6f32338 100644 --- a/src/generic/vscroll.cpp +++ b/src/generic/vscroll.cpp @@ -53,6 +53,38 @@ void wxVScrolledWindow::Init() // 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)m_heightTotal / (3*NUM_LINES_TO_SAMPLE)) * m_lineMax); + } + + return heightTotal; +} + wxCoord wxVScrolledWindow::GetLinesHeight(size_t lineMin, size_t lineMax) const { if ( lineMin == lineMax ) @@ -147,33 +179,8 @@ void wxVScrolledWindow::SetLineCount(size_t count) // 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 -- 2.45.2