Add support for specifying high DPI animations in XRC

Deprecate wxXmlResourceHandler::GetAnimation() function which returns
just a single animation and add a new GetAnimations() replacing it.

Use the new function in wxAnimationCtrl XRC handler to pass all the
animations defined in the XRC file to the control.
This commit is contained in:
Vadim Zeitlin 2023-08-25 20:19:56 +02:00
parent 27e80f81b4
commit cb99932114
5 changed files with 105 additions and 40 deletions

View file

@ -653,7 +653,9 @@ controls cannot have children.
@beginTable
@hdr3col{property, type, description}
@row3col{animation, @ref overview_xrcformat_type_url,
Animation file to load into the control (default: none).}
Animation file to load into the control or, since wxWindow 3.3.0, multiple
semicolon-separated files in order of increasing size, corresponding to
multiple versions of the animation for different resolutions (default: none).}
@row3col{inactive-bitmap, @ref overview_xrcformat_type_bitmap,
Bitmap to use when not playing the animation (default: the default).}
@endTable

View file

@ -621,11 +621,19 @@ public:
wxImageList *GetImageList(const wxString& param = wxT("imagelist")) override;
#if wxUSE_ANIMATIONCTRL
// Get all the animations defined in the given parameter which may contain
// more than one semicolon-separated paths.
wxAnimationBundle GetAnimations(const wxString& param = wxT("animation"),
wxAnimationCtrlBase* ctrl = nullptr) override;
#if WXWIN_COMPATIBILITY_3_2
wxDEPRECATED_MSG("Use GetAnimations() instead")
// Gets an animation creating it using the provided control (so that it
// will be compatible with it) if any.
wxAnimation* GetAnimation(const wxString& param = wxT("animation"),
wxAnimationCtrlBase* ctrl = nullptr) override;
#endif
#endif // WXWIN_COMPATIBILITY_3_2
#endif // wxUSE_ANIMATIONCTRL
// Gets a font.
wxFont GetFont(const wxString& param = wxT("font"), wxWindow* parent = nullptr) override;

View file

@ -22,6 +22,7 @@
#include "wx/window.h"
class WXDLLIMPEXP_FWD_CORE wxAnimation;
class WXDLLIMPEXP_FWD_CORE wxAnimationBundle;
class WXDLLIMPEXP_FWD_CORE wxAnimationCtrlBase;
class WXDLLIMPEXP_FWD_XML wxXmlNode;
@ -109,9 +110,15 @@ public:
virtual wxImageList *GetImageList(const wxString& param = wxT("imagelist")) = 0;
#if wxUSE_ANIMATIONCTRL
virtual wxAnimationBundle GetAnimations(const wxString& param = wxT("animation"),
wxAnimationCtrlBase* ctrl = nullptr) = 0;
#if WXWIN_COMPATIBILITY_3_2
wxDEPRECATED_BUT_USED_INTERNALLY_MSG("Use GetAnimations() instead")
virtual wxAnimation* GetAnimation(const wxString& param = wxT("animation"),
wxAnimationCtrlBase* ctrl = nullptr) = 0;
#endif
#endif // WXWIN_COMPATIBILITY_3_2
#endif // wxUSE_ANIMATIONCTRL
virtual wxFont GetFont(const wxString& param = wxT("font"), wxWindow* parent = nullptr) = 0;
virtual bool GetBoolAttr(const wxString& attr, bool defaultv) = 0;
@ -377,12 +384,14 @@ protected:
}
#if wxUSE_ANIMATIONCTRL
wxAnimationBundle GetAnimations(const wxString& param = wxT("animation"),
wxAnimationCtrlBase* ctrl = nullptr);
#if WXWIN_COMPATIBILITY_3_2
wxAnimation* GetAnimation(const wxString& param = wxT("animation"),
wxAnimationCtrlBase* ctrl = nullptr)
{
return GetImpl()->GetAnimation(param, ctrl);
}
#endif
wxAnimationCtrlBase* ctrl = nullptr);
#endif // WXWIN_COMPATIBILITY_3_2
#endif // wxUSE_ANIMATIONCTRL
wxFont GetFont(const wxString& param = wxT("font"),
wxWindow* parent = nullptr)

View file

