diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h index 0c676c36fe..ed9a8627e4 100644 --- a/docs/doxygen/overviews/xrc_format.h +++ b/docs/doxygen/overviews/xrc_format.h @@ -384,6 +384,42 @@ If both specifications are provided, then @c stock_id is used if it is recognized by wxArtProvider and the provided bitmap file is used as a fallback. +@subsection overview_xrcformat_type_bitmaps Multi-resolution bitmap + +BitmapBundle properties contain specification of a set of bitmaps or SVG file, +which are mutually exclusive. +Example with a set of bitmaps: +@code + + new.png + new_2x.png + +@endcode +While using SVG file you also should specify @c size, +because usually SVG file doesn't have it: +@code + + new.svg + 16,16 + +@endcode + +@beginTable +@hdr3col{property, type, description} +@row3col{bitmap, @ref overview_xrcformat_type_bitmap, + Adds a new bitmap to BitmapBundle. Unlike normal object properties, + @c bitmap may be used more than once to add multiple bitmaps. + Mutually exclusive with @c svg.} +@row3col{svg, @ref overview_xrcformat_type_url, + SVG file to create BitmapBundle. Require @c size. + Mutually exclusive with @c bitmap.} +@row3col{size, @ref overview_xrcformat_type_size, + The default size to return from GetDefaultSize() for this bundle. + As SVG images usually don't have any natural default size, + it should be provided when creating the bundle with @c svg.} +@endTable + + @subsection overview_xrcformat_type_style Style Style properties (such as window's style or sizer flags) use syntax similar to diff --git a/include/wx/xrc/xmlres.h b/include/wx/xrc/xmlres.h index 603b35eff4..ddf2e51ce6 100644 --- a/include/wx/xrc/xmlres.h +++ b/include/wx/xrc/xmlres.h @@ -583,6 +583,12 @@ public: const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), wxSize size = wxDefaultSize) wxOVERRIDE; + // Gets a bitmap bundle from or . + wxBitmapBundle GetBitmapOrBitmaps(const wxString& paramBitmapName = wxT("bitmap"), + const wxString& paramBitmapsName = wxT("bitmaps"), + const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), + wxSize size = wxDefaultSize) wxOVERRIDE; + // Gets an icon. wxIcon GetIcon(const wxString& param = wxT("icon"), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), diff --git a/include/wx/xrc/xmlreshandler.h b/include/wx/xrc/xmlreshandler.h index 7f132b99a9..e1f0825ce2 100644 --- a/include/wx/xrc/xmlreshandler.h +++ b/include/wx/xrc/xmlreshandler.h @@ -90,6 +90,10 @@ public: virtual wxBitmap GetBitmap(const wxXmlNode* node, const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), wxSize size = wxDefaultSize) = 0; + virtual wxBitmapBundle GetBitmapOrBitmaps(const wxString& paramBitmapName = wxT("bitmap"), + const wxString& paramBitmapsName = wxT("bitmaps"), + const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), + wxSize size = wxDefaultSize) = 0; virtual wxIcon GetIcon(const wxString& param = wxT("icon"), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), wxSize size = wxDefaultSize) = 0; @@ -332,6 +336,13 @@ protected: { return GetImpl()->GetBitmap(node, defaultArtClient, size); } + wxBitmapBundle GetBitmapOrBitmaps(const wxString& paramBitmapName = wxT("bitmap"), + const wxString& paramBitmapsName = wxT("bitmaps"), + const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), + wxSize size = wxDefaultSize) + { + return GetImpl()->GetBitmapOrBitmaps(paramBitmapName, paramBitmapsName, defaultArtClient, size); + } wxIcon GetIcon(const wxString& param = wxT("icon"), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), wxSize size = wxDefaultSize) diff --git a/misc/schema/xrc_schema.rnc b/misc/schema/xrc_schema.rnc index 742190bc0c..bc9fb38ebd 100644 --- a/misc/schema/xrc_schema.rnc +++ b/misc/schema/xrc_schema.rnc @@ -469,6 +469,14 @@ t_bitmap = t_url?, attribute stock_client { t_identifier}? )? +t_bitmaps = ( + element bitmap {_, t_bitmap }+ | + ( + element svg {_, t_url } & + element size {_, t_size } + ) + ) + t_font = ( [xrc:p="o"] element size {_, t_float }* & [xrc:p="o"] element style {_, ("normal" | "italic" | "slant") }* & diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index 046b0004c4..30dc328165 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -1925,6 +1925,114 @@ wxBitmap wxXmlResourceHandlerImpl::GetBitmap(const wxXmlNode* node, } +wxBitmapBundle wxXmlResourceHandlerImpl::GetBitmapOrBitmaps(const wxString& paramBitmapName, + const wxString& paramBitmapsName, + const wxArtClient& defaultArtClient, + wxSize size) +{ + if ( HasParam(paramBitmapsName) ) + { + wxBitmapBundle bitmap_bundle; + wxXmlNode * const bitmaps_node = GetParamNode(paramBitmapsName); + if ( !bitmaps_node ) + return bitmap_bundle; + + wxXmlNode * const oldnode = m_handler->m_node; + m_handler->m_node = bitmaps_node; + + wxString parambitmap = wxT("bitmap"); + wxString paramsvg = wxT("svg"); + if ( HasParam(parambitmap) && HasParam(paramsvg) ) + { + ReportParamError + ( + paramBitmapsName, + "cannot contain both and tags" + ); + } + else if ( HasParam(parambitmap) ) + { + wxVector bitmaps; + wxXmlNode *n = m_handler->m_node->GetChildren(); + while (n) + { + if (n->GetType() == wxXML_ELEMENT_NODE && n->GetName() == parambitmap) + { + bitmaps.push_back(GetBitmap(n, defaultArtClient, size)); + } + n = n->GetNext(); + } + bitmap_bundle = wxBitmapBundle::FromBitmaps(bitmaps); + } + else if ( HasParam(paramsvg) ) + { + wxString paramsize = wxT("size"); + if ( !HasParam(paramsize) ) + { + ReportParamError + ( + paramBitmapsName, + " tag required with tag" + ); + } + else + { +#ifdef wxHAS_SVG + wxXmlNode* const svg_node = GetParamNode(paramsvg); + wxSize svg_size = GetSize(paramsize); + wxString name = GetFilePath(svg_node); +#if wxUSE_FILESYSTEM + wxFSFile* fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE); + if (fsfile == NULL) + { + ReportParamError + ( + paramBitmapsName, + wxString::Format("cannot open SVG resource \"%s\"", name) + ); + } + else + { + wxInputStream* s = fsfile->GetStream(); + const size_t len = static_cast(s->GetLength()); + wxCharBuffer buf(len); + char* const ptr = buf.data(); + + if (s->ReadAll(ptr, len)) + { + bitmap_bundle = wxBitmapBundle::FromSVG(ptr, svg_size); + } + delete fsfile; + } +#else + bitmap_bundle = wxBitmapBundle::FromSVGFile(name, svg_size); +#endif +#else // !wxHAS_SVG + ReportParamError + ( + paramBitmapsName, + "SVG bitmaps are not supported in this build of the library" + ); +#endif // wxHAS_SVG/!wxHAS_SVG + } + } + else + { + ReportParamError + ( + paramBitmapsName, + "should contain or tag" + ); + } + + m_handler->m_node = oldnode; + return bitmap_bundle; + } + + return GetBitmap(paramBitmapName, defaultArtClient, size); +} + + wxIcon wxXmlResourceHandlerImpl::GetIcon(const wxString& param, const wxArtClient& defaultArtClient, wxSize size)