XRC: add GetBitmapBundle function

The function creates wxBitmapBundle from <bitmaps> xrc tag.

Co-authored-by: Vadim Zeitlin <vadim@wxwidgets.org>
This commit is contained in:
Alexander Koshelev
2021-12-31 13:54:41 +03:00
parent 3c7b40e999
commit 612c37f706
5 changed files with 169 additions and 0 deletions

View File

@@ -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. 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
<bitmaps>
<bitmap>new.png</bitmap>
<bitmap>new_2x.png</bitmap>
</bitmaps>
@endcode
While using SVG file you also should specify @c size,
because usually SVG file doesn't have it:
@code
<bitmaps>
<svg>new.svg</svg>
<size>16,16</size>
</bitmaps>
@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 @subsection overview_xrcformat_type_style Style
Style properties (such as window's style or sizer flags) use syntax similar to Style properties (such as window's style or sizer flags) use syntax similar to

View File

@@ -583,6 +583,12 @@ public:
const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER),
wxSize size = wxDefaultSize) wxOVERRIDE; wxSize size = wxDefaultSize) wxOVERRIDE;
// Gets a bitmap bundle from <bitmap> or <bitmaps>.
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. // Gets an icon.
wxIcon GetIcon(const wxString& param = wxT("icon"), wxIcon GetIcon(const wxString& param = wxT("icon"),
const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER),

View File

@@ -90,6 +90,10 @@ public:
virtual wxBitmap GetBitmap(const wxXmlNode* node, virtual wxBitmap GetBitmap(const wxXmlNode* node,
const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER),
wxSize size = wxDefaultSize) = 0; 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"), virtual wxIcon GetIcon(const wxString& param = wxT("icon"),
const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER),
wxSize size = wxDefaultSize) = 0; wxSize size = wxDefaultSize) = 0;
@@ -332,6 +336,13 @@ protected:
{ {
return GetImpl()->GetBitmap(node, defaultArtClient, size); 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"), wxIcon GetIcon(const wxString& param = wxT("icon"),
const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER), const wxArtClient& defaultArtClient = wxASCII_STR(wxART_OTHER),
wxSize size = wxDefaultSize) wxSize size = wxDefaultSize)

View File

@@ -469,6 +469,14 @@ t_bitmap = t_url?,
attribute stock_client { t_identifier}? attribute stock_client { t_identifier}?
)? )?
t_bitmaps = (
element bitmap {_, t_bitmap }+ |
(
element svg {_, t_url } &
element size {_, t_size }
)
)
t_font = ( t_font = (
[xrc:p="o"] element size {_, t_float }* & [xrc:p="o"] element size {_, t_float }* &
[xrc:p="o"] element style {_, ("normal" | "italic" | "slant") }* & [xrc:p="o"] element style {_, ("normal" | "italic" | "slant") }* &

View File

@@ -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 <svg> and <bitmap> tags"
);
}
else if ( HasParam(parambitmap) )
{
wxVector<wxBitmap> 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,
"<size> tag required with <svg> 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<size_t>(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 <svg> or <bitmap> tag"
);
}
m_handler->m_node = oldnode;
return bitmap_bundle;
}
return GetBitmap(paramBitmapName, defaultArtClient, size);
}
wxIcon wxXmlResourceHandlerImpl::GetIcon(const wxString& param, wxIcon wxXmlResourceHandlerImpl::GetIcon(const wxString& param,
const wxArtClient& defaultArtClient, const wxArtClient& defaultArtClient,
wxSize size) wxSize size)