added wxVListBox using wxVScrolledWindow and wxHtmlListBox using it

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20808 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2003-06-01 13:35:26 +00:00
parent 6fac75c355
commit e0c6027b5a
10 changed files with 1034 additions and 2 deletions

View File

@@ -91,6 +91,7 @@ that are not static can have \helpref{validators}{wxvalidator} associated with t
\twocolitem{\helpref{wxComboBox}{wxcombobox}}{A choice with an editable area}
\twocolitem{\helpref{wxGauge}{wxgauge}}{A control to represent a varying quantity, such as time remaining}
\twocolitem{\helpref{wxGenericDirCtrl}{wxgenericdirctrl}}{A control for displaying a directory tree}
\twocolitem{\helpref{wxHtmlListBox}{wxhtmllistbox}}{A listbox showing HTML content}
\twocolitem{\helpref{wxStaticBox}{wxstaticbox}}{A static, or group box for visually grouping related controls}
\twocolitem{\helpref{wxListBox}{wxlistbox}}{A list of strings for single or multiple selection}
\twocolitem{\helpref{wxListCtrl}{wxlistctrl}}{A control for displaying lists of strings and/or icons, plus a multicolumn report view}
@@ -106,6 +107,7 @@ that are not static can have \helpref{validators}{wxvalidator} associated with t
\twocolitem{\helpref{wxRadioBox}{wxradiobox}}{A group of radio buttons}
\twocolitem{\helpref{wxRadioButton}{wxradiobutton}}{A round button to be used with others in a mutually exclusive way}
\twocolitem{\helpref{wxSlider}{wxslider}}{A slider that can be dragged by the user}
\twocolitem{\helpref{wxVListBox}{wxvlistbox}}{A listbox supporting variable height rows}
\end{twocollist}
{\large {\bf Menus}}

View File

@@ -144,6 +144,7 @@
\input hthlpdat.tex
\input hthlpfrm.tex
\input htlnkinf.tex
\input htmllbox.tex
\input htparser.tex
\input htprint.tex
\input httag.tex
@@ -308,6 +309,7 @@
\input validatr.tex
\input variant.tex
\input view.tex
\input vlbox.tex
\input vscroll.tex
\input wave.tex
\input window.tex

View File

@@ -0,0 +1,82 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Name: htmllbox.tex
%% Purpose: wxHtmlListBox documentation
%% Author: Vadim Zeitlin
%% Modified by:
%% Created: 01.06.03
%% RCS-ID: $Id$
%% Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
%% License: wxWindows license
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{\class{wxHtmlListBox}}\label{wxhtmllistbox}
wxHtmlListBox is an implementation of \helpref{wxVListBox}{wxvlistbox} which
shows HTML content in the listbox rows. This is still an abstract base class
and you will need to derive your own class from it (see htlbox sample for the
example) but you will only need to override a single
\helpref{OnGetItem()}{wxhtmllistboxongetitem} function.
\wxheading{Derived from}
\helpref{wxVListBox}{wxvlistbox}
\wxheading{Include files}
<wx/htmllbox.h>
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxHtmlListBox::wxHtmlListBox}\label{wxhtmllistboxwxhtmllistbox}
\func{}{wxHtmlListBox}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{size\_t }{countItems = 0}, \param{long }{style = 0}, \param{const wxString\& }{name = wxVListBoxNameStr}}
Normal constructor which calls \helpref{Create()}{wxhtmllistboxcreate}
internally.
\func{}{wxHtmlListBox}{\void}
Default constructor, you must call \helpref{Create()}{wxhtmllistboxcreate}
later.
\membersection{wxHtmlListBox::\destruct{wxHtmlListBox}}\label{wxhtmllistboxdtor}
\func{}{\destruct{wxHtmlListBox}}{\void}
Destructor cleans up whatever resources we use.
\membersection{wxHtmlListBox::Create}\label{wxhtmllistboxcreate}
\func{bool}{Create}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{size\_t }{countItems = 0}, \param{long }{style = 0}, \param{const wxString\& }{name = wxVListBoxNameStr}}
Creates the control and optionally sets the initial number of items in it
(it may also be set or changed later with
\helpref{SetItemCount()}{wxvlistboxsetitemcount}).
There are no special styles defined for wxHtmlListBox, in particular the
wxListBox styles can not be used here.
Returns {\tt true} on success or {\tt false} if the control couldn't be created
\membersection{wxHtmlListBox::OnGetItem}\label{wxhtmllistboxongetitem}
\constfunc{wxString}{OnGetItem}{\param{size\_t }{n}}
This method must be implemented in the derived class and should return
the body (i.e. without {\tt <html>} nor {\tt <body>} tags) of the HTML fragment
for the given item.
\membersection{wxHtmlListBox::OnGetItemMarkup}\label{wxhtmllistboxongetitemmarkup}
\constfunc{wxString}{OnGetItemMarkup}{\param{size\_t }{n}}
This function may be overridden to decorate HTML returned by
\helpref{OnGetItem()}{wxhtmllistboxongetitem}.

