diff --git a/docs/doxygen/overviews/xrc_format.h b/docs/doxygen/overviews/xrc_format.h index 0c676c36fe..c1e96c37c4 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 @@ -876,7 +912,9 @@ Example: @row3col{label, @ref overview_xrcformat_type_text, Label to display on the button (may be omitted if only the bitmap or stock ID is used).} @row3col{bitmap, @ref overview_xrcformat_type_bitmap, - Bitmap to display in the button (optional).} + Bitmap to display in the button (optional). Mutually exclusive with @c bitmaps.} +@row3col{bitmaps, @ref overview_xrcformat_type_bitmaps, + BitmapBundle to display in the button (optional). Mutually exclusive with @c bitmap.} @row3col{bitmapposition, @c wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, Position of the bitmap in the button, see wxButton::SetBitmapPosition() (default: wxLEFT).} @row3col{default, @ref overview_xrcformat_type_bool, @@ -1003,7 +1041,9 @@ just as @ref xrc_wxbutton wxButton. @row3col{note, @ref overview_xrcformat_type_text, Second line of text describing the action performed when the button is pressed (default: none). } @row3col{bitmap, @ref overview_xrcformat_type_bitmap, - Bitmap to display in the button (optional).} + Bitmap to display in the button (optional). Mutually exclusive with @c bitmaps.} +@row3col{bitmaps, @ref overview_xrcformat_type_bitmaps, + BitmapBundle to display in the button (optional). Mutually exclusive with @c bitmap.} @row3col{default, @ref overview_xrcformat_type_bool, Should this button be the default button in dialog (default: 0)?} @endTable @@ -2109,10 +2149,14 @@ child and the second one for right/bottom child window. @subsubsection xrc_wxstaticbitmap wxStaticBitmap +wxStaticBitmap requires @c bitmap or @c bitmaps tag. + @beginTable @hdr3col{property, type, description} @row3col{bitmap, @ref overview_xrcformat_type_bitmap, - Bitmap to display (required).} + Bitmap to display. Mutually exclusive with @c bitmaps.} +@row3col{bitmaps, @ref overview_xrcformat_type_bitmaps, + BitmapBundle to display. Mutually exclusive with @c bitmap.} @endTable @subsubsection xrc_wxstaticbox wxStaticBox @@ -2228,9 +2272,13 @@ properties: @beginTable @hdr3col{property, type, description} @row3col{bitmap, @ref overview_xrcformat_type_bitmap, - Tool's bitmap (default: empty).} + Tool's bitmap (default: empty). Mutually exclusive with @c bitmaps.} @row3col{bitmap2, @ref overview_xrcformat_type_bitmap, Bitmap for disabled tool (default: derived from @c bitmap).} +@row3col{bitmaps, @ref overview_xrcformat_type_bitmaps, + Tool's BitmapBundle. Mutually exclusive with @c bitmap.} +@row3col{bitmaps2, @ref overview_xrcformat_type_bitmaps, + BitmapBundle for disabled tool (default: derived from @c bitmaps).} @row3col{label, @ref overview_xrcformat_type_text, Label to display on the tool (default: no label).} @row3col{radio, @ref overview_xrcformat_type_bool, 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..8a61d8f746 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") }* & @@ -734,7 +742,10 @@ wxButton = stdObjectNodeAttributes & stdWindowProperties & [xrc:p="o"] element label {_, t_text }* & - [xrc:p="o"] element bitmap {_, t_bitmap }* & + [xrc:p="o"]( + element bitmap {_, t_bitmap } | + element bitmaps {_, t_bitmaps } + )* & [xrc:p="o"] element bitmapposition {_, t_direction }* & [xrc:p="o"] element default {_, t_bool }* } @@ -816,7 +827,10 @@ wxCommandLinkButton = stdWindowProperties & [xrc:p="important"] element label {_, t_text }* & [xrc:p="o"] element note {_, t_text }* & - [xrc:p="o"] element bitmap {_, t_bitmap }* & + [xrc:p="o"]( + element bitmap {_, t_bitmap } | + element bitmaps {_, t_bitmaps } + )* & [xrc:p="o"] element default {_, t_bool }* } @@ -1548,7 +1562,10 @@ wxStaticBitmap = attribute class { "wxStaticBitmap" } & stdObjectNodeAttributes & stdWindowProperties & - element bitmap {_, t_bitmap } + ( + element bitmap {_, t_bitmap } | + element bitmaps {_, t_bitmaps } + ) } @@ -1633,8 +1650,16 @@ wxToolBar_tool = element object { attribute class { "tool" } & stdObjectNodeAttributes & - [xrc:p="important"] element bitmap {_, t_bitmap }* & - [xrc:p="o"] element bitmap2 {_, t_bitmap }* & + ( + ( + [xrc:p="important"] element bitmap {_, t_bitmap }* & + [xrc:p="o"] element bitmap2 {_, t_bitmap }* + ) | + ( + [xrc:p="important"] element bitmaps {_, t_bitmaps }* & + [xrc:p="o"] element bitmaps2 {_, t_bitmaps }* + ) + ) & [xrc:p="o"] element label {_, t_text }* & [xrc:p="o"] element tooltip {_, t_text }* & [xrc:p="o"] element longhelp {_, t_text }* & diff --git a/src/xrc/xh_bttn.cpp b/src/xrc/xh_bttn.cpp index 5fa3b8867d..328866d7a3 100644 --- a/src/xrc/xh_bttn.cpp +++ b/src/xrc/xh_bttn.cpp @@ -47,10 +47,10 @@ wxObject *wxButtonXmlHandler::DoCreateResource() if (GetBool(wxT("default"), 0)) button->SetDefault(); - if ( GetParamNode("bitmap") ) + wxBitmapBundle bb = GetBitmapOrBitmaps("bitmap", "bitmaps", wxART_BUTTON); + if ( bb.IsOk() ) { - button->SetBitmap(GetBitmap("bitmap", wxART_BUTTON), - GetDirection("bitmapposition")); + button->SetBitmap(bb); } SetupWindow(button); diff --git a/src/xrc/xh_cmdlinkbn.cpp b/src/xrc/xh_cmdlinkbn.cpp index 06b8a65744..b16288662b 100644 --- a/src/xrc/xh_cmdlinkbn.cpp +++ b/src/xrc/xh_cmdlinkbn.cpp @@ -46,10 +46,10 @@ wxObject *wxCommandLinkButtonXmlHandler::DoCreateResource() if (GetBool(wxT("default"), 0)) button->SetDefault(); - if ( GetParamNode("bitmap") ) + wxBitmapBundle bb = GetBitmapOrBitmaps("bitmap", "bitmaps", wxART_BUTTON); + if ( bb.IsOk() ) { - button->SetBitmap(GetBitmap("bitmap", wxART_BUTTON), - GetDirection("bitmapposition")); + button->SetBitmap(bb); } SetupWindow(button); diff --git a/src/xrc/xh_stbmp.cpp b/src/xrc/xh_stbmp.cpp index 2cb248b24c..e0a06ffeaa 100644 --- a/src/xrc/xh_stbmp.cpp +++ b/src/xrc/xh_stbmp.cpp @@ -33,7 +33,7 @@ wxObject *wxStaticBitmapXmlHandler::DoCreateResource() bmp->Create(m_parentAsWindow, GetID(), - GetBitmap(wxT("bitmap"), wxART_OTHER, GetSize()), + GetBitmapOrBitmaps(wxT("bitmap"), wxT("bitmaps"), wxART_OTHER, GetSize()), GetPosition(), GetSize(), GetStyle(), GetName()); diff --git a/src/xrc/xh_toolb.cpp b/src/xrc/xh_toolb.cpp index 8348c55433..26e7265021 100644 --- a/src/xrc/xh_toolb.cpp +++ b/src/xrc/xh_toolb.cpp @@ -126,8 +126,8 @@ wxObject *wxToolBarXmlHandler::DoCreateResource() ( GetID(), GetText(wxT("label")), - GetBitmap(wxT("bitmap"), wxART_TOOLBAR, m_toolSize), - GetBitmap(wxT("bitmap2"), wxART_TOOLBAR, m_toolSize), + GetBitmapOrBitmaps(wxT("bitmap"), wxT("bitmaps"), wxART_TOOLBAR, m_toolSize), + GetBitmapOrBitmaps(wxT("bitmap2"), wxT("bitmaps2"), wxART_TOOLBAR, m_toolSize), kind, GetText(wxT("tooltip")), GetText(wxT("longhelp")) 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)