From f18eaf2687ab42c97ccf469a2617306cadc0c6ef Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin <vadim@wxwidgets.org> Date: Sun, 8 Apr 2007 01:58:16 +0000 Subject: [PATCH] The great wxVScrolledWindow refactoring: allow using it both horizontal and vertical directions (slightly modified patch 1671181) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45330 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 1 + docs/latex/wx/classes.tex | 9 +- docs/latex/wx/hscrolledwindow.tex | 99 +++ docs/latex/wx/hvscrolledwindow.tex | 105 +++ docs/latex/wx/minimald.tex | 2 +- docs/latex/wx/position.tex | 108 +++ docs/latex/wx/varhscrollhelper.tex | 178 +++++ docs/latex/wx/varhvscrollhelper.tex | 173 +++++ docs/latex/wx/varscrollhelperbase.tex | 243 +++++++ docs/latex/wx/varvscrollhelper.tex | 178 +++++ docs/latex/wx/vscroll.tex | 302 --------- docs/latex/wx/vscrolledwindow.tex | 173 +++++ include/wx/htmllbox.h | 4 +- include/wx/vlbox.h | 4 +- include/wx/vscroll.h | 935 ++++++++++++++++++++++---- samples/vscroll/vstest.cpp | 382 ++++++++++- src/generic/htmllbox.cpp | 4 +- src/generic/vlbox.cpp | 4 +- src/generic/vscroll.cpp | 866 +++++++++++++++++------- src/richtext/richtextfontpage.cpp | 2 +- src/richtext/richtextsymboldlg.cpp | 14 +- 21 files changed, 3073 insertions(+), 713 deletions(-) create mode 100644 docs/latex/wx/hscrolledwindow.tex create mode 100644 docs/latex/wx/hvscrolledwindow.tex create mode 100755 docs/latex/wx/position.tex create mode 100644 docs/latex/wx/varhscrollhelper.tex create mode 100644 docs/latex/wx/varhvscrollhelper.tex create mode 100644 docs/latex/wx/varscrollhelperbase.tex create mode 100644 docs/latex/wx/varvscrollhelper.tex delete mode 100644 docs/latex/wx/vscroll.tex create mode 100644 docs/latex/wx/vscrolledwindow.tex diff --git a/docs/changes.txt b/docs/changes.txt index 11341667f0..9256834e9e 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -83,6 +83,7 @@ All: All (GUI): +- Added wxH[V]ScrolledWindow (Brad Anderson, Bryan Petty) - Added wxDC::StretchBlit() for wxMac and wxMSW (Vince Harron) - Added support for labels for toolbar controls (Vince Harron) - Added wxEventBlocker class (Francesco Montorsi). diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex index 5046e4ceaa..2a3c3c74c7 100644 --- a/docs/latex/wx/classes.tex +++ b/docs/latex/wx/classes.tex @@ -196,6 +196,7 @@ \input hprovcnt.tex \input helpevt.tex \input helpprov.tex +\input hscrolledwindow.tex \input htcell.tex \input htcolor.tex \input htcontnr.tex @@ -217,6 +218,7 @@ \input htwinprs.tex \input htwinhnd.tex \input http.tex +\input hvscrolledwindow.tex \input hyperlink.tex \input icon.tex \input iconbndl.tex @@ -294,6 +296,7 @@ \input pickerbase.tex \input platinfo.tex \input point.tex +\input position.tex \input postscpt.tex \input powerevt.tex \input prevwin.tex @@ -430,10 +433,14 @@ \input url.tex \input urldataob.tex \input validatr.tex +\input varhscrollhelper.tex +\input varhvscrollhelper.tex \input variant.tex +\input varscrollhelperbase.tex +\input varvscrollhelper.tex \input view.tex \input vlbox.tex -\input vscroll.tex +\input vscrolledwindow.tex \input window.tex \input wupdlock.tex \input createevt.tex diff --git a/docs/latex/wx/hscrolledwindow.tex b/docs/latex/wx/hscrolledwindow.tex new file mode 100644 index 0000000000..4055c75c52 --- /dev/null +++ b/docs/latex/wx/hscrolledwindow.tex @@ -0,0 +1,99 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: hscrolledwindow.tex +%% Purpose: wxHScrolledWindow Documentation +%% Author: Bryan Petty +%% Modified by: +%% Created: 2007-04-04 +%% RCS-ID: $Id$ +%% Copyright: (c) 2007 wxWidgets Team +%% License: wxWindows Licence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxHScrolledWindow}}\label{wxhscrolledwindow} + +In the name of this class, "H" stands for "horizontal" because it can be +used for scrolling columns of variable widths. It is not necessary to know +the widths of all columns in advance -- only those which are shown on the +screen need to be measured. + +In any case, this is a generalization of the +\helpref{wxScrolledWindow}{wxscrolledwindow} class which can be only used when +all columns have the same widths. It lacks some other wxScrolledWindow features +however, notably it can't scroll only a rectangle of the window and not its +entire client area. + +To use this class, you need to derive from it and implement the +\helpref{OnGetColumnWidth()}{wxvarhscrollhelperongetcolumnwidth} pure virtual +method. You also must call \helpref{SetColumnCount()}{wxvarhscrollhelpersetcolumncount} +to let the base class know how many columns it should display, but from that +moment on the scrolling is handled entirely by wxHScrolledWindow. You only +need to draw the visible part of contents in your {\tt OnPaint()} method as +usual. You should use \helpref{GetVisibleColumnsBegin()}{wxvarhscrollhelpergetvisiblecolumnsbegin} +and \helpref{GetVisibleColumnsEnd()}{wxvarhscrollhelpergetvisiblecolumnsend} to +select the lines to display. Note that the device context origin is not shifted +so the first visible column always appears at the point $(0, 0)$ in physical as +well as logical coordinates. + +\wxheading{Derived from} + +\helpref{wxPanel}{wxpanel}\\ +\helpref{wxWindow}{wxwindow}\\ +\helpref{wxEvtHandler}{wxevthandler}\\ +\helpref{wxObject}{wxobject} + +\helpref{wxVarHScrollHelper}{wxvarhscrollhelper}\\ +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} + +\wxheading{Include files} + +<wx/vscroll.h> + +\wxheading{See also} + +\helpref{wxHVScrolledWindow}{wxhvscrolledwindow}, +\rtfsp\helpref{wxVScrolledWindow}{wxvscrolledwindow} + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxHScrolledWindow::wxHScrolledWindow}\label{wxhscrolledwindowwxhscrolledwindow} + +\func{}{wxHScrolledWindow}{\void} + +Default constructor, you must call \helpref{Create()}{wxhscrolledwindowcreate} +later. + +\func{}{wxHScrolledWindow}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = 0}, \param{const wxString\& }{name = wxPanelNameStr}} + +This is the normal constructor, no need to call {\tt Create()} after using this one. + +Note that {\tt wxHSCROLL} is always automatically added to our style, there is +no need to specify it explicitly. + +\wxheading{Parameters} + +\docparam{parent}{The parent window, must not be {\tt NULL}} + +\docparam{id}{The identifier of this window, {\tt wxID\_ANY} by default} + +\docparam{pos}{The initial window position} + +\docparam{size}{The initial window size} + +\docparam{style}{The window style. There are no special style bits defined for +this class.} + +\docparam{name}{The name for this window; usually not used} + + +\membersection{wxHScrolledWindow::Create}\label{wxhscrolledwindowcreate} + +\func{bool}{Create}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = 0}, \param{const wxString\& }{name = wxPanelNameStr}} + +Same as the \helpref{non-default constuctor}{wxhscrolledwindowwxhscrolledwindow} +but returns status code: {\tt true} if ok, {\tt false} if the window couldn't +be created. + +Just as with the constructor above, the {\tt wxHSCROLL} style is always used, +there is no need to specify it explicitly. + diff --git a/docs/latex/wx/hvscrolledwindow.tex b/docs/latex/wx/hvscrolledwindow.tex new file mode 100644 index 0000000000..d97df10d13 --- /dev/null +++ b/docs/latex/wx/hvscrolledwindow.tex @@ -0,0 +1,105 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: hvscrolledwindow.tex +%% Purpose: wxHVScrolledWindow Documentation +%% Author: Bryan Petty +%% Modified by: +%% Created: 2007-04-04 +%% RCS-ID: $Id$ +%% Copyright: (c) 2007 wxWidgets Team +%% License: wxWindows Licence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxHVScrolledWindow}}\label{wxhvscrolledwindow} + +This window inherits all functionality of both vertical and horizontal, +variable scrolled windows. It automatically handles everything needed to +scroll both axis simultaneously with both variable row heights and variable +column widths. + +This is a generalization of the \helpref{wxScrolledWindow}{wxscrolledwindow} +class which can be only used when all rows and columns are the same size. It +lacks some other wxScrolledWindow features however, notably it can't scroll +only a rectangle of the window and not its entire client area. + +To use this class, you must derive from it and implement both the +\helpref{OnGetRowHeight()}{wxvarvscrollhelperongetrowheight} and +\helpref{OnGetColumnWidth()}{wxvarhscrollhelperongetcolumnwidth} pure virtual +methods to let the base class know how many rows and columns it should +display. You also need to set the total rows and columns the window contains, +but from that moment on the scrolling is handled entirely by +wxHVScrolledWindow. You only need to draw the visible part of contents in +your {\tt OnPaint()} method as usual. You should use +\helpref{GetVisibleBegin()}{wxvarhvscrollhelpergetvisiblebegin} +and \helpref{GetVisibleEnd()}{wxvarhvscrollhelpergetvisibleend} to select the +lines to display. Note that the device context origin is not shifted so the +first visible row and column always appear at the point $(0, 0)$ in physical +as well as logical coordinates. + +\wxheading{Derived from} + +\helpref{wxPanel}{wxpanel}\\ +\helpref{wxWindow}{wxwindow}\\ +\helpref{wxEvtHandler}{wxevthandler}\\ +\helpref{wxObject}{wxobject} + +\helpref{wxVarHVScrollHelper}{wxvarhvscrollhelper} + +\helpref{wxVarVScrollHelper}{wxvarvscrollhelper}\\ +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} + +\helpref{wxVarHScrollHelper}{wxvarhscrollhelper}\\ +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} + +\wxheading{Include files} + +<wx/vscroll.h> + +\wxheading{See also} + +\helpref{wxHScrolledWindow}{wxhscrolledwindow}, +\rtfsp\helpref{wxVScrolledWindow}{wxvscrolledwindow} + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxHVScrolledWindow::wxHVScrolledWindow}\label{wxhvscrolledwindowwxhvscrolledwindow} + +\func{}{wxHVScrolledWindow}{\void} + +Default constructor, you must call \helpref{Create()}{wxhvscrolledwindowcreate} +later. + +\func{}{wxHVScrolledWindow}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = 0}, \param{const wxString\& }{name = wxPanelNameStr}} + +This is the normal constructor, no need to call {\tt Create()} after using this one. + +Note that {\tt wxHSCROLL} and {\tt wxVSCROLL} are always automatically added +to our styles, there is no need to specify it explicitly. + +\wxheading{Parameters} + +\docparam{parent}{The parent window, must not be {\tt NULL}} + +\docparam{id}{The identifier of this window, {\tt wxID\_ANY} by default} + +\docparam{pos}{The initial window position} + +\docparam{size}{The initial window size} + +\docparam{style}{The window style. There are no special style bits defined for +this class.} + +\docparam{name}{The name for this window; usually not used} + + +\membersection{wxHVScrolledWindow::Create}\label{wxhvscrolledwindowcreate} + +\func{bool}{Create}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = 0}, \param{const wxString\& }{name = wxPanelNameStr}} + +Same as the \helpref{non-default constuctor}{wxhvscrolledwindowwxhvscrolledwindow} +but returns status code: {\tt true} if ok, {\tt false} if the window couldn't +be created. + +Just as with the constructor above, the {\tt wxHSCROLL} and {\tt wxVSCROLL} +styles are always used, there is no need to specify it explicitly. + diff --git a/docs/latex/wx/minimald.tex b/docs/latex/wx/minimald.tex index 0e5f72265b..c9e37c7092 100644 --- a/docs/latex/wx/minimald.tex +++ b/docs/latex/wx/minimald.tex @@ -35,7 +35,7 @@ \setfooter{\thepage}{}{}{}{}{\thepage} % put your file(s) in an \input{} statement here -\input{arrstrng.tex} +\input{locale.tex} \addcontentsline{toc}{chapter}{Index} \setheader{{\it INDEX}}{}{}{}{}{{\it INDEX}}% diff --git a/docs/latex/wx/position.tex b/docs/latex/wx/position.tex new file mode 100755 index 0000000000..c956a8ef66 --- /dev/null +++ b/docs/latex/wx/position.tex @@ -0,0 +1,108 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: position.tex (moved from gbposition.tex) +%% Purpose: wxPosition Documentation +%% Author: Robin Dunn, Bryan Petty +%% Modified by: +%% Created: 2003-11-06, modified 2007-04-05 +%% RCS-ID: $Id$ +%% Copyright: (c) 2003, 2007 wxWidgets Team +%% License: wxWindows Licence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxPosition}}\label{wxposition} + +This class represents the position of an item in any kind of grid of rows and +columns such as \helpref{wxGridBagSizer}{wxgridbagsizer}, or +\helpref{wxHVScrolledWindow}{wxhvscrolledwindow}. + +\wxheading{Derived from} + +No base class + +\wxheading{Include files} + +<wx/position.h> + +\wxheading{See also} + +\helpref{wxPoint}{wxpoint}, \helpref{wxSize}{wxsize} + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxPosition::wxPosition}\label{wxpositionwxposition} + +\func{}{wxPosition}{\void} + +\func{}{wxPosition}{\param{int }{row}, \param{int }{col}} + +Construct a new wxPosition, optionally setting the row and column. The +default value is $(0, 0)$. + + +\membersection{wxPosition::GetCol}\label{wxpositiongetcol} + +\constfunc{int}{GetCol}{\void} + +A synonym for \helpref{GetColumn()}{wxpositiongetcolumn}. + + +\membersection{wxPosition::GetColumn}\label{wxpositiongetcolumn} + +\constfunc{int}{GetColumn}{\void} + +Get the current row value. + + +\membersection{wxPosition::GetRow}\label{wxpositiongetrow} + +\constfunc{int}{GetRow}{\void} + +Get the current row value. + + +\membersection{wxPosition::SetCol}\label{wxpositionsetcol} + +\func{void}{SetCol}{\param{int }{column}} + +A synonym for \helpref{SetColumn()}{wxpositionsetcolumn}. + + +\membersection{wxPosition::SetColumn}\label{wxpositionsetcolumn} + +\func{void}{SetColumn}{\param{int }{column}} + +Set a new column value. + + +\membersection{wxPosition::SetRow}\label{wxpositionsetrow} + +\func{void}{SetRow}{\param{int }{row}} + +Set a new row value. + + +\membersection{Operators}\label{wxpositionoperators} + +\constfunc{bool}{operator $==$}{\param{const wxPosition\& }{p}} + +\constfunc{bool}{operator $!=$}{\param{const wxPosition\& }{p}} + +Compare equality of two wxPositions. + +\func{wxPosition\&}{operator $+=$}{\param{const wxPosition\& }{p}} + +\func{wxPosition\&}{operator $-=$}{\param{const wxPosition\& }{p}} + +\func{wxPosition\&}{operator $+=$}{\param{const wxSize\& }{s}} + +\func{wxPosition\&}{operator $-=$}{\param{const wxSize\& }{s}} + +\constfunc{wxPosition}{operator $+$}{\param{const wxPosition\& }{p}} + +\constfunc{wxPosition}{operator $-$}{\param{const wxPosition\& }{p}} + +\constfunc{wxPosition}{operator $+$}{\param{const wxSize\& }{s}} + +\constfunc{wxPosition}{operator $-$}{\param{const wxSize\& }{s}} + diff --git a/docs/latex/wx/varhscrollhelper.tex b/docs/latex/wx/varhscrollhelper.tex new file mode 100644 index 0000000000..0f9b6e3f38 --- /dev/null +++ b/docs/latex/wx/varhscrollhelper.tex @@ -0,0 +1,178 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: varhscrollhelper.tex +%% Purpose: wxVarHScrollHelper Documentation +%% Author: Bryan Petty +%% Modified by: +%% Created: 2007-04-04 +%% RCS-ID: $Id$ +%% Copyright: (c) 2007 wxWidgets Team +%% License: wxWindows Licence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxVarHScrollHelper}}\label{wxvarhscrollhelper} + +This class provides functions wrapping the +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} class, targeted for +horizontal-specific scrolling using \helpref{wxHScrolledWindow}{wxhscrolledwindow}. + +Like wxVarScrollHelperBase, this class is mostly only useful to those classes +built into wxWidgets deriving from here, and this documentation is mostly +only provided for referencing those functions provided. You will likely want +to derive your window from wxHScrolledWindow rather than from here directly. + +\wxheading{Derived from} + +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} + +\wxheading{Include files} + +<wx/vscroll.h> + +\wxheading{See also} + +\helpref{wxHScrolledWindow}{wxhscrolledwindow}, +\rtfsp\helpref{wxHVScrolledWindow}{wxhvscrolledwindow}, +\rtfsp\helpref{wxVScrolledWindow}{wxvscrolledwindow} + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxVarHScrollHelper::wxVarHScrollHelper}\label{wxvarhscrollhelperwxvarhscrollhelper} + +\func{}{wxVarHScrollHelper}{\param{wxWindow* }{winToScroll}} + +Constructor taking the target window to be scrolled by this helper class. +This will attach scroll event handlers to the target window to catch and +handle scroll events appropriately. + + +\membersection{wxVarHScrollHelper::EstimateTotalWidth}\label{wxvarhscrollhelperestimatetotalwidth} + +\constfunc{virtual wxCoord}{EstimateTotalWidth}{\void} + +This class forwards calls from +\helpref{wxVarScrollHelperBase::EstimateTotalSize}{wxvarscrollhelperbaseestimatetotalsize} +to this function so derived classes can override either just the height or +the width estimation, or just estimate both differently if desired in any +\helpref{wxHVScrolledWindow}{wxhvscrolledwindow} derived class. + +Please note that this function will not be called if {\tt EstimateTotalSize()} +is overridden in your derived class. + + +\membersection{wxVarHScrollHelper::GetColumnCount}\label{wxvarhscrollhelpergetcolumncount} + +\constfunc{size\_t}{GetColumnCount}{\void} + +Returns the number of columns the target window contains. + +\wxheading{See also} + +\helpref{SetColumnCount()}{wxvarhscrollhelpersetcolumncount} + + +\membersection{wxVarHScrollHelper::GetVisibleColumnsBegin}\label{wxvarhscrollhelpergetvisiblecolumnsbegin} + +\constfunc{size\_t}{GetVisibleColumnsBegin}{\void} + +Returns the index of the first visible column based on the scroll position. + + +\membersection{wxVarHScrollHelper::GetVisibleColumnsEnd}\label{wxvarhscrollhelpergetvisiblecolumnsend} + +\constfunc{size\_t}{GetVisibleColumnsEnd}{\void} + +Returns the index of the last visible column based on the scroll position. This +includes the last column even if it is only partially visible. + + +\membersection{wxVarHScrollHelper::IsColumnVisible}\label{wxvarhscrollhelperiscolumnvisible} + +\constfunc{bool}{IsColumnVisible}{\param{size\_t }{column}} + +Returns {\tt true} if the given column is currently visible (even if only +partially visible) or {\tt false} otherwise. + + +\membersection{wxVarHScrollHelper::OnGetColumnWidth}\label{wxvarhscrollhelperongetcolumnwidth} + +\constfunc{virtual wxCoord}{OnGetColumnWidth}{\param{size\_t }{column}} + +This function must be overridden in the derived class, and should return the +width of the given column in pixels. + + +\membersection{wxVarHScrollHelper::OnGetColumnsWidthHint}\label{wxvarhscrollhelperongetcolumnswidthhint} + +\constfunc{virtual void}{OnGetColumnsWidthHint}{\param{size\_t }{columnMin}, \param{size\_t }{columnMax}} + +This function doesn't have to be overridden but it may be useful to do so if +calculating the columns' sizes is a relatively expensive operation as it gives +your code a chance to calculate several of them at once and cache the result +if necessary. + +{\tt OnGetColumnsWidthHint()} is normally called just before +\helpref{OnGetColumnWidth()}{wxvarhscrollhelperongetcolumnwidth} but you +shouldn't rely on the latter being called for all columns in the interval +specified here. It is also possible that OnGetColumnWidth() will be called for +units outside of this interval, so this is really just a hint, not a promise. + +Finally, note that columnMin is inclusive, while columnMax is exclusive. + + +\membersection{wxVarHScrollHelper::RefreshColumn}\label{wxvarhscrollhelperrefreshcolumn} + +\func{virtual void}{RefreshColumn}{\param{size\_t }{column}} + +Triggers a refresh for just the given column's area of the window if it's visible. + + +\membersection{wxVarHScrollHelper::RefreshColumns}\label{wxvarhscrollhelperrefreshcolumns} + +\func{virtual void}{RefreshColumns}{\param{size\_t }{from}, \param{size\_t }{to}} + +Triggers a refresh for the area between the specified range of columns given +(inclusively). + + +\membersection{wxVarHScrollHelper::ScrollColumnPages}\label{wxvarhscrollhelperscrollcolumnpages} + +\func{virtual bool}{ScrollColumnPages}{\param{int }{pages}} + +Scroll by the specified number of pages which may be positive (to scroll right) +or negative (to scroll left). + + +\membersection{wxVarHScrollHelper::ScrollColumns}\label{wxvarhscrollhelperscrollcolumns} + +\func{virtual bool}{ScrollColumns}{\param{int }{columns}} + +Scroll by the specified number of columns which may be positive (to scroll right) +or negative (to scroll left). + +Returns {\tt true} if the window was scrolled, {\tt false} otherwise (for +example, if we're trying to scroll right but we are already showing the last +column). + + +\membersection{wxVarHScrollHelper::ScrollToColumn}\label{wxvarhscrollhelperscrolltocolumn} + +\func{bool}{ScrollToColumn}{\param{size\_t }{column}} + +Scroll to the specified column. It will become the first visible column in the window. + +Returns {\tt true} if we scrolled the window, {\tt false} if nothing was done. + + +\membersection{wxVarHScrollHelper::SetColumnCount}\label{wxvarhscrollhelpersetcolumncount} + +\func{void}{SetColumnCount}{\param{size\_t }{columnCount}} + +Set the number of columns the window contains. The derived class must provide +the widths for all columns with indices up to the one given here in it's +\helpref{OnGetColumnWidth()}{wxvarhscrollhelperongetcolumnwidth} implementation. + +\wxheading{See also} + +\helpref{GetColumnCount()}{wxvarhscrollhelpergetcolumncount} + diff --git a/docs/latex/wx/varhvscrollhelper.tex b/docs/latex/wx/varhvscrollhelper.tex new file mode 100644 index 0000000000..c50f0f8bbd --- /dev/null +++ b/docs/latex/wx/varhvscrollhelper.tex @@ -0,0 +1,173 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: varhvscrollhelper.tex +%% Purpose: wxVarHVScrollHelper Documentation +%% Author: Bryan Petty +%% Modified by: +%% Created: 2007-04-04 +%% RCS-ID: $Id$ +%% Copyright: (c) 2007 wxWidgets Team +%% License: wxWindows Licence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxVarHVScrollHelper}}\label{wxvarhvscrollhelper} + +This class provides functions wrapping the +\helpref{wxVarHScrollHelper}{wxvarhscrollhelper} and +\helpref{wxVarVScrollHelper}{wxvarvscrollhelper} classes, targeted for +scrolling a window in both axis using +\helpref{wxHVScrolledWindow}{wxhvscrolledwindow}. Since this class is also +the join class of the horizontal and vertical scrolling functionality, it +also addresses some wrappers that help avoid the need to specify class scope +in your wxHVScrolledWindow-derived class when using wxVarScrollHelperBase +functionality. + +Like all three of it's scroll helper base classes, this class is mostly only +useful to those classes built into wxWidgets deriving from here, and this +documentation is mostly only provided for referencing those functions +provided. You will likely want to derive your window from wxHVScrolledWindow +rather than from here directly. + +\wxheading{Derived from} + +\helpref{wxVarVScrollHelper}{wxvarvscrollhelper}\\ +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} + +\helpref{wxVarHScrollHelper}{wxvarhscrollhelper}\\ +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} + +\wxheading{Include files} + +<wx/vscroll.h> + +\wxheading{See also} + +\helpref{wxHScrolledWindow}{wxhscrolledwindow}, +\rtfsp\helpref{wxHVScrolledWindow}{wxhvscrolledwindow}, +\rtfsp\helpref{wxVScrolledWindow}{wxvscrolledwindow} + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxVarHVScrollHelper::wxVarHVScrollHelper}\label{wxvarhvscrollhelperwxvarhvscrollhelper} + +\func{}{wxVarHVScrollHelper}{\param{wxWindow* }{winToScroll}} + +Constructor taking the target window to be scrolled by this helper class. +This will attach scroll event handlers to the target window to catch and +handle scroll events appropriately. + + +\membersection{wxVarHVScrollHelper::EnablePhysicalScrolling}\label{wxvarhvscrollhelperenablephysicalscrolling} + +\func{void}{EnablePhysicalScrolling}{\param{bool }{vscrolling = true}, \param{bool }{hscrolling = true}} + +With physical scrolling on (when this is {\tt true}), the device origin is +changed properly when a \rtfsp\helpref{wxPaintDC}{wxpaintdc} is prepared, +children are actually moved and laid out properly, and the contents of the +window (pixels) are actually moved. When this is {\tt false}, you are +responsible for repainting any invalidated areas of the window yourself to +account for the new scroll position. + +\wxheading{Parameters} + +\docparam{vscrolling}{Specifies if physical scrolling should be turned on when scrolling vertically.} + +\docparam{hscrolling}{Specifies if physical scrolling should be turned on when scrolling horizontally.} + + +\membersection{wxVarHVScrollHelper::GetRowColumnCount}\label{wxvarhvscrollhelpergetrowcolumncount} + +\constfunc{wxSize}{GetRowColumnCount}{\void} + +Returns the number of columns and rows the target window contains. + +\wxheading{See also} + +\helpref{SetRowColumnCount()}{wxvarhvscrollhelpersetrowcolumncount} + + +\membersection{wxVarHVScrollHelper::GetVisibleBegin}\label{wxvarhvscrollhelpergetvisiblebegin} + +\constfunc{wxPosition}{GetVisibleBegin}{\void} + +Returns the index of the first visible column and row based on the current +scroll position. + + +\membersection{wxVarHVScrollHelper::GetVisibleEnd}\label{wxvarhvscrollhelpergetvisibleend} + +\constfunc{wxPosition}{GetVisibleEnd}{\void} + +Returns the index of the last visible column and row based on the scroll +position. This includes any partially visible columns or rows. + + +\membersection{wxVarHVScrollHelper::HitTest}\label{wxvarhvscrollhelperhittest} + +\constfunc{virtual wxPosition}{HitTest}{\param{wxCoord }{x}, \param{wxCoord }{y}} + +\constfunc{virtual wxPosition}{HitTest}{\param{const wxPoint\& }{pos}} + +Returns the scroll unit under the device unit given accounting for scroll +position or {\tt wxNOT\_FOUND} (for the row, column, or possibly both values) +if none. + + +\membersection{wxVarHVScrollHelper::IsVisible}\label{wxvarhvscrollhelperisvisible} + +\constfunc{bool}{IsVisible}{\param{size\_t }{row}, \param{size\_t }{column}} + +\constfunc{bool}{IsVisible}{\param{const wxPosition\& }{pos}} + +Returns {\tt true} if both the given row and column are currently visible +(even if only partially visible) or {\tt false} otherwise. + + +\membersection{wxVarHVScrollHelper::RefreshRowColumn}\label{wxvarhvscrollhelperrefreshrowcolumn} + +\func{virtual void}{RefreshRowColumn}{\param{size\_t }{row}, \param{size\_t }{column}} + +\func{virtual void}{RefreshRowColumn}{\param{const wxPosition\& }{pos}} + +Triggers a refresh for just the area shared between the given row and column +of the window if it is visible. + + +\membersection{wxVarHVScrollHelper::RefreshRowsColumns}\label{wxvarhvscrollhelperrefreshrowscolumns} + +\func{virtual void}{RefreshRowsColumns}{\param{size\_t }{fromRow}, \param{size\_t }{toRow}, \param{size\_t }{fromColumn}, \param{size\_t }{toColumn}} + +\func{virtual void}{RefreshRowsColumns}{\param{const wxPosition\& }{from}, \param{const wxPosition\& }{to}} + +Triggers a refresh for the visible area shared between all given rows and +columns (inclusive) of the window. If the target window for both orientations +is the same, the rectangle of cells is refreshed; if the target windows +differ, the entire client size opposite the orientation direction is +refreshed between the specified limits. + + +\membersection{wxVarHVScrollHelper::ScrollToRowColumn}\label{wxvarhvscrollhelperscrolltorowcolumn} + +\func{bool}{ScrollToRowColumn}{\param{size\_t }{row}, \param{size\_t }{column}} + +\func{bool}{ScrollToRowColumn}{\param{const wxPosition\& }{pos}} + +Scroll to the specified row and column. It will become the first visible row +and column in the window. Returns {\tt true} if we scrolled the window, +{\tt false} if nothing was done. + + +\membersection{wxVarHVScrollHelper::SetRowColumnCount}\label{wxvarhvscrollhelpersetrowcolumncount} + +\func{void}{SetRowColumnCount}{\param{size\_t }{rowCount}, \param{size\_t }{columnCount}} + +Set the number of rows and columns the target window will contain. The +derived class must provide the sizes for all rows and columns with indices up +to the ones given here in it's \helpref{OnGetRowHeight()}{wxvarvscrollhelperongetrowheight} +and \helpref{OnGetColumnWidth()}{wxvarhscrollhelperongetcolumnwidth} implementations, +respectively. + +\wxheading{See also} + +\helpref{GetRowColumnCount()}{wxvarhvscrollhelpergetrowcolumncount} + diff --git a/docs/latex/wx/varscrollhelperbase.tex b/docs/latex/wx/varscrollhelperbase.tex new file mode 100644 index 0000000000..223cd84eba --- /dev/null +++ b/docs/latex/wx/varscrollhelperbase.tex @@ -0,0 +1,243 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: varscrollhelperbase.tex +%% Purpose: wxVarScrollHelperBase Documentation +%% Author: Bryan Petty +%% Modified by: +%% Created: 2007-04-04 +%% RCS-ID: $Id$ +%% Copyright: (c) 2007 wxWidgets Team +%% License: wxWindows Licence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxVarScrollHelperBase}}\label{wxvarscrollhelperbase} + +This class provides all common base functionality for scroll calculations +shared among all variable scrolled window implementations as well as +automatic scrollbar functionality, saved scroll positions, controlling +target windows to be scrolled, as well as defining all required virtual +functions that need to be implemented for any orientation specific work. + +Documentation of this class is provided specifically for referencing use +of the functions provided by this class for use with the variable scrolled +windows that derive from here. You will likely want to derive your window +from one of the already implemented variable scrolled windows rather than +from wxVarScrollHelperBase directly. + +\wxheading{Include files} + +<wx/vscroll.h> + +\wxheading{See also} + +\helpref{wxHScrolledWindow}{wxhscrolledwindow}, +\rtfsp\helpref{wxHVScrolledWindow}{wxhvscrolledwindow}, +\rtfsp\helpref{wxVScrolledWindow}{wxvscrolledwindow} + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxVarScrollHelperBase::wxVarScrollHelperBase}\label{wxvarscrollhelperbasewxvarscrollhelperbase} + +\func{}{wxVarScrollHelperBase}{\param{wxWindow* }{winToScroll}} + +Constructor taking the target window to be scrolled by this helper class. +This will attach scroll event handlers to the target window to catch and +handle scroll events appropriately. + + +\membersection{wxVarScrollHelperBase::\destruct{wxVarScrollHelperBase}}\label{wxvarscrollhelperbasedtor} + +\func{virtual }{\destruct{wxVarScrollHelperBase}}{\void} + +Virtual destructor for detaching scroll event handlers attached with this +helper class. + + +\membersection{wxVarScrollHelperBase::CalcScrolledPosition}\label{wxvarscrollhelperbasecalcscrolledposition} + +\constfunc{int}{CalcScrolledPosition}{\param{int }{coord}} + +Translates the logical coordinate given to the current device coordinate. +For example, if the window is scrolled 10 units and each scroll unit +represents 10 device units (which may not be the case since this class allows +for variable scroll unit sizes), a call to this function with a coordinate of +15 will return -85. + +\wxheading{See also} + +\helpref{CalcUnscrolledPosition()}{wxvarscrollhelperbasecalcunscrolledposition} + + +\membersection{wxVarScrollHelperBase::CalcUnscrolledPosition}\label{wxvarscrollhelperbasecalcunscrolledposition} + +\constfunc{int}{CalcUnscrolledPosition}{\param{int }{coord}} + +Translates the device coordinate given to the corresponding logical +coordinate. For example, if the window is scrolled 10 units and each scroll +unit represents 10 device units (which may not be the case since this class +allows for variable scroll unit sizes), a call to this function with a +coordinate of 15 will return 115. + +\wxheading{See also} + +\helpref{CalcScrolledPosition()}{wxvarscrollhelperbasecalcscrolledposition} + + +\membersection{wxVarScrollHelperBase::EnablePhysicalScrolling}\label{wxvarscrollhelperbaseenablephysicalscrolling} + +\func{void}{EnablePhysicalScrolling}{\param{bool }{scrolling = true}} + +With physical scrolling on (when this is {\tt true}), the device origin is +changed properly when a \rtfsp\helpref{wxPaintDC}{wxpaintdc} is prepared, +children are actually moved and laid out properly, and the contents of the +window (pixels) are actually moved. When this is {\tt false}, you are +responsible for repainting any invalidated areas of the window yourself to +account for the new scroll position. + + +\membersection{wxVarScrollHelperBase::EstimateTotalSize}\label{wxvarscrollhelperbaseestimatetotalsize} + +\constfunc{virtual wxCoord}{EstimateTotalSize}{\void} + +When the number of scroll units change, we try to estimate the total size of +all units when the full window size is needed (i.e. to calculate the scrollbar +thumb size). This is a rather expensive operation in terms of unit access, so +if the user code may estimate the average size better or faster than we do, it +should override this function to implement its own logic. This function should +return the best guess for the total virtual window size. + +Note that although returning a totally wrong value would still work, it risks +resulting in very strange scrollbar behaviour so this function should really +try to make the best guess possible. + + +\membersection{wxVarScrollHelperBase::GetNonOrientationTargetSize}\label{wxvarscrollhelperbasegetnonorientationtargetsize} + +\constfunc{virtual int}{GetNonOrientationTargetSize}{\void} + +This function needs to be overridden in the in the derived class to return the +window size with respect to the opposing orientation. If this is a vertical +scrolled window, it should return the height. + +\wxheading{See also} + +\helpref{GetOrientationTargetSize()}{wxvarscrollhelperbasegetorientationtargetsize} + + +\membersection{wxVarScrollHelperBase::GetOrientation}\label{wxvarscrollhelperbasegetorientation} + +\constfunc{virtual wxOrientation}{GetOrientation}{\void} + +This function need to be overridden to return the orientation that this helper +is working with, either {\tt wxHORIZONTAL} or {\tt wxVERTICAL}. + + +\membersection{wxVarScrollHelperBase::GetOrientationTargetSize}\label{wxvarscrollhelperbasegetorientationtargetsize} + +\constfunc{virtual int}{GetOrientationTargetSize}{\void} + +This function needs to be overridden in the in the derived class to return the +window size with respect to the orientation this helper is working with. If +this is a vertical scrolled window, it should return the width. + +\wxheading{See also} + +\helpref{GetNonOrientationTargetSize()}{wxvarscrollhelperbasegetnonorientationtargetsize} + + +\membersection{wxVarScrollHelperBase::GetTargetWindow}\label{wxvarscrollhelperbasegettargetwindow} + +\constfunc{wxWindow*}{GetTargetWindow}{\void} + +This function will return the target window this helper class is currently +scrolling. + +\wxheading{See also} + +\helpref{SetTargetWindow()}{wxvarscrollhelperbasesettargetwindow} + + +\membersection{wxVarScrollHelperBase::GetVisibleBegin}\label{wxvarscrollhelperbasegetvisiblebegin} + +\constfunc{size\_t}{GetVisibleBegin}{\void} + +Returns the index of the first visible unit based on the scroll position. + + +\membersection{wxVarScrollHelperBase::GetVisibleEnd}\label{wxvarscrollhelperbasegetvisibleend} + +\constfunc{size\_t}{GetVisibleEnd}{\void} + +Returns the index of the last visible unit based on the scroll position. This +includes the last unit even if it is only partially visible. + + +\membersection{wxVarScrollHelperBase::HitTest}\label{wxvarscrollhelperbasehittest} + +\constfunc{virtual int}{HitTest}{\param{wxCoord }{coord}} + +Returns the scroll unit under the device unit given accounting for scroll +position or {\tt wxNOT\_FOUND} if none (i.e. if it is below the last item). + + +\membersection{wxVarScrollHelperBase::IsVisible}\label{wxvarscrollhelperbaseisvisible} + +\constfunc{bool}{IsVisible}{\param{size\_t }{unit}} + +Returns {\tt true} if the given scroll unit is currently visible (even if only +partially visible) or {\tt false} otherwise. + + +\membersection{wxVarScrollHelperBase::OnGetUnitSize}\label{wxvarscrollhelperbaseongetunitsize} + +\constfunc{virtual wxCoord}{OnGetUnitSize}{\param{size\_t }{unit}} + +This function must be overridden in the derived class, and should return the +size of the given unit in pixels. + + +\membersection{wxVarScrollHelperBase::OnGetUnitsSizeHint}\label{wxvarscrollhelperbaseongetunitssizehint} + +\constfunc{virtual void}{OnGetUnitsSizeHint}{\param{size\_t }{unitMin}, \param{size\_t }{unitMax}} + +This function doesn't have to be overridden but it may be useful to do so if +calculating the units' sizes is a relatively expensive operation as it gives +your code a chance to calculate several of them at once and cache the result +if necessary. + +{\tt OnGetUnitsSizeHint()} is normally called just before +\helpref{OnGetUnitSize()}{wxvarscrollhelperbaseongetunitsize} but you +shouldn't rely on the latter being called for all units in the interval +specified here. It is also possible that OnGetUnitSize() will be called for +units outside of this interval, so this is really just a hint, not a promise. + +Finally, note that unitMin is inclusive, while unitMax is exclusive. + + +\membersection{wxVarScrollHelperBase::RefreshAll}\label{wxvarscrollhelperbaserefreshall} + +\func{virtual void}{RefreshAll}{\void} + +Recalculate all parameters and repaint all units. + + +\membersection{wxVarScrollHelperBase::SetTargetWindow}\label{wxvarscrollhelperbasesettargetwindow} + +\func{void}{SetTargetWindow}{\param{wxWindow* }{target}} + +Normally the window will scroll itself, but in some rare occasions you might +want it to scroll (part of) another window (e.g. a child of it in order to +scroll only a portion the area between the scrollbars like a spreadsheet where +only the cell area will move). + +\wxheading{See also} + +\helpref{GetTargetWindow()}{wxvarscrollhelperbasegettargetwindow} + + +\membersection{wxVarScrollHelperBase::UpdateScrollbar}\label{wxvarscrollhelperbaseupdatescrollbar} + +\func{virtual void}{UpdateScrollbar}{\void} + +Update the thumb size shown by the scrollbar. + diff --git a/docs/latex/wx/varvscrollhelper.tex b/docs/latex/wx/varvscrollhelper.tex new file mode 100644 index 0000000000..dc63514060 --- /dev/null +++ b/docs/latex/wx/varvscrollhelper.tex @@ -0,0 +1,178 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: varvscrollhelper.tex +%% Purpose: wxVarVScrollHelper Documentation +%% Author: Bryan Petty +%% Modified by: +%% Created: 2007-04-04 +%% RCS-ID: $Id$ +%% Copyright: (c) 2007 wxWidgets Team +%% License: wxWindows Licence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxVarVScrollHelper}}\label{wxvarvscrollhelper} + +This class provides functions wrapping the +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} class, targeted for +vertical-specific scrolling using \helpref{wxVScrolledWindow}{wxvscrolledwindow}. + +Like wxVarScrollHelperBase, this class is mostly only useful to those classes +built into wxWidgets deriving from here, and this documentation is mostly +only provided for referencing those functions provided. You will likely want +to derive your window from wxVScrolledWindow rather than from here directly. + +\wxheading{Derived from} + +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} + +\wxheading{Include files} + +<wx/vscroll.h> + +\wxheading{See also} + +\helpref{wxHScrolledWindow}{wxhscrolledwindow}, +\rtfsp\helpref{wxHVScrolledWindow}{wxhvscrolledwindow}, +\rtfsp\helpref{wxVScrolledWindow}{wxvscrolledwindow} + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxVarVScrollHelper::wxVarVScrollHelper}\label{wxvarvscrollhelperwxvarvscrollhelper} + +\func{}{wxVarVScrollHelper}{\param{wxWindow* }{winToScroll}} + +Constructor taking the target window to be scrolled by this helper class. +This will attach scroll event handlers to the target window to catch and +handle scroll events appropriately. + + +\membersection{wxVarVScrollHelper::EstimateTotalHeight}\label{wxvarvscrollhelperestimatetotalheight} + +\constfunc{virtual wxCoord}{EstimateTotalHeight}{\void} + +This class forwards calls from +\helpref{wxVarScrollHelperBase::EstimateTotalSize}{wxvarscrollhelperbaseestimatetotalsize} +to this function so derived classes can override either just the height or +the width estimation, or just estimate both differently if desired in any +\helpref{wxHVScrolledWindow}{wxhvscrolledwindow} derived class. + +Please note that this function will not be called if {\tt EstimateTotalSize()} +is overridden in your derived class. + + +\membersection{wxVarVScrollHelper::GetRowCount}\label{wxvarvscrollhelpergetrowcount} + +\constfunc{size\_t}{GetRowCount}{\void} + +Returns the number of rows the target window contains. + +\wxheading{See also} + +\helpref{SetRowCount()}{wxvarvscrollhelpersetrowcount} + + +\membersection{wxVarVScrollHelper::GetVisibleRowsBegin}\label{wxvarvscrollhelpergetvisiblerowsbegin} + +\constfunc{size\_t}{GetVisibleRowsBegin}{\void} + +Returns the index of the first visible row based on the scroll position. + + +\membersection{wxVarVScrollHelper::GetVisibleRowsEnd}\label{wxvarvscrollhelpergetvisiblerowsend} + +\constfunc{size\_t}{GetVisibleRowsEnd}{\void} + +Returns the index of the last visible row based on the scroll position. This +includes the last row even if it is only partially visible. + + +\membersection{wxVarVScrollHelper::IsRowVisible}\label{wxvarvscrollhelperisrowvisible} + +\constfunc{bool}{IsRowVisible}{\param{size\_t }{row}} + +Returns {\tt true} if the given row is currently visible (even if only +partially visible) or {\tt false} otherwise. + + +\membersection{wxVarVScrollHelper::OnGetRowHeight}\label{wxvarvscrollhelperongetrowheight} + +\constfunc{virtual wxCoord}{OnGetRowHeight}{\param{size\_t }{row}} + +This function must be overridden in the derived class, and should return the +height of the given row in pixels. + + +\membersection{wxVarVScrollHelper::OnGetRowsHeightHint}\label{wxvarvscrollhelperongetrowsheighthint} + +\constfunc{virtual void}{OnGetRowsHeightHint}{\param{size\_t }{rowMin}, \param{size\_t }{rowMax}} + +This function doesn't have to be overridden but it may be useful to do so if +calculating the rows' sizes is a relatively expensive operation as it gives +your code a chance to calculate several of them at once and cache the result +if necessary. + +{\tt OnGetRowsHeightHint()} is normally called just before +\helpref{OnGetRowHeight()}{wxvarvscrollhelperongetrowheight} but you +shouldn't rely on the latter being called for all rows in the interval +specified here. It is also possible that OnGetRowHeight() will be called for +units outside of this interval, so this is really just a hint, not a promise. + +Finally, note that rowMin is inclusive, while rowMax is exclusive. + + +\membersection{wxVarVScrollHelper::RefreshRow}\label{wxvarvscrollhelperrefreshrow} + +\func{virtual void}{RefreshRow}{\param{size\_t }{row}} + +Triggers a refresh for just the given row's area of the window if it's visible. + + +\membersection{wxVarVScrollHelper::RefreshRows}\label{wxvarvscrollhelperrefreshrows} + +\func{virtual void}{RefreshRows}{\param{size\_t }{from}, \param{size\_t }{to}} + +Triggers a refresh for the area between the specified range of rows given +(inclusively). + + +\membersection{wxVarVScrollHelper::ScrollRowPages}\label{wxvarvscrollhelperscrollrowpages} + +\func{virtual bool}{ScrollRowPages}{\param{int }{pages}} + +Scroll by the specified number of pages which may be positive (to scroll down) +or negative (to scroll up). + + +\membersection{wxVarVScrollHelper::ScrollRows}\label{wxvarvscrollhelperscrollrows} + +\func{virtual bool}{ScrollRows}{\param{int }{rows}} + +Scroll by the specified number of rows which may be positive (to scroll down) +or negative (to scroll up). + +Returns {\tt true} if the window was scrolled, {\tt false} otherwise (for +example, if we're trying to scroll down but we are already showing the last +row). + + +\membersection{wxVarVScrollHelper::ScrollToRow}\label{wxvarvscrollhelperscrolltorow} + +\func{bool}{ScrollToRow}{\param{size\_t }{row}} + +Scroll to the specified row. It will become the first visible row in the window. + +Returns {\tt true} if we scrolled the window, {\tt false} if nothing was done. + + +\membersection{wxVarVScrollHelper::SetRowCount}\label{wxvarvscrollhelpersetrowcount} + +\func{void}{SetRowCount}{\param{size\_t }{rowCount}} + +Set the number of rows the window contains. The derived class must provide the +heights for all rows with indices up to the one given here in it's +\helpref{OnGetRowHeight()}{wxvarvscrollhelperongetrowheight} implementation. + +\wxheading{See also} + +\helpref{GetRowCount()}{wxvarvscrollhelpergetrowcount} + diff --git a/docs/latex/wx/vscroll.tex b/docs/latex/wx/vscroll.tex deleted file mode 100644 index d75c477519..0000000000 --- a/docs/latex/wx/vscroll.tex +++ /dev/null @@ -1,302 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Name: vscroll.tex -%% Purpose: wxVScrolledWindow documentation -%% Author: Vadim Zeitlin -%% Modified by: -%% Created: 30.05.03 -%% RCS-ID: $Id$ -%% Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org> -%% License: wxWindows license -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -\section{\class{wxVScrolledWindow}}\label{wxvscrolledwindow} - -In the name of this class, "V" may stand for "variable" because it can be -used for scrolling lines of variable heights; "virtual" because it is not -necessary to know the heights of all lines in advance -- only those which -are shown on the screen need to be measured; or, even, "vertical" because -this class only supports scrolling in one direction currently (this could -and probably will change in the future however). - -In any case, this is a generalization of the -\helpref{wxScrolledWindow}{wxscrolledwindow} class which can be only used when -all lines have the same height. It lacks some other wxScrolledWindow features -however, notably there is currently no support for horizontal scrolling; it -can't scroll another window nor only a rectangle of the window and not its -entire client area. - -To use this class, you need to derive from it and implement -\helpref{OnGetLineHeight()}{wxvscrolledwindowongetlineheight} pure virtual -method. You also must call \helpref{SetLineCount}{wxvscrolledwindowsetlinecount} -to let the base class know how many lines it should display but from that -moment on the scrolling is handled entirely by wxVScrolledWindow, you only -need to draw the visible part of contents in your {\tt OnPaint()} method as -usual. You should use \helpref{GetFirstVisibleLine()}{wxvscrolledwindowgetfirstvisibleline} -and \helpref{GetLastVisibleLine()}{wxvscrolledwindowgetlastvisibleline} to -select the lines to display. Note that the device context origin is not shifted -so the first visible line always appears at the point $(0, 0)$ in physical as -well as logical coordinates. - -\wxheading{Derived from} - -\helpref{wxPanel}{wxpanel}\\ -\helpref{wxWindow}{wxwindow}\\ -\helpref{wxEvtHandler}{wxevthandler}\\ -\helpref{wxObject}{wxobject} - -\wxheading{Include files} - -<wx/vscroll.h> - - -\latexignore{\rtfignore{\wxheading{Members}}} - - -\membersection{wxVScrolledWindow::wxVScrolledWindow}\label{wxvscrolledwindowctor} - -\func{}{wxVScrolledWindow}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = 0}, \param{const wxString\& }{name = wxPanelNameStr}} - -This is the normal constructor, no need to call Create() after using this one. - -Note that {\tt wxVSCROLL} is always automatically added to our style, there is -no need to specify it explicitly. - -\func{}{wxVScrolledWindow}{\void} - -Default constructor, you must call \helpref{Create()}{wxvscrolledwindowcreate} -later. - -\wxheading{Parameters} - -\docparam{parent}{The parent window, must not be {\tt NULL}} - -\docparam{id}{The identifier of this window, {\tt wxID\_ANY} by default} - -\docparam{pos}{The initial window position} - -\docparam{size}{The initial window size} - -\docparam{style}{The window style. There are no special style bits defined for -this class.} - -\docparam{name}{The name for this window; usually not used} - - -\membersection{wxVScrolledWindow::Create}\label{wxvscrolledwindowcreate} - -\func{bool}{Create}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = 0}, \param{const wxString\& }{name = wxPanelNameStr}} - -Same as the \helpref{non default ctor}{wxvscrolledwindowctor} but returns -status code: {\tt true} if ok, {\tt false} if the window couldn't have been created. - -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} - -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. 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} - -\constfunc{size\_t}{GetLineCount}{\void} - -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}{wxvscrolledwindowgetlinecount}. - -\wxheading{See also} - -\helpref{GetVisibleBegin}{wxvscrolledwindowgetvisiblebegin} - - -\membersection{wxVScrolledWindow::HitTest}\label{wxvscrolledwindowhittest} - -\constfunc{int}{HitTest}{\param{wxCoord }{x}, \param{wxCoord }{y}} - -\constfunc{int}{HitTest}{\param{const wxPoint\& }{pt}} - -Return the item at the specified (in physical coordinates) position or -{\tt wxNOT\_FOUND} if none, i.e. if it is below the last item. - - -\membersection{wxVScrolledWindow::IsVisible}\label{wxvscrolledwindowisvisible} - -\constfunc{bool}{IsVisible}{\param{size\_t }{line}} - -Returns {\tt true} if the given line is (at least partially) visible or -{\tt false} otherwise. - - -\membersection{wxVScrolledWindow::OnGetLineHeight}\label{wxvscrolledwindowongetlineheight} - -\constfunc{virtual wxCoord}{OnGetLineHeight}{\param{size\_t }{n}} - -This protected virtual function must be overridden in the derived class and it -should return the height of the given line in pixels. - -\wxheading{See also} - -\helpref{OnGetLinesHint}{wxvscrolledwindowongetlineshint} - - -\membersection{wxVScrolledWindow::OnGetLinesHint}\label{wxvscrolledwindowongetlineshint} - -\constfunc{virtual void}{OnGetLinesHint}{\param{size\_t }{lineMin}, \param{size\_t }{lineMax}} - -This function doesn't have to be overridden but it may be useful to do -it if calculating the lines heights is a relatively expensive operation -as it gives the user code a possibility to calculate several of them at -once. - -{\tt OnGetLinesHint()} is normally called just before -\helpref{OnGetLineHeight()}{wxvscrolledwindowongetlineheight} but you -shouldn't rely on the latter being called for all lines in the interval -specified here. It is also possible that OnGetLineHeight() will be -called for the lines outside of this interval, so this is really just a -hint, not a promise. - -Finally note that {\it lineMin} is inclusive, while {\it lineMax} is exclusive, -as usual. - - -\membersection{wxVScrolledWindow::RefreshLine}\label{wxvscrolledwindowrefreshline} - -\func{void}{RefreshLine}{\param{size\_t }{line}} - -Refreshes the specified line -- it will be redrawn during the next main loop -iteration. - -\wxheading{See also} - -\helpref{RefreshLines}{wxvscrolledwindowrefreshlines} - - -\membersection{wxVScrolledWindow::RefreshLines}\label{wxvscrolledwindowrefreshlines} - -\func{void}{RefreshLines}{\param{size\_t }{from}, \param{size\_t }{to}} - -Refreshes all lines between {\it from} and {\it to}, inclusive. {\it from} -should be less than or equal to {\it to}. - -\wxheading{See also} - -\helpref{RefreshLine}{wxvscrolledwindowrefreshline} - - -\membersection{wxVScrolledWindow::RefreshAll}\label{wxvscrolledwindowrefreshall} - -\func{void}{RefreshAll}{\void} - -This function completely refreshes the control, recalculating the number of -items shown on screen and repainting them. It should be called when the values -returned by \helpref{OnGetLineHeight}{wxvscrolledwindowongetlineheight} change -for some reason and the window must be updated to reflect this. - - -\membersection{wxVScrolledWindow::ScrollLines}\label{wxvscrolledwindowscrolllines} - -\func{bool}{ScrollLines}{\param{int }{lines}} - -Scroll by the specified number of lines which may be positive (to scroll down) -or negative (to scroll up). - -Returns {\tt true} if the window was scrolled, {\tt false} otherwise (for -example if we're trying to scroll down but we are already showing the last -line). - -\wxheading{See also} - -\helpref{LineUp}{wxwindowlineup}, \helpref{LineDown}{wxwindowlinedown} - - -\membersection{wxVScrolledWindow::ScrollPages}\label{wxvscrolledwindowscrollpages} - -\func{bool}{ScrollPages}{\param{int }{pages}} - -Scroll by the specified number of pages which may be positive (to scroll down) -or negative (to scroll up). - -\wxheading{See also} - -\helpref{ScrollLines}{wxvscrolledwindowscrolllines},\\ -\helpref{PageUp}{wxwindowpageup}, \helpref{PageDown}{wxwindowpagedown} - - -\membersection{wxVScrolledWindow::ScrollToLine}\label{wxvscrolledwindowscrolltoline} - -\func{bool}{ScrollToLine}{\param{size\_t }{line}} - -Scroll to the specified line: it will become the first visible line in -the window. - -Return {\tt true} if we scrolled the window, {\tt false} if nothing was done. - - -\membersection{wxVScrolledWindow::SetLineCount}\label{wxvscrolledwindowsetlinecount} - -\func{void}{SetLineCount}{\param{size\_t }{count}} - -Set the number of lines the window contains: the derived class must -provide the heights for all lines with indices up to the one given here -in its \helpref{OnGetLineHeight()}{wxvscrolledwindowongetlineheight}. - diff --git a/docs/latex/wx/vscrolledwindow.tex b/docs/latex/wx/vscrolledwindow.tex new file mode 100644 index 0000000000..b66c55bca5 --- /dev/null +++ b/docs/latex/wx/vscrolledwindow.tex @@ -0,0 +1,173 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: vscrolledwindow.tex (moved from vscroll.tex) +%% Purpose: wxVScrolledWindow Documentation +%% Author: Vadim Zeitlin, Bryan Petty +%% Modified by: +%% Created: 2003-05-30, modified 2007-04-04 +%% RCS-ID: $Id$ +%% Copyright: (c) 2003, 2007 wxWidgets Team +%% License: wxWindows Licence +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxVScrolledWindow}}\label{wxvscrolledwindow} + +In the name of this class, "V" may stand for "variable" because it can be +used for scrolling rows of variable heights; "virtual", because it is not +necessary to know the heights of all rows in advance -- only those which +are shown on the screen need to be measured; or even "vertical", because +this class only supports scrolling vertically. + +In any case, this is a generalization of the +\helpref{wxScrolledWindow}{wxscrolledwindow} class which can be only used when +all rows have the same heights. It lacks some other wxScrolledWindow features +however, notably it can't scroll only a rectangle of the window and not its +entire client area. + +To use this class, you need to derive from it and implement the +\helpref{OnGetRowHeight()}{wxvarvscrollhelperongetrowheight} pure virtual +method. You also must call \helpref{SetRowCount}{wxvarvscrollhelpersetrowcount} +to let the base class know how many rows it should display, but from that +moment on the scrolling is handled entirely by wxVScrolledWindow. You only +need to draw the visible part of contents in your {\tt OnPaint()} method as +usual. You should use \helpref{GetVisibleRowsBegin()}{wxvarvscrollhelpergetvisiblerowsbegin} +and \helpref{GetVisibleRowsEnd()}{wxvarvscrollhelpergetvisiblerowsend} to +select the lines to display. Note that the device context origin is not shifted +so the first visible row always appears at the point $(0, 0)$ in physical as +well as logical coordinates. + +\wxheading{Derived from} + +\helpref{wxPanel}{wxpanel}\\ +\helpref{wxWindow}{wxwindow}\\ +\helpref{wxEvtHandler}{wxevthandler}\\ +\helpref{wxObject}{wxobject} + +\helpref{wxVarVScrollHelper}{wxvarvscrollhelper}\\ +\helpref{wxVarScrollHelperBase}{wxvarscrollhelperbase} + +\wxheading{Include files} + +<wx/vscroll.h> + +\wxheading{See also} + +\helpref{wxHScrolledWindow}{wxhscrolledwindow}, +\rtfsp\helpref{wxHVScrolledWindow}{wxhvscrolledwindow} + +\latexignore{\rtfignore{\wxheading{Members}}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% wxVarVScrollLegacyAdapter Compatibility Functions +%% This section will need to be removed when 2.8 compatibility is removed. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\membersection{wxWidgets 2.6 and 2.8 Compatibility Functions}\label{wxvscrolledwindowbackwardcompatibility} + +The following functions provide backwards compatibility for applications +originally built using wxVScrolledWindow in 2.6 or 2.8. Originally, +wxVScrolledWindow referred to scrolling "lines". We now use "units" in +wxVarScrollHelperBase to avoid implying any orientation (since the functions +are used for both horizontal and vertical scrolling in derived classes). And +in the new wxVScrolledWindow and wxHScrolledWindow classes, we refer to them +as "rows" and "columns", respectively. This is to help clear some confusion +in not only those classes, but also in wxHVScrolledWindow where functions +are inherited from both. + +You are encouraged to update any existing code using these function to use +the new replacements mentioned below, and avoid using these functions for +any new code as they are deprecated. + +\constfunc{size\_t}{GetFirstVisibleLine}{\void} + +Deprecated for \helpref{GetVisibleRowsBegin()}{wxvarvscrollhelpergetvisiblerowsbegin}. + +\constfunc{size\_t}{GetLastVisibleLine}{\void} + +Deprecated for \helpref{GetVisibleRowsEnd()}{wxvarvscrollhelpergetvisiblerowsend}. + +This function originally had a slight design flaw in that it was possible to +return \texttt{(size\_t)-1} (ie: a large positive number) if the scroll +position was 0 and the first line wasn't completely visible. + +\constfunc{size\_t}{GetLineCount}{\void} + +Deprecated for \helpref{GetRowCount()}{wxvarvscrollhelpergetrowcount}. + +\constfunc{virtual wxCoord}{OnGetLineHeight}{\param{size\_t }{line}} + +Deprecated for \helpref{OnGetRowHeight()}{wxvarvscrollhelperongetrowheight}. + +\constfunc{virtual void}{OnGetLinesHint}{\param{size\_t }{lineMin}, \param{size\_t }{lineMax}} + +Deprecated for \helpref{OnGetRowsHeightHint()}{wxvarvscrollhelperongetrowsheighthint}. + +\func{virtual void}{RefreshLine}{\param{size\_t }{line}} + +Deprecated for \helpref{RefreshRow()}{wxvarvscrollhelperrefreshrow}. + +\func{virtual void}{RefreshLines}{\param{size\_t }{from}, \param{size\_t }{to}} + +Deprecated for \helpref{RefreshRows()}{wxvarvscrollhelperrefreshrows}. + +\func{virtual bool}{ScrollLines}{\param{int }{lines}} + +Deprecated for \helpref{ScrollRows()}{wxvarvscrollhelperscrollrows}. + +\func{virtual bool}{ScrollPages}{\param{int }{pages}} + +Deprecated for \helpref{ScrollRowPages()}{wxvarvscrollhelperscrollrowpages}. + +\func{bool}{ScrollToLine}{\param{size\_t }{line}} + +Deprecated for \helpref{ScrollToRow()}{wxvarvscrollhelperscrolltorow}. + +\func{void}{SetLineCount}{\param{size\_t }{count}} + +Deprecated for \helpref{SetRowCount()}{wxvarvscrollhelpersetrowcount}. + +%%%%%%%%%%%%%%%%%%%%%%% END COMPATIBILITY FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\membersection{wxVScrolledWindow::wxVScrolledWindow}\label{wxvscrolledwindowwxvscrolledwindow} + +\func{}{wxVScrolledWindow}{\void} + +Default constructor, you must call \helpref{Create()}{wxvscrolledwindowcreate} +later. + +\func{}{wxVScrolledWindow}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = 0}, \param{const wxString\& }{name = wxPanelNameStr}} + +This is the normal constructor, no need to call {\tt Create()} after using this one. + +Note that {\tt wxVSCROLL} is always automatically added to our style, there is +no need to specify it explicitly. + +\wxheading{Parameters} + +\docparam{parent}{The parent window, must not be {\tt NULL}} + +\docparam{id}{The identifier of this window, {\tt wxID\_ANY} by default} + +\docparam{pos}{The initial window position} + +\docparam{size}{The initial window size} + +\docparam{style}{The window style. There are no special style bits defined for +this class.} + +\docparam{name}{The name for this window; usually not used} + + +\membersection{wxVScrolledWindow::Create}\label{wxvscrolledwindowcreate} + +\func{bool}{Create}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{long }{style = 0}, \param{const wxString\& }{name = wxPanelNameStr}} + +Same as the \helpref{non-default constuctor}{wxvscrolledwindowwxvscrolledwindow} +but returns status code: {\tt true} if ok, {\tt false} if the window couldn't +be created. + +Just as with the constructor above, the {\tt wxVSCROLL} style is always used, +there is no need to specify it explicitly. + diff --git a/include/wx/htmllbox.h b/include/wx/htmllbox.h index a7ee460e6f..132416819d 100644 --- a/include/wx/htmllbox.h +++ b/include/wx/htmllbox.h @@ -305,8 +305,8 @@ protected: // wxSimpleHtmlListBox shouldn't be allowed to call them directly! virtual void SetItemCount(size_t count) { wxHtmlListBox::SetItemCount(count); } - virtual void SetLineCount(size_t count) - { wxHtmlListBox::SetLineCount(count); } + virtual void SetRowCount(size_t count) + { wxHtmlListBox::SetRowCount(count); } virtual wxString OnGetItem(size_t n) const { return m_items[n]; } diff --git a/include/wx/vlbox.h b/include/wx/vlbox.h index b14bfd98f9..aa3618c2a1 100644 --- a/include/wx/vlbox.h +++ b/include/wx/vlbox.h @@ -75,7 +75,7 @@ public: // --------- // get the number of items in the control - size_t GetItemCount() const { return GetLineCount(); } + size_t GetItemCount() const { return GetRowCount(); } // does this control use multiple selection? bool HasMultipleSelection() const { return m_selStore != NULL; } @@ -133,7 +133,7 @@ public: // set the number of items to be shown in the control // - // this is just a synonym for wxVScrolledWindow::SetLineCount() + // this is just a synonym for wxVScrolledWindow::SetRowCount() virtual void SetItemCount(size_t count); // delete all items from the control diff --git a/include/wx/vscroll.h b/include/wx/vscroll.h index 33fc7aa1f8..1d15edfb5d 100644 --- a/include/wx/vscroll.h +++ b/include/wx/vscroll.h @@ -1,8 +1,8 @@ ///////////////////////////////////////////////////////////////////////////// // Name: include/wx/vscroll.h -// Purpose: wxVScrolledWindow: generalization of wxScrolledWindow +// Purpose: Variable scrolled windows (wx[V/H/HV]ScrolledWindow) // Author: Vadim Zeitlin -// Modified by: +// Modified by: Brad Anderson, Bryan Petty // Created: 30.05.03 // RCS-ID: $Id$ // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org> @@ -12,137 +12,623 @@ #ifndef _WX_VSCROLL_H_ #define _WX_VSCROLL_H_ -#include "wx/panel.h" // base class - -// ---------------------------------------------------------------------------- -// wxVScrolledWindow -// ---------------------------------------------------------------------------- - -/* - In the name of this class, "V" may stand for "variable" because it can be - used for scrolling lines of variable heights; "virtual" because it is not - necessary to know the heights of all lines in advance -- only those which - are shown on the screen need to be measured; or, even, "vertical" because - this class only supports scrolling in one direction currently (this could - and probably will change in the future however). - - In any case, this is a generalization of the wxScrolledWindow class which - can be only used when all lines have the same height. It lacks some other - wxScrolledWindow features however, notably it currently lacks support for - horizontal scrolling; it can't scroll another window nor only a rectangle - of the window and not its entire client area. - */ -class WXDLLEXPORT wxVScrolledWindow : public wxPanel +#include "wx/panel.h" +#include "wx/position.h" + +class WXDLLEXPORT wxVarScrollHelperEvtHandler; + + +// Using the same techniques as the wxScrolledWindow class | +// hierarchy, the wx[V/H/HV]ScrolledWindow classes are slightly | +// more complex (compare with the diagram outlined in | +// scrolwin.h) for the purpose of reducing code duplication | +// through the use of mix-in classes. | +// | +// wxVarScrollHelperBase | +// / \ | +// / \ | +// V V | +// wxVarHScrollHelper wxVarVScrollHelper | +// | \ / | | +// | \ / | | +// | V V | | +// | wxVarHVScrollHelper | | +// | | | | +// | | V | +// | wxPanel | wxVarVScrollLegacyAdaptor | +// | / \ \ | | | +// | / \ `-----|----------. | | +// | / \ | \ | | +// | / \ | \ | | +// V V \ | V V | +// wxHScrolledWindow \ | wxVScrolledWindow | +// V V | +// wxHVScrolledWindow | +// | +// | +// Border added to suppress GCC multi-line comment warnings ->| + + +// =========================================================================== +// wxVarScrollHelperBase +// =========================================================================== + +// Provides all base common scroll calculations needed for either orientation, +// automatic scrollbar functionality, saved scroll positions, functionality +// for changing the target window to be scrolled, as well as defining all +// required virtual functions that need to be implemented for any orientation +// specific work. + +class WXDLLEXPORT wxVarScrollHelperBase { public: // constructors and such // --------------------- - // default ctor, you must call Create() later - wxVScrolledWindow() { Init(); } + wxVarScrollHelperBase(wxWindow *winToScroll); + virtual ~wxVarScrollHelperBase(); - // normal ctor, no need to call Create() after this one + // operations + // ---------- + + // with physical scrolling on, the device origin is changed properly when + // a wxPaintDC is prepared, children are actually moved and laid out + // properly, and the contents of the window (pixels) are actually moved + void EnablePhysicalScrolling(bool scrolling = true) + { m_physicalScrolling = scrolling; } + + // wxNOT_FOUND if none, i.e. if it is below the last item + virtual int HitTest(wxCoord coord) const; + + // recalculate all our parameters and redisplay all units + virtual void RefreshAll(); + + // accessors + // --------- + + // get the first currently visible unit + size_t GetVisibleBegin() const { return m_unitFirst; } + + // get the last currently visible unit + size_t GetVisibleEnd() const + { return m_unitFirst + m_nUnitsVisible; } + + // is this unit currently visible? + bool IsVisible(size_t unit) const + { return unit >= m_unitFirst && unit < GetVisibleEnd(); } + + // translate between scrolled and unscrolled coordinates + int CalcScrolledPosition(int coord) const + { return DoCalcScrolledPosition(coord); } + int CalcUnscrolledPosition(int coord) const + { return DoCalcUnscrolledPosition(coord); } + + virtual int DoCalcScrolledPosition(int coord) const; + virtual int DoCalcUnscrolledPosition(int coord) const; + + // update the thumb size shown by the scrollbar + virtual void UpdateScrollbar(); + void RemoveScrollbar(); + + // Normally the wxScrolledWindow will scroll itself, but in some rare + // occasions you might want it to scroll [part of] another window (e.g. a + // child of it in order to scroll only a portion the area between the + // scrollbars (spreadsheet: only cell area will move). + virtual void SetTargetWindow(wxWindow *target); + virtual wxWindow *GetTargetWindow() const { return m_targetWindow; } + + // Override this function to draw the graphic (or just process EVT_PAINT) + //virtual void OnDraw(wxDC& WXUNUSED(dc)) { } + + // change the DC origin according to the scroll position. To properly + // forward calls to wxWindow::Layout use WX_FORWARD_TO_SCROLL_HELPER() + // derived class + virtual void DoPrepareDC(wxDC& dc); + + // the methods to be called from the window event handlers + void HandleOnScroll(wxScrollWinEvent& event); + void HandleOnSize(wxSizeEvent& event); +#if wxUSE_MOUSEWHEEL + void HandleOnMouseWheel(wxMouseEvent& event); +#endif // wxUSE_MOUSEWHEEL + + // these functions must be overidden in the derived class to return + // orientation specific data (e.g. the width for vertically scrolling + // derivatives in the case of GetOrientationTargetSize()) + virtual int GetOrientationTargetSize() const = 0; + virtual int GetNonOrientationTargetSize() const = 0; + virtual wxOrientation GetOrientation() const = 0; + +protected: + // all *Unit* functions are protected to be exposed by + // wxVarScrollHelperBase implementations (with appropriate names) + + // get the number of units this window contains (previously set by + // SetUnitCount()) + size_t GetUnitCount() const { return m_unitMax; } + + // set the number of units the helper contains: the derived class must + // provide the sizes for all units with indices up to the one given here + // in its OnGetUnitSize() + void SetUnitCount(size_t count); + + // redraw the specified unit + virtual void RefreshUnit(size_t unit); + + // redraw all units in the specified range (inclusive) + virtual void RefreshUnits(size_t from, size_t to); + + // scroll to the specified unit: it will become the first visible unit in + // the window // - // note that wxVSCROLL is always automatically added to our style, there is - // no need to specify it explicitly - wxVScrolledWindow(wxWindow *parent, - wxWindowID id = wxID_ANY, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxString& name = wxPanelNameStr) + // return true if we scrolled the window, false if nothing was done + bool DoScrollToUnit(size_t unit); + + // scroll by the specified number of units/pages + virtual bool DoScrollUnits(int units); + virtual bool DoScrollPages(int pages); + + // this function must be overridden in the derived class and it should + // return the size of the given unit in pixels + virtual wxCoord OnGetUnitSize(size_t n) const = 0; + + // this function doesn't have to be overridden but it may be useful to do + // it if calculating the units' sizes is a relatively expensive operation + // as it gives the user code a possibility to calculate several of them at + // once + // + // OnGetUnitsSizeHint() is normally called just before OnGetUnitSize() but + // you shouldn't rely on the latter being called for all units in the + // interval specified here. It is also possible that OnGetUnitHeight() will + // be called for the units outside of this interval, so this is really just + // a hint, not a promise. + // + // finally note that unitMin is inclusive, while unitMax is exclusive, as + // usual + virtual void OnGetUnitsSizeHint(size_t WXUNUSED(unitMin), + size_t WXUNUSED(unitMax)) const + { } + + // when the number of units changes, we try to estimate the total size + // of all units which is a rather expensive operation in terms of unit + // access, so if the user code may estimate the average size + // 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 size it may + // make + virtual wxCoord EstimateTotalSize() const { return DoEstimateTotalSize(); } + + wxCoord DoEstimateTotalSize() const; + + // find the index of the unit we need to show to fit the specified unit on + // the opposite side either fully or partially (depending on fullyVisible) + size_t FindFirstVisibleFromLast(size_t last, + bool fullyVisible = false) const; + + // get the total size of the units between unitMin (inclusive) and + // unitMax (exclusive) + wxCoord GetUnitsSize(size_t unitMin, size_t unitMax) const; + + // get the offset of the first visible unit + wxCoord GetScrollOffset() const + { return GetUnitsSize(0, GetVisibleBegin()); } + + // get the size of the target window + wxSize GetTargetSize() const { return m_targetWindow->GetClientSize(); } + + void GetTargetSize(int *w, int *h) { - Init(); + wxSize size = GetTargetSize(); + if ( w ) + *w = size.x; + if ( h ) + *h = size.y; + } - (void)Create(parent, id, pos, size, style, name); + // calculate the new scroll position based on scroll event type + size_t GetNewScrollPosition(wxScrollWinEvent& event) const; + + // replacement implementation of wxWindow::Layout virtual method. To + // properly forward calls to wxWindow::Layout use + // WX_FORWARD_TO_SCROLL_HELPER() derived class + bool ScrollLayout(); + +#ifdef __WXMAC__ + // queue mac window update after handling scroll event + virtual void UpdateMacScrollWindow() = 0; +#endif // __WXMAC__ + + // change the target window + void DoSetTargetWindow(wxWindow *target); + + // delete the event handler we installed + void DeleteEvtHandler(); + + // helper function abstracting the orientation test: with vertical + // orientation, it assigns the first value to x and the second one to y, + // with horizontal orientation it reverses them, i.e. the first value is + // assigned to y and the second one to x + void AssignOrient(wxCoord& x, wxCoord& y, wxCoord first, wxCoord second); + + // similar to "oriented assignment" above but does "oriented increment": + // for vertical orientation, y is incremented by the given value and x if + // left unchanged, for horizontal orientation x is incremented + void IncOrient(wxCoord& x, wxCoord& y, wxCoord inc); + +private: + + // the window that receives the scroll events and the window to actually + // scroll, respectively + wxWindow *m_win, + *m_targetWindow; + + // the total number of (logical) units + size_t m_unitMax; + + // the total (estimated) size + wxCoord m_sizeTotal; + + // the first currently visible unit + size_t m_unitFirst; + + // the number of currently visible units (including the last, possibly only + // partly, visible one) + size_t m_nUnitsVisible; + + // accumulated mouse wheel rotation +#if wxUSE_MOUSEWHEEL + int m_sumWheelRotation; +#endif + + // do child scrolling (used in DoPrepareDC()) + bool m_physicalScrolling; + + // handler injected into target window to forward some useful events to us + wxVarScrollHelperEvtHandler *m_handler; +}; + + + +// =========================================================================== +// wxVarVScrollHelper +// =========================================================================== + +// Provides public API functions targeted for vertical-specific scrolling, +// wrapping the functionality of wxVarScrollHelperBase. + +class WXDLLEXPORT wxVarVScrollHelper : public wxVarScrollHelperBase +{ +public: + // constructors and such + // --------------------- + + // ctor must be given the associated window + wxVarVScrollHelper(wxWindow *winToScroll) + : wxVarScrollHelperBase(winToScroll) + { } - // same as the previous ctor but returns status code: true if ok - // - // just as with the ctor above, wxVSCROLL style is always used, there is no - // need to specify it - bool Create(wxWindow *parent, - wxWindowID id = wxID_ANY, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxString& name = wxPanelNameStr) + // operators + + void SetRowCount(size_t rowCount) { SetUnitCount(rowCount); } + bool ScrollToRow(size_t row) { return DoScrollToUnit(row); } + + virtual bool ScrollRows(int rows) + { return DoScrollUnits(rows); } + virtual bool ScrollRowPages(int pages) + { return DoScrollPages(pages); } + + virtual void RefreshRow(size_t row) + { RefreshUnit(row); } + virtual void RefreshRows(size_t from, size_t to) + { RefreshUnits(from, to); } + + virtual int HitTest(wxCoord y) const + { return wxVarScrollHelperBase::HitTest(y); } + + // accessors + + size_t GetRowCount() const { return GetUnitCount(); } + size_t GetVisibleRowsBegin() const { return GetVisibleBegin(); } + size_t GetVisibleRowsEnd() const { return GetVisibleEnd(); } + bool IsRowVisible(size_t row) const { return IsVisible(row); } + + virtual int GetOrientationTargetSize() const + { return GetTargetWindow()->GetClientSize().y; } + virtual int GetNonOrientationTargetSize() const + { return GetTargetWindow()->GetClientSize().x; } + virtual wxOrientation GetOrientation() const { return wxVERTICAL; } + +protected: + // this function must be overridden in the derived class and it should + // return the size of the given row in pixels + virtual wxCoord OnGetRowHeight(size_t n) const = 0; + wxCoord OnGetUnitSize(size_t n) const { return OnGetRowHeight(n); } + + virtual void OnGetRowsHeightHint(size_t WXUNUSED(rowMin), + size_t WXUNUSED(rowMax)) const { } + + // forward calls to OnGetRowsHeightHint() + virtual void OnGetUnitsSizeHint(size_t unitMin, size_t unitMax) const + { return OnGetRowsHeightHint(unitMin, unitMax); } + + // again, if not overridden, it will fall back on default method + virtual wxCoord EstimateTotalHeight() const + { return DoEstimateTotalSize(); } + + // forward calls to EstimateTotalHeight() + virtual wxCoord EstimateTotalSize() const { return EstimateTotalHeight(); } + + wxCoord GetRowsHeight(size_t rowMin, size_t rowMax) const + { return GetUnitsSize(rowMin, rowMax); } +}; + + + +// =========================================================================== +// wxVarHScrollHelper +// =========================================================================== + +// Provides public API functions targeted for horizontal-specific scrolling, +// wrapping the functionality of wxVarScrollHelperBase. + +class WXDLLEXPORT wxVarHScrollHelper : public wxVarScrollHelperBase +{ +public: + // constructors and such + // --------------------- + + // ctor must be given the associated window + wxVarHScrollHelper(wxWindow *winToScroll) + : wxVarScrollHelperBase(winToScroll) { - return wxPanel::Create(parent, id, pos, size, style | wxVSCROLL, name); } + // operators - // operations - // ---------- + void SetColumnCount(size_t columnCount) + { SetUnitCount(columnCount); } - // set the number of lines the window contains: the derived class must - // provide the heights for all lines with indices up to the one given here - // in its OnGetLineHeight() - void SetLineCount(size_t count); + bool ScrollToColumn(size_t column) + { return DoScrollToUnit(column); } + virtual bool ScrollColumns(int columns) + { return DoScrollUnits(columns); } + virtual bool ScrollColumnPages(int pages) + { return DoScrollPages(pages); } - // scroll to the specified line: it will become the first visible line in - // the window - // - // return true if we scrolled the window, false if nothing was done - bool ScrollToLine(size_t line); + virtual void RefreshColumn(size_t column) + { RefreshUnit(column); } + virtual void RefreshColumns(size_t from, size_t to) + { RefreshUnits(from, to); } + virtual int HitTest(wxCoord x) const + { return wxVarScrollHelperBase::HitTest(x); } - // scroll by the specified number of lines/pages - virtual bool ScrollLines(int lines); - virtual bool ScrollPages(int pages); + // accessors - // redraw the specified line - virtual void RefreshLine(size_t line); + size_t GetColumnCount() const + { return GetUnitCount(); } + size_t GetVisibleColumnsBegin() const + { return GetVisibleBegin(); } + size_t GetVisibleColumnsEnd() const + { return GetVisibleEnd(); } + bool IsColumnVisible(size_t column) const + { return IsVisible(column); } - // redraw all lines in the specified range (inclusive) - virtual void RefreshLines(size_t from, size_t to); - // return the item at the specified (in physical coordinates) position or. + virtual int GetOrientationTargetSize() const + { return GetTargetWindow()->GetClientSize().x; } + virtual int GetNonOrientationTargetSize() const + { return GetTargetWindow()->GetClientSize().y; } + virtual wxOrientation GetOrientation() const { return wxHORIZONTAL; } - // wxNOT_FOUND if none, i.e. if it is below the last item - int HitTest(wxCoord x, wxCoord y) const; - int HitTest(const wxPoint& pt) const { return HitTest(pt.x, pt.y); } +protected: + // this function must be overridden in the derived class and it should + // return the size of the given column in pixels + virtual wxCoord OnGetColumnWidth(size_t n) const = 0; + wxCoord OnGetUnitSize(size_t n) const { return OnGetColumnWidth(n); } - // recalculate all our parameters and redisplay all lines - virtual void RefreshAll(); + virtual void OnGetColumnsWidthHint(size_t WXUNUSED(columnMin), + size_t WXUNUSED(columnMax)) const + { } + // forward calls to OnGetColumnsWidthHint() + virtual void OnGetUnitsSizeHint(size_t unitMin, size_t unitMax) const + { return OnGetColumnsWidthHint(unitMin, unitMax); } + + // again, if not overridden, it will fall back on default method + virtual wxCoord EstimateTotalWidth() const { return DoEstimateTotalSize(); } + + // forward calls to EstimateTotalWidth() + virtual wxCoord EstimateTotalSize() const { return EstimateTotalWidth(); } + + wxCoord GetColumnsWidth(size_t columnMin, size_t columnMax) const + { return GetUnitsSize(columnMin, columnMax); } +}; + + + +// =========================================================================== +// wxVarHVScrollHelper +// =========================================================================== + +// Provides public API functions targeted at functions with similar names in +// both wxVScrollHelper and wxHScrollHelper so class scope doesn't need to be +// specified (since we are using multiple inheritance). It also provides +// functions to make changing values for both orientations at the same time +// easier. + +class WXDLLEXPORT wxVarHVScrollHelper : public wxVarVScrollHelper, + public wxVarHScrollHelper +{ +public: + // constructors and such + // --------------------- + + // ctor must be given the associated window + wxVarHVScrollHelper(wxWindow *winToScroll) + : wxVarVScrollHelper(winToScroll), wxVarHScrollHelper(winToScroll) { } + + // operators + // --------- + + // set the number of units the window contains for each axis: the derived + // class must provide the widths and heights for all units with indices up + // to each of the one given here in its OnGetColumnWidth() and + // OnGetRowHeight() + void SetRowColumnCount(size_t rowCount, size_t columnCount); + + + // with physical scrolling on, the device origin is changed properly when + // a wxPaintDC is prepared, children are actually moved and laid out + // properly, and the contents of the window (pixels) are actually moved + void EnablePhysicalScrolling(bool vscrolling = true, bool hscrolling = true) + { + wxVarVScrollHelper::EnablePhysicalScrolling(vscrolling); + wxVarHScrollHelper::EnablePhysicalScrolling(hscrolling); + } + + // scroll to the specified row/column: it will become the first visible + // cell in the window + // + // return true if we scrolled the window, false if nothing was done + bool ScrollToRowColumn(size_t row, size_t column); + bool ScrollToRowColumn(const wxPosition &pos) + { return ScrollToRowColumn(pos.GetRow(), pos.GetColumn()); } + + // redraw the specified cell + virtual void RefreshRowColumn(size_t row, size_t column); + virtual void RefreshRowColumn(const wxPosition &pos) + { RefreshRowColumn(pos.GetRow(), pos.GetColumn()); } + + // redraw the specified regions (inclusive). If the target window for + // both orientations is the same the rectangle of cells is refreshed; if + // the target windows differ the entire client size opposite the + // orientation direction is refreshed between the specified limits + virtual void RefreshRowsColumns(size_t fromRow, size_t toRow, + size_t fromColumn, size_t toColumn); + virtual void RefreshRowsColumns(const wxPosition& from, + const wxPosition& to) + { + RefreshRowsColumns(from.GetRow(), to.GetRow(), + from.GetColumn(), to.GetColumn()); + } + + // Override wxPanel::HitTest to use our version + virtual wxPosition HitTest(wxCoord x, wxCoord y) const; + virtual wxPosition HitTest(const wxPoint &pos) const + { return HitTest(pos.x, pos.y); } + + // change the DC origin according to the scroll position. To properly + // forward calls to wxWindow::Layout use WX_FORWARD_TO_SCROLL_HELPER() + // derived class. We use this version to call both base classes' + // DoPrepareDC() + virtual void DoPrepareDC(wxDC& dc); + + // replacement implementation of wxWindow::Layout virtual method. To + // properly forward calls to wxWindow::Layout use + // WX_FORWARD_TO_SCROLL_HELPER() derived class. We use this version to + // call both base classes' ScrollLayout() + bool ScrollLayout(); // accessors // --------- - // get the number of lines this window contains (previously set by - // SetLineCount()) - size_t GetLineCount() const { return m_lineMax; } + // get the number of units this window contains (previously set by + // Set[Column/Row/RowColumn/Unit]Count()) + wxSize GetRowColumnCount() const; + + // get the first currently visible units + wxPosition GetVisibleBegin() const; + wxPosition GetVisibleEnd() const; + + // is this cell currently visible? + bool IsVisible(size_t row, size_t column) const; + bool IsVisible(const wxPosition &pos) const + { return IsVisible(pos.GetRow(), pos.GetColumn()); } +}; + + - // get the first currently visible line - size_t GetVisibleBegin() const { return m_lineFirst; } +#if WXWIN_COMPATIBILITY_2_8 - // get the first currently visible line - size_t GetVisibleEnd() const { return m_lineFirst + m_nVisible; } +// =========================================================================== +// wxVarVScrollLegacyAdaptor +// =========================================================================== - // is this line currently visible? - bool IsVisible(size_t line) const - { return line >= GetVisibleBegin() && line < GetVisibleEnd(); } +// Provides backwards compatible API for applications originally built using +// wxVScrolledWindow in 2.6 or 2.8. Originally, wxVScrolledWindow referred +// to scrolling "lines". We use "units" in wxVarScrollHelperBase to avoid +// implying any orientation (since the functions are used for both horizontal +// and vertical scrolling in derived classes). And in the new +// wxVScrolledWindow and wxHScrolledWindow classes, we refer to them as +// "rows" and "columns", respectively. This is to help clear some confusion +// in not only those classes, but also in wxHVScrolledWindow where functions +// are inherited from both. +class WXDLLEXPORT wxVarVScrollLegacyAdaptor : public wxVarVScrollHelper +{ +public: + // constructors and such + // --------------------- + wxVarVScrollLegacyAdaptor(wxWindow *winToScroll) + : wxVarVScrollHelper(winToScroll) + { + } + + // accessors + // --------- - // this is the same as GetVisibleBegin(), exists to match + // this is the same as GetVisibleRowsBegin(), exists to match // GetLastVisibleLine() and for backwards compatibility only - size_t GetFirstVisibleLine() const { return m_lineFirst; } + size_t GetFirstVisibleLine() const { return GetVisibleRowsBegin(); } // 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; } + // number) if the control is empty, use GetVisibleRowsEnd() instead, this + // one is kept for backwards compatibility + size_t GetLastVisibleLine() const { return GetVisibleRowsEnd() - 1; } - // layout the children (including the sizer if needed) - virtual bool Layout(); + // "line" to "unit" compatibility functions + // ---------------------------------------- + + // get the number of lines this window contains (set by SetLineCount()) + size_t GetLineCount() const { return GetRowCount(); } + + // set the number of lines the helper contains: the derived class must + // provide the sizes for all lines with indices up to the one given here + // in its OnGetLineHeight() + void SetLineCount(size_t count) { SetRowCount(count); } + + // redraw the specified line + virtual void RefreshLine(size_t line) { RefreshRow(line); } + + // redraw all lines in the specified range (inclusive) + virtual void RefreshLines(size_t from, size_t to) { RefreshRows(from, to); } + + // scroll to the specified line: it will become the first visible line in + // the window + // + // return true if we scrolled the window, false if nothing was done + bool ScrollToLine(size_t line) { return ScrollToRow(line); } + + // scroll by the specified number of lines/pages + virtual bool ScrollLines(int lines) { return ScrollRows(lines); } + virtual bool ScrollPages(int pages) { return ScrollRowPages(pages); } protected: // this function must be overridden in the derived class and it should - // return the height of the given line in pixels + // return the height of the given row in pixels virtual wxCoord OnGetLineHeight(size_t n) const = 0; + // forwards the calls from base class pure virtual function to pure virtual + // OnGetLineHeight instead (backwards compatible name) + // note that we don't need to forward OnGetUnitSize() as it is already + // forwarded to OnGetRowHeight() in wxVarVScrollHelper + virtual wxCoord OnGetRowHeight(size_t n) const + { return OnGetLineHeight(n); } + // this function doesn't have to be overridden but it may be useful to do // it if calculating the lines heights is a relatively expensive operation // as it gives the user code a possibility to calculate several of them at @@ -159,65 +645,252 @@ protected: virtual void OnGetLinesHint(size_t WXUNUSED(lineMin), size_t WXUNUSED(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; - + // forwards the calls from base class pure virtual function to pure virtual + // OnGetLinesHint instead (backwards compatible name) + void OnGetRowsHeightHint(size_t rowMin, size_t rowMax) const + { return OnGetLinesHint(rowMin, rowMax); } - // the event handlers - void OnSize(wxSizeEvent& event); - void OnScroll(wxScrollWinEvent& event); -#if wxUSE_MOUSEWHEEL - void OnMouseWheel(wxMouseEvent& event); -#endif - - // find the index of the line we need to show at the top of the window such - // that the last (fully or partially) visible line is the given one - size_t FindFirstFromBottom(size_t lineLast, bool fullyVisible = false); // get the total height of the lines between lineMin (inclusive) and // lineMax (exclusive) - wxCoord GetLinesHeight(size_t lineMin, size_t lineMax) const; + wxCoord GetLinesHeight(size_t lineMin, size_t lineMax) const + { return GetRowsHeight(lineMin, lineMax); } +}; - // update the thumb size shown by the scrollbar - void UpdateScrollbar(); +#else // !WXWIN_COMPATIBILITY_2_8 - // remove the scrollbar completely because we don't need it - void RemoveScrollbar(); +// shortcut to avoid checking compatibility modes later +// remove this and all references to wxVarVScrollLegacyAdapter once +// wxWidgets 2.6 and 2.8 compatibility is removed +typedef wxVarVScrollLegacyAdapter wxVarVScrollHelper; -private: - // common part of all ctors - void Init(); +#endif // WXWIN_COMPATIBILITY_2_8/!WXWIN_COMPATIBILITY_2_8 - // the total number of (logical) lines - size_t m_lineMax; +// this macro must be used in declaration of wxVarScrollHelperBase-derived +// classes +#define WX_FORWARD_TO_VAR_SCROLL_HELPER() \ +public: \ + virtual void PrepareDC(wxDC& dc) { DoPrepareDC(dc); } \ + virtual bool Layout() { return ScrollLayout(); } - // the total (estimated) height - wxCoord m_heightTotal; - // the first currently visible line - size_t m_lineFirst; - // the number of currently visible lines (including the last, possibly only - // partly, visible one) - size_t m_nVisible; +// =========================================================================== +// wxVScrolledWindow +// =========================================================================== - // accumulated mouse wheel rotation -#if wxUSE_MOUSEWHEEL - int m_sumWheelRotation; -#endif +// In the name of this class, "V" may stand for "variable" because it can be +// used for scrolling rows of variable heights; "virtual", because it is not +// necessary to know the heights of all rows in advance -- only those which +// are shown on the screen need to be measured; or even "vertical", because +// this class only supports scrolling vertically. + +// In any case, this is a generalization of the wxScrolledWindow class which +// can be only used when all rows have the same heights. It lacks some other +// wxScrolledWindow features however, notably it can't scroll only a rectangle +// of the window and not its entire client area. + +class WXDLLEXPORT wxVScrolledWindow : public wxPanel, + public wxVarVScrollLegacyAdaptor +{ +public: + // constructors and such + // --------------------- + + // default ctor, you must call Create() later + wxVScrolledWindow() : wxVarVScrollLegacyAdaptor(this) { } + + // normal ctor, no need to call Create() after this one + // + // note that wxVSCROLL is always automatically added to our style, there is + // no need to specify it explicitly + wxVScrolledWindow(wxWindow *parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr) + : wxVarVScrollLegacyAdaptor(this) + { + (void)Create(parent, id, pos, size, style, name); + } + + // same as the previous ctor but returns status code: true if ok + // + // just as with the ctor above, wxVSCROLL style is always used, there is no + // need to specify it + bool Create(wxWindow *parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr) + { + return wxPanel::Create(parent, id, pos, size, style | wxVSCROLL, name); + } + + // Make sure we prefer our version of HitTest rather than wxWindow's + int HitTest(wxCoord WXUNUSED(x), wxCoord y) const + { return wxVarVScrollHelper::HitTest(y); } + int HitTest(const wxPoint& pt) const + { return HitTest(pt.x, pt.y); } + + WX_FORWARD_TO_VAR_SCROLL_HELPER() - DECLARE_EVENT_TABLE() +#ifdef __WXMAC__ +protected: + virtual void UpdateMacScrollWindow() { Update(); } +#endif // __WXMAC__ + +private: DECLARE_NO_COPY_CLASS(wxVScrolledWindow) DECLARE_ABSTRACT_CLASS(wxVScrolledWindow) }; + + +// =========================================================================== +// wxHScrolledWindow +// =========================================================================== + +// In the name of this class, "H" stands for "horizontal" because it can be +// used for scrolling columns of variable widths. It is not necessary to know +// the widths of all columns in advance -- only those which are shown on the +// screen need to be measured. + +// This is a generalization of the wxScrolledWindow class which can be only +// used when all columns have the same width. It lacks some other +// wxScrolledWindow features however, notably it can't scroll only a rectangle +// of the window and not its entire client area. + +class WXDLLEXPORT wxHScrolledWindow : public wxPanel, + public wxVarHScrollHelper +{ +public: + // constructors and such + // --------------------- + + // default ctor, you must call Create() later + wxHScrolledWindow() : wxVarHScrollHelper(this) { } + + // normal ctor, no need to call Create() after this one + // + // note that wxHSCROLL is always automatically added to our style, there is + // no need to specify it explicitly + wxHScrolledWindow(wxWindow *parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr) + : wxVarHScrollHelper(this) + { + (void)Create(parent, id, pos, size, style, name); + } + + // same as the previous ctor but returns status code: true if ok + // + // just as with the ctor above, wxHSCROLL style is always used, there is no + // need to specify it + bool Create(wxWindow *parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr) + { + return wxPanel::Create(parent, id, pos, size, style | wxHSCROLL, name); + } + + // Make sure we prefer our version of HitTest rather than wxWindow's + int HitTest(wxCoord x, wxCoord WXUNUSED(y)) const + { return wxVarHScrollHelper::HitTest(x); } + int HitTest(const wxPoint& pt) const + { return HitTest(pt.x, pt.y); } + + WX_FORWARD_TO_VAR_SCROLL_HELPER() + +#ifdef __WXMAC__ +protected: + virtual void UpdateMacScrollWindow() { Update(); } +#endif // __WXMAC__ + +private: + DECLARE_NO_COPY_CLASS(wxHScrolledWindow) + DECLARE_ABSTRACT_CLASS(wxHScrolledWindow) +}; + + + +// =========================================================================== +// wxHVScrolledWindow +// =========================================================================== + +// This window inherits all functionality of both vertical and horizontal +// scrolled windows automatically handling everything needed to scroll both +// axis simultaneously. + +class WXDLLEXPORT wxHVScrolledWindow : public wxPanel, + public wxVarHVScrollHelper +{ +public: + // constructors and such + // --------------------- + + // default ctor, you must call Create() later + wxHVScrolledWindow() + : wxPanel(), + wxVarHVScrollHelper(this) { } + + // normal ctor, no need to call Create() after this one + // + // note that wxVSCROLL and wxHSCROLL are always automatically added to our + // style, there is no need to specify them explicitly + wxHVScrolledWindow(wxWindow *parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr) + : wxPanel(), + wxVarHVScrollHelper(this) + { + (void)Create(parent, id, pos, size, style, name); + } + + // same as the previous ctor but returns status code: true if ok + // + // just as with the ctor above, wxVSCROLL and wxHSCROLL styles are always + // used, there is no need to specify them + bool Create(wxWindow *parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name = wxPanelNameStr) + { + return wxPanel::Create(parent, id, pos, size, + style | wxVSCROLL | wxHSCROLL, name); + } + + // Make sure we prefer our version of HitTest rather than wxWindow's + wxPosition HitTest(wxCoord x, wxCoord y) const + { return wxVarHVScrollHelper::HitTest(x, y); } + wxPosition HitTest(const wxPoint &pt) const + { return HitTest(pt.x, pt.y); } + + WX_FORWARD_TO_VAR_SCROLL_HELPER() + +#ifdef __WXMAC__ +protected: + virtual void UpdateMacScrollWindow() { Update(); } +#endif // __WXMAC__ + +private: + DECLARE_NO_COPY_CLASS(wxHVScrolledWindow) + DECLARE_ABSTRACT_CLASS(wxHVScrolledWindow) +}; + #endif // _WX_VSCROLL_H_ diff --git a/samples/vscroll/vstest.cpp b/samples/vscroll/vstest.cpp index 432c032a7e..f80409a443 100644 --- a/samples/vscroll/vstest.cpp +++ b/samples/vscroll/vstest.cpp @@ -2,7 +2,7 @@ // Name: samples/vscroll/vstest.cpp // Purpose: VScroll wxWidgets sample // Author: Vadim Zeitlin -// Modified by: +// Modified by: Brad Anderson // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org> @@ -44,12 +44,18 @@ #include "../sample.xpm" #endif +// ---------------------------------------------------------------------------- +// definitions +// ---------------------------------------------------------------------------- + +#define MAX_LINES 10000 + // ---------------------------------------------------------------------------- // private classes // ---------------------------------------------------------------------------- // Define a new application type, each program should derive a class from wxApp -class VScrollApp : public wxApp +class VarScrollApp : public wxApp { public: // create our main window @@ -57,14 +63,17 @@ public: }; // Define a new frame type: this is going to be our main frame -class VScrollFrame : public wxFrame +class VarScrollFrame : public wxFrame { public: // ctor - VScrollFrame(); + VarScrollFrame(); // event handlers (these functions should _not_ be virtual) void OnQuit(wxCommandEvent& event); + void OnModeVScroll(wxCommandEvent& event); + void OnModeHScroll(wxCommandEvent& event); + void OnModeHVScroll(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); void OnSize(wxSizeEvent& event) @@ -82,6 +91,9 @@ public: } private: + // either a wxVScrolledWindow or a wxHVScrolled window, depending on current mode + wxPanel *m_scrollWindow; + // any class wishing to process wxWidgets events must use this macro DECLARE_EVENT_TABLE() }; @@ -93,7 +105,11 @@ public: { m_frame = frame; - SetLineCount(200); + SetLineCount(MAX_LINES); + + int i; + for ( i = 0; i < MAX_LINES; ++i ) + m_heights[i] = rand()%25+16; // low: 16; high: 40 m_changed = true; } @@ -116,21 +132,23 @@ public: { wxPaintDC dc(this); - dc.SetPen(*wxBLACK_DASHED_PEN); + dc.SetPen(*wxBLACK_PEN); - const size_t lineFirst = GetFirstVisibleLine(), - lineLast = GetLastVisibleLine(); + const size_t lineFirst = GetVisibleBegin(), + lineLast = GetVisibleEnd(); const wxCoord hText = dc.GetCharHeight(); + wxSize clientSize = GetClientSize(); + wxCoord y = 0; - for ( size_t line = lineFirst; line <= lineLast; line++ ) + for ( size_t line = lineFirst; line < lineLast; line++ ) { - dc.DrawLine(0, y, 1000, y); + dc.DrawLine(0, y, clientSize.GetWidth(), y); wxCoord hLine = OnGetLineHeight(line); dc.DrawText(wxString::Format(_T("Line %lu"), (unsigned long)line), - 0, y + (hLine - hText) / 2); + 2, y + (hLine - hText) / 2); y += hLine; dc.DrawLine(0, y, 1000, y); @@ -144,17 +162,27 @@ public: event.Skip(); } + void OnMouse(wxMouseEvent& event) + { + if(event.LeftDown()) + CaptureMouse(); + else if(event.LeftUp()) + ReleaseMouse(); + event.Skip(); + } virtual wxCoord OnGetLineHeight(size_t n) const { wxASSERT( n < GetLineCount() ); - return n % 2 ? 15 : 30; // 15 + 2*n + return m_heights[n]; } private: wxFrame *m_frame; + int m_heights[MAX_LINES]; + bool m_changed; DECLARE_EVENT_TABLE() @@ -164,6 +192,233 @@ BEGIN_EVENT_TABLE(VScrollWindow, wxVScrolledWindow) EVT_IDLE(VScrollWindow::OnIdle) EVT_PAINT(VScrollWindow::OnPaint) EVT_SCROLLWIN(VScrollWindow::OnScroll) + EVT_MOUSE_EVENTS(VScrollWindow::OnMouse) +END_EVENT_TABLE() + +class HScrollWindow : public wxHScrolledWindow +{ +public: + HScrollWindow(wxFrame *frame) : wxHScrolledWindow(frame, wxID_ANY) + { + m_frame = frame; + + SetColumnCount(MAX_LINES); + + int i; + for ( i = 0; i < MAX_LINES; ++i ) + m_heights[i] = rand()%25+16; // low: 15; high: 40 + + m_changed = true; + } + + void OnIdle(wxIdleEvent&) + { +#if wxUSE_STATUSBAR + m_frame->SetStatusText(wxString::Format + ( + _T("Page size = %d, pos = %d, max = %d"), + GetScrollThumb(wxVERTICAL), + GetScrollPos(wxVERTICAL), + GetScrollRange(wxVERTICAL) + )); +#endif // wxUSE_STATUSBAR + m_changed = false; + } + + void OnPaint(wxPaintEvent&) + { + wxPaintDC dc(this); + + dc.SetPen(*wxBLACK_PEN); + + const size_t lineFirst = GetVisibleBegin(), + lineLast = GetVisibleEnd(); + + const wxCoord hText = dc.GetCharHeight(); + + wxSize clientSize = GetClientSize(); + + wxCoord x = 0; + for ( size_t line = lineFirst; line < lineLast; line++ ) + { + dc.DrawLine(x, 0, x, clientSize.GetHeight()); + + wxCoord wLine = OnGetColumnWidth(line); + dc.DrawRotatedText(wxString::Format(_T("Line %lu"), (unsigned long)line), + x + (wLine - hText) / 2, clientSize.GetHeight() - 5, 90); + + x += wLine; + dc.DrawLine(x, 0, x, 1000); + } + } + + void OnScroll(wxScrollWinEvent& event) + { + m_changed = true; + + event.Skip(); + } + + void OnMouse(wxMouseEvent& event) + { + if(event.LeftDown()) + CaptureMouse(); + else if(event.LeftUp()) + ReleaseMouse(); + event.Skip(); + } + + virtual wxCoord OnGetColumnWidth(size_t n) const + { + wxASSERT( n < GetColumnCount() ); + + return m_heights[n]; + } + +private: + wxFrame *m_frame; + + int m_heights[MAX_LINES]; + + bool m_changed; + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(HScrollWindow, wxHScrolledWindow) + EVT_IDLE(HScrollWindow::OnIdle) + EVT_PAINT(HScrollWindow::OnPaint) + EVT_SCROLLWIN(HScrollWindow::OnScroll) + EVT_MOUSE_EVENTS(HScrollWindow::OnMouse) +END_EVENT_TABLE() + +class HVScrollWindow : public wxHVScrolledWindow +{ +public: + HVScrollWindow(wxFrame *frame) : wxHVScrolledWindow(frame, wxID_ANY) + { + m_frame = frame; + + SetRowColumnCount(MAX_LINES, MAX_LINES); + + int i; + for ( i = 0; i < MAX_LINES; ++i ) + { + m_heights[i] = rand()%30+31; // low: 30; high: 60 + m_widths[i] = rand()%30+61; // low: 60; high: 90 + } + + m_changed = true; + } + + void OnIdle(wxIdleEvent&) + { +#if wxUSE_STATUSBAR + m_frame->SetStatusText(wxString::Format + ( + _T("Page size = %d rows %d columns; pos = row: %d, column: %d; max = %d rows, %d columns"), + GetScrollThumb(wxVERTICAL), + GetScrollThumb(wxHORIZONTAL), + GetScrollPos(wxVERTICAL), + GetScrollPos(wxHORIZONTAL), + GetScrollRange(wxVERTICAL), + GetScrollRange(wxHORIZONTAL) + )); +#endif // wxUSE_STATUSBAR + m_changed = false; + } + + void OnPaint(wxPaintEvent&) + { + wxPaintDC dc(this); + + dc.SetPen(*wxBLACK_PEN); + + const size_t rowFirst = GetVisibleRowsBegin(), + rowLast = GetVisibleRowsEnd(); + const size_t columnFirst = GetVisibleColumnsBegin(), + columnLast = GetVisibleColumnsEnd(); + + const wxCoord hText = dc.GetCharHeight(); + + wxSize clientSize = GetClientSize(); + + wxCoord y = 0; + wxCoord x = 0; + for ( size_t row = rowFirst; row < rowLast; row++ ) + { + wxCoord rowHeight = OnGetRowHeight(row); + dc.DrawLine(0, y, clientSize.GetWidth(), y); + + x = 0; + for ( size_t col = columnFirst; col < columnLast; col++ ) + { + wxCoord colWidth = OnGetColumnWidth(col); + + if ( row == rowFirst ) + dc.DrawLine(x, 0, x, clientSize.GetHeight()); + + dc.DrawText(wxString::Format(_T("Row %lu"), (unsigned long)row), + x + 2, y + rowHeight / 2 - hText); + dc.DrawText(wxString::Format(_T("Col %lu"), (unsigned long)col), + x + 2, y + rowHeight / 2); + + x += colWidth; + if ( row == rowFirst) + dc.DrawLine(x, 0, x, clientSize.GetHeight()); + } + + y += rowHeight; + dc.DrawLine(0, y, clientSize.GetWidth(), y); + } + } + + void OnScroll(wxScrollWinEvent& event) + { + m_changed = true; + + event.Skip(); + } + + void OnMouse(wxMouseEvent& event) + { + if(event.LeftDown()) + CaptureMouse(); + else if(event.LeftUp()) + ReleaseMouse(); + event.Skip(); + } + + virtual wxCoord OnGetRowHeight(size_t n) const + { + wxASSERT( n < GetRowCount() ); + + return m_heights[n]; + } + + virtual wxCoord OnGetColumnWidth(size_t n) const + { + wxASSERT( n < GetColumnCount() ); + + return m_widths[n]; + } + +private: + wxFrame *m_frame; + + int m_heights[MAX_LINES]; + int m_widths[MAX_LINES]; + + bool m_changed; + + DECLARE_EVENT_TABLE() +}; + +BEGIN_EVENT_TABLE(HVScrollWindow, wxHVScrolledWindow) + EVT_IDLE(HVScrollWindow::OnIdle) + EVT_PAINT(HVScrollWindow::OnPaint) + EVT_SCROLLWIN(HVScrollWindow::OnScroll) + EVT_MOUSE_EVENTS(HVScrollWindow::OnMouse) END_EVENT_TABLE() // ---------------------------------------------------------------------------- @@ -179,7 +434,11 @@ enum // it is important for the id corresponding to the "About" command to have // this standard value as otherwise it won't be handled properly under Mac // (where it is special and put into the "Apple" menu) - VScroll_About = wxID_ABOUT + VScroll_About = wxID_ABOUT, + + VScroll_VScrollMode = wxID_HIGHEST + 1, + VScroll_HScrollMode, + VScroll_HVScrollMode }; // ---------------------------------------------------------------------------- @@ -189,18 +448,21 @@ enum // the event tables connect the wxWidgets events with the functions (event // handlers) which process them. It can be also done at run-time, but for the // simple menu events like this the static method is much simpler. -BEGIN_EVENT_TABLE(VScrollFrame, wxFrame) - EVT_MENU(VScroll_Quit, VScrollFrame::OnQuit) - EVT_MENU(VScroll_About, VScrollFrame::OnAbout) - EVT_SIZE(VScrollFrame::OnSize) +BEGIN_EVENT_TABLE(VarScrollFrame, wxFrame) + EVT_MENU(VScroll_Quit, VarScrollFrame::OnQuit) + EVT_MENU(VScroll_VScrollMode, VarScrollFrame::OnModeVScroll) + EVT_MENU(VScroll_HScrollMode, VarScrollFrame::OnModeHScroll) + EVT_MENU(VScroll_HVScrollMode, VarScrollFrame::OnModeHVScroll) + EVT_MENU(VScroll_About, VarScrollFrame::OnAbout) + EVT_SIZE(VarScrollFrame::OnSize) END_EVENT_TABLE() // Create a new application object: this macro will allow wxWidgets to create // the application object during program execution (it's better than using a // static object for many reasons) and also declares the accessor function -// wxGetApp() which will return the reference of the right type (i.e. VScrollApp and +// wxGetApp() which will return the reference of the right type (i.e. VarScrollApp and // not wxApp) -IMPLEMENT_APP(VScrollApp) +IMPLEMENT_APP(VarScrollApp) // ============================================================================ // implementation @@ -211,13 +473,13 @@ IMPLEMENT_APP(VScrollApp) // ---------------------------------------------------------------------------- // 'Main program' equivalent: the program execution "starts" here -bool VScrollApp::OnInit() +bool VarScrollApp::OnInit() { if ( !wxApp::OnInit() ) return false; // create the main application window - VScrollFrame *frame = new VScrollFrame; + VarScrollFrame *frame = new VarScrollFrame; // and show it (the frames, unlike simple controls, are not shown when // created initially) @@ -232,12 +494,13 @@ bool VScrollApp::OnInit() // ---------------------------------------------------------------------------- // frame constructor -VScrollFrame::VScrollFrame() - : wxFrame(NULL, - wxID_ANY, - _T("VScroll wxWidgets Sample"), - wxDefaultPosition, - wxSize(400, 350)) +VarScrollFrame::VarScrollFrame() + : wxFrame(NULL, + wxID_ANY, + _T("VScroll wxWidgets Sample"), + wxDefaultPosition, + wxSize(400, 350)), + m_scrollWindow(NULL) { // set the frame icon SetIcon(wxICON(sample)); @@ -246,15 +509,36 @@ VScrollFrame::VScrollFrame() // create a menu bar wxMenu *menuFile = new wxMenu; + wxMenu *menuMode = new wxMenu; + // the "About" item should be in the help menu wxMenu *menuHelp = new wxMenu; menuHelp->Append(VScroll_About, _T("&About...\tF1"), _T("Show about dialog")); +#ifdef wxHAS_RADIO_MENU_ITEMS + menuMode->AppendRadioItem(VScroll_VScrollMode, _T("&Vertical\tAlt-V"), + _T("Vertical scrolling only")); + menuMode->AppendRadioItem(VScroll_HScrollMode, _T("&Horizontal\tAlt-H"), + _T("Horizontal scrolling only")); + menuMode->AppendRadioItem(VScroll_HVScrollMode, + _T("Hori&zontal/Vertical\tAlt-Z"), + _T("Horizontal and vertical scrolling")); + menuMode->Check(VScroll_VScrollMode, true); +#else + menuMode->Append(VScroll_VScrollMode, _T("&Vertical\tAlt-V"), + _T("Vertical scrolling only")); + menuMode->Append(VScroll_HScrollMode, _T("&Horizontal\tAlt-H"), + _T("Horizontal scrolling only")); + menuMode->Append(VScroll_HVScrollMode, _T("Hori&zontal/Vertical\tAlt-Z"), + _T("Horizontal and vertical scrolling")); +#endif + menuFile->Append(VScroll_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); // now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar; menuBar->Append(menuFile, _T("&File")); + menuBar->Append(menuMode, _T("&Mode")); menuBar->Append(menuHelp, _T("&Help")); // ... and attach this menu bar to the frame @@ -265,26 +549,62 @@ VScrollFrame::VScrollFrame() // create a status bar just for fun (by default with 1 pane only) CreateStatusBar(2); SetStatusText(_T("Welcome to wxWidgets!")); + int widths[2]; + widths[0] = -1; + widths[1] = 100; + SetStatusWidths(2, widths); #endif // wxUSE_STATUSBAR // create our one and only child -- it will take our entire client area - new VScrollWindow(this); + if ( menuMode->IsChecked(VScroll_VScrollMode) ) + m_scrollWindow = new VScrollWindow(this); + else if ( menuMode->IsChecked(VScroll_HScrollMode) ) + m_scrollWindow = new HScrollWindow(this); + else + m_scrollWindow = new HVScrollWindow(this); } // ---------------------------------------------------------------------------- // event handlers // ---------------------------------------------------------------------------- -void VScrollFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) +void VarScrollFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { // true is to force the frame to close Close(true); } -void VScrollFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) +void VarScrollFrame::OnModeVScroll(wxCommandEvent& WXUNUSED(event)) +{ + if ( m_scrollWindow ) + m_scrollWindow->Destroy(); + + m_scrollWindow = new VScrollWindow(this); + SendSizeEvent(); +} + +void VarScrollFrame::OnModeHScroll(wxCommandEvent& WXUNUSED(event)) +{ + if ( m_scrollWindow ) + m_scrollWindow->Destroy(); + + m_scrollWindow = new HScrollWindow(this); + SendSizeEvent(); +} + +void VarScrollFrame::OnModeHVScroll(wxCommandEvent& WXUNUSED(event)) +{ + if ( m_scrollWindow ) + m_scrollWindow->Destroy(); + + m_scrollWindow = new HVScrollWindow(this); + SendSizeEvent(); +} + +void VarScrollFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxMessageBox(_T("VScroll shows how to implement scrolling with\n") - _T("variable line heights.\n") + _T("variable line widths and heights.\n") _T("(c) 2003 Vadim Zeitlin"), _T("About VScroll"), wxOK | wxICON_INFORMATION, diff --git a/src/generic/htmllbox.cpp b/src/generic/htmllbox.cpp index c97e9f347c..a8a472cde2 100644 --- a/src/generic/htmllbox.cpp +++ b/src/generic/htmllbox.cpp @@ -327,14 +327,14 @@ void wxHtmlListBox::RefreshLine(size_t line) { m_cache->InvalidateRange(line, line); - wxVListBox::RefreshLine(line); + wxVListBox::RefreshRow(line); } void wxHtmlListBox::RefreshLines(size_t from, size_t to) { m_cache->InvalidateRange(from, to); - wxVListBox::RefreshLines(from, to); + wxVListBox::RefreshRows(from, to); } void wxHtmlListBox::RefreshAll() diff --git a/src/generic/vlbox.cpp b/src/generic/vlbox.cpp index a9bfc5ceb6..094637ed21 100644 --- a/src/generic/vlbox.cpp +++ b/src/generic/vlbox.cpp @@ -111,7 +111,7 @@ void wxVListBox::SetItemCount(size_t count) m_selStore->SetItemCount(count); } - SetLineCount(count); + SetRowCount(count); } // ---------------------------------------------------------------------------- @@ -312,7 +312,7 @@ void wxVListBox::RefreshSelected() for ( size_t n = GetVisibleBegin(), end = GetVisibleEnd(); n < end; n++ ) { if ( IsSelected(n) ) - RefreshLine(n); + RefreshRow(n); } } diff --git a/src/generic/vscroll.cpp b/src/generic/vscroll.cpp index ec48cb9103..a670b41955 100644 --- a/src/generic/vscroll.cpp +++ b/src/generic/vscroll.cpp @@ -2,7 +2,7 @@ // Name: src/generic/vscroll.cpp // Purpose: wxVScrolledWindow implementation // Author: Vadim Zeitlin -// Modified by: +// Modified by: Brad Anderson // Created: 30.05.03 // RCS-ID: $Id$ // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org> @@ -30,401 +30,632 @@ #include "wx/vscroll.h" +// ============================================================================ +// wxVarScrollHelperEvtHandler declaration +// ============================================================================ + // ---------------------------------------------------------------------------- -// event tables +// wxScrollHelperEvtHandler: intercept the events from the window and forward +// them to wxVarScrollHelperBase // ---------------------------------------------------------------------------- -BEGIN_EVENT_TABLE(wxVScrolledWindow, wxPanel) - EVT_SIZE(wxVScrolledWindow::OnSize) - EVT_SCROLLWIN(wxVScrolledWindow::OnScroll) -#if wxUSE_MOUSEWHEEL - EVT_MOUSEWHEEL(wxVScrolledWindow::OnMouseWheel) -#endif -END_EVENT_TABLE() +class WXDLLEXPORT wxVarScrollHelperEvtHandler : public wxEvtHandler +{ +public: + wxVarScrollHelperEvtHandler(wxVarScrollHelperBase *scrollHelper) + { + m_scrollHelper = scrollHelper; + } + virtual bool ProcessEvent(wxEvent& event); + +private: + wxVarScrollHelperBase *m_scrollHelper; + + DECLARE_NO_COPY_CLASS(wxVarScrollHelperEvtHandler) +}; // ============================================================================ -// implementation +// wxVarScrollHelperEvtHandler implementation // ============================================================================ -IMPLEMENT_ABSTRACT_CLASS(wxVScrolledWindow, wxPanel) +bool wxVarScrollHelperEvtHandler::ProcessEvent(wxEvent& event) +{ + wxEventType evType = event.GetEventType(); + + // pass it on to the real handler + bool processed = wxEvtHandler::ProcessEvent(event); + + // always process the size events ourselves, even if the user code handles + // them as well, as we need to AdjustScrollbars() + // + // NB: it is important to do it after processing the event in the normal + // way as HandleOnSize() may generate a wxEVT_SIZE itself if the + // scrollbar[s] (dis)appear and it should be seen by the user code + // after this one + if ( evType == wxEVT_SIZE ) + { + m_scrollHelper->HandleOnSize((wxSizeEvent &)event); + + return !event.GetSkipped(); + } + + if ( processed ) + { + // normally, nothing more to do here - except if we have a command + // event + if ( event.IsCommandEvent() ) + { + return true; + } + } + + // reset the skipped flag (which might have been set to true in + // ProcessEvent() above) to be able to test it below + bool wasSkipped = event.GetSkipped(); + 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 || + evType == wxEVT_SCROLLWIN_LINEDOWN || + evType == wxEVT_SCROLLWIN_PAGEUP || + evType == wxEVT_SCROLLWIN_PAGEDOWN || + evType == wxEVT_SCROLLWIN_THUMBTRACK || + evType == wxEVT_SCROLLWIN_THUMBRELEASE ) + { + m_scrollHelper->HandleOnScroll((wxScrollWinEvent &)event); + if ( !event.GetSkipped() ) + { + // it makes sense to indicate that we processed the message as we + // did scroll the window (and also notice that wxAutoScrollTimer + // relies on our return value for continuous scrolling) + processed = true; + wasSkipped = false; + } + } +#if wxUSE_MOUSEWHEEL + else if ( evType == wxEVT_MOUSEWHEEL ) + { + m_scrollHelper->HandleOnMouseWheel((wxMouseEvent &)event); + } +#endif // wxUSE_MOUSEWHEEL + + if ( processed ) + event.Skip(wasSkipped); + + return processed; +} + + +// ============================================================================ +// wxVarScrollHelperBase implementation +// ============================================================================ // ---------------------------------------------------------------------------- -// initialization +// wxVarScrollHelperBase initialization // ---------------------------------------------------------------------------- -void wxVScrolledWindow::Init() +wxVarScrollHelperBase::wxVarScrollHelperBase(wxWindow *win) { - // we're initially empty - m_lineMax = - m_lineFirst = 0; - - // this one should always be strictly positive - m_nVisible = 1; - - m_heightTotal = 0; + wxASSERT_MSG( win, _T("associated window can't be NULL in wxVarScrollHelperBase") ); #if wxUSE_MOUSEWHEEL m_sumWheelRotation = 0; #endif + + m_unitMax = 0; + m_sizeTotal = 0; + m_unitFirst = 0; + + m_win = + m_targetWindow = (wxWindow *)NULL; + + m_handler = NULL; + + m_win = win; + + // by default, the associated window is also the target window + DoSetTargetWindow(win); + +} + +wxVarScrollHelperBase::~wxVarScrollHelperBase() +{ + DeleteEvtHandler(); } // ---------------------------------------------------------------------------- -// various helpers +// wxVarScrollHelperBase various helpers // ---------------------------------------------------------------------------- -wxCoord wxVScrolledWindow::EstimateTotalHeight() const +void +wxVarScrollHelperBase::AssignOrient(wxCoord& x, + wxCoord& y, + wxCoord first, + wxCoord second) +{ + if ( GetOrientation() == wxVERTICAL ) + { + x = first; + y = second; + } + else // horizontal + { + x = second; + y = first; + } +} + +void +wxVarScrollHelperBase::IncOrient(wxCoord& x, wxCoord& y, wxCoord inc) +{ + if ( GetOrientation() == wxVERTICAL ) + y += inc; + else + x += inc; +} + +wxCoord wxVarScrollHelperBase::DoEstimateTotalSize() 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, + // OnGetUnitSize() for every unit because there may be too many of + // them, so we just make a guess using some units in the beginning, // some in the end and some in the middle - static const size_t NUM_LINES_TO_SAMPLE = 10; + static const size_t NUM_UNITS_TO_SAMPLE = 10; - wxCoord heightTotal; - if ( m_lineMax < 3*NUM_LINES_TO_SAMPLE ) + wxCoord sizeTotal; + if ( m_unitMax < 3*NUM_UNITS_TO_SAMPLE ) { - // in this case calculating exactly is faster and more correct than + // in this case, full calculations are faster and more correct than // guessing - heightTotal = GetLinesHeight(0, m_lineMax); + sizeTotal = GetUnitsSize(0, m_unitMax); } - else // too many lines to calculate exactly + else // too many units 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); + // look at some units in the beginning/middle/end + sizeTotal = + GetUnitsSize(0, NUM_UNITS_TO_SAMPLE) + + GetUnitsSize(m_unitMax - NUM_UNITS_TO_SAMPLE, + m_unitMax) + + GetUnitsSize(m_unitMax/2 - NUM_UNITS_TO_SAMPLE/2, + m_unitMax/2 + NUM_UNITS_TO_SAMPLE/2); + + // use the height of the units we looked as the average + sizeTotal = (wxCoord) + (((float)sizeTotal / (3*NUM_UNITS_TO_SAMPLE)) * m_unitMax); } - return heightTotal; + return sizeTotal; } -wxCoord wxVScrolledWindow::GetLinesHeight(size_t lineMin, size_t lineMax) const +wxCoord wxVarScrollHelperBase::GetUnitsSize(size_t unitMin, size_t unitMax) const { - if ( lineMin == lineMax ) + if ( unitMin == unitMax ) return 0; - else if ( lineMin > lineMax ) - return -GetLinesHeight(lineMax, lineMin); - //else: lineMin < lineMax + else if ( unitMin > unitMax ) + return -GetUnitsSize(unitMax, unitMin); + //else: unitMin < unitMax - // let the user code know that we're going to need all these lines - OnGetLinesHint(lineMin, lineMax); + // let the user code know that we're going to need all these units + OnGetUnitsSizeHint(unitMin, unitMax); - // do sum up their heights - wxCoord height = 0; - for ( size_t line = lineMin; line < lineMax; line++ ) + // sum up their sizes + wxCoord size = 0; + for ( size_t unit = unitMin; unit < unitMax; ++unit ) { - height += OnGetLineHeight(line); + size += OnGetUnitSize(unit); } - return height; + return size; } -size_t wxVScrolledWindow::FindFirstFromBottom(size_t lineLast, bool full) +size_t wxVarScrollHelperBase::FindFirstVisibleFromLast(size_t unitLast, bool full) const { - const wxCoord hWindow = GetClientSize().y; + const wxCoord sWindow = GetOrientationTargetSize(); - // go upwards until we arrive at a line such that lineLast is not visible + // go upwards until we arrive at a unit such that unitLast is not visible // any more when it is shown - size_t lineFirst = lineLast; - wxCoord h = 0; + size_t unitFirst = unitLast; + wxCoord s = 0; for ( ;; ) { - h += OnGetLineHeight(lineFirst); + s += OnGetUnitSize(unitFirst); - if ( h > hWindow ) + if ( s > sWindow ) { - // for this line to be fully visible we need to go one line + // for this unit to be fully visible we need to go one unit // down, but if it is enough for it to be only partly visible then - // this line will do as well + // this unit will do as well if ( full ) { - lineFirst++; + ++unitFirst; } break; } - if ( !lineFirst ) + if ( !unitFirst ) break; - lineFirst--; + --unitFirst; } - return lineFirst; + return unitFirst; } -void wxVScrolledWindow::RemoveScrollbar() +size_t wxVarScrollHelperBase::GetNewScrollPosition(wxScrollWinEvent& event) const { - m_lineFirst = 0; - m_nVisible = m_lineMax; - SetScrollbar(wxVERTICAL, 0, 0, 0); + wxEventType evtType = event.GetEventType(); + + if ( evtType == wxEVT_SCROLLWIN_TOP ) + { + return 0; + } + else if ( evtType == wxEVT_SCROLLWIN_BOTTOM ) + { + return m_unitMax; + } + else if ( evtType == wxEVT_SCROLLWIN_LINEUP ) + { + return m_unitFirst ? m_unitFirst - 1 : 0; + } + else if ( evtType == wxEVT_SCROLLWIN_LINEDOWN ) + { + return m_unitFirst + 1; + } + else if ( evtType == wxEVT_SCROLLWIN_PAGEUP ) + { + return FindFirstVisibleFromLast(m_unitFirst); + } + else if ( evtType == wxEVT_SCROLLWIN_PAGEDOWN ) + { + if ( GetVisibleEnd() ) + return GetVisibleEnd() - 1; + else + return GetVisibleEnd(); + } + else if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE ) + { + return event.GetPosition(); + } + else if ( evtType == wxEVT_SCROLLWIN_THUMBTRACK ) + { + return event.GetPosition(); + } + + // unknown scroll event? + wxFAIL_MSG( _T("unknown scroll event type?") ); + return 0; } -void wxVScrolledWindow::UpdateScrollbar() +void wxVarScrollHelperBase::UpdateScrollbar() { // if there is nothing to scroll, remove the scrollbar - if ( !m_lineMax ) + if ( !m_unitMax ) { RemoveScrollbar(); return; } - // see how many lines can we fit on screen - const wxCoord hWindow = GetClientSize().y; + // see how many units can we fit on screen + const wxCoord sWindow = GetOrientationTargetSize(); - wxCoord h = 0; - size_t line; - for ( line = m_lineFirst; line < m_lineMax; line++ ) + // do vertical calculations + wxCoord s = 0; + size_t unit; + for ( unit = m_unitFirst; unit < m_unitMax; ++unit ) { - if ( h > hWindow ) + if ( s > sWindow ) break; - h += OnGetLineHeight(line); + s += OnGetUnitSize(unit); } - // if we still have remaining space below, maybe we can fit everything? - if ( h < hWindow ) + m_nUnitsVisible = unit - m_unitFirst; + + int unitsPageSize = m_nUnitsVisible; + if ( s > sWindow ) { - wxCoord hAll = h; - for ( size_t lineFirst = m_lineFirst; lineFirst > 0; lineFirst-- ) - { - hAll += OnGetLineHeight(m_lineFirst - 1); - if ( hAll > hWindow ) - break; - } + // last unit is only partially visible, we still need the scrollbar and + // so we have to "fix" pageSize because if it is equal to m_unitMax + // the scrollbar is not shown at all under MSW + --unitsPageSize; + } + + // set the scrollbar parameters to reflect this + m_win->SetScrollbar(GetOrientation(), m_unitFirst, unitsPageSize, m_unitMax); +} + +void wxVarScrollHelperBase::RemoveScrollbar() +{ + m_unitFirst = 0; + m_nUnitsVisible = m_unitMax; + m_win->SetScrollbar(GetOrientation(), 0, 0, 0); +} - if ( hAll < hWindow ) +void wxVarScrollHelperBase::DeleteEvtHandler() +{ + // search for m_handler in the handler list + if ( m_win && m_handler ) + { + if ( m_win->RemoveEventHandler(m_handler) ) { - // we don't need scrollbar at all - RemoveScrollbar(); - return; + delete m_handler; } + //else: something is very wrong, so better [maybe] leak memory than + // risk a crash because of double deletion + + m_handler = NULL; } +} - m_nVisible = line - m_lineFirst; +void wxVarScrollHelperBase::DoSetTargetWindow(wxWindow *target) +{ + m_targetWindow = target; +#ifdef __WXMAC__ + target->MacSetClipChildren( true ) ; +#endif - int pageSize = m_nVisible; - if ( h > hWindow ) + // install the event handler which will intercept the events we're + // interested in (but only do it for our real window, not the target window + // which we scroll - we don't need to hijack its events) + if ( m_targetWindow == m_win ) { - // last line is only partially visible, we still need the scrollbar and - // so we have to "fix" pageSize because if it is equal to m_lineMax the - // scrollbar is not shown at all under MSW - pageSize--; - } + // if we already have a handler, delete it first + DeleteEvtHandler(); - // set the scrollbar parameters to reflect this - SetScrollbar(wxVERTICAL, m_lineFirst, pageSize, m_lineMax); + m_handler = new wxVarScrollHelperEvtHandler(this); + m_targetWindow->PushEventHandler(m_handler); + } } // ---------------------------------------------------------------------------- -// operations +// wxVarScrollHelperBase operations // ---------------------------------------------------------------------------- -void wxVScrolledWindow::SetLineCount(size_t count) +void wxVarScrollHelperBase::SetTargetWindow(wxWindow *target) { - // save the number of lines - m_lineMax = count; + wxCHECK_RET( target, wxT("target window must not be NULL") ); + + if ( target == m_targetWindow ) + return; + + DoSetTargetWindow(target); +} + +void wxVarScrollHelperBase::SetUnitCount(size_t count) +{ + // save the number of units + m_unitMax = count; // and our estimate for their total height - m_heightTotal = EstimateTotalHeight(); + m_sizeTotal = EstimateTotalSize(); - // ScrollToLine() will update the scrollbar itself if it changes the line + // ScrollToUnit() will update the scrollbar itself if it changes the unit // we pass to it because it's out of [new] range - size_t oldScrollPos = m_lineFirst; - ScrollToLine(m_lineFirst); - if ( oldScrollPos == m_lineFirst ) + size_t oldScrollPos = m_unitFirst; + DoScrollToUnit(m_unitFirst); + if ( oldScrollPos == m_unitFirst ) { // but if it didn't do it, we still need to update the scrollbar to - // reflect the changed number of lines ourselves + // reflect the changed number of units ourselves UpdateScrollbar(); } } -void wxVScrolledWindow::RefreshLine(size_t line) +void wxVarScrollHelperBase::RefreshUnit(size_t unit) { - // is this line visible? - if ( !IsVisible(line) ) + // is this unit visible? + if ( !IsVisible(unit) ) { // no, it is useless to do anything return; } - // calculate the rect occupied by this line on screen + // calculate the rect occupied by this unit on screen wxRect rect; - rect.width = GetClientSize().x; - rect.height = OnGetLineHeight(line); - for ( size_t n = GetVisibleBegin(); n < line; n++ ) + AssignOrient(rect.width, rect.height, + GetNonOrientationTargetSize(), OnGetUnitSize(unit)); + + for ( size_t n = GetVisibleBegin(); n < unit; ++n ) { - rect.y += OnGetLineHeight(n); + IncOrient(rect.x, rect.y, OnGetUnitSize(n)); } // do refresh it - RefreshRect(rect); + m_targetWindow->RefreshRect(rect); } -void wxVScrolledWindow::RefreshLines(size_t from, size_t to) +void wxVarScrollHelperBase::RefreshUnits(size_t from, size_t to) { - wxASSERT_MSG( from <= to, _T("RefreshLines(): empty range") ); + wxASSERT_MSG( from <= to, _T("RefreshUnits(): empty range") ); - // clump the range to just the visible lines -- it is useless to refresh + // clump the range to just the visible units -- it is useless to refresh // the other ones if ( from < GetVisibleBegin() ) from = GetVisibleBegin(); - if ( to >= GetVisibleEnd() ) + 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 = GetVisibleBegin(); nBefore < from; nBefore++ ) + // calculate the rect occupied by these units on screen + int orient_size, nonorient_size, orient_pos; + orient_size = nonorient_size = orient_pos = 0; + + nonorient_size = GetNonOrientationTargetSize(); + + for ( size_t nBefore = GetVisibleBegin(); + nBefore < from; + nBefore++ ) { - rect.y += OnGetLineHeight(nBefore); + orient_pos += OnGetUnitSize(nBefore); } - for ( size_t nBetween = from; nBetween < to; nBetween++ ) + for ( size_t nBetween = from; nBetween <= to; nBetween++ ) { - rect.height += OnGetLineHeight(nBetween); + orient_size += OnGetUnitSize(nBetween); } + wxRect rect; + AssignOrient(rect.x, rect.y, 0, orient_pos); + AssignOrient(rect.width, rect.height, nonorient_size, orient_size); + // do refresh it - RefreshRect(rect); + m_targetWindow->RefreshRect(rect); } -void wxVScrolledWindow::RefreshAll() +void wxVarScrollHelperBase::RefreshAll() { UpdateScrollbar(); - Refresh(); + m_targetWindow->Refresh(); } -bool wxVScrolledWindow::Layout() +bool wxVarScrollHelperBase::ScrollLayout() { - if ( GetSizer() ) + if ( m_targetWindow->GetSizer() && m_physicalScrolling ) { // adjust the sizer dimensions/position taking into account the // virtual size and scrolled position of the window. - int w = 0, h = 0; - GetVirtualSize(&w, &h); + int x, y; + AssignOrient(x, y, 0, -GetScrollOffset()); - // x is always 0 so no variable needed - int y = -GetLinesHeight(0, GetFirstVisibleLine()); + int w, h; + m_targetWindow->GetVirtualSize(&w, &h); - GetSizer()->SetDimension(0, y, w, h); + m_targetWindow->GetSizer()->SetDimension(x, y, w, h); return true; } // fall back to default for LayoutConstraints - return wxPanel::Layout(); + return m_targetWindow->wxWindow::Layout(); } -int wxVScrolledWindow::HitTest(wxCoord WXUNUSED(x), wxCoord y) const +int wxVarScrollHelperBase::HitTest(wxCoord coord) const { - const size_t lineMax = GetVisibleEnd(); - for ( size_t line = GetVisibleBegin(); line < lineMax; line++ ) + const size_t unitMax = GetVisibleEnd(); + for ( size_t unit = GetVisibleBegin(); unit < unitMax; ++unit ) { - y -= OnGetLineHeight(line); - if ( y < 0 ) - return line; + coord -= OnGetUnitSize(unit); + if ( coord < 0 ) + return unit; } return wxNOT_FOUND; } // ---------------------------------------------------------------------------- -// scrolling +// wxVarScrollHelperBase scrolling // ---------------------------------------------------------------------------- -bool wxVScrolledWindow::ScrollToLine(size_t line) +bool wxVarScrollHelperBase::DoScrollToUnit(size_t unit) { - if ( !m_lineMax ) + if ( !m_unitMax ) { // we're empty, code below doesn't make sense in this case return false; } - // determine the real first line to scroll to: we shouldn't scroll beyond + // determine the real first unit to scroll to: we shouldn't scroll beyond // the end - size_t lineFirstLast = FindFirstFromBottom(m_lineMax - 1, true); - if ( line > lineFirstLast ) - line = lineFirstLast; + size_t unitFirstLast = FindFirstVisibleFromLast(m_unitMax - 1, true); + if ( unit > unitFirstLast ) + unit = unitFirstLast; // anything to do? - if ( line == m_lineFirst ) + if ( unit == m_unitFirst ) { // no return false; } - // remember the currently shown lines for the refresh code below - size_t lineFirstOld = GetVisibleBegin(), - lineLastOld = GetVisibleEnd(); + // remember the currently shown units for the refresh code below + size_t unitFirstOld = GetVisibleBegin(), + unitLastOld = GetVisibleEnd(); - m_lineFirst = line; + m_unitFirst = unit; // the size of scrollbar thumb could have changed UpdateScrollbar(); - - // finally refresh the display -- but only redraw as few lines as possible - // to avoid flicker - if ( GetVisibleBegin() >= lineLastOld || - GetVisibleEnd() <= lineFirstOld ) + // finally refresh the display -- but only redraw as few units as possible + // to avoid flicker. We can't do this if we have children because they + // won't be scrolled + if ( m_targetWindow->GetChildren().empty() && + GetVisibleBegin() >= unitLastOld || GetVisibleEnd() <= unitFirstOld ) { - // the simplest case: we don't have any old lines left, just redraw + // the simplest case: we don't have any old units left, just redraw // everything - Refresh(); + m_targetWindow->Refresh(); } - else // overlap between the lines we showed before and should show now + else // scroll the window { - ScrollWindow(0, GetLinesHeight(GetVisibleBegin(), lineFirstOld)); + if ( m_physicalScrolling ) + { + wxCoord dx = 0, + dy = GetUnitsSize(GetVisibleBegin(), unitFirstOld); + + if ( GetOrientation() == wxHORIZONTAL ) + { + wxCoord tmp = dx; + dx = dy; + dy = tmp; + } + + m_targetWindow->ScrollWindow(dx, dy); + } + else // !m_physicalScrolling + { + // we still need to invalidate but we can't use ScrollWindow + // because physical scrolling is disabled (the user either didn't + // want children scrolled and/or doesn't want pixels to be + // physically scrolled). + m_targetWindow->Refresh(); + } } return true; } -bool wxVScrolledWindow::ScrollLines(int lines) +bool wxVarScrollHelperBase::DoScrollUnits(int units) { - lines += m_lineFirst; - if ( lines < 0 ) - lines = 0; + units += m_unitFirst; + if ( units < 0 ) + units = 0; - return ScrollToLine(lines); + return DoScrollToUnit(units); } -bool wxVScrolledWindow::ScrollPages(int pages) +bool wxVarScrollHelperBase::DoScrollPages(int pages) { bool didSomething = false; while ( pages ) { - int line; + int unit; if ( pages > 0 ) { - line = GetVisibleEnd(); - if ( line ) - line--; - pages--; + unit = GetVisibleEnd(); + if ( unit ) + --unit; + --pages; } else // pages < 0 { - line = FindFirstFromBottom(GetVisibleBegin()); - pages++; + unit = FindFirstVisibleFromLast(GetVisibleEnd()); + ++pages; } - didSomething = ScrollToLine(line); + didSomething = DoScrollToUnit(unit); } return didSomething; @@ -434,87 +665,260 @@ bool wxVScrolledWindow::ScrollPages(int pages) // event handling // ---------------------------------------------------------------------------- -void wxVScrolledWindow::OnSize(wxSizeEvent& event) +void wxVarScrollHelperBase::HandleOnSize(wxSizeEvent& event) { UpdateScrollbar(); event.Skip(); } -void wxVScrolledWindow::OnScroll(wxScrollWinEvent& event) +void wxVarScrollHelperBase::HandleOnScroll(wxScrollWinEvent& event) { - size_t lineFirstNew; + if (GetOrientation() != event.GetOrientation()) + { + event.Skip(); + return; + } - const wxEventType evtType = event.GetEventType(); + DoScrollToUnit(GetNewScrollPosition(event)); - if ( evtType == wxEVT_SCROLLWIN_TOP ) +#ifdef __WXMAC__ + UpdateMacScrollWindow(); +#endif // __WXMAC__ +} + +void wxVarScrollHelperBase::DoPrepareDC(wxDC& dc) +{ + if ( m_physicalScrolling ) { - lineFirstNew = 0; + wxPoint pt = dc.GetDeviceOrigin(); + + IncOrient(pt.x, pt.y, -GetScrollOffset()); + + dc.SetDeviceOrigin(pt.x, pt.y); } - else if ( evtType == wxEVT_SCROLLWIN_BOTTOM ) +} + +int wxVarScrollHelperBase::DoCalcScrolledPosition(int coord) const +{ + return coord - GetScrollOffset(); +} + +int wxVarScrollHelperBase::DoCalcUnscrolledPosition(int coord) const +{ + return coord + GetScrollOffset(); +} + +#if wxUSE_MOUSEWHEEL + +void wxVarScrollHelperBase::HandleOnMouseWheel(wxMouseEvent& event) +{ + // we only want to process wheel events for vertical implementations. + // There is no way to determine wheel orientation (and on MSW horizontal + // wheel rotation just fakes scroll events, rather than sending a MOUSEWHEEL + // event). + if ( GetOrientation() != wxVERTICAL ) + return; + + 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() ) + DoScrollUnits( units_to_scroll*event.GetLinesPerAction() ); + else // scroll pages instead of units + DoScrollPages( units_to_scroll ); +} + +#endif // wxUSE_MOUSEWHEEL + + +// ============================================================================ +// wxVarHVScrollHelper implementation +// ============================================================================ + +// ---------------------------------------------------------------------------- +// wxVarHVScrollHelper operations +// ---------------------------------------------------------------------------- + +void wxVarHVScrollHelper::SetRowColumnCount(size_t rowCount, size_t columnCount) +{ + SetRowCount(rowCount); + SetColumnCount(columnCount); +} + +bool wxVarHVScrollHelper::ScrollToRowColumn(size_t row, size_t column) +{ + bool result = false; + result |= ScrollToRow(row); + result |= ScrollToColumn(column); + return result; +} + +void wxVarHVScrollHelper::RefreshRowColumn(size_t row, size_t column) +{ + // is this unit visible? + if ( !IsRowVisible(row) || !IsColumnVisible(column) ) { - lineFirstNew = m_lineMax; + // no, it is useless to do anything + return; } - else if ( evtType == wxEVT_SCROLLWIN_LINEUP ) + + // calculate the rect occupied by this cell on screen + wxRect v_rect, h_rect; + v_rect.height = OnGetRowHeight(row); + h_rect.width = OnGetColumnWidth(column); + + size_t n; + + for ( n = GetVisibleRowsBegin(); n < row; n++ ) { - lineFirstNew = m_lineFirst ? m_lineFirst - 1 : 0; + v_rect.y += OnGetRowHeight(n); } - else if ( evtType == wxEVT_SCROLLWIN_LINEDOWN ) + + for ( n = GetVisibleColumnsBegin(); n < column; n++ ) { - lineFirstNew = m_lineFirst + 1; + h_rect.x += OnGetColumnWidth(n); } - else if ( evtType == wxEVT_SCROLLWIN_PAGEUP ) + + // refresh but specialize the behavior if we have a single target window + if ( wxVarVScrollHelper::GetTargetWindow() == wxVarHScrollHelper::GetTargetWindow() ) { - lineFirstNew = FindFirstFromBottom(m_lineFirst); + v_rect.x = h_rect.x; + v_rect.width = h_rect.width; + wxVarVScrollHelper::GetTargetWindow()->RefreshRect(v_rect); } - else if ( evtType == wxEVT_SCROLLWIN_PAGEDOWN ) + else { - lineFirstNew = GetVisibleEnd(); - if ( lineFirstNew ) - lineFirstNew--; + v_rect.x = 0; + v_rect.width = wxVarVScrollHelper::GetNonOrientationTargetSize(); + h_rect.y = 0; + h_rect.width = wxVarHScrollHelper::GetNonOrientationTargetSize(); + + wxVarVScrollHelper::GetTargetWindow()->RefreshRect(v_rect); + wxVarHScrollHelper::GetTargetWindow()->RefreshRect(h_rect); } - else if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE ) +} + +void wxVarHVScrollHelper::RefreshRowsColumns(size_t fromRow, size_t toRow, + size_t fromColumn, size_t toColumn) +{ + wxASSERT_MSG( fromRow <= toRow || fromColumn <= toColumn, + _T("RefreshRowsColumns(): empty range") ); + + // clump the range to just the visible units -- it is useless to refresh + // the other ones + if ( fromRow < GetVisibleRowsBegin() ) + fromRow = GetVisibleRowsBegin(); + + if ( toRow > GetVisibleRowsEnd() ) + toRow = GetVisibleRowsEnd(); + + if ( fromColumn < GetVisibleColumnsBegin() ) + fromColumn = GetVisibleColumnsBegin(); + + if ( toColumn > GetVisibleColumnsEnd() ) + toColumn = GetVisibleColumnsEnd(); + + // calculate the rect occupied by these units on screen + wxRect v_rect, h_rect; + size_t nBefore, nBetween; + + for ( nBefore = GetVisibleRowsBegin(); + nBefore < fromRow; + nBefore++ ) { - lineFirstNew = event.GetPosition(); + v_rect.y += OnGetRowHeight(nBefore); } - else if ( evtType == wxEVT_SCROLLWIN_THUMBTRACK ) + + for ( nBetween = fromRow; nBetween <= toRow; nBetween++ ) { - lineFirstNew = event.GetPosition(); + v_rect.height += OnGetRowHeight(nBetween); } - else // unknown scroll event? + for ( nBefore = GetVisibleColumnsBegin(); + nBefore < fromColumn; + nBefore++ ) { - wxFAIL_MSG( _T("unknown scroll event type?") ); - return; + h_rect.x += OnGetColumnWidth(nBefore); } - ScrollToLine(lineFirstNew); + for ( nBetween = fromColumn; nBetween <= toColumn; nBetween++ ) + { + h_rect.width += OnGetColumnWidth(nBetween); + } -#ifdef __WXMAC__ - Update(); -#endif // __WXMAC__ + // refresh but specialize the behavior if we have a single target window + if ( wxVarVScrollHelper::GetTargetWindow() == wxVarHScrollHelper::GetTargetWindow() ) + { + v_rect.x = h_rect.x; + v_rect.width = h_rect.width; + wxVarVScrollHelper::GetTargetWindow()->RefreshRect(v_rect); + } + else + { + v_rect.x = 0; + v_rect.width = wxVarVScrollHelper::GetNonOrientationTargetSize(); + h_rect.y = 0; + h_rect.width = wxVarHScrollHelper::GetNonOrientationTargetSize(); + + wxVarVScrollHelper::GetTargetWindow()->RefreshRect(v_rect); + wxVarHScrollHelper::GetTargetWindow()->RefreshRect(h_rect); + } } -#if wxUSE_MOUSEWHEEL +wxPosition wxVarHVScrollHelper::HitTest(wxCoord x, wxCoord y) const +{ + return wxPosition(wxVarVScrollHelper::HitTest(y), + wxVarHScrollHelper::HitTest(x)); +} -void wxVScrolledWindow::OnMouseWheel(wxMouseEvent& event) +void wxVarHVScrollHelper::DoPrepareDC(wxDC& dc) { - m_sumWheelRotation += event.GetWheelRotation(); - int delta = event.GetWheelDelta(); + wxVarVScrollHelper::DoPrepareDC(dc); + wxVarHScrollHelper::DoPrepareDC(dc); +} - // how much to scroll this time - int units_to_scroll = -(m_sumWheelRotation/delta); - if ( !units_to_scroll ) - return; +bool wxVarHVScrollHelper::ScrollLayout() +{ + bool layout_result = false; + layout_result |= wxVarVScrollHelper::ScrollLayout(); + layout_result |= wxVarHScrollHelper::ScrollLayout(); + return layout_result; +} - m_sumWheelRotation += units_to_scroll*delta; +wxSize wxVarHVScrollHelper::GetRowColumnCount() const +{ + return wxSize(GetColumnCount(), GetRowCount()); +} - if ( !event.IsPageScroll() ) - ScrollLines( units_to_scroll*event.GetLinesPerAction() ); - else - // scroll pages instead of lines - ScrollPages( units_to_scroll ); +wxPosition wxVarHVScrollHelper::GetVisibleBegin() const +{ + return wxPosition(GetVisibleRowsBegin(), GetVisibleColumnsBegin()); } -#endif // wxUSE_MOUSEWHEEL +wxPosition wxVarHVScrollHelper::GetVisibleEnd() const +{ + return wxPosition(GetVisibleRowsEnd(), GetVisibleColumnsEnd()); +} + +bool wxVarHVScrollHelper::IsVisible(size_t row, size_t column) const +{ + return IsRowVisible(row) && IsColumnVisible(column); +} + + +// ============================================================================ +// wx[V/H/HV]ScrolledWindow implementations +// ============================================================================ + +IMPLEMENT_ABSTRACT_CLASS(wxVScrolledWindow, wxPanel) +IMPLEMENT_ABSTRACT_CLASS(wxHScrolledWindow, wxPanel) +IMPLEMENT_ABSTRACT_CLASS(wxHVScrolledWindow, wxPanel) diff --git a/src/richtext/richtextfontpage.cpp b/src/richtext/richtextfontpage.cpp index d2b5c8b067..1324dab7f1 100644 --- a/src/richtext/richtextfontpage.cpp +++ b/src/richtext/richtextfontpage.cpp @@ -622,7 +622,7 @@ void wxRichTextFontPage::OnFaceTextCtrlUpdated( wxCommandEvent& WXUNUSED(event) { if (arr[i].Mid(0, facename.Length()).Lower() == facename.Lower()) { - m_faceListBox->ScrollToLine(i); + m_faceListBox->ScrollToRow(i); break; } } diff --git a/src/richtext/richtextsymboldlg.cpp b/src/richtext/richtextsymboldlg.cpp index 0f89a1dbc7..36ee21fa01 100644 --- a/src/richtext/richtextsymboldlg.cpp +++ b/src/richtext/richtextsymboldlg.cpp @@ -832,7 +832,7 @@ bool wxSymbolListCtrl::DoSetCurrent(int current) } if ( m_current != wxNOT_FOUND ) - RefreshLine(SymbolValueToLineNumber(m_current)); + RefreshRow(SymbolValueToLineNumber(m_current)); m_current = current; @@ -844,19 +844,19 @@ bool wxSymbolListCtrl::DoSetCurrent(int current) // don't need to refresh it -- it will be redrawn anyhow if ( !IsVisible(lineNo) ) { - ScrollToLine(lineNo); + ScrollToRow(lineNo); } else // line is at least partly visible { // it is, indeed, only partly visible, so scroll it into view to // make it entirely visible while ( unsigned(lineNo) == GetLastVisibleLine() && - ScrollToLine(GetVisibleBegin()+1) ) + ScrollToRow(GetVisibleBegin()+1) ) ; // but in any case refresh it as even if it was only partly visible // before we need to redraw it entirely as its background changed - RefreshLine(lineNo); + RefreshRow(lineNo); } } @@ -1200,12 +1200,12 @@ void wxSymbolListCtrl::SetupCtrl(bool scrollToSelection) m_symbolsPerLine = sz.x/(m_cellSize.x+m_ptMargins.x); int noLines = (1 + SymbolValueToLineNumber(m_maxSymbolValue)); - SetLineCount(noLines); + SetRowCount(noLines); Refresh(); if (scrollToSelection && m_current != wxNOT_FOUND && m_current >= m_minSymbolValue && m_current <= m_maxSymbolValue) { - ScrollToLine(SymbolValueToLineNumber(m_current)); + ScrollToRow(SymbolValueToLineNumber(m_current)); } } @@ -1214,7 +1214,7 @@ void wxSymbolListCtrl::EnsureVisible(int item) { if (item != wxNOT_FOUND && item >= m_minSymbolValue && item <= m_maxSymbolValue) { - ScrollToLine(SymbolValueToLineNumber(item)); + ScrollToRow(SymbolValueToLineNumber(item)); } } -- 2.45.2