174
docs/latex/wx/vlbox.tex Normal file
View File

@@ -0,0 +1,174 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Name: vlbox.tex
%% Purpose: wxVListBox documentation
%% Author: Vadim Zeitlin
%% Modified by:
%% Created: 01.06.03
%% RCS-ID: $Id$
%% Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
%% License: wxWindows license
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\section{\class{wxVListBox}}\label{wxvlistbox}
wxVListBox is a listbox-like control with the following two main differences
from a regular listbox: it can have an arbitrarily huge number of items because
it doesn't store them itself but uses \helpref{OnDrawItem()}{wxvlistboxondrawitem}
callback to draw them (so it is a {\Large V}irtual listbox) and its items can
have variable height as determined by
\helpref{OnMeasureItem()}{wxvlistboxonmeasureitem} (so it is also a listbox
with the lines of {\Large V}ariable height).
Also, as a consequence of its virtual nature, it doesn't have any methods to
append or insert items in it as it isn't necessary to do it: you just have to
call \helpref{SetItemCount()}{wxvlistboxsetitemcount} to tell the control how
many items it should display. Of course, this also means that you will never
use this class directly because it has pure virtual functions, but will need to
derive your own class, such as \helpref{wxHtmlListBox}{wxhtmllistbox}, from it.
However it emits the same events as \helpref{wxListBox}{wxlistbox} and the same
event macros may be used with it.
\wxheading{Derived from}
\helpref{wxVScrolledWindow}{wxvscrolledwindow}
\wxheading{Include files}
<wx/vlbox.h>
\latexignore{\rtfignore{\wxheading{Members}}}
\membersection{wxVListBox::wxVListBox}\label{wxvlistboxctor}
\func{}{wxVListBox}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{size\_t }{countItems = 0}, \param{long }{style = 0}, \param{const wxString\& }{name = wxVListBoxNameStr}}
Normal constructor which calls \helpref{Create()}{wxvlistboxcreate} internally.
\func{}{wxVListBox}{\void}
Default constructor, you must call \helpref{Create()}{wxvlistboxcreate} later.
\membersection{wxVListBox::Clear}\label{wxvlistboxclear}
\func{void}{Clear}{\void}
Deletes all items from the control.
\membersection{wxVListBox::Create}\label{wxvlistboxcreate}
\func{bool}{Create}{\param{wxWindow* }{parent}, \param{wxWindowID }{id = wxID\_ANY}, \param{const wxPoint\& }{pos = wxDefaultPosition}, \param{const wxSize\& }{size = wxDefaultSize}, \param{size\_t }{countItems = 0}, \param{long }{style = 0}, \param{const wxString\& }{name = wxVListBoxNameStr}}
Creates the control and optionally sets the initial number of items in it
(it may also be set or changed later with
\helpref{SetItemCount()}{wxvlistboxsetitemcount}).
There are no special styles defined for wxVListBox, in particular the wxListBox
styles can not be used here.
Returns {\tt true} on success or {\tt false} if the control couldn't be created
\membersection{wxVListBox::GetItemCount}\label{wxvlistboxgetitemcount}
\constfunc{size\_t}{GetItemCount}{\void}
Get the number of items in the control.
\wxheading{See also}
\helpref{SetItemCount()}{wxvlistboxsetitemcount}
\membersection{wxVListBox::GetSelection}\label{wxvlistboxgetselection}
\constfunc{int}{GetSelection}{\void}
Get the currently selected item or $-1$ if there is no selection.
\membersection{wxVListBox::IsSelected}\label{wxvlistboxisselected}
\constfunc{bool}{IsSelected}{\param{size\_t }{line}}
Returns {\tt true} if this item is selected, {\tt false} otherwise.
\membersection{wxVListBox::OnDrawItem}\label{wxvlistboxondrawitem}
\constfunc{void}{OnDrawItem}{\param{wxDC\& }{dc}, \param{const wxRect\& }{rect}, \param{size\_t }{n}}
The derived class must implement this function to actually draw the item
with the given index on the provided DC.
\wxheading{Parameters}
\docparam{dc}{The device context to use for drawing}
\docparam{rect}{The bounding rectangle for the item being drawn (DC clipping
region is set to this rectangle before calling this function)}
\docparam{n}{The index of the item to be drawn}
\membersection{wxVListBox::OnDrawSeparator}\label{wxvlistboxondrawseparator}
\constfunc{void}{OnDrawSeparator}{\param{wxDC\& }{dc}, \param{wxRect\& }{rect}, \param{size\_t }{n}}
This method may be used to draw separators between the lines. The rectangle
passed to it may be modified, typically to deflate it a bit before passing to
\helpref{OnDrawItem()}{wxvlistboxondrawitem}.
The base class version of this method doesn't do anything.
\wxheading{Parameters}
\docparam{dc}{The device context to use for drawing}
\docparam{rect}{The bounding rectangle for the item}
\docparam{n}{The index of the item}
\membersection{wxVListBox::OnMeasureItem}\label{wxvlistboxonmeasureitem}
\constfunc{wxCoord}{OnMeasureItem}{\param{size\_t }{n}}
The derived class must implement this method to return the height of the
specified item (in pixels).
\membersection{wxVListBox::SetItemCount}\label{wxvlistboxsetitemcount}
\func{void}{SetItemCount}{\param{size\_t }{count}}
Set the number of items to be shown in the control.
This is just a synonym for
\helpref{wxVScrolledWindow::SetLineCount()}{wxvscrolledwindowsetlinecount}.
\membersection{wxVListBox::SetMargins}\label{wxvlistboxsetmargins}
\func{void}{SetMargins}{\param{const wxPoint\& }{pt}}
\func{void}{SetMargins}{\param{wxCoord }{x}, \param{wxCoord }{y}}
Set the margins: horizontal margin is the distance between the window
border and the item contents while vertical margin is half of the
distance between items.
By default both margins are $0$.
\membersection{wxVListBox::SetSelection}\label{wxvlistboxsetselection}
\func{void}{SetSelection}{\param{int }{selection}}
Set the selection to the specified item, if it is $-1$ the selection is
unset. The selected item will be automatically scrolled into view if it isn't
currently visible.

