From: Vadim Zeitlin Date: Thu, 7 May 2009 17:29:57 +0000 (+0000) Subject: add support for loading wxListCtrl items and wxImageLists from XRC (closes #10647) X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/326462ae94e4b1d4fb6a8d56875ce0fcbd9d1c33 add support for loading wxListCtrl items and wxImageLists from XRC (closes #10647) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@60548 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/changes.txt b/docs/changes.txt index bf4619c764..9ffd122ebf 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -333,6 +333,7 @@ All: All (GUI): +- Support loading wxListCtrl items and image lists from XRC (Kinaou Hervé). - wxGrid: add possibility to prevent resizing of individual rows/columns. - wxHTML: add support for table borders width (Laurent Humbertclaude). - Added wxMouseEventsManager. diff --git a/docs/doxygen/overviews/xrc.h b/docs/doxygen/overviews/xrc.h index 628dd164fc..7b91f86468 100644 --- a/docs/doxygen/overviews/xrc.h +++ b/docs/doxygen/overviews/xrc.h @@ -384,6 +384,7 @@ This is the XML file (resource.xrc) for the XRC sample. + 0 @@ -397,8 +398,14 @@ This is the XML file (resource.xrc) for the XRC sample. + 1 1 + + 16,16 + + + wxEXPAND diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h index 28845bfd4a..bc07cb0c45 100644 --- a/docs/doxygen/overviews/xrc_format.h +++ b/docs/doxygen/overviews/xrc_format.h @@ -660,11 +660,10 @@ Example: @subsubsection xrc_wxchoicebook wxChoicebook -No additional properties. - A choicebook can have one or more child objects of the @c choicebookpage pseudo-class (similarly to @ref xrc_wxnotebook "wxNotebook" and its -@c notebookpage). @c choicebookpage objects have the following properties: +@c notebookpage) and one child object of the @ref xrc_wximagelist class. +@c choicebookpage objects have the following properties: @beginTable @hdr3col{property, type, description} @@ -672,6 +671,9 @@ pseudo-class (similarly to @ref xrc_wxnotebook "wxNotebook" and its Sheet page's title (required).} @row3col{bitmap, @ref overview_xrcformat_type_bitmap, Bitmap shown alongside the label (default: none).} +@row3col{image, integer, + The zero-based index of the image associated with the item + into the image list.} @row3col{selected, @ref overview_xrcformat_type_bool, Is the page selected initially (only one page can be selected; default: 0)?} @endTable @@ -868,6 +870,42 @@ page. @endTable +@subsubsection xrc_wximagelist wxImageList + +The imagelist can be used as a child object for the following classes: + - @ref xrc_wxchoicebook + - @ref xrc_wxlistbook + - @ref xrc_wxlistctrl + - @ref xrc_wxnotebook + - @ref xrc_wxtreebook + - @ref xrc_wxtreectrl + +The available properties are: + +@beginTable +@hdr3col{property, type, description} +@row3col{bitmap, @ref overview_xrcformat_type_bitmap, + Adds a new image by keeping its optional mask bitmap (see below).} +@row3col{mask, @ref overview_xrcformat_type_bool, + If masks should be created for all images (default: true).} +@row3col{size, @ref overview_xrcformat_type_size, + The size of the images in the list (default: system default icon size)).} +@endTable + +Example: +@code + + 32,32 + + + +@endcode + +In the specific case of the @ref xrc_wxlistctrl, the tag can take the name +@c \ to define the 'small' image list, related to the flag +@c wxIMAGE_LIST_SMALL (see wxListCtrl documentation). + + @subsubsection xrc_wxlistbox wxListBox @beginTable @@ -898,11 +936,10 @@ Example: @subsubsection xrc_wxlistbook wxListbook -No additional properties. - A listbook can have one or more child objects of the @c listbookpage pseudo-class (similarly to @ref xrc_wxnotebook "wxNotebook" and its -@c notebookpage). @c listbookpage objects have the following properties: +@c notebookpage) and one child object of the @ref xrc_wximagelist class. +@c listbookpage objects have the following properties: @beginTable @hdr3col{property, type, description} @@ -910,6 +947,9 @@ pseudo-class (similarly to @ref xrc_wxnotebook "wxNotebook" and its Sheet page's title (required).} @row3col{bitmap, @ref overview_xrcformat_type_bitmap, Bitmap shown alongside the label (default: none).} +@row3col{image, integer, + The zero-based index of the image associated with the item + into the image list.} @row3col{selected, @ref overview_xrcformat_type_bool, Is the page selected initially (only one page can be selected; default: 0)?} @endTable @@ -919,7 +959,79 @@ Each @c listbookpage has exactly one non-toplevel window as its child. @subsubsection xrc_wxlistctrl wxListCtrl -No additional properties. +A listctrl can have one or more child objects of the class @ref xrc_wxlistitem +and one or more objects of the @ref xrc_wximagelist class. The latter is +defined either using @c \ tag for the control with @c wxLC_ICON +style or using @c \ tag for the control with @c +wxLC_SMALL_ICON style. + +@subsubsection xrc_wxlistitem wxListItem + +The @c listitem is a child object for the class @ref xrc_wxlistctrl. +It can have the following properties: + +@beginTable +@hdr3col{property, type, description} +@row3col{align, wxListColumnFormat, + The alignment for the item. + Can be one of @c wxLIST_FORMAT_LEFT, @c wxLIST_FORMAT_RIGHT or + @c wxLIST_FORMAT_CENTRE.} +@row3col{bg, @ref overview_xrcformat_type_colour, + The background color for the item.} +@row3col{bitmap, @ref overview_xrcformat_type_bitmap, + Add a bitmap to the (normal) @ref xrc_wximagelist associated with the + @ref xrc_wxlistctrl parent and associate it with this item. + If the imagelist is not defined it will be created implicitly.} +@row3col{bitmap-small, @ref overview_xrcformat_type_bitmap, + Add a bitmap in the 'small' @ref xrc_wximagelist associated with the + @ref xrc_wxlistctrl parent and associate it with this item. + If the 'small' imagelist is not defined it will be created implicitly.} +@row3col{image, integer, + The zero-based index of the image associated with the item + in the (normal) image list.} +@row3col{image-small, integer, + The zero-based index of the image associated with the item + in the 'small' image list.} +@row3col{col, integer, + The zero-based column index.} +@row3col{data, integer, + The client data for the item.} +@row3col{font, @ref overview_xrcformat_type_font, + The font for the item.} +@row3col{image, integer, + The zero-based index of the image associated with the item + into the image list.} +@row3col{mask, @ref overview_xrcformat_type_style, + The mask indicating which fields of this class are valid. + Can be any combination of the following values: + - wxLIST_MASK_STATE: @b GetState is valid. + - wxLIST_MASK_TEXT: @b GetText is valid. + - wxLIST_MASK_IMAGE: @b GetImage is valid. + - wxLIST_MASK_DATA: @b GetData is valid. + - wxLIST_MASK_WIDTH: @b GetWidth is valid. + - wxLIST_MASK_FORMAT: @b GetFormat is valid. } +@row3col{state, @ref overview_xrcformat_type_style, + The item state flags (note that the valid state flags are influenced + by the value of the @c statemask, see below). + Can be any combination of the following values: + - @c wxLIST_STATE_FOCUSED: The item has the focus. + - @c wxLIST_STATE_SELECTED: The item is selected. + - @c wxLIST_STATE_DONTCARE: Don't care what the state is. Win32 only. + - @c wxLIST_STATE_DROPHILITED: The item is highlighted to receive a drop event. Win32 only. + - @c wxLIST_STATE_CUT: The item is in the cut state. Win32 only. } +@row3col{statemask, bitlist, + A mask indicating which state flags are valid. This is a bitlist of the + flags reported above for the item state. } +@row3col{text, @ref overview_xrcformat_type_string, + The text label (or header for columns) for the item. } +@row3col{textcolour, @ref overview_xrcformat_type_colour, + The text colour for the item. } +@row3col{width, integer, + The column width. } +@endTable + +Notice that the item position can't be specified here, the items are appended +to the list control in order of their appearance. @subsubsection xrc_wxmdiparentframe wxMDIParentFrame @@ -1030,10 +1142,9 @@ class. @subsubsection xrc_wxnotebook wxNotebook -No additional properties. - A notebook can have one or more child objects of the @c notebookpage -pseudo-class. @c notebookpage objects have the following properties: +pseudo-class and one child object of the @ref xrc_wximagelist class. +@c notebookpage objects have the following properties: @beginTable @hdr3col{property, type, description} @@ -1041,6 +1152,9 @@ pseudo-class. @c notebookpage objects have the following properties: Page's title (required).} @row3col{bitmap, @ref overview_xrcformat_type_bitmap, Bitmap shown alongside the label (default: none).} +@row3col{image, integer, + The zero-based index of the image associated with the item + into the image list.} @row3col{selected, @ref overview_xrcformat_type_bool, Is the page selected initially (only one page can be selected; default: 0)?} @endTable @@ -1502,16 +1616,17 @@ Example: @subsubsection xrc_wxtreectrl wxTreeCtrl +A treectrl can have one child object of the @ref xrc_wximagelist class. + No additional properties. @subsubsection xrc_wxtreebook wxTreebook -No additional properties. - A treebook can have one or more child objects of the @c treebookpage pseudo-class (similarly to @ref xrc_wxnotebook "wxNotebook" and its -@c notebookpage). @c treebookpage objects have the following properties: +@c notebookpage) and one child object of the @ref xrc_wximagelist class. +@c treebookpage objects have the following properties: @beginTable @hdr3col{property, type, description} @@ -1521,6 +1636,9 @@ pseudo-class (similarly to @ref xrc_wxnotebook "wxNotebook" and its Sheet page's title (required).} @row3col{bitmap, @ref overview_xrcformat_type_bitmap, Bitmap shown alongside the label (default: none).} +@row3col{image, integer, + The zero-based index of the image associated with the item + into the image list.} @row3col{selected, @ref overview_xrcformat_type_bool, Is the page selected initially (only one page can be selected; default: 0)?} @endTable diff --git a/include/wx/xrc/xh_listc.h b/include/wx/xrc/xh_listc.h index 25847467f1..5ca936f28b 100644 --- a/include/wx/xrc/xh_listc.h +++ b/include/wx/xrc/xh_listc.h @@ -15,14 +15,24 @@ #if wxUSE_XRC && wxUSE_LISTCTRL +class WXDLLIMPEXP_FWD_CORE wxListCtrl; + class WXDLLIMPEXP_XRC wxListCtrlXmlHandler : public wxXmlResourceHandler { - DECLARE_DYNAMIC_CLASS(wxListCtrlXmlHandler) - public: wxListCtrlXmlHandler(); virtual wxObject *DoCreateResource(); virtual bool CanHandle(wxXmlNode *node); + +private: + long Handle_wxListItem(); + wxObject* Handle_wxListCtrl(); + + // gets the items image index in the corresponding image list (normal if + // which is wxIMAGE_LIST_NORMAL or small if it is wxIMAGE_LIST_SMALL) + long GetImageIndex(wxListCtrl *listctrl, int which); + + DECLARE_DYNAMIC_CLASS(wxListCtrlXmlHandler) }; #endif // wxUSE_XRC && wxUSE_LISTCTRL diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h index 3ec28e0da7..26c54f4f25 100644 --- a/include/wx/xrc/xmlres.h +++ b/include/wx/xrc/xmlres.h @@ -34,6 +34,7 @@ class WXDLLIMPEXP_FWD_BASE wxFileName; class WXDLLIMPEXP_FWD_CORE wxIconBundle; +class WXDLLIMPEXP_FWD_CORE wxImageList; class WXDLLIMPEXP_FWD_CORE wxMenu; class WXDLLIMPEXP_FWD_CORE wxMenuBar; class WXDLLIMPEXP_FWD_CORE wxDialog; @@ -442,7 +443,7 @@ protected: // wxXML_ENTITY_NODE name="tag", content="" // |-- wxXML_TEXT_NODE or // wxXML_CDATA_SECTION_NODE name="" content="content" - wxString GetNodeContent(wxXmlNode *node); + wxString GetNodeContent(const wxXmlNode *node); // Check to see if a parameter exists. bool HasParam(const wxString& param); @@ -453,6 +454,9 @@ protected: // Finds the parameter value or returns the empty string. wxString GetParamValue(const wxString& param); + // Returns the parameter value from given node. + wxString GetParamValue(const wxXmlNode* node); + // Add a style flag (e.g. wxMB_DOCKABLE) to the list of flags // understood by this handler. void AddStyle(const wxString& name, int value); @@ -504,15 +508,28 @@ protected: const wxArtClient& defaultArtClient = wxART_OTHER, wxSize size = wxDefaultSize); + // Gets a bitmap from an XmlNode. + wxBitmap GetBitmap(const wxXmlNode* node, + const wxArtClient& defaultArtClient = wxART_OTHER, + wxSize size = wxDefaultSize); + // Gets an icon. wxIcon GetIcon(const wxString& param = wxT("icon"), const wxArtClient& defaultArtClient = wxART_OTHER, wxSize size = wxDefaultSize); + // Gets an icon from an XmlNode. + wxIcon GetIcon(const wxXmlNode* node, + const wxArtClient& defaultArtClient = wxART_OTHER, + wxSize size = wxDefaultSize); + // Gets an icon bundle. wxIconBundle GetIconBundle(const wxString& param, const wxArtClient& defaultArtClient = wxART_OTHER); + // Gets an image list. + wxImageList *GetImageList(const wxString& param = wxT("imagelist")); + #if wxUSE_ANIMATIONCTRL // Gets an animation. wxAnimation GetAnimation(const wxString& param = wxT("animation")); diff --git a/interface/wx/xrc/xmlres.h b/interface/wx/xrc/xmlres.h index c07f44c017..eba741549b 100644 --- a/interface/wx/xrc/xmlres.h +++ b/interface/wx/xrc/xmlres.h @@ -492,6 +492,14 @@ protected: wxBitmap GetBitmap(const wxString& param = "bitmap", const wxArtClient& defaultArtClient = wxART_OTHER, wxSize size = wxDefaultSize); + /** + Gets a bitmap from an XmlNode. + + @since 2.9.1 + */ + wxBitmap GetBitmap(const wxXmlNode* node, + const wxArtClient& defaultArtClient = wxART_OTHER, + wxSize size = wxDefaultSize); /** Gets a bool flag (1, t, yes, on, true are @true, everything else is @false). @@ -532,6 +540,15 @@ protected: const wxArtClient& defaultArtClient = wxART_OTHER, wxSize size = wxDefaultSize); + /** + Gets an icon from an XmlNode. + + @since 2.9.1 + */ + wxIcon GetIcon(const wxXmlNode* node, + const wxArtClient& defaultArtClient = wxART_OTHER, + wxSize size = wxDefaultSize); + /** Returns an icon bundle. @@ -545,6 +562,16 @@ protected: wxIconBundle GetIconBundle(const wxString& param, const wxArtClient& defaultArtClient = wxART_OTHER); + /** + Creates an image list from the @a param markup data. + + @return + The new instance of wxImageList or @NULL if no data is found. + + @since 2.9.1 + */ + wxImageList *GetImageList(const wxString& param = wxT("imagelist")); + /** Gets the integer value from the parameter. */ @@ -570,6 +597,13 @@ protected: */ wxString GetParamValue(const wxString& param); + /** + Returns the node parameter value. + + @since 2.9.1 + */ + wxString GetParamValue(const wxXmlNode* node); + /** Gets the position (may be in dialog units). */ diff --git a/samples/xrc/rc/controls.xrc b/samples/xrc/rc/controls.xrc index d6b92a1d42..c93c7d9cdc 100644 --- a/samples/xrc/rc/controls.xrc +++ b/samples/xrc/rc/controls.xrc @@ -578,19 +578,51 @@ - - 1 - 0 - 0 - 0 - 0 - 0 + wxALIGN_CENTER|wxALL 5 220,160 - + + + + + + wxALIGN_CENTER|wxALL + 5 + + 220,160 + + + Information + + + + Question? + + + + + + wxALIGN_CENTER|wxALL + 5 + + 220,160 + + + 20,20 + + + + + Information + 0 + + + Question? + 1 + diff --git a/src/xrc/xh_choicbk.cpp b/src/xrc/xh_choicbk.cpp index 4b8390db17..16b9afcd25 100644 --- a/src/xrc/xh_choicbk.cpp +++ b/src/xrc/xh_choicbk.cpp @@ -84,6 +84,19 @@ wxObject *wxChoicebookXmlHandler::DoCreateResource() int imgIndex = imgList->Add(bmp); m_choicebook->SetPageImage(m_choicebook->GetPageCount()-1, imgIndex ); } + else if ( HasParam(wxT("image")) ) + { + if ( m_choicebook->GetImageList() ) + { + m_choicebook->SetPageImage(m_choicebook->GetPageCount()-1, + GetLong(wxT("image")) ); + } + else // image without image list? + { + ReportError(n, "image can only be used in conjunction " + "with imagelist"); + } + } } else { @@ -108,6 +121,10 @@ wxObject *wxChoicebookXmlHandler::DoCreateResource() GetStyle(wxT("style")), GetName()); + wxImageList *imagelist = GetImageList(); + if ( imagelist ) + nb->AssignImageList(imagelist); + wxChoicebook *old_par = m_choicebook; m_choicebook = nb; bool old_ins = m_isInside; diff --git a/src/xrc/xh_listbk.cpp b/src/xrc/xh_listbk.cpp index 470be509ba..1d3fb67c58 100644 --- a/src/xrc/xh_listbk.cpp +++ b/src/xrc/xh_listbk.cpp @@ -84,6 +84,19 @@ wxObject *wxListbookXmlHandler::DoCreateResource() int imgIndex = imgList->Add(bmp); m_listbook->SetPageImage(m_listbook->GetPageCount()-1, imgIndex ); } + else if ( HasParam(wxT("image")) ) + { + if ( m_listbook->GetImageList() ) + { + m_listbook->SetPageImage(m_listbook->GetPageCount()-1, + GetLong(wxT("image")) ); + } + else // image without image list? + { + ReportError(n, "image can only be used in conjunction " + "with imagelist"); + } + } } else { @@ -108,6 +121,10 @@ wxObject *wxListbookXmlHandler::DoCreateResource() GetStyle(wxT("style")), GetName()); + wxImageList *imagelist = GetImageList(); + if ( imagelist ) + nb->AssignImageList(imagelist); + wxListbook *old_par = m_listbook; m_listbook = nb; bool old_ins = m_isInside; diff --git a/src/xrc/xh_listc.cpp b/src/xrc/xh_listc.cpp index 64eec4e746..db99373ef7 100644 --- a/src/xrc/xh_listc.cpp +++ b/src/xrc/xh_listc.cpp @@ -24,6 +24,7 @@ #endif #include "wx/listctrl.h" +#include "wx/imaglist.h" IMPLEMENT_DYNAMIC_CLASS(wxListCtrlXmlHandler, wxXmlResourceHandler) @@ -31,6 +32,23 @@ IMPLEMENT_DYNAMIC_CLASS(wxListCtrlXmlHandler, wxXmlResourceHandler) wxListCtrlXmlHandler::wxListCtrlXmlHandler() : wxXmlResourceHandler() { + // wxListItem styles + XRC_ADD_STYLE(wxLIST_FORMAT_LEFT); + XRC_ADD_STYLE(wxLIST_FORMAT_RIGHT); + XRC_ADD_STYLE(wxLIST_FORMAT_CENTRE); + XRC_ADD_STYLE(wxLIST_MASK_STATE); + XRC_ADD_STYLE(wxLIST_MASK_TEXT); + XRC_ADD_STYLE(wxLIST_MASK_IMAGE); + XRC_ADD_STYLE(wxLIST_MASK_DATA); + XRC_ADD_STYLE(wxLIST_MASK_WIDTH); + XRC_ADD_STYLE(wxLIST_MASK_FORMAT); + XRC_ADD_STYLE(wxLIST_STATE_DONTCARE); + XRC_ADD_STYLE(wxLIST_STATE_DROPHILITED); + XRC_ADD_STYLE(wxLIST_STATE_FOCUSED); + XRC_ADD_STYLE(wxLIST_STATE_SELECTED); + XRC_ADD_STYLE(wxLIST_STATE_CUT); + + // wxListCtrl styles XRC_ADD_STYLE(wxLC_LIST); XRC_ADD_STYLE(wxLC_REPORT); XRC_ADD_STYLE(wxLC_ICON); @@ -52,6 +70,73 @@ wxListCtrlXmlHandler::wxListCtrlXmlHandler() } wxObject *wxListCtrlXmlHandler::DoCreateResource() +{ + if (m_class == wxT("listitem")) + { + Handle_wxListItem(); + return m_parentAsWindow; + } + else + return Handle_wxListCtrl(); +} + +bool wxListCtrlXmlHandler::CanHandle(wxXmlNode *node) +{ + return IsOfClass(node, wxT("wxListCtrl")) || + IsOfClass(node, wxT("listitem")); +} + +long wxListCtrlXmlHandler::Handle_wxListItem() +{ + wxListCtrl * const list = wxDynamicCast(m_parentAsWindow, wxListCtrl); + wxCHECK_MSG( list, -1, "must have wxListCtrl parent" ); + + wxListItem item; + + if (HasParam(wxT("align"))) + item.SetAlign((wxListColumnFormat)GetStyle(wxT("align"))); + if (HasParam(wxT("bg"))) + item.SetBackgroundColour(GetColour(wxT("bg"))); + if (HasParam(wxT("col"))) + item.SetColumn((int)GetLong(wxT("col"))); + if (HasParam(wxT("data"))) + item.SetData(GetLong(wxT("data"))); + if (HasParam(wxT("font"))) + item.SetFont(GetFont()); + if (HasParam(wxT("mask"))) + item.SetMask(GetStyle(wxT("mask"))); + if (HasParam(wxT("state"))) + item.SetState(GetStyle(wxT("state"))); + if (HasParam(wxT("statemask"))) + item.SetStateMask(GetStyle(wxT("statemask"))); + if (HasParam(wxT("text"))) + item.SetText(GetText(wxT("text"))); + if (HasParam(wxT("textcolour"))) + item.SetTextColour(GetColour(wxT("textcolour"))); + if (HasParam(wxT("textcolor"))) + item.SetTextColour(GetColour(wxT("textcolor"))); + if (HasParam(wxT("width"))) + item.SetWidth((int)GetLong(wxT("width"))); + + // the list control icon style, may be 0 + int image; + if ( list->HasFlag(wxLC_ICON) ) + image = GetImageIndex(list, wxIMAGE_LIST_NORMAL); + else if ( list->HasFlag(wxLC_SMALL_ICON) ) + image = GetImageIndex(list, wxIMAGE_LIST_SMALL); + else + image = wxNOT_FOUND; + + if ( image != wxNOT_FOUND ) + item.SetImage(image); + + // append the list item to the control + item.SetId(list->GetItemCount()); + + return list->InsertItem(item); +} + +wxObject* wxListCtrlXmlHandler::Handle_wxListCtrl() { XRC_MAKE_INSTANCE(list, wxListCtrl) @@ -62,16 +147,80 @@ wxObject *wxListCtrlXmlHandler::DoCreateResource() wxDefaultValidator, GetName()); - // FIXME: add columns definition + // we can optionally have normal and/or small image lists + wxImageList *imagelist; + imagelist = GetImageList(wxT("imagelist")); + if ( imagelist ) + list->AssignImageList(imagelist, wxIMAGE_LIST_NORMAL); + imagelist = GetImageList(wxT("imagelist-small")); + if ( imagelist ) + list->AssignImageList(imagelist, wxIMAGE_LIST_SMALL); + CreateChildrenPrivately(list); SetupWindow(list); return list; } -bool wxListCtrlXmlHandler::CanHandle(wxXmlNode *node) +long wxListCtrlXmlHandler::GetImageIndex(wxListCtrl *listctrl, int which) { - return IsOfClass(node, wxT("wxListCtrl")); + // use different tag names depending on whether we need a normal or small + // image + wxString + bmpParam("bitmap"), + imgParam("image"); + switch ( which ) + { + case wxIMAGE_LIST_SMALL: + bmpParam += "-small"; + imgParam += "-small"; + break; + + case wxIMAGE_LIST_NORMAL: + // nothing to do + break; + + default: + wxFAIL_MSG( "unsupported image list kind" ); + return wxNOT_FOUND; + } + + // look for either bitmap or image tags + int imgIndex = wxNOT_FOUND; + if ( HasParam(bmpParam) ) + { + // we implicitly construct an image list containing the specified + // bitmaps + wxBitmap bmp = GetBitmap(bmpParam, wxART_OTHER); + + // create the image list on demand for the first bitmap + wxImageList *imgList = listctrl->GetImageList(which); + if ( !imgList ) + { + imgList = new wxImageList( bmp.GetWidth(), bmp.GetHeight() ); + listctrl->AssignImageList( imgList, which ); + } + + imgIndex = imgList->Add(bmp); + } + + if ( HasParam(imgParam) ) + { + if ( imgIndex != wxNOT_FOUND ) + { + // TODO: we should really check that only bitmap or only image tags + // are used across all items of the control, not just in this + // one + ReportError(wxString::Format( + "listitem %s attribute ignored because %s is also specified", + bmpParam, imgParam)); + } + + // just use the specified index directly + imgIndex = GetLong(imgParam); + } + + return imgIndex; } #endif // wxUSE_XRC && wxUSE_LISTCTRL diff --git a/src/xrc/xh_notbk.cpp b/src/xrc/xh_notbk.cpp index 2908984fbf..c683fbc273 100644 --- a/src/xrc/xh_notbk.cpp +++ b/src/xrc/xh_notbk.cpp @@ -87,6 +87,19 @@ wxObject *wxNotebookXmlHandler::DoCreateResource() int imgIndex = imgList->Add(bmp); m_notebook->SetPageImage(m_notebook->GetPageCount()-1, imgIndex ); } + else if ( HasParam(wxT("image")) ) + { + if ( m_notebook->GetImageList() ) + { + m_notebook->SetPageImage(m_notebook->GetPageCount()-1, + GetLong(wxT("image")) ); + } + else // image without image list? + { + ReportError(n, "image can only be used in conjunction " + "with imagelist"); + } + } } else { @@ -111,6 +124,10 @@ wxObject *wxNotebookXmlHandler::DoCreateResource() GetStyle(wxT("style")), GetName()); + wxImageList *imagelist = GetImageList(); + if ( imagelist ) + nb->AssignImageList(imagelist); + SetupWindow(nb); wxNotebook *old_par = m_notebook; diff --git a/src/xrc/xh_tree.cpp b/src/xrc/xh_tree.cpp index 1591d626a7..ef66aa4334 100644 --- a/src/xrc/xh_tree.cpp +++ b/src/xrc/xh_tree.cpp @@ -55,6 +55,10 @@ wxObject *wxTreeCtrlXmlHandler::DoCreateResource() wxDefaultValidator, GetName()); + wxImageList *imagelist = GetImageList(); + if ( imagelist ) + tree->AssignImageList(imagelist); + SetupWindow(tree); return tree; diff --git a/src/xrc/xh_treebk.cpp b/src/xrc/xh_treebk.cpp index cd199b7bb6..efc5c36f99 100644 --- a/src/xrc/xh_treebk.cpp +++ b/src/xrc/xh_treebk.cpp @@ -61,6 +61,10 @@ wxObject *wxTreebookXmlHandler::DoCreateResource() GetStyle(wxT("style")), GetName()); + wxImageList *imagelist = GetImageList(); + if ( imagelist ) + tbk->AssignImageList(imagelist); + wxTreebook * old_par = m_tbk; m_tbk = tbk; @@ -117,6 +121,18 @@ wxObject *wxTreebookXmlHandler::DoCreateResource() } imgIndex = imgList->Add(bmp); } + else if ( HasParam(wxT("image")) ) + { + if ( m_tbk->GetImageList() ) + { + imgIndex = GetLong(wxT("image")); + } + else // image without image list? + { + ReportError(n, "image can only be used in conjunction " + "with imagelist"); + } + } // then add the page to the corresponding parent if( depth < m_treeContext.GetCount() ) diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index e9942ba285..988d73027a 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -44,6 +44,7 @@ #include "wx/fontenum.h" #include "wx/fontmap.h" #include "wx/artprov.h" +#include "wx/imaglist.h" #include "wx/dir.h" #include "wx/xml/xml.h" @@ -1332,10 +1333,17 @@ bool GetStockArtAttrs(const wxXmlNode *paramNode, wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, const wxArtClient& defaultArtClient, wxSize size) +{ + return GetBitmap(GetParamNode(param), defaultArtClient, size); +} + +wxBitmap wxXmlResourceHandler::GetBitmap(const wxXmlNode* node, + const wxArtClient& defaultArtClient, + wxSize size) { /* If the bitmap is specified as stock item, query wxArtProvider for it: */ wxString art_id, art_client; - if ( GetStockArtAttrs(GetParamNode(param), defaultArtClient, + if ( GetStockArtAttrs(node, defaultArtClient, art_id, art_client) ) { wxBitmap stockArt(wxArtProvider::GetBitmap(art_id, art_client, size)); @@ -1344,7 +1352,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, } /* ...or load the bitmap from file: */ - wxString name = GetParamValue(param); + wxString name = GetParamValue(node); if (name.empty()) return wxNullBitmap; #if wxUSE_FILESYSTEM wxFSFile *fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE); @@ -1352,7 +1360,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, { ReportParamError ( - param, + node->GetName(), wxString::Format("cannot open bitmap resource \"%s\"", name) ); return wxNullBitmap; @@ -1367,7 +1375,7 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, { ReportParamError ( - param, + node->GetName(), wxString::Format("cannot create bitmap from \"%s\"", name) ); return wxNullBitmap; @@ -1380,12 +1388,20 @@ wxBitmap wxXmlResourceHandler::GetBitmap(const wxString& param, wxIcon wxXmlResourceHandler::GetIcon(const wxString& param, const wxArtClient& defaultArtClient, wxSize size) +{ + return GetIcon(GetParamNode(param), defaultArtClient, size); +} + +wxIcon wxXmlResourceHandler::GetIcon(const wxXmlNode* node, + const wxArtClient& defaultArtClient, + wxSize size) { wxIcon icon; - icon.CopyFromBitmap(GetBitmap(param, defaultArtClient, size)); + icon.CopyFromBitmap(GetBitmap(node, defaultArtClient, size)); return icon; } + wxIconBundle wxXmlResourceHandler::GetIconBundle(const wxString& param, const wxArtClient& defaultArtClient) { @@ -1434,6 +1450,46 @@ wxIconBundle wxXmlResourceHandler::GetIconBundle(const wxString& param, } +wxImageList *wxXmlResourceHandler::GetImageList(const wxString& param) +{ + wxXmlNode * const imagelist_node = GetParamNode(param); + if ( !imagelist_node ) + return NULL; + + wxXmlNode * const oldnode = m_node; + m_node = imagelist_node; + + // size + wxSize size = GetSize(); + size.SetDefaults(wxSize(wxSystemSettings::GetMetric(wxSYS_ICON_X), + wxSystemSettings::GetMetric(wxSYS_ICON_Y))); + + // mask: true by default + bool mask = HasParam(wxT("mask")) ? GetBool(wxT("mask"), true) : true; + + // now we have everything we need to create the image list + wxImageList *imagelist = new wxImageList(size.x, size.y, mask); + + // add images + wxString parambitmap = wxT("bitmap"); + if ( HasParam(parambitmap) ) + { + wxXmlNode *n = m_node->GetChildren(); + while (n) + { + if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == parambitmap) + { + // add icon instead of bitmap to keep the bitmap mask + imagelist->Add(GetIcon(n)); + } + n = n->GetNext(); + } + } + + m_node = oldnode; + return imagelist; +} + wxXmlNode *wxXmlResourceHandler::GetParamNode(const wxString& param) { wxCHECK_MSG(m_node, NULL, wxT("You can't access handler data before it was initialized!")); @@ -1464,9 +1520,9 @@ bool wxXmlResourceHandler::IsOfClass(wxXmlNode *node, const wxString& classname) -wxString wxXmlResourceHandler::GetNodeContent(wxXmlNode *node) +wxString wxXmlResourceHandler::GetNodeContent(const wxXmlNode *node) { - wxXmlNode *n = node; + const wxXmlNode *n = node; if (n == NULL) return wxEmptyString; n = n->GetChildren(); @@ -1490,6 +1546,10 @@ wxString wxXmlResourceHandler::GetParamValue(const wxString& param) return GetNodeContent(GetParamNode(param)); } +wxString wxXmlResourceHandler::GetParamValue(const wxXmlNode* node) +{ + return GetNodeContent(node); +} wxSize wxXmlResourceHandler::GetSize(const wxString& param,