]> git.saurik.com Git - wxWidgets.git/commitdiff
added wxVListBox using wxVScrolledWindow and wxHtmlListBox using it
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 1 Jun 2003 13:35:26 +0000 (13:35 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 1 Jun 2003 13:35:26 +0000 (13:35 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@20808 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/latex/wx/category.tex
docs/latex/wx/classes.tex
docs/latex/wx/htmllbox.tex [new file with mode: 0644]
docs/latex/wx/vlbox.tex [new file with mode: 0644]
include/wx/htmllbox.h [new file with mode: 0644]
include/wx/vlbox.h [new file with mode: 0644]
include/wx/vscroll.h
src/generic/htmllbox.cpp [new file with mode: 0644]
src/generic/vlbox.cpp [new file with mode: 0644]
src/generic/vscroll.cpp

index f41578b7c2d7455bf91e9b0d311a4731007cc245..0959dd071b3ebdb36c85ca51eab765c343e34bf7 100644 (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}}
index 4d374a4d410a1d5570ee4c6f5255c8add3d12d81..d263aaa0a501aafcd4f43d2e63407f49241c4768 100644 (file)
 \input hthlpdat.tex
 \input hthlpfrm.tex
 \input htlnkinf.tex
+\input htmllbox.tex
 \input htparser.tex
 \input htprint.tex
 \input httag.tex
 \input validatr.tex
 \input variant.tex
 \input view.tex
+\input vlbox.tex
 \input vscroll.tex
 \input wave.tex
 \input window.tex
diff --git a/docs/latex/wx/htmllbox.tex b/docs/latex/wx/htmllbox.tex
new file mode 100644 (file)
index 0000000..9e6875e
--- /dev/null
@@ -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}.
+
diff --git a/docs/latex/wx/vlbox.tex b/docs/latex/wx/vlbox.tex
new file mode 100644 (file)
index 0000000..90e6334
--- /dev/null
@@ -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.
+
diff --git a/include/wx/htmllbox.h b/include/wx/htmllbox.h
new file mode 100644 (file)
index 0000000..c3764c3
--- /dev/null
@@ -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_
+
diff --git a/include/wx/vlbox.h b/include/wx/vlbox.h
new file mode 100644 (file)
index 0000000..84fcfdf
--- /dev/null
@@ -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_
+
index 58b693f1e2e8562f4582f5da274ec1f3ef1732d1..6d830f6417f2286dab8f44621a62f767c90fe0c2 100644 (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);
diff --git a/src/generic/htmllbox.cpp b/src/generic/htmllbox.cpp
new file mode 100644 (file)
index 0000000..c38650b
--- /dev/null
@@ -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();
+}
+
diff --git a/src/generic/vlbox.cpp b/src/generic/vlbox.cpp
new file mode 100644 (file)
index 0000000..7ebf949
--- /dev/null
@@ -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);
+    }
+}
+
index aa52fab013343200cf29a6f6a68d69389362b3a2..e7cb8cfa06c9d7d4afc6747edbefbff5bd735dbd 100644 (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
 // ----------------------------------------------------------------------------