added GetVisibleBegin/End() to complement/replace GetFirst/LastVisibleLine() and use them in the code to fix problems when the control is empty and GetLastVisibleLine() returns (size_t)-1 (closes bug 1176561)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@33360 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2005-04-05 22:43:41 +00:00
parent 9c2a1d53c0
commit dd932cbe1c
3 changed files with 75 additions and 22 deletions

View File

@@ -115,12 +115,22 @@ try to make the best guess possible.
Returns the index of the first currently visible line.
This is same as \helpref{GetVisibleBegin}{wxvscrolledwindowgetvisiblebegin} and
exists only for symmetry with \helpref{GetLastVisibleLine}{wxvscrolledwindowgetlastvisibleline}.
\membersection{wxVScrolledWindow::GetLastVisibleLine}\label{wxvscrolledwindowgetlastvisibleline}
\constfunc{size\_t}{GetLastVisibleLine}{\void}
Returns the index of the last currently visible line.
Returns the index of the last currently visible line. Note that this method
returns \texttt{(size\_t)-1} (i.e. a huge positive number) if the control is
empty so if this is possible you should use \helpref{GetVisibleEnd}{wxvscrolledwindowgetvisibleend}
instead.
\wxheading{See also}
\helpref{GetFirstVisibleLine}{wxvscrolledwindowgetfirstvisibleline}
\membersection{wxVScrolledWindow::GetLineCount}\label{wxvscrolledwindowgetlinecount}
@@ -131,6 +141,31 @@ Get the number of lines this window contains (previously set by
\helpref{SetLineCount()}{wxvscrolledwindowsetlinecount})
\membersection{wxVScrolledWindow::GetVisibleBegin}\label{wxvscrolledwindowgetvisiblebegin}
\constfunc{size\_t}{GetVisibleBegin}{\void}
Returns the index of the first currently visible line.
\wxheading{See also}
\helpref{GetVisibleEnd}{wxvscrolledwindowgetvisibleend}
\membersection{wxVScrolledWindow::GetVisibleEnd}\label{wxvscrolledwindowgetvisibleend}
\constfunc{size\_t}{GetVisibleEnd}{\void}
Returns the index of the first line after the currently visible one. If the
return value is $0$ it means that no lines are currently shown (which only
happens if the control is empty). Note that the index returned by this method
is not always a valid index as it may be equal to \helpref{GetLineCount}{wxvscrolledwindowsetlinecount}.
\wxheading{See also}
\helpref{GetVisibleBegin}{wxvscrolledwindowgetvisiblebegin}
\membersection{wxVScrolledWindow::HitTest}\label{wxvscrolledwindowhittest}
\constfunc{int}{HitTest}{\param{wxCoord }{x}, \param{wxCoord }{y}}

View File

@@ -118,14 +118,26 @@ public:
size_t GetLineCount() const { return m_lineMax; }
// get the first currently visible line
size_t GetFirstVisibleLine() const { return m_lineFirst; }
size_t GetVisibleBegin() const { return m_lineFirst; }
// get the last currently visible line
size_t GetLastVisibleLine() const { return m_lineFirst + m_nVisible - 1; }
// get the first currently visible line
size_t GetVisibleEnd() const { return m_lineFirst + m_nVisible; }
// is this line currently visible?
bool IsVisible(size_t line) const
{ return line >= m_lineFirst && line <= GetLastVisibleLine(); }
{ return line >= GetVisibleBegin() && line < GetVisibleEnd(); }
// this is the same as GetVisibleBegin(), exists to match
// GetLastVisibleLine() and for backwards compatibility only
size_t GetFirstVisibleLine() const { return m_lineFirst; }
// get the last currently visible line
//
// this function is unsafe as it returns (size_t)-1 (i.e. a huge positive
// number) if the control is empty, use GetVisibleEnd() instead, this one
// is kept for backwards compatibility
size_t GetLastVisibleLine() const { return GetVisibleEnd() - 1; }
protected:

View File

