From 9ebb7cade2df5aeb8531950d2a79cd57a336bcec Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 22 Oct 2006 22:09:16 +0000 Subject: [PATCH] added wxSimpleHtmlListBox (patch 1576109 by Francesco) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42257 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- build/bakefiles/files.bkl | 2 + docs/changes.txt | 1 + docs/latex/wx/category.tex | 3 +- docs/latex/wx/htmllbox.tex | 173 ++++++++++++++++++++++++++++++++++- docs/latex/wx/vlbox.tex | 4 + include/wx/ctrlsub.h | 8 +- include/wx/htmllbox.h | 142 +++++++++++++++++++++++++++- include/wx/xrc/xh_all.h | 1 + include/wx/xrc/xh_htmllbox.h | 34 +++++++ samples/htlbox/htlbox.cpp | 113 +++++++++++++++++++---- samples/xrc/rc/controls.xrc | 28 ++++++ src/generic/htmllbox.cpp | 130 ++++++++++++++++++++++++++ src/xrc/xh_htmllbox.cpp | 86 +++++++++++++++++ src/xrc/xmlrsall.cpp | 1 + 14 files changed, 696 insertions(+), 30 deletions(-) create mode 100644 include/wx/xrc/xh_htmllbox.h create mode 100644 src/xrc/xh_htmllbox.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 5ac20c086e..4522b5c657 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -2956,6 +2956,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/xrc/xh_radbx.cpp src/xrc/xh_scrol.cpp src/xrc/xh_scwin.cpp + src/xrc/xh_htmllbox.cpp src/xrc/xh_sizer.cpp src/xrc/xh_slidr.cpp src/xrc/xh_spin.cpp @@ -3012,6 +3013,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/xrc/xh_radbx.h wx/xrc/xh_scrol.h wx/xrc/xh_scwin.h + wx/xrc/xh_htmllbox.h wx/xrc/xh_sizer.h wx/xrc/xh_slidr.h wx/xrc/xh_spin.h diff --git a/docs/changes.txt b/docs/changes.txt index 5afdfed18b..7d21c120d3 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -71,6 +71,7 @@ All (GUI): - Reverted wxBuffered[Paint]DC to pre 2.7.1 state, added wxAutoBufferedPaintDC and wxAutoBufferedPaintDCFactory. - Renamed wxProgressDialog::UpdatePulse() to just Pulse() +- Added wxSimpleHtmlListBox (Francesco Montorsi) Unix Ports: diff --git a/docs/latex/wx/category.tex b/docs/latex/wx/category.tex index 06d8021a8a..52b546326c 100644 --- a/docs/latex/wx/category.tex +++ b/docs/latex/wx/category.tex @@ -102,7 +102,8 @@ that are not static can have \helpref{validators}{wxvalidator} associated with t \twocolitem{\helpref{wxDataViewCtrl}{wxdataviewctrl}}{A control to tabular or tree like data} \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{wxHtmlListBox}{wxhtmllistbox}}{An abstract class for creating listboxes showing HTML content} +\twocolitem{\helpref{wxSimpleHtmlListBox}{wxsimplehtmllistbox}}{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} diff --git a/docs/latex/wx/htmllbox.tex b/docs/latex/wx/htmllbox.tex index 2cdd92b8c0..d7cc8f62cd 100644 --- a/docs/latex/wx/htmllbox.tex +++ b/docs/latex/wx/htmllbox.tex @@ -1,6 +1,6 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Name: htmllbox.tex -%% Purpose: wxHtmlListBox documentation +%% Purpose: wxHtmlListBox and wxSimpleHtmlListBox documentation %% Author: Vadim Zeitlin %% Modified by: %% Created: 01.06.03 @@ -30,13 +30,17 @@ example) but you will only need to override a single +\wxheading{See also} + +\helpref{wxSimpleHtmlListBox}{wxsimplehtmllistbox} + \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{long }{style = 0}, \param{const wxString\& }{name = wxVListBoxNameStr}} +\func{}{wxHtmlListBox}{\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 = wxHtmlListBoxNameStr}} Normal constructor which calls \helpref{Create()}{wxhtmllistboxcreate} internally. @@ -56,14 +60,14 @@ 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{long }{style = 0}, \param{const wxString\& }{name = wxVListBoxNameStr}} +\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 = wxHtmlListBoxNameStr}} 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. +wxListBox styles (with the exception of {\tt wxLB_MULTIPLE}) can not be used here. Returns {\tt true} on success or {\tt false} if the control couldn't be created @@ -124,6 +128,12 @@ This method must be implemented in the derived class and should return the body (i.e. without {\tt } nor {\tt } tags) of the HTML fragment for the given item. +Note that this function should always return a text fragment for the \arg{n} item +which renders with the same height both when it is selected and when it's not: +i.e. if you call, inside your OnGetItem() implementation, {\tt IsSelected(n)} to +make the items appear differently when they are selected, then you should make sure +that the returned HTML fragment will render with the same height or else you'll +see some artifacts when the user selects an item. \membersection{wxHtmlListBox::OnGetItemMarkup}\label{wxhtmllistboxongetitemmarkup} @@ -148,3 +158,158 @@ Called when the user clicks on hypertext link. Does nothing by default. See also \helpref{wxHtmlLinkInfo}{wxhtmllinkinfo}. + + + + + + +% +% wxSimpleHtmlListBox +% + + +\section{\class{wxSimpleHtmlListBox}}\label{wxsimplehtmllistbox} + +wxSimpleHtmlListBox is an implementation of \helpref{wxHtmlListBox}{wxhtmllistbox} which +shows HTML content in the listbox rows. + +Unlike \helpref{wxHtmlListBox}{wxhtmllistbox}, this is not an abstract class and thus it +has the advantage that you can use it without deriving your own class from it. +However, it also has the disadvantage that this is not a virtual control and thus it's not +well-suited for those cases where you need to show a huge number of items: every time you +add/insert a string, it will be stored internally and thus will take memory. + +The interface exposed by wxSimpleHtmlListBox fully implements the +\helpref{wxControlWithItems}{wxcontrolwithitems} interface, thus you should refer to +\helpref{wxControlWithItems}{wxcontrolwithitems}'s documentation for the API reference +for adding/removing/retrieving items in the listbox. +Also note that the \helpref{wxVListBox::SetItemCount}{wxvlistboxsetitemcount} function is +{\tt protected} in wxSimpleHtmlListBox's context so that you cannot call it directly, +wxSimpleHtmlListBox will do it for you. + +Note: in case you need to append a lot of items to the control at once, make sure to use the +\helpref{Append(const wxArrayString \&)}{wxcontrolwithitemsappend} function. + +Thus the only difference between a \helpref{wxListBox}{wxlistbox} and a wxSimpleHtmlListBox +is that the latter stores strings which can contain HTML fragments (see the list of +\helpref{tags supported by wxHTML}{htmltagssupported}). + +Note that the HTML strings you fetch to wxSimpleHtmlListBox should not contain the {\tt } +or {\tt } tags. + + +\wxheading{Derived from} + +\helpref{wxHtmlListBox}{wxhtmllistbox}, \helpref{wxControlWithItems}{wxcontrolwithitems}\\ +\helpref{wxVListBox}{wxvlistbox}\\ +\helpref{wxVScrolledWindow}{wxvscrolledwindow}\\ +\helpref{wxPanel}{wxpanel}\\ +\helpref{wxWindow}{wxwindow}\\ +\helpref{wxEvtHandler}{wxevthandler}\\ +\helpref{wxObject}{wxobject} + +\wxheading{Include files} + + + +\wxheading{Window styles} + +\twocolwidtha{5cm}% +\begin{twocollist}\itemsep=0pt +\twocolitem{\windowstyle{wxHLB\_DEFAULT\_STYLE}}{The default style: wxSUNKEN_BORDER} +\twocolitem{\windowstyle{wxHLB\_MULTIPLE}}{Multiple-selection list: the user can toggle multiple +items on and off.} +\end{twocollist} + +See also \helpref{window styles overview}{windowstyles}. + +\wxheading{Event handling} + +A wxSimpleHtmlListBox emits the same events used by \helpref{wxListBox}{wxlistbox}: + +\twocolwidtha{7cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf EVT\_LISTBOX(id, func)}}{Process a wxEVT\_COMMAND\_LISTBOX\_SELECTED event, +when an item on the list is selected.} +\twocolitem{{\bf EVT\_LISTBOX\_DCLICK(id, func)}}{Process a wxEVT\_COMMAND\_LISTBOX\_DOUBLECLICKED event, +when the listbox is double-clicked.} +\end{twocollist} + + +\latexignore{\rtfignore{\wxheading{Members}}} + + +\membersection{wxSimpleHtmlListBox::wxSimpleHtmlListBox}\label{wxsimplehtmllistboxctor} + +\func{}{wxHtmlListBox}{\param{wxWindow*}{ parent}, \param{wxWindowID}{ id},\rtfsp +\param{const wxPoint\&}{ pos = wxDefaultPosition}, \param{const wxSize\&}{ size = wxDefaultSize},\rtfsp +\param{int}{ n = 0}, \param{const wxString }{choices[] = NULL},\rtfsp +\param{long}{ style = wxHLB\_DEFAULT\_STYLE}, \param{const wxValidator\& }{validator = wxDefaultValidator},\rtfsp +\param{const wxString\& }{name = ``simpleHtmlListBox"}} + +\func{}{wxHtmlListBox}{\param{wxWindow*}{ parent}, \param{wxWindowID}{ id},\rtfsp +\param{const wxPoint\&}{ pos}, \param{const wxSize\&}{ size},\rtfsp +\param{const wxArrayString\& }{choices},\rtfsp +\param{long}{ style = wxHLB\_DEFAULT\_STYLE}, \param{const wxValidator\& }{validator = wxDefaultValidator},\rtfsp +\param{const wxString\& }{name = ``simpleHtmlListBox"}} + +Constructor, creating and showing the HTML list box. + +\wxheading{Parameters} + +\docparam{parent}{Parent window. Must not be NULL.} + +\docparam{id}{Window identifier. A value of -1 indicates a default value.} + +\docparam{pos}{Window position.} + +\docparam{size}{Window size. If the default size (-1, -1) is specified then the window is sized +appropriately.} + +\docparam{n}{Number of strings with which to initialise the control.} + +\docparam{choices}{An array of strings with which to initialise the control.} + +\docparam{style}{Window style. See {\tt wxHLB\_*} flags.} + +\docparam{validator}{Window validator.} + +\docparam{name}{Window name.} + +\wxheading{See also} + +\helpref{wxSimpleHtmlListBox::Create}{wxsimplehtmllistboxcreate} + + + +\func{}{wxSimpleHtmlListBox}{\void} + +Default constructor, you must call \helpref{Create()}{wxsimplehtmllistboxcreate} +later. + + +\membersection{wxSimpleHtmlListBox::\destruct{wxSimpleHtmlListBox}}\label{wxsimplehtmllistboxdtor} + +\func{}{\destruct{wxSimpleHtmlListBox}}{\void} + +Frees the array of stored items and relative client data. + + +\membersection{wxSimpleHtmlListBox::Create}\label{wxsimplehtmllistboxcreate} + +\func{bool}{Create}{\param{wxWindow*}{ parent}, \param{wxWindowID}{ id},\rtfsp +\param{const wxPoint\&}{ pos = wxDefaultPosition}, \param{const wxSize\&}{ size = wxDefaultSize},\rtfsp +\param{int}{ n}, \param{const wxString }{choices[] = NULL},\rtfsp +\param{long}{ style = wxHLB\_DEFAULT\_STYLE}, \param{const wxValidator\& }{validator = wxDefaultValidator},\rtfsp +\param{const wxString\& }{name = ``simpleHtmlListBox"}} + +\func{bool}{Create}{\param{wxWindow*}{ parent}, \param{wxWindowID}{ id},\rtfsp +\param{const wxPoint\&}{ pos}, \param{const wxSize\&}{ size},\rtfsp +\param{const wxArrayString\& }{choices},\rtfsp +\param{long}{ style = wxHLB\_DEFAULT\_STYLE}, \param{const wxValidator\& }{validator = wxDefaultValidator},\rtfsp +\param{const wxString\& }{name = ``simpleHtmlListBox"}} + +Creates the HTML listbox for two-step construction. +See \helpref{wxSimpleHtmlListBox::wxSimpleHtmlListBox}{wxsimplehtmllistboxctor} for further details. + diff --git a/docs/latex/wx/vlbox.tex b/docs/latex/wx/vlbox.tex index 1723177aa5..00e4c8f295 100644 --- a/docs/latex/wx/vlbox.tex +++ b/docs/latex/wx/vlbox.tex @@ -41,6 +41,10 @@ event macros may be used with it. +\wxheading{See also} + +\helpref{wxSimpleHtmlListBox}{wxsimplehtmllistbox}, \helpref{wxHtmlListBox}{wxhtmllistbox} + \latexignore{\rtfignore{\wxheading{Members}}} diff --git a/include/wx/ctrlsub.h b/include/wx/ctrlsub.h index e6ad7e9f71..308fb6a03a 100644 --- a/include/wx/ctrlsub.h +++ b/include/wx/ctrlsub.h @@ -155,13 +155,13 @@ protected: // two versions #define wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST \ void SetClientData(void *data) \ - { wxControl::SetClientData(data); } \ + { wxEvtHandler::SetClientData(data); } \ void *GetClientData() const \ - { return wxControl::GetClientData(); } \ + { return wxEvtHandler::GetClientData(); } \ void SetClientObject(wxClientData *data) \ - { wxControl::SetClientObject(data); } \ + { wxEvtHandler::SetClientObject(data); } \ wxClientData *GetClientObject() const \ - { return wxControl::GetClientObject(); } \ + { return wxEvtHandler::GetClientObject(); } \ void SetClientData(unsigned int n, void* clientData) \ { wxItemContainer::SetClientData(n, clientData); } \ void* GetClientData(unsigned int n) const \ diff --git a/include/wx/htmllbox.h b/include/wx/htmllbox.h index 8a2a379e35..9e5a4b44b7 100644 --- a/include/wx/htmllbox.h +++ b/include/wx/htmllbox.h @@ -14,6 +14,7 @@ #include "wx/vlbox.h" // base class #include "wx/html/htmlwin.h" +#include "wx/ctrlsub.h" #if wxUSE_FILESYSTEM #include "wx/filesys.h" @@ -24,6 +25,9 @@ class WXDLLIMPEXP_HTML wxHtmlWinParser; class WXDLLIMPEXP_HTML wxHtmlListBoxCache; class WXDLLIMPEXP_HTML wxHtmlListBoxStyle; +extern WXDLLEXPORT_DATA(const wxChar) wxHtmlListBoxNameStr[]; +extern WXDLLEXPORT_DATA(const wxChar) wxSimpleHtmlListBoxNameStr[]; + // ---------------------------------------------------------------------------- // wxHtmlListBox // ---------------------------------------------------------------------------- @@ -46,7 +50,7 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, - const wxString& name = wxVListBoxNameStr); + const wxString& name = wxHtmlListBoxNameStr); // really creates the control and sets the initial number of items in it // (which may be changed later with SetItemCount()) @@ -59,7 +63,7 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, - const wxString& name = wxVListBoxNameStr); + const wxString& name = wxHtmlListBoxNameStr); // destructor cleans up whatever resources we use virtual ~wxHtmlListBox(); @@ -111,7 +115,7 @@ protected: // This method may be overriden to handle clicking on a link in // the listbox. By default, clicking links is ignored. virtual void OnLinkClicked(size_t WXUNUSED(n), - const wxHtmlLinkInfo& WXUNUSED(link)) {} + const wxHtmlLinkInfo& WXUNUSED(link)) { } // event handlers void OnSize(wxSizeEvent& event); @@ -183,5 +187,137 @@ private: DECLARE_NO_COPY_CLASS(wxHtmlListBox) }; + +// ---------------------------------------------------------------------------- +// wxSimpleHtmlListBox +// ---------------------------------------------------------------------------- + +#define wxHLB_DEFAULT_STYLE wxBORDER_SUNKEN +#define wxHLB_MULTIPLE wxLB_MULTIPLE + +class WXDLLIMPEXP_HTML wxSimpleHtmlListBox : public wxHtmlListBox, + public wxItemContainer +{ +public: + // wxListbox-compatible constructors + // --------------------------------- + + wxSimpleHtmlListBox() { } + + wxSimpleHtmlListBox(wxWindow *parent, + wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + int n = 0, const wxString choices[] = NULL, + long style = wxHLB_DEFAULT_STYLE, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxSimpleHtmlListBoxNameStr) + { + Create(parent, id, pos, size, n, choices, style, validator, name); + } + + wxSimpleHtmlListBox(wxWindow *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + const wxArrayString& choices, + long style = wxHLB_DEFAULT_STYLE, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxSimpleHtmlListBoxNameStr) + { + Create(parent, id, pos, size, choices, style, validator, name); + } + + bool Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + int n = 0, const wxString choices[] = NULL, + long style = wxHLB_DEFAULT_STYLE, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxSimpleHtmlListBoxNameStr); + bool Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, + const wxSize& size, + const wxArrayString& choices, + long style = wxHLB_DEFAULT_STYLE, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxSimpleHtmlListBoxNameStr); + + virtual ~wxSimpleHtmlListBox(); + + // these must be overloaded otherwise the compiler will complain + // about wxItemContainerImmutable::[G|S]etSelection being pure virtuals... + void SetSelection(int n) + { return wxVListBox::SetSelection(n); } + int GetSelection() const + { return wxVListBox::GetSelection(); } + + // see ctrlsub.h for more info about this: + wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST + + + // accessing strings + // ----------------- + + virtual unsigned int GetCount() const + { return m_items.GetCount(); } + + virtual wxString GetString(unsigned int n) const; + + // override default unoptimized wxItemContainer::GetStrings() function + wxArrayString GetStrings() const + { return m_items; } + + virtual void SetString(unsigned int n, const wxString& s); + + virtual void Clear(); + virtual void Delete(unsigned int n); + + // override default unoptimized wxItemContainer::Append() function + void Append(const wxArrayString& strings); + + // since we override one Append() overload, we need to overload all others too + int Append(const wxString& item) + { return wxItemContainer::Append(item); } + int Append(const wxString& item, void *clientData) + { return wxItemContainer::Append(item, clientData); } + int Append(const wxString& item, wxClientData *clientData) + { return wxItemContainer::Append(item, clientData); } + + +protected: + + virtual int DoAppend(const wxString& item); + virtual int DoInsert(const wxString& item, unsigned int pos); + + virtual void DoSetItemClientData(unsigned int n, void *clientData) + { m_clientData[n] = clientData; } + + virtual void *DoGetItemClientData(unsigned int n) const + { return m_clientData[n]; } + virtual void DoSetItemClientObject(unsigned int n, wxClientData *clientData) + { m_clientData[n] = (void *)clientData; } + virtual wxClientData *DoGetItemClientObject(unsigned int n) const + { return (wxClientData *)m_clientData[n]; } + + // calls wxHtmlListBox::SetItemCount() and RefreshAll() + void UpdateCount(); + + // overload these functions just to change their visibility: users of + // wxSimpleHtmlListBox shouldn't be allowed to call them directly! + virtual void SetItemCount(size_t count) + { return wxHtmlListBox::SetItemCount(count); } + virtual void SetLineCount(size_t count) + { return wxHtmlListBox::SetLineCount(count); } + + virtual wxString OnGetItem(size_t n) const + { return m_items[n]; } + + wxArrayString m_items; + wxArrayPtrVoid m_clientData; + + DECLARE_NO_COPY_CLASS(wxSimpleHtmlListBox) +}; + #endif // _WX_HTMLLBOX_H_ diff --git a/include/wx/xrc/xh_all.h b/include/wx/xrc/xh_all.h index d3364fc18e..bf900cf07f 100644 --- a/include/wx/xrc/xh_all.h +++ b/include/wx/xrc/xh_all.h @@ -53,6 +53,7 @@ #include "wx/xrc/xh_gdctl.h" #include "wx/xrc/xh_frame.h" #include "wx/xrc/xh_scwin.h" +#include "wx/xrc/xh_htmllbox.h" #include "wx/xrc/xh_split.h" #include "wx/xrc/xh_wizrd.h" #include "wx/xrc/xh_statbar.h" diff --git a/include/wx/xrc/xh_htmllbox.h b/include/wx/xrc/xh_htmllbox.h new file mode 100644 index 0000000000..1550697920 --- /dev/null +++ b/include/wx/xrc/xh_htmllbox.h @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/xrc/xh_htmllbox.h +// Purpose: XML resource handler for wxSimpleHtmlListBox +// Author: Francesco Montorsi +// Created: 2006/10/21 +// RCS-ID: $Id$ +// Copyright: (c) 2006 Francesco Montorsi +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_XH_SIMPLEHTMLLISTBOX_H_ +#define _WX_XH_SIMPLEHTMLLISTBOX_H_ + +#include "wx/xrc/xmlres.h" + +#if wxUSE_XRC && wxUSE_HTML + +class WXDLLIMPEXP_XRC wxSimpleHtmlListBoxXmlHandler : public wxXmlResourceHandler +{ +public: + wxSimpleHtmlListBoxXmlHandler(); + virtual wxObject *DoCreateResource(); + virtual bool CanHandle(wxXmlNode *node); + +private: + bool m_insideBox; + wxArrayString strList; + + DECLARE_DYNAMIC_CLASS(wxSimpleHtmlListBoxXmlHandler) +}; + +#endif // wxUSE_XRC && wxUSE_HTML + +#endif // _WX_XH_SIMPLEHTMLLISTBOX_H_ diff --git a/samples/htlbox/htlbox.cpp b/samples/htlbox/htlbox.cpp index f0b76886b1..a53accf347 100644 --- a/samples/htlbox/htlbox.cpp +++ b/samples/htlbox/htlbox.cpp @@ -63,6 +63,7 @@ class MyHtmlListBox : public wxHtmlListBox { public: + MyHtmlListBox() { } MyHtmlListBox(wxWindow *parent, bool multi = false); void SetChangeSelFg(bool change) { m_change = change; } @@ -97,8 +98,10 @@ protected: #endif DECLARE_NO_COPY_CLASS(MyHtmlListBox) + DECLARE_DYNAMIC_CLASS(MyHtmlListBox) }; + class MyFrame : public wxFrame { public: @@ -106,6 +109,7 @@ public: virtual ~MyFrame(); // event handlers + void OnSimpleOrCustomBox(wxCommandEvent& event); void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); @@ -127,9 +131,16 @@ public: { wxLogMessage(_T("Listbox item %d double clicked."), event.GetInt()); } + + wxSimpleHtmlListBox *GetSimpleBox() + { return wxDynamicCast(m_hlbox, wxSimpleHtmlListBox); } + MyHtmlListBox *GetMyBox() + { return wxDynamicCast(m_hlbox, MyHtmlListBox); } + + void CreateBox(); private: - MyHtmlListBox *m_hlbox; + wxHtmlListBox *m_hlbox; // any class wishing to process wxWidgets events must use this macro DECLARE_EVENT_TABLE() @@ -149,7 +160,9 @@ public: enum { // menu items - HtmlLbox_Quit = 1, + HtmlLbox_CustomBox = 1, + HtmlLbox_SimpleBox, + HtmlLbox_Quit, HtmlLbox_SetMargins, HtmlLbox_DrawSeparator, @@ -172,6 +185,8 @@ enum // ---------------------------------------------------------------------------- BEGIN_EVENT_TABLE(MyFrame, wxFrame) + EVT_MENU(HtmlLbox_CustomBox, MyFrame::OnSimpleOrCustomBox) + EVT_MENU(HtmlLbox_SimpleBox, MyFrame::OnSimpleOrCustomBox) EVT_MENU(HtmlLbox_Quit, MyFrame::OnQuit) EVT_MENU(HtmlLbox_SetMargins, MyFrame::OnSetMargins) @@ -206,7 +221,7 @@ IMPLEMENT_APP(MyApp) // frame constructor MyFrame::MyFrame() : wxFrame(NULL, wxID_ANY, _T("HtmlLbox wxWidgets Sample"), - wxDefaultPosition, wxSize(400, 500)) + wxDefaultPosition, wxSize(500, 500)) { // set the frame icon SetIcon(wxIcon(sample_xpm)); @@ -214,6 +229,11 @@ MyFrame::MyFrame() #if wxUSE_MENUS // create a menu bar wxMenu *menuFile = new wxMenu; + menuFile->AppendRadioItem(HtmlLbox_CustomBox, _T("Use custom box"), + _T("Use a wxHtmlListBox virtual class control")); + menuFile->AppendRadioItem(HtmlLbox_SimpleBox, _T("Use simple box"), + _T("Use a wxSimpleHtmlListBox control")); + menuFile->AppendSeparator(); menuFile->Append(HtmlLbox_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); // create our specific menu @@ -259,9 +279,9 @@ MyFrame::MyFrame() CreateStatusBar(2); SetStatusText(_T("Welcome to wxWidgets!")); #endif // wxUSE_STATUSBAR - + // create the child controls - m_hlbox = new MyHtmlListBox(this); + CreateBox(); wxTextCtrl *text = new wxTextCtrl(this, wxID_ANY, _T(""), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); @@ -269,8 +289,8 @@ MyFrame::MyFrame() // and lay them out wxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); - sizer->Add(m_hlbox, 1, wxGROW); - sizer->Add(text, 1, wxGROW); + sizer->Add(m_hlbox, 2, wxGROW); + sizer->Add(text, 3, wxGROW); SetSizer(sizer); } @@ -280,10 +300,61 @@ MyFrame::~MyFrame() delete wxLog::SetActiveTarget(NULL); } +void MyFrame::CreateBox() +{ + bool multi = GetMenuBar()->IsChecked(HtmlLbox_ToggleMulti); + + if ( GetMenuBar()->IsChecked(HtmlLbox_CustomBox) ) + { + m_hlbox = new MyHtmlListBox(this, multi); + } + else // simple listbox + { + m_hlbox = new wxSimpleHtmlListBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, + 0, NULL, multi ? wxLB_MULTIPLE : 0); + + // unlike wxHtmlListBox which is abstract, wxSimpleHtmlListBox is a + // concrete control and doesn't support virtual mode, this we need + // to add all of its items from the beginning + wxArrayString arr; + for (size_t n = 0; n < 1000; n++ ) + { + wxColour clr((unsigned char)(abs((int)n - 192) % 256), + (unsigned char)(abs((int)n - 256) % 256), + (unsigned char)(abs((int)n - 128) % 256)); + int level = n % 6 + 1; + + wxString label = wxString::Format(_T("") + _T("Item %lu") + _T(""), + level, + clr.GetAsString(wxC2S_HTML_SYNTAX).c_str(), + (unsigned long)n, level); + arr.Add(label); + } + + GetSimpleBox()->Append(arr); + } +} + + // ---------------------------------------------------------------------------- // menu event handlers // ---------------------------------------------------------------------------- +void MyFrame::OnSimpleOrCustomBox(wxCommandEvent& WXUNUSED(event)) +{ + wxWindow *old = m_hlbox; + + // we need to recreate the listbox + CreateBox(); + GetSizer()->Replace(old, m_hlbox); + delete old; + + GetSizer()->Layout(); + Refresh(); +} + void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) { // true is to force the frame to close @@ -318,17 +389,16 @@ void MyFrame::OnSetMargins(wxCommandEvent& WXUNUSED(event)) } } -void MyFrame::OnToggleMulti(wxCommandEvent& event) +void MyFrame::OnToggleMulti(wxCommandEvent& WXUNUSED(event)) { + wxWindow *old = m_hlbox; + // we need to recreate the listbox - wxSizer *sizer = GetSizer(); - sizer->Detach(m_hlbox); - delete m_hlbox; - - m_hlbox = new MyHtmlListBox(this, event.IsChecked()); - sizer->Prepend(m_hlbox, 1, wxGROW); + CreateBox(); + GetSizer()->Replace(old, m_hlbox); + delete old; - sizer->Layout(); + GetSizer()->Layout(); } void MyFrame::OnSelectAll(wxCommandEvent& WXUNUSED(event)) @@ -343,7 +413,8 @@ void MyFrame::OnUpdateUISelectAll(wxUpdateUIEvent& event) void MyFrame::OnUpdateItem(wxCommandEvent& WXUNUSED(event)) { - m_hlbox->UpdateFirstItem(); + if (GetMyBox()) + GetMyBox()->UpdateFirstItem(); } void MyFrame::OnSetBgCol(wxCommandEvent& WXUNUSED(event)) @@ -376,8 +447,11 @@ void MyFrame::OnSetSelBgCol(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnSetSelFgCol(wxCommandEvent& event) { - m_hlbox->SetChangeSelFg(!event.IsChecked()); - m_hlbox->Refresh(); + if (GetMyBox()) + { + GetMyBox()->SetChangeSelFg(!event.IsChecked()); + GetMyBox()->Refresh(); + } } // ---------------------------------------------------------------------------- @@ -422,6 +496,8 @@ void MyFrame::OnLboxSelect(wxCommandEvent& event) // MyHtmlListBox // ============================================================================ +IMPLEMENT_DYNAMIC_CLASS(MyHtmlListBox, wxHtmlListBox) + MyHtmlListBox::MyHtmlListBox(wxWindow *parent, bool multi) : wxHtmlListBox(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, multi ? wxLB_MULTIPLE : 0) @@ -517,3 +593,4 @@ void MyHtmlListBox::OnLinkClicked(size_t WXUNUSED(n), RefreshLine(1); } + diff --git a/samples/xrc/rc/controls.xrc b/samples/xrc/rc/controls.xrc index 71c4e565d6..8ddde48b50 100644 --- a/samples/xrc/rc/controls.xrc +++ b/samples/xrc/rc/controls.xrc @@ -558,6 +558,34 @@ + + + + + 1 + 0 + 0 + 0 + 0 + 0 + + wxALIGN_CENTER|wxALL + 5 + + 250,160 + + + <b>Bold</b> Milk + <i>Rainbow <font color="red">P</font><font color="blue">i</font><font color="yellow">z</font><font color="green">z</font><font color="purple">a</font></i> + <tt>Plain bread</tt> + <font color="orange" size="+1">Orange juice</font> + Paper towels + + + + + + diff --git a/src/generic/htmllbox.cpp b/src/generic/htmllbox.cpp index b104f3c2f5..7e4f8d73e4 100644 --- a/src/generic/htmllbox.cpp +++ b/src/generic/htmllbox.cpp @@ -46,6 +46,9 @@ FORCE_WXHTML_MODULES() // small border always added to the cells: static const wxCoord CELL_BORDER = 2; +const wxChar wxHtmlListBoxNameStr[] = wxT("htmlListBox"); +const wxChar wxSimpleHtmlListBoxNameStr[] = wxT("simpleHtmlListBox"); + // ============================================================================ // private classes // ============================================================================ @@ -541,4 +544,131 @@ void wxHtmlListBox::OnLeftDown(wxMouseEvent& event) } } + +// ---------------------------------------------------------------------------- +// wxSimpleHtmlListBox +// ---------------------------------------------------------------------------- + +bool wxSimpleHtmlListBox::Create(wxWindow *parent, wxWindowID id, + const wxPoint& pos, + const wxSize& size, + int n, const wxString choices[], + long style, + const wxValidator& validator, + const wxString& name) +{ + if (!wxHtmlListBox::Create(parent, id, pos, size, style, name)) + return false; + + SetValidator(validator); + for (int i=0; iIsFrozen()) + RefreshAll(); +} + #endif // wxUSE_HTML diff --git a/src/xrc/xh_htmllbox.cpp b/src/xrc/xh_htmllbox.cpp new file mode 100644 index 0000000000..f351b04cae --- /dev/null +++ b/src/xrc/xh_htmllbox.cpp @@ -0,0 +1,86 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: xh_simplehtmllbox.cpp +// Purpose: XML resource handler for wxSimpleHtmlListBox +// Author: Francesco Montorsi +// Created: 2006/10/21 +// RCS-ID: $Id$ +// Copyright: (c) 2006 Francesco Montorsi +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_XRC && wxUSE_HTML + +#include "wx/xrc/xh_htmllbox.h" + +#include "wx/htmllbox.h" +#include "wx/filesys.h" + +IMPLEMENT_DYNAMIC_CLASS(wxSimpleHtmlListBoxXmlHandler, wxXmlResourceHandler) + +wxSimpleHtmlListBoxXmlHandler::wxSimpleHtmlListBoxXmlHandler() +: wxXmlResourceHandler(), m_insideBox(false) +{ + XRC_ADD_STYLE(wxHLB_DEFAULT_STYLE); + XRC_ADD_STYLE(wxHLB_MULTIPLE); + AddWindowStyles(); +} + +wxObject *wxSimpleHtmlListBoxXmlHandler::DoCreateResource() +{ + if ( m_class == wxT("wxSimpleHtmlListBox")) + { + // find the selection + long selection = GetLong(wxT("selection"), -1); + + // need to build the list of strings from children + m_insideBox = true; + CreateChildrenPrivately(NULL, GetParamNode(wxT("content"))); + m_insideBox = false; + + XRC_MAKE_INSTANCE(control, wxSimpleHtmlListBox) + + control->Create(m_parentAsWindow, + GetID(), + GetPosition(), GetSize(), + strList, + GetStyle(_T("style"), wxHLB_DEFAULT_STYLE), + wxDefaultValidator, + GetName()); + + if (selection != -1) + control->SetSelection(selection); + + SetupWindow(control); + strList.Clear(); // dump the strings + + return control; + } + else + { + // on the inside now. + // handle Label + + // add to the list + wxString str = GetNodeContent(m_node); + if (m_resource->GetFlags() & wxXRC_USE_LOCALE) + str = wxGetTranslation(str, m_resource->GetDomain()); + strList.Add(str); + + return NULL; + } +} + +bool wxSimpleHtmlListBoxXmlHandler::CanHandle(wxXmlNode *node) +{ + return (IsOfClass(node, wxT("wxSimpleHtmlListBox")) || + (m_insideBox && node->GetName() == wxT("item"))); +} + +#endif // wxUSE_XRC && wxUSE_HTML diff --git a/src/xrc/xmlrsall.cpp b/src/xrc/xmlrsall.cpp index 45dfefdd9b..8c5757e1aa 100644 --- a/src/xrc/xmlrsall.cpp +++ b/src/xrc/xmlrsall.cpp @@ -92,6 +92,7 @@ void wxXmlResource::InitAllHandlers() #endif #if wxUSE_HTML AddHandler(new wxHtmlWindowXmlHandler); + AddHandler(new wxSimpleHtmlListBoxXmlHandler); #endif #if wxUSE_HYPERLINKCTRL AddHandler( new wxHyperlinkCtrlXmlHandler); -- 2.45.2