94
include/wx/htmllbox.h Normal file
View File

@@ -0,0 +1,94 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/htmllbox.h
// Purpose: wxHtmlListBox is a listbox whose items are wxHtmlCells
// Author: Vadim Zeitlin
// Modified by:
// Created: 31.05.03
// RCS-ID: $Id$
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_HTMLLBOX_H_
#define _WX_HTMLLBOX_H_
#include "wx/vlbox.h" // base class
class WXDLLEXPORT wxHtmlCell;
class WXDLLEXPORT wxHtmlWinParser;
class WXDLLEXPORT wxHtmlListBoxCache;
// ----------------------------------------------------------------------------
// wxHtmlListBox
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxHtmlListBox : public wxVListBox
{
public:
// constructors and such
// ---------------------
// default constructor, you must call Create() later
wxHtmlListBox() { Init(); }
// normal constructor which calls Create() internally
wxHtmlListBox(wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
size_t countItems = 0,
long style = 0,
const wxString& name = wxVListBoxNameStr)
{
Init();
(void)Create(parent, id, pos, size, countItems, style, name);
}
// really creates the control and sets the initial number of items in it
// (which may be changed later with SetItemCount())
//
// there are no special styles defined for wxVListBox
//
// returns true on success or false if the control couldn't be created
bool Create(wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
size_t countItems = 0,
long style = 0,
const wxString& name = wxVListBoxNameStr);
// destructor cleans up whatever resources we use
virtual ~wxHtmlListBox();
protected:
// this method must be implemented in the derived class and should return
// the body (i.e. without <html>) of the HTML for the given item
virtual wxString OnGetItem(size_t n) const = 0;
// this function may be overridden to decorate HTML returned by OnGetItem()
virtual wxString OnGetItemMarkup(size_t n) const;
// we implement both of these functions in terms of OnGetItem(), they are
// not supposed to be overridden by our descendants
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const;
virtual wxCoord OnMeasureItem(size_t n) const;
// common part of all ctors
void Init();
// ensure that the given item is cached
void CacheItem(size_t n) const;
private:
wxHtmlListBoxCache *m_cache;
// HTML parser we use
wxHtmlWinParser *m_htmlParser;
};
#endif // _WX_HTMLLBOX_H_