@@ -220,7 +220,7 @@ void wxVScrolledWindow::RefreshLine(size_t line)
wxRect rect;
rect.width = GetClientSize().x;
rect.height = OnGetLineHeight(line);
for ( size_t n = GetFirstVisibleLine(); n < line; n++ )
for ( size_t n = GetVisibleBegin(); n < line; n++ )
{
rect.y += OnGetLineHeight(n);
}
@@ -235,21 +235,23 @@ void wxVScrolledWindow::RefreshLines(size_t from, size_t to)
// clump the range to just the visible lines -- it is useless to refresh
// the other ones
if ( from < GetFirstVisibleLine() )
from = GetFirstVisibleLine();
if ( from < GetVisibleBegin() )
from = GetVisibleBegin();
if ( to > GetLastVisibleLine() )
to = GetLastVisibleLine();
if ( to >= GetVisibleEnd() )
to = GetVisibleEnd();
else
to++;
// calculate the rect occupied by these lines on screen
wxRect rect;
rect.width = GetClientSize().x;
for ( size_t nBefore = GetFirstVisibleLine(); nBefore < from; nBefore++ )
for ( size_t nBefore = GetVisibleBegin(); nBefore < from; nBefore++ )
{
rect.y += OnGetLineHeight(nBefore);
}
for ( size_t nBetween = from; nBetween <= to; nBetween++ )
for ( size_t nBetween = from; nBetween < to; nBetween++ )
{
rect.height += OnGetLineHeight(nBetween);
}
@@ -267,8 +269,8 @@ void wxVScrolledWindow::RefreshAll()
int wxVScrolledWindow::HitTest(wxCoord WXUNUSED(x), wxCoord y) const
{
const size_t lineMax = GetLastVisibleLine();
for ( size_t line = GetFirstVisibleLine(); line <= lineMax; line++ )
const size_t lineMax = GetVisibleEnd();
for ( size_t line = GetVisibleBegin(); line < lineMax; line++ )
{
y -= OnGetLineHeight(line);
if ( y < 0 )
@@ -305,8 +307,8 @@ bool wxVScrolledWindow::ScrollToLine(size_t line)
// remember the currently shown lines for the refresh code below
size_t lineFirstOld = GetFirstVisibleLine(),
lineLastOld = GetLastVisibleLine();
size_t lineFirstOld = GetVisibleBegin(),
lineLastOld = GetVisibleEnd();
m_lineFirst = line;
@@ -317,8 +319,8 @@ bool wxVScrolledWindow::ScrollToLine(size_t line)
// finally refresh the display -- but only redraw as few lines as possible
// to avoid flicker
if ( GetFirstVisibleLine() > lineLastOld ||
GetLastVisibleLine() < lineFirstOld )
if ( GetVisibleBegin() >= lineLastOld ||
GetVisibleEnd() <= lineFirstOld )
{
// the simplest case: we don't have any old lines left, just redraw
// everything
@@ -326,7 +328,7 @@ bool wxVScrolledWindow::ScrollToLine(size_t line)
}
else // overlap between the lines we showed before and should show now
{
ScrollWindow(0, GetLinesHeight(GetFirstVisibleLine(), lineFirstOld));
ScrollWindow(0, GetLinesHeight(GetVisibleBegin(), lineFirstOld));
}
return true;
@@ -350,12 +352,14 @@ bool wxVScrolledWindow::ScrollPages(int pages)
int line;
if ( pages > 0 )
{
line = GetLastVisibleLine();
line = GetVisibleEnd();
if ( line )
line--;
pages--;
}
else // pages < 0
{
line = FindFirstFromBottom(GetFirstVisibleLine());
line = FindFirstFromBottom(GetVisibleBegin());
pages++;
}
@@ -404,7 +408,9 @@ void wxVScrolledWindow::OnScroll(wxScrollWinEvent& event)
}
else if ( evtType == wxEVT_SCROLLWIN_PAGEDOWN )
{
lineFirstNew = GetLastVisibleLine();
lineFirstNew = GetVisibleEnd();
if ( lineFirstNew )
lineFirstNew--;
}
else if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE )
{