@ -58,9 +58,9 @@ wxObject *wxAnimationCtrlXmlHandler::DoCreateResource()
if ( GetBool("hidden", 0) == 1 )
ctrl->Hide();
std::unique_ptr<wxAnimation> animation(GetAnimation("animation", ctrl));
if ( animation )
ctrl->SetAnimation(*animation);
const auto animations = GetAnimations("animation", ctrl);
if ( animations.IsOk() )
ctrl->SetAnimation(animations);
// if no inactive-bitmap has been provided, GetBitmapBundle() will return
// an empty bundle, which just tells wxAnimationCtrl to use the default
@ -78,39 +78,61 @@ bool wxAnimationCtrlXmlHandler::CanHandle(wxXmlNode *node)
IsOfClass(node, wxT("wxGenericAnimationCtrl"));
}
wxAnimationBundle
wxXmlResourceHandlerImpl::GetAnimations(const wxString& param,
wxAnimationCtrlBase* ctrl)
{
wxString paths = GetFilePath(GetParamNode(param));
if ( paths.empty() )
return {};
wxAnimationBundle animations;
for ( const auto& name: wxSplit(paths, ';', '\0') )
{
// create compatible animation object
wxAnimation ani;
if ( ctrl )
ani = ctrl->CreateAnimation();
// load the animation from file
#if wxUSE_FILESYSTEM
wxFSFile * const
fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE);
if ( fsfile )
{
ani.Load(*fsfile->GetStream());
delete fsfile;
}
#else
ani.LoadFile(name);
#endif
if ( !ani.IsOk() )
{
ReportParamError
(
param,
wxString::Format("cannot create animation from \"%s\"", name)
);
return {};
}
animations.Add(ani);
}
return animations;
}
#if WXWIN_COMPATIBILITY_3_2
wxAnimation* wxXmlResourceHandlerImpl::GetAnimation(const wxString& param,
wxAnimationCtrlBase* ctrl)
{
wxString name = GetFilePath(GetParamNode(param));
if ( name.empty() )
return nullptr;
const auto animations = GetAnimations(param, ctrl);
// load the animation from file
std::unique_ptr<wxAnimation> ani(ctrl ? new wxAnimation(ctrl->CreateAnimation())
: new wxAnimation);
#if wxUSE_FILESYSTEM
wxFSFile * const
fsfile = GetCurFileSystem().OpenFile(name, wxFS_READ | wxFS_SEEKABLE);
if ( fsfile )
{
ani->Load(*fsfile->GetStream());
delete fsfile;
}
#else
ani->LoadFile(name);
#endif
if ( !ani->IsOk() )
{
ReportParamError
(
param,
wxString::Format("cannot create animation from \"%s\"", name)
);
return nullptr;
}
return ani.release();
return animations.IsOk() ? new wxAnimation(animations.GetAll()[0]) : nullptr;
}
#endif // WXWIN_COMPATIBILITY_3_2
#endif // wxUSE_XRC && wxUSE_ANIMATIONCTRL

View file

@ -14,6 +14,10 @@
#include "wx/xrc/xmlreshandler.h"
#if wxUSE_ANIMATIONCTRL
#include "wx/animate.h"
#endif
wxIMPLEMENT_ABSTRACT_CLASS(wxXmlResourceHandler, wxObject);
wxXmlResourceHandlerImplBase* wxXmlResourceHandler::GetImpl() const
@ -65,4 +69,24 @@ void wxXmlResourceHandler::AddWindowStyles()
XRC_ADD_STYLE(wxWS_EX_PROCESS_UI_UPDATES);
}
#if wxUSE_ANIMATIONCTRL
wxAnimationBundle
wxXmlResourceHandler::GetAnimations(const wxString& param,
wxAnimationCtrlBase* ctrl)
{
return GetImpl()->GetAnimations(param, ctrl);
}
#if WXWIN_COMPATIBILITY_3_2
wxAnimation*
wxXmlResourceHandler::GetAnimation(const wxString& param,
wxAnimationCtrlBase* ctrl)
{
return GetImpl()->GetAnimation(param, ctrl);
}
#endif // WXWIN_COMPATIBILITY_3_2
#endif // wxUSE_ANIMATIONCTRL
#endif // wxUSE_XRC