added wxVScrolledWindow

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20772 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2003-05-30 21:08:31 +00:00
parent 95ac740c3b
commit cf7d632953
8 changed files with 1128 additions and 1 deletions

View File

@ -43,6 +43,7 @@ The following are a variety of classes that are derived from wxWindow.
\twocolitem{\helpref{wxPlotWindow}{wxplotwindow}}{A class to display data.}
\twocolitem{\helpref{wxSashWindow}{wxsashwindow}}{Window with four optional sashes that can be dragged}
\twocolitem{\helpref{wxSashLayoutWindow}{wxsashlayoutwindow}}{Window that can be involved in an IDE-like layout arrangement}
\twocolitem{\helpref{wxVScrolledWindow}{wxvscrolledwindow}}{As wxScrolledWindow but supports lines of variable height}
\twocolitem{\helpref{wxWizardPage}{wxwizardpage}}{A base class for the page in wizard dialog.}
\twocolitem{\helpref{wxWizardPageSimple}{wxwizardpagesimple}}{A page in wizard dialog.}
\end{twocollist}

View File

@ -308,6 +308,7 @@
\input validatr.tex
\input variant.tex
\input view.tex
\input vscroll.tex
\input wave.tex
\input window.tex
\input windowdc.tex

View File

@ -97,7 +97,8 @@ to build your own scroll behaviour.
\wxheading{See also}
\helpref{wxScrollBar}{wxscrollbar}, \helpref{wxClientDC}{wxclientdc}, \helpref{wxPaintDC}{wxpaintdc}
\helpref{wxScrollBar}{wxscrollbar}, \helpref{wxClientDC}{wxclientdc},\\
\helpref{wxPaintDC}{wxpaintdc}, \helpref{wxVScrolledWindow}{wxvscrolledwindow}
\latexignore{\rtfignore{\wxheading{Members}}}

194
docs/latex/wx/vscroll.tex Normal file
View File

