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.50.0

