From dd932cbe1c594a3adceaa521f0cf735b09810f4e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 5 Apr 2005 22:43:41 +0000 Subject: [PATCH] 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 --- docs/latex/wx/vscroll.tex | 37 +++++++++++++++++++++++++++++++++++- include/wx/vscroll.h | 20 ++++++++++++++++---- src/generic/vscroll.cpp | 40 ++++++++++++++++++++++----------------- 3 files changed, 75 insertions(+), 22 deletions(-) diff --git a/docs/latex/wx/vscroll.tex b/docs/latex/wx/vscroll.tex index 7ed7688716..d304d6f172 100644 --- a/docs/latex/wx/vscroll.tex +++ b/docs/latex/wx/vscroll.tex @@ -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}} diff --git a/include/wx/vscroll.h b/include/wx/vscroll.h index cc500db1a9..5ac9a142c0 100644 --- a/include/wx/vscroll.h +++ b/include/wx/vscroll.h @@ -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: diff --git a/src/generic/vscroll.cpp b/src/generic/vscroll.cpp index d8d57b6e97..be1b108865 100644 --- a/src/generic/vscroll.cpp +++ b/src/generic/vscroll.cpp @@ -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 ) { -- 2.47.2