@ -0,0 +1,194 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 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. ote 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}
\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::GetFirstVisibleLine}\label{wxvscrolledwindowgetfirstvisibleline}
\constfunc{size\_t}{GetFirstVisibleLine}{\void}
Returns the index of the first currently visible line.
\membersection{wxVScrolledWindow::GetLastVisibleLine}\label{wxvscrolledwindowgetlastvisibleline}
\constfunc{size\_t}{GetLastVisibleLine}{\void}
Returns the index of the last currently visible line.
\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::OnGetLineHeight}\label{wxvscrolledwindowongetlineheight}
\constfunc{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{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::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}.

167
include/wx/vscroll.h Normal file
View File

@ -0,0 +1,167 @@
/////////////////////////////////////////////////////////////////////////////
// Name: include/wx/vscroll.h
// Purpose: wxVScrolledWindow: generalization of wxScrolledWindow
// Author: Vadim Zeitlin
// Modified by:
// Created: 30.05.03
// RCS-ID: $Id$
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#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 wxVScrolledWindow : public wxPanel
{
public:
// constructors and such
// ---------------------
// default ctor, you must call Create() later
wxVScrolledWindow() { Init(); }
// 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)
{
Init();
(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,
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);
}
// operations
// ----------
// 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);
// 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);
// scroll by the specified number of lines/pages
virtual bool ScrollLines(int lines);
virtual bool ScrollPages(int pages);
// accessors
// ---------
// get the number of lines this window contains (previously set by
// SetLineCount())
size_t GetLineCount() const { return m_lineMax; }
// get the first currently visible line
size_t GetFirstVisibleLine() const { return m_lineFirst; }
// get the last currently visible line
size_t GetLastVisibleLine() const { return m_lineFirst + m_nVisible - 1; }
//protected:
// this function must be overridden in the derived class and it should
// return the height of the given line in pixels
virtual wxCoord OnGetLineHeight(size_t n) const = 0;
// 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
//
// OnGetLinesHint() is normally called just before OnGetLineHeight() 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 lineMin is inclusive, while lineMax is exclusive, as
// usual
virtual void OnGetLinesHint(size_t lineMin, size_t lineMax) const { }
protected:
// the event handlers
void OnSize(wxSizeEvent& event);
void OnScroll(wxScrollWinEvent& event);
// find the index of the line we need to show at the top of the window such
// that the last line shown is the given one
size_t FindFirstFromBottom(size_t lineLast);
// get the total height of the lines between lineMin (inclusive) and
// lineMax (exclusive)
wxCoord GetLinesHeight(size_t lineMin, size_t lineMax) const;
// update the thumb size shown by the scrollbar
void UpdateScrollbar();
private:
// common part of all ctors
void Init();
// the total number of (logical) lines
size_t m_lineMax;
// 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;
DECLARE_EVENT_TABLE()
};
#endif // _WX_VSCROLL_H_

155
samples/vscroll/vscroll.dsp Normal file
View File

@ -0,0 +1,155 @@
# Microsoft Developer Studio Project File - Name="vscroll" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=vscroll - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "vscroll.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "vscroll.mak" CFG="vscroll - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "vscroll - Win32 Release DLL" (based on "Win32 (x86) Application")
!MESSAGE "vscroll - Win32 Debug DLL" (based on "Win32 (x86) Application")
!MESSAGE "vscroll - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "vscroll - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "vscroll - Win32 Release DLL"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "ReleaseDll"
# PROP BASE Intermediate_Dir "ReleaseDll"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "ReleaseDll"
# PROP Intermediate_Dir "ReleaseDll"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W4 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D WINVER=0x400 /YX /FD /c
# ADD CPP /nologo /MD /W4 /O2 /I "../../include" /I "..\..\lib\mswdll" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D WINVER=0x400 /D "_MT" /D wxUSE_GUI=1 /D "WXUSINGDLL" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /i "../../include" /d "NDEBUG"
# ADD RSC /l 0x409 /i "../../include" /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib ..\..\lib\wxmsw250.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "vscroll - Win32 Debug DLL"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "DebugDll"
# PROP BASE Intermediate_Dir "DebugDll"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "DebugDll"
# PROP Intermediate_Dir "DebugDll"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W4 /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D WINVER=0x400 /YX /FD /c
# ADD CPP /nologo /MDd /W4 /Zi /Od /I "../../include" /I "..\..\lib\mswdlld" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D WINVER=0x400 /D "_MT" /D wxUSE_GUI=1 /D "__WXDEBUG__" /D WXDEBUG=1 /D "WXUSINGDLL" /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /i "../../include" /d "_DEBUG"
# ADD RSC /l 0x409 /i "../../include" /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib ..\..\lib\wxmsw250d.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ELSEIF "$(CFG)" == "vscroll - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W4 /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D WINVER=0x400 /YX /FD /c
# ADD CPP /nologo /MD /W4 /O2 /I "../../include" /I "..\..\lib\msw" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D WINVER=0x400 /D "_MT" /D wxUSE_GUI=1 /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /i "../../include" /d "NDEBUG"
# ADD RSC /l 0x409 /i "../../include" /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib ..\..\lib\zlib.lib ..\..\lib\regex.lib ..\..\lib\png.lib ..\..\lib\jpeg.lib ..\..\lib\tiff.lib ..\..\lib\wxmsw.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "vscroll - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W4 /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D WINVER=0x400 /YX /FD /c
# ADD CPP /nologo /MDd /W4 /Zi /Od /I "../../include" /I "..\..\lib\mswd" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D WINVER=0x400 /D "_MT" /D wxUSE_GUI=1 /D "__WXDEBUG__" /D WXDEBUG=1 /YX /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32
# ADD BASE RSC /l 0x409 /i "../../include" /d "_DEBUG"
# ADD RSC /l 0x409 /i "../../include" /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib wsock32.lib ..\..\lib\zlibd.lib ..\..\lib\regexd.lib ..\..\lib\pngd.lib ..\..\lib\jpegd.lib ..\..\lib\tiffd.lib ..\..\lib\wxmswd.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "vscroll - Win32 Release DLL"
# Name "vscroll - Win32 Debug DLL"
# Name "vscroll - Win32 Release"
# Name "vscroll - Win32 Debug"
# Begin Source File
SOURCE=.\vscroll.cpp
# End Source File
# Begin Source File
SOURCE=.\vstest.cpp
# End Source File
# End Target
# End Project

286
samples/vscroll/vstest.cpp Normal file
View File

@ -0,0 +1,286 @@
/////////////////////////////////////////////////////////////////////////////
// Name: vscroll.cpp
// Purpose: VScroll wxWindows sample
// Author: Vadim Zeitlin
// Modified by:
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWindows headers)
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/frame.h"
#endif
// we need to include the headers not included from wx/wx.h explicitly anyhow
#include "wx/vscroll.h"
// ----------------------------------------------------------------------------
// resources
// ----------------------------------------------------------------------------
// the application icon (under Windows and OS/2 it is in resources)
#if !defined(__WXMSW__) && !defined(__WXOS2__)
#include "mondrian.xpm"
#endif
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
// Define a new application type, each program should derive a class from wxApp
class VScrollApp : public wxApp
{
public:
// create our main window
virtual bool OnInit();
};
// Define a new frame type: this is going to be our main frame
class VScrollFrame : public wxFrame
{
public:
// ctor
VScrollFrame();
// event handlers (these functions should _not_ be virtual)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnSize(wxSizeEvent& event)
{
// show current size in the status bar
#if wxUSE_STATUSBAR
if ( m_frameStatusBar )
{
wxSize sz = GetClientSize();
SetStatusText(wxString::Format("%dx%d", sz.x, sz.y), 1);
}
#endif // wxUSE_STATUSBAR
event.Skip();
}
private:
// any class wishing to process wxWindows events must use this macro
DECLARE_EVENT_TABLE()
};
class VScrollWindow : public wxVScrolledWindow
{
public:
VScrollWindow(wxFrame *frame) : wxVScrolledWindow(frame, -1)
{
m_frame = frame;
SetLineCount(200);
m_changed = true;
}
void OnIdle(wxIdleEvent&)
{
m_frame->SetStatusText(wxString::Format
(
"Page size = %d, pos = %d, max = %d",
GetScrollThumb(wxVERTICAL),
GetScrollPos(wxVERTICAL),
GetScrollRange(wxVERTICAL)
));
m_changed = false;
}
void OnPaint(wxPaintEvent&)
{
wxPaintDC dc(this);
dc.SetPen(*wxBLACK_DASHED_PEN);
const size_t lineFirst = GetFirstVisibleLine(),
lineLast = GetLastVisibleLine();
const wxCoord hText = dc.GetCharHeight();
wxCoord y = 0;
for ( size_t line = lineFirst; line <= lineLast; line++ )
{
dc.DrawLine(0, y, 1000, y);
wxCoord hLine = OnGetLineHeight(line);
dc.DrawText(wxString::Format(_T("Line %lu"), (unsigned long)line),
0, y + (hLine - hText) / 2);
y += hLine;
dc.DrawLine(0, y, 1000, y);
}
}
void OnScroll(wxScrollWinEvent& event)
{
m_changed = true;
event.Skip();
}
virtual wxCoord OnGetLineHeight(size_t n) const
{
wxASSERT( n < GetLineCount() );
return n % 2 ? 15 : 30; // 15 + 2*n
}
private:
wxFrame *m_frame;
bool m_changed;
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(VScrollWindow, wxVScrolledWindow)
EVT_IDLE(VScrollWindow::OnIdle)
EVT_PAINT(VScrollWindow::OnPaint)
EVT_SCROLLWIN(VScrollWindow::OnScroll)
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// IDs for the controls and the menu commands
enum
{
// menu items
VScroll_Quit = 1,
// 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
};
// ----------------------------------------------------------------------------
// event tables and other macros for wxWindows
// ----------------------------------------------------------------------------
// the event tables connect the wxWindows 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)
END_EVENT_TABLE()
// Create a new application object: this macro will allow wxWindows 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
// not wxApp)
IMPLEMENT_APP(VScrollApp)
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------
// 'Main program' equivalent: the program execution "starts" here
bool VScrollApp::OnInit()
{
// create the main application window
VScrollFrame *frame = new VScrollFrame;
// and show it (the frames, unlike simple controls, are not shown when
// created initially)
frame->Show(TRUE);
// ok
return TRUE;
}
// ----------------------------------------------------------------------------
// main frame
// ----------------------------------------------------------------------------
// frame constructor
VScrollFrame::VScrollFrame()
: wxFrame(NULL,
-1,
_T("VScroll wxWindows Sample"),
wxDefaultPosition,
wxSize(400, 350))
{
// set the frame icon
SetIcon(wxICON(mondrian));
#if wxUSE_MENUS
// create a menu bar
wxMenu *menuFile = 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"));
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(menuHelp, _T("&Help"));
// ... and attach this menu bar to the frame
SetMenuBar(menuBar);
#endif // wxUSE_MENUS
#if wxUSE_STATUSBAR
// create a status bar just for fun (by default with 1 pane only)
CreateStatusBar(2);
SetStatusText(_T("Welcome to wxWindows!"));
#endif // wxUSE_STATUSBAR
// create our one and only child -- it will take our entire client area
new VScrollWindow(this);
}
// ----------------------------------------------------------------------------
// event handlers
// ----------------------------------------------------------------------------
void VScrollFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
// TRUE is to force the frame to close
Close(TRUE);
}
void VScrollFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(_T("VScroll shows how to implement scrolling with\n")
_T("variable line heights.\n")
_T("© 2003 Vadim Zeitlin"),
_T("About VScroll"),
wxOK | wxICON_INFORMATION,
this);
}