157
include/wx/vlbox.h Normal file
View File

@@ -0,0 +1,157 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/vlbox.h
// Purpose: wxVListBox is a virtual listbox with lines of variable height
// Author: Vadim Zeitlin
// Modified by:
// Created: 31.05.03
// RCS-ID: $Id$
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_VLBOX_H_
#define _WX_VLBOX_H_
#include "wx/vscroll.h" // base class
#define wxVListBoxNameStr _T("wxVListBox")
// ----------------------------------------------------------------------------
// wxVListBox
// ----------------------------------------------------------------------------
/*
This class has two main differences from a regular listbox: it can have an
arbitrarily huge number of items because it doesn't store them itself but
uses OnDrawItem() callback to draw them and its items can have variable
height as determined by OnMeasureItem().
It emits the same events as wxListBox and the same event macros may be used
with it.
*/
class WXDLLEXPORT wxVListBox : public wxVScrolledWindow
{
public:
// constructors and such
// ---------------------
// default constructor, you must call Create() later
wxVListBox() { Init(); }
// normal constructor which calls Create() internally
wxVListBox(wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
size_t countItems = 0,
long style = 0,
const wxString& name = wxVListBoxNameStr)
{
Init();
(void)Create(parent, id, pos, size, countItems, style, name);
}
// really creates the control and sets the initial number of items in it
// (which may be changed later with SetItemCount())
//
// there are no special styles defined for wxVListBox
//
// returns true on success or false if the control couldn't be created
bool Create(wxWindow *parent,
wxWindowID id = wxID_ANY,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
size_t countItems = 0,
long style = 0,
const wxString& name = wxVListBoxNameStr);
// operations
// ----------
// set the number of items to be shown in the control
//
// this is just a synonym for wxVScrolledWindow::SetLineCount()
void SetItemCount(size_t count) { SetLineCount(count); }
// delete all items from the control
void Clear() { SetItemCount(0); }
// set the selection to the specified item, if it is -1 the selection is
// unset
void SetSelection(int selection) { DoSetSelection(selection, false); }
// set the margins: horizontal margin is the distance between the window
// border and the item contents while vertical margin is half of the
// distance between items
//
// by default both margins are 0
void SetMargins(const wxPoint& pt);
void SetMargins(wxCoord x, wxCoord y) { SetMargins(wxPoint(x, y)); }
// accessors
// ---------
// get the number of items in the control
size_t GetItemCount() const { return GetLineCount(); }
// get the currently selected item or -1 if there is no selection
int GetSelection() const { return m_selection; }
// is this item selected?
bool IsSelected(size_t line) const { return (int)line == m_selection; }
protected:
// the derived class must implement this function to actually draw the item
// with the given index on the provided DC
virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const = 0;
// the derived class must implement this method to return the height of the
// specified item
virtual wxCoord OnMeasureItem(size_t n) const = 0;
// this method may be used to draw separators between the lines; note that
// the rectangle may be modified, typically to deflate it a bit before
// passing to OnDrawItem()
//
// the base class version doesn't do anything
virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const;
// we implement OnGetLineHeight() in terms of OnMeasureItem() because this
// allows us to add borders to the items easily
//
// this function is not upposed to be overridden by the derived classes
virtual wxCoord OnGetLineHeight(size_t line) const;
// event handlers
void OnPaint(wxPaintEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnLeftDown(wxMouseEvent& event);
void OnLeftDClick(wxMouseEvent& event);
// common part of all ctors
void Init();
// SetSelection() with additional parameter telling it whether to send a
// notification event or not
void DoSetSelection(int selection, bool sendEvent = true);
private:
// the current selection or -1
int m_selection;
// margins
wxPoint m_ptMargins;
DECLARE_EVENT_TABLE()
};
#endif // _WX_VLBOX_H_

View File

@@ -90,6 +90,14 @@ public:
virtual bool ScrollLines(int lines);
virtual bool ScrollPages(int pages);
// redraw the specified line
void RefreshLine(size_t line);
// return the item at the specified (in physical coordinates) position or
// 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); }
// accessors
// ---------
@@ -104,8 +112,12 @@ public:
// get the last currently visible line
size_t GetLastVisibleLine() const { return m_lineFirst + m_nVisible - 1; }
// is this line currently visible?
bool IsVisible(size_t line) const
{ return line >= m_lineFirst && line <= GetLastVisibleLine(); }
//protected:
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;
@@ -125,7 +137,7 @@ public:
// usual
virtual void OnGetLinesHint(size_t lineMin, size_t lineMax) const { }
protected:
// the event handlers
void OnSize(wxSizeEvent& event);
void OnScroll(wxScrollWinEvent& event);

185
src/generic/htmllbox.cpp Normal file
View File

@@ -0,0 +1,185 @@
///////////////////////////////////////////////////////////////////////////////
// Name: generic/htmllbox.cpp
// Purpose: implementation of wxHtmlListBox
// Author: Vadim Zeitlin
// Modified by:
// Created: 31.05.03
// RCS-ID: $Id$
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// License: wxWindows license
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#endif //WX_PRECOMP
#include "wx/htmllbox.h"
#include "wx/html/htmlcell.h"
#include "wx/html/winpars.h"
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
// this class is used by wxHtmlListBox to cache the parsed representation of
// the items to avoid doing it anew each time an item must be drawn
//
// TODO: extend the class to cache more than item
class wxHtmlListBoxCache
{
public:
wxHtmlListBoxCache() { m_cell = NULL; }
~wxHtmlListBoxCache() { delete m_cell; }
// returns true if we already have this item cached
bool Has(size_t n) const { return m_cell && n == m_item; }
// ensure that the item is cached
void Store(size_t n, wxHtmlCell *cell)
{
m_item = n;
delete m_cell;
m_cell = cell;
}
// return the cached cell for this index or NULL if none
wxHtmlCell *Get(size_t n) const
{
// we could be reading uninitialized m_item here but the code is still
// correct
return n == m_item ? m_cell : NULL;
}
private:
// the parsed representation of the cached item or NULL
wxHtmlCell *m_cell;
// the index of the currently cached item (only valid if m_cell != NULL)
size_t m_item;
};
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxHtmlListBox creation
// ----------------------------------------------------------------------------
void wxHtmlListBox::Init()
{
m_htmlParser = NULL;
m_cache = new wxHtmlListBoxCache;
}
bool wxHtmlListBox::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
size_t countItems,
long style,
const wxString& name)
{
return wxVListBox::Create(parent, id, pos, size, countItems, style, name);
}
wxHtmlListBox::~wxHtmlListBox()
{
delete m_cache;
if ( m_htmlParser )
{
delete m_htmlParser->GetDC();
delete m_htmlParser;
}
}
// ----------------------------------------------------------------------------
// wxHtmlListBox items markup
// ----------------------------------------------------------------------------
wxString wxHtmlListBox::OnGetItemMarkup(size_t n) const
{
// we don't even need to wrap the value returned by OnGetItem() inside
// "<html><body>" and "</body></html>" because wxHTML can parse it even
// without these tags
return OnGetItem(n);
}
void wxHtmlListBox::CacheItem(size_t n) const
{
if ( !m_cache->Has(n) )
{
if ( !m_htmlParser )
{
wxHtmlListBox *self = wxConstCast(this, wxHtmlListBox);
self->m_htmlParser = new wxHtmlWinParser;
m_htmlParser->SetDC(new wxClientDC(self));
}
wxHtmlContainerCell *cell = (wxHtmlContainerCell *)m_htmlParser->
Parse(OnGetItemMarkup(n));
wxCHECK_RET( cell, _T("wxHtmlParser::Parse() returned NULL?") );
cell->Layout(GetClientSize().x);
m_cache->Store(n, cell);
}
}
// ----------------------------------------------------------------------------
// wxHtmlListBox implementation of wxVListBox pure virtuals
// ----------------------------------------------------------------------------
void wxHtmlListBox::OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const
{
CacheItem(n);
wxHtmlCell *cell = m_cache->Get(n);
wxCHECK_RET( cell, _T("this cell should be cached!") );
// draw the selected cell in selected state
if ( IsSelected(n) )
{
wxHtmlSelection htmlSel;
htmlSel.Set(wxPoint(0, 0), cell, wxPoint(INT_MAX, INT_MAX), cell);
wxHtmlRenderingState htmlRendState(&htmlSel);
htmlRendState.SetSelectionState(wxHTML_SEL_IN);
cell->Draw(dc, rect.x, rect.y, 0, INT_MAX, htmlRendState);
}
else
{
// note that we can't stop drawing exactly at the window boundary as then
// even the visible cells part could be not drawn, so always draw the
// entire cell
wxHtmlRenderingState htmlRendState(NULL);
cell->Draw(dc, rect.x, rect.y, 0, INT_MAX, htmlRendState);
}
}
wxCoord wxHtmlListBox::OnMeasureItem(size_t n) const
{
CacheItem(n);
wxHtmlCell *cell = m_cache->Get(n);
wxCHECK_MSG( cell, 0, _T("this cell should be cached!") );
return cell->GetHeight() + cell->GetDescent();
}

288
src/generic/vlbox.cpp Normal file
View File

@@ -0,0 +1,288 @@
///////////////////////////////////////////////////////////////////////////////
// Name: generic/vlbox.cpp
// Purpose: implementation of wxVListBox
// Author: Vadim Zeitlin
// Modified by:
// Created: 31.05.03
// RCS-ID: $Id$
// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwindows.org>
// License: wxWindows license
///////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/settings.h"
#endif //WX_PRECOMP
#include "wx/vlbox.h"
// ----------------------------------------------------------------------------
// event tables
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxVListBox, wxVScrolledWindow)
EVT_PAINT(wxVListBox::OnPaint)
EVT_KEY_DOWN(wxVListBox::OnKeyDown)
EVT_LEFT_DOWN(wxVListBox::OnLeftDown)
EVT_LEFT_DCLICK(wxVListBox::OnLeftDClick)
END_EVENT_TABLE()
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// wxVListBox creation
// ----------------------------------------------------------------------------
void wxVListBox::Init()
{
m_selection = -1;
}
bool wxVListBox::Create(wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
size_t countItems,
long style,
const wxString& name)
{
if ( !wxVScrolledWindow::Create(parent, id, pos, size, style, name) )
return false;
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOX));
SetItemCount(countItems);
return true;
}
// ----------------------------------------------------------------------------
// selection handling
// ----------------------------------------------------------------------------
void wxVListBox::DoSetSelection(int selection, bool sendEvent)
{
if ( selection == m_selection )
{
// nothing to do
return;
}
if ( m_selection != -1 )
RefreshLine(m_selection);
m_selection = selection;
if ( m_selection != -1 )
{
// if the line is not visible at all, we scroll it into view but we
// don't need to refresh it -- it will be redrawn anyhow
if ( !IsVisible(m_selection) )
{
ScrollToLine(m_selection);
}
else // line is at least partly visible
{
// it is, indeed, only partly visible, so scroll it into view to
// make it entirely visible
if ( (size_t)m_selection == GetLastVisibleLine() )
{
ScrollToLine(m_selection);
}
// 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(m_selection);
}
// send a notification event if we were not called directly by user
if ( sendEvent )
{
wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId());
event.SetEventObject(this);
event.m_commandInt = selection;
(void)GetEventHandler()->ProcessEvent(event);
}
}
}
// ----------------------------------------------------------------------------
// wxVListBox painting
// ----------------------------------------------------------------------------
void wxVListBox::SetMargins(const wxPoint& pt)
{
if ( pt != m_ptMargins )
{
m_ptMargins = pt;
Refresh();
}
}
wxCoord wxVListBox::OnGetLineHeight(size_t line) const
{
return OnMeasureItem(line) + 2*m_ptMargins.y;
}
void wxVListBox::OnDrawSeparator(wxDC& WXUNUSED(dc),
wxRect& WXUNUSED(rect),
size_t WXUNUSED(n)) const
{
}
void wxVListBox::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
// the update rectangle
wxRect rectUpdate = GetUpdateClientRect();
// the bounding rectangle of the current line
wxRect rectLine;
rectLine.width = GetClientSize().x;
// iterate over all visible lines
const size_t lineMax = GetLastVisibleLine();
for ( size_t line = GetFirstVisibleLine(); line <= lineMax; line++ )
{
const wxCoord hLine = OnGetLineHeight(line);
rectLine.height = hLine;
// and draw the ones which intersect the update rect
if ( rectLine.Intersects(rectUpdate) )
{
// don't allow drawing outside of the lines rectangle
wxDCClipper clip(dc, rectLine);
if ( IsSelected(line) )
{
wxBrush brush(wxSystemSettings::
GetColour(wxSYS_COLOUR_HIGHLIGHT),
wxSOLID);
dc.SetBrush(brush);
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(rectLine);
}
wxRect rect = rectLine;
OnDrawSeparator(dc, rect, line);
rect.Deflate(m_ptMargins.x, m_ptMargins.y);
OnDrawItem(dc, rect, line);
}
else // no intersection
{
if ( rectLine.GetTop() > rectUpdate.GetBottom() )
{
// we are already below the update rect, no need to continue
// further
break;
}
//else: the next line may intersect the update rect
}
rectLine.y += hLine;
}
}
// ----------------------------------------------------------------------------
// wxVListBox keyboard handling
// ----------------------------------------------------------------------------
void wxVListBox::OnKeyDown(wxKeyEvent& event)
{
int selection = 0; // just to silent the stupid compiler warnings
switch ( event.GetKeyCode() )
{
case WXK_HOME:
selection = 0;
break;
case WXK_END:
selection = GetLineCount() - 1;
break;
case WXK_DOWN:
if ( m_selection == (int)GetLineCount() - 1 )
return;
selection = m_selection + 1;
break;
case WXK_UP:
if ( m_selection == -1 )
selection = GetLineCount() - 1;
else if ( m_selection != 0 )
selection = m_selection - 1;
else // m_selection == 0
return;
break;
case WXK_PAGEDOWN:
case WXK_NEXT:
PageDown();
selection = GetFirstVisibleLine();
break;
case WXK_PAGEUP:
case WXK_PRIOR:
if ( m_selection == (int)GetFirstVisibleLine() )
{
PageUp();
}
selection = GetFirstVisibleLine();
break;
default:
event.Skip();
return;
}
DoSetSelection(selection);
}
// ----------------------------------------------------------------------------
// wxVListBox mouse handling
// ----------------------------------------------------------------------------
void wxVListBox::OnLeftDown(wxMouseEvent& event)
{
int item = HitTest(event.GetPosition());
DoSetSelection(item);
}
void wxVListBox::OnLeftDClick(wxMouseEvent& event)
{
int item = HitTest(event.GetPosition());
if ( item != -1 )
{
wxCommandEvent event(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, GetId());
event.SetEventObject(this);
event.m_commandInt = item;
(void)GetEventHandler()->ProcessEvent(event);
}
}

View File

@@ -170,9 +170,45 @@ void wxVScrolledWindow::SetLineCount(size_t count)
// recalculate the scrollbars parameters
m_lineFirst = 1; // make sure it is != 0
ScrollToLine(0);
}
void wxVScrolledWindow::RefreshLine(size_t line)
{
// is this line visible?
if ( !IsVisible(line) )
{
// no, it is useless to do anything
return;
}
// calculate the rect occupied by this line on screen
wxRect rect;
rect.width = GetClientSize().x;
rect.height = OnGetLineHeight(line);
for ( size_t n = GetFirstVisibleLine(); n < line; n++ )
{
rect.y += OnGetLineHeight(n);
}
// do refresh it
RefreshRect(rect);
}
int wxVScrolledWindow::HitTest(wxCoord WXUNUSED(x), wxCoord y) const
{
const size_t lineMax = GetLastVisibleLine();
for ( size_t line = GetFirstVisibleLine(); line <= lineMax; line++ )
{
y -= OnGetLineHeight(line);
if ( y < 0 )
return line;
}
return wxNOT_FOUND;
}
// ----------------------------------------------------------------------------
// scrolling
// ----------------------------------------------------------------------------