322
src/generic/vscroll.cpp Normal file
View File

@ -0,0 +1,322 @@
/////////////////////////////////////////////////////////////////////////////
// Name: src/generic/vscroll.cpp
// Purpose: wxVScrolledWindow implementation
// Author: Vadim Zeitlin
// Modified by:
// Created: 30.05.03
// RCS-ID: $Id$
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "wx/vscroll.h"
// ----------------------------------------------------------------------------
// event tables
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxVScrolledWindow, wxPanel)
EVT_SIZE(wxVScrolledWindow::OnSize)
EVT_SCROLLWIN(wxVScrolledWindow::OnScroll)
END_EVENT_TABLE()
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// initialization
// ----------------------------------------------------------------------------
void wxVScrolledWindow::Init()
{
// we're initially empty
m_lineMax =
m_lineFirst = 0;
// this one should always be strictly positive
m_nVisible = 1;
m_heightTotal = 0;
}
// ----------------------------------------------------------------------------
// various helpers
// ----------------------------------------------------------------------------
wxCoord wxVScrolledWindow::GetLinesHeight(size_t lineMin, size_t lineMax) const
{
if ( lineMin == lineMax )
return 0;
else if ( lineMin > lineMax )
return -GetLinesHeight(lineMax, lineMin);
//else: lineMin < lineMax
// let the user code know that we're going to need all these lines
OnGetLinesHint(lineMin, lineMax);
// do sum up their heights
wxCoord height = 0;
for ( size_t line = lineMin; line < lineMax; line++ )
{
height += OnGetLineHeight(line);
}
return height;
}
size_t wxVScrolledWindow::FindFirstFromBottom(size_t lineLast)
{
const wxCoord hWindow = GetClientSize().y;
// go upwards until we arrive at a line such that lineLast is not visible
// any more when it is shown
size_t lineFirst = lineLast;
wxCoord h = 0;
for ( ;; )
{
h += OnGetLineHeight(lineFirst);
if ( h > hWindow )
{
lineFirst++;
break;
}
if ( !lineFirst )
break;
lineFirst--;
}
return lineFirst;
}
void wxVScrolledWindow::UpdateScrollbar()
{
// see how many lines can we fit on screen
const wxCoord hWindow = GetClientSize().y;
wxCoord h = 0;
size_t line;
for ( line = m_lineFirst; line < m_lineMax; line++ )
{
if ( h > hWindow )
break;
h += OnGetLineHeight(line);
}
m_nVisible = line - m_lineFirst;
int pageSize = m_nVisible;
if ( h > hWindow )
{
// 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--;
}
// set the scrollbar parameters to reflect this
SetScrollbar(wxVERTICAL, m_lineFirst, pageSize, m_lineMax);
}
// ----------------------------------------------------------------------------
// operations
// ----------------------------------------------------------------------------
void wxVScrolledWindow::SetLineCount(size_t count)
{
// save the number of lines
m_lineMax = count;
// estimate the total height: it is impossible to call
// OnGetLineHeight() for every line because there may be too many of
// them, so we just make a guess using some lines in the beginning,
// some in the end and some in the middle
static const size_t NUM_LINES_TO_SAMPLE = 10;
if ( count < 3*NUM_LINES_TO_SAMPLE )
{
// in this case calculating exactly is faster and more correct than
// guessing
m_heightTotal = GetLinesHeight(0, m_lineMax);
}
else // too many lines to calculate exactly
{
// look at some lines in the beginning/middle/end
m_heightTotal =
GetLinesHeight(0, NUM_LINES_TO_SAMPLE) +
GetLinesHeight(count - NUM_LINES_TO_SAMPLE, count) +
GetLinesHeight(count/2 - NUM_LINES_TO_SAMPLE/2,
count/2 + NUM_LINES_TO_SAMPLE/2);
// use the height of the lines we looked as the average
m_heightTotal = ((float)m_heightTotal / (3*NUM_LINES_TO_SAMPLE)) *
m_lineMax;
}
// recalculate the scrollbars parameters
ScrollToLine(0);
}
// ----------------------------------------------------------------------------
// scrolling
// ----------------------------------------------------------------------------
bool wxVScrolledWindow::ScrollToLine(size_t line)
{
if ( !m_lineMax )
{
// 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
// the end
size_t lineFirstLast = FindFirstFromBottom(m_lineMax - 1);
if ( line > lineFirstLast )
line = lineFirstLast;
// anything to do?
if ( line == m_lineFirst )
{
// no
return false;
}
// remember the currently shown lines for the refresh code below
size_t lineFirstOld = GetFirstVisibleLine(),
lineLastOld = GetLastVisibleLine();
m_lineFirst = line;
// 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 ( GetFirstVisibleLine() > lineLastOld ||
GetLastVisibleLine() < lineFirstOld )
{
// the simplest case: we don't have any old lines left, just redraw
// everything
Refresh();
}
else // overlap between the lines we showed before and should show now
{
ScrollWindow(0, GetLinesHeight(GetFirstVisibleLine(), lineFirstOld));
}
return true;
}
bool wxVScrolledWindow::ScrollLines(int lines)
{
lines += m_lineFirst;
if ( lines < 0 )
lines = 0;
return ScrollToLine(lines);
}
bool wxVScrolledWindow::ScrollPages(int pages)
{
bool didSomething = false;
while ( pages )
{
int line;
if ( pages > 0 )
{
line = GetLastVisibleLine();
pages--;
}
else // pages < 0
{
line = FindFirstFromBottom(GetFirstVisibleLine());
pages++;
}
didSomething = ScrollToLine(line);
}
return didSomething;
}
// ----------------------------------------------------------------------------
// event handling
// ----------------------------------------------------------------------------
void wxVScrolledWindow::OnSize(wxSizeEvent& event)
{
UpdateScrollbar();
event.Skip();
}
void wxVScrolledWindow::OnScroll(wxScrollWinEvent& event)
{
size_t lineFirstNew;
const wxEventType evtType = event.GetEventType();
if ( evtType == wxEVT_SCROLLWIN_TOP )
{
lineFirstNew = 0;
}
else if ( evtType == wxEVT_SCROLLWIN_BOTTOM )
{
lineFirstNew = m_lineMax;
}
else if ( evtType == wxEVT_SCROLLWIN_LINEUP )
{
lineFirstNew = m_lineFirst ? m_lineFirst - 1 : 0;
}
else if ( evtType == wxEVT_SCROLLWIN_LINEDOWN )
{
lineFirstNew = m_lineFirst + 1;
}
else if ( evtType == wxEVT_SCROLLWIN_PAGEUP )
{
lineFirstNew = FindFirstFromBottom(m_lineFirst);
}
else if ( evtType == wxEVT_SCROLLWIN_PAGEDOWN )
{
lineFirstNew = GetLastVisibleLine();
}
else // unknown scroll event?
{
if ( evtType == wxEVT_SCROLLWIN_THUMBRELEASE )
{
lineFirstNew = event.GetPosition();
}
else
{
wxASSERT_MSG( evtType == wxEVT_SCROLLWIN_THUMBTRACK,
_T("unknown scroll event type?") );
// don't do anything, otherwise dragging the thumb around would
// be too slow
return;
}
}
ScrollToLine(lineFirstNew);
}