diff --git a/include/wx/animate.h b/include/wx/animate.h index 2a0454a0e8..ac50ddc2f6 100644 --- a/include/wx/animate.h +++ b/include/wx/animate.h @@ -21,46 +21,13 @@ #include "wx/bitmap.h" class WXDLLIMPEXP_FWD_CORE wxAnimation; +class wxAnimationImpl; extern WXDLLIMPEXP_DATA_CORE(wxAnimation) wxNullAnimation; extern WXDLLIMPEXP_DATA_CORE(const char) wxAnimationCtrlNameStr[]; WX_DECLARE_LIST_WITH_DECL(wxAnimationDecoder, wxAnimationDecoderList, class WXDLLIMPEXP_CORE); -// ---------------------------------------------------------------------------- -// wxAnimationImpl -// ---------------------------------------------------------------------------- - -enum wxAnimationImplType -{ - wxANIMATION_IMPL_TYPE_NATIVE, - wxANIMATION_IMPL_TYPE_GENERIC -}; - -class WXDLLIMPEXP_CORE wxAnimationImpl : public wxRefCounter -{ -public: - wxAnimationImpl() {} - virtual ~wxAnimationImpl() {} - - virtual wxAnimationImplType GetImplType() = 0; - - virtual bool IsOk() const = 0; - - // can be -1 - virtual int GetDelay(unsigned int frame) const = 0; - - virtual unsigned int GetFrameCount() const = 0; - virtual wxImage GetFrame(unsigned int frame) const = 0; - virtual wxSize GetSize() const = 0; - - virtual bool LoadFile(const wxString& name, - wxAnimationType type = wxANIMATION_TYPE_ANY) = 0; - virtual bool Load(wxInputStream& stream, - wxAnimationType type = wxANIMATION_TYPE_ANY) = 0; -}; - - // ---------------------------------------------------------------------------- // wxAnimation // ---------------------------------------------------------------------------- @@ -68,18 +35,14 @@ public: class WXDLLIMPEXP_CORE wxAnimation : public wxObject { public: - explicit wxAnimation(wxAnimationImplType implType = wxANIMATION_IMPL_TYPE_NATIVE); - explicit wxAnimation(const wxString &name, wxAnimationType type = wxANIMATION_TYPE_ANY, - wxAnimationImplType implType = wxANIMATION_IMPL_TYPE_NATIVE); + wxAnimation(); + explicit wxAnimation(const wxString &name, wxAnimationType type = wxANIMATION_TYPE_ANY); wxAnimation(const wxAnimation& other); wxAnimation& operator=(const wxAnimation& other); - wxAnimationImpl* GetImpl() const - { return static_cast(m_refData); } - - bool IsOk() const - { return GetImpl() && GetImpl()->IsOk(); } + bool IsOk() const; + bool IsCompatibleWith(wxClassInfo* ci) const; int GetDelay(unsigned int frame) const; unsigned int GetFrameCount() const; @@ -99,8 +62,18 @@ public: static void InitStandardHandlers(); protected: + wxAnimationImpl* GetImpl() const; + +private: static wxAnimationDecoderList sm_handlers; + // Ctor used by wxAnimationCtrl::CreateAnimation() only. + explicit wxAnimation(wxAnimationImpl* impl); + + // Give it permission to create objects of this class using specific impl + // and access our GetImpl(). + friend class wxAnimationCtrlBase; + wxDECLARE_DYNAMIC_CLASS(wxAnimation); }; @@ -141,7 +114,16 @@ public: wxBitmap GetInactiveBitmap() const { return m_bmpStatic; } + wxAnimation CreateAnimation() const + { return wxAnimation(DoCreateAnimationImpl()); } + protected: + virtual wxAnimationImpl* DoCreateAnimationImpl() const = 0; + + // This method allows derived classes access to wxAnimation::GetImpl(). + wxAnimationImpl* GetAnimImpl(const wxAnimation& anim) const + { return anim.GetImpl(); } + // the inactive bitmap as it was set by the user wxBitmap m_bmpStatic; diff --git a/include/wx/generic/animate.h b/include/wx/generic/animate.h index 50f3143214..d8ed6799e9 100644 --- a/include/wx/generic/animate.h +++ b/include/wx/generic/animate.h @@ -92,9 +92,8 @@ public: // extended API specific to this implementation of wxAnimateCtrl wxBitmap& GetBackingStore() { return m_backingStore; } - static wxAnimationImpl* CreateAnimationImpl(wxAnimationImplType implType); - protected: // internal utilities + virtual wxAnimationImpl* DoCreateAnimationImpl() const wxOVERRIDE; // resize this control to fit m_animation void FitToAnimation(); diff --git a/include/wx/generic/private/animate.h b/include/wx/generic/private/animate.h index 49300d61b4..9906b0c893 100644 --- a/include/wx/generic/private/animate.h +++ b/include/wx/generic/private/animate.h @@ -11,6 +11,8 @@ #ifndef _WX_GENERIC_PRIVATE_ANIMATEH__ #define _WX_GENERIC_PRIVATE_ANIMATEH__ +#include "wx/private/animate.h" + // ---------------------------------------------------------------------------- // wxAnimationGenericImpl // ---------------------------------------------------------------------------- @@ -21,11 +23,9 @@ public: wxAnimationGenericImpl() : m_decoder(NULL) {} virtual ~wxAnimationGenericImpl() { UnRef(); } - virtual wxAnimationImplType GetImplType() wxOVERRIDE - { return wxANIMATION_IMPL_TYPE_GENERIC; } - virtual bool IsOk() const wxOVERRIDE { return m_decoder != NULL; } + virtual bool IsCompatibleWith(wxClassInfo* ci) const wxOVERRIDE; virtual unsigned int GetFrameCount() const wxOVERRIDE; virtual int GetDelay(unsigned int i) const wxOVERRIDE; diff --git a/include/wx/gtk/animate.h b/include/wx/gtk/animate.h index 08afe23002..24c0dc7f9a 100644 --- a/include/wx/gtk/animate.h +++ b/include/wx/gtk/animate.h @@ -65,10 +65,8 @@ public: // public API bool SetBackgroundColour( const wxColour &colour ) wxOVERRIDE; - static wxAnimationImpl* CreateAnimationImpl(wxAnimationImplType implType); - - protected: + virtual wxAnimationImpl* DoCreateAnimationImpl() const wxOVERRIDE; virtual void DisplayStaticImage() wxOVERRIDE; virtual wxSize DoGetBestSize() const wxOVERRIDE; diff --git a/include/wx/gtk/private/animate.h b/include/wx/gtk/private/animate.h index a923984679..214ae7db7e 100644 --- a/include/wx/gtk/private/animate.h +++ b/include/wx/gtk/private/animate.h @@ -11,6 +11,8 @@ #ifndef _WX_GTK_PRIVATE_ANIMATEH__ #define _WX_GTK_PRIVATE_ANIMATEH__ +#include "wx/private/animate.h" + typedef struct _GdkPixbufAnimation GdkPixbufAnimation; typedef struct _GdkPixbufAnimationIter GdkPixbufAnimationIter; @@ -28,12 +30,9 @@ public: : m_pixbuf(NULL) {} ~wxAnimationGTKImpl() { UnRef(); } - - virtual wxAnimationImplType GetImplType() wxOVERRIDE - { return wxANIMATION_IMPL_TYPE_NATIVE; } - virtual bool IsOk() const wxOVERRIDE { return m_pixbuf != NULL; } + virtual bool IsCompatibleWith(wxClassInfo* ci) const wxOVERRIDE; // unfortunately GdkPixbufAnimation does not expose these info: diff --git a/include/wx/private/animate.h b/include/wx/private/animate.h new file mode 100644 index 0000000000..3e85dd854b --- /dev/null +++ b/include/wx/private/animate.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/private/animate.h +// Purpose: wxAnimationImpl declaration +// Author: Robin Dunn, Vadim Zeitlin +// Created: 2020-04-06 +// Copyright: (c) 2020 wxWidgets development team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PRIVATE_ANIMATEH__ +#define _WX_PRIVATE_ANIMATEH__ + +// ---------------------------------------------------------------------------- +// wxAnimationImpl +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_CORE wxAnimationImpl : public wxRefCounter +{ +public: + wxAnimationImpl() {} + virtual ~wxAnimationImpl() {} + + virtual bool IsOk() const = 0; + virtual bool IsCompatibleWith(wxClassInfo* ci) const = 0; + + // can be -1 + virtual int GetDelay(unsigned int frame) const = 0; + + virtual unsigned int GetFrameCount() const = 0; + virtual wxImage GetFrame(unsigned int frame) const = 0; + virtual wxSize GetSize() const = 0; + + virtual bool LoadFile(const wxString& name, + wxAnimationType type = wxANIMATION_TYPE_ANY) = 0; + virtual bool Load(wxInputStream& stream, + wxAnimationType type = wxANIMATION_TYPE_ANY) = 0; + + // This function creates the default implementation for this platform: + // currently it's wxAnimationGTKImpl under wxGTK and wxAnimationGenericImpl + // under all the other platforms. + static wxAnimationImpl *CreateDefault(); +}; + +#endif // _WX_PRIVATE_ANIMATEH__ diff --git a/interface/wx/animate.h b/interface/wx/animate.h index 9628338551..276ca7bd7f 100644 --- a/interface/wx/animate.h +++ b/interface/wx/animate.h @@ -26,21 +26,6 @@ enum wxAnimationType #define wxAC_NO_AUTORESIZE (0x0010) #define wxAC_DEFAULT_STYLE (wxBORDER_NONE) -/** - Animation implementation types - - @since 3.1.4 -*/ -enum wxAnimationImplType -{ - /** With this flag wxAnimation will use a native implemetation if available. */ - wxANIMATION_IMPL_TYPE_NATIVE, - /** Using this flag will cause wxAnimation to use a generic implementation. */ - wxANIMATION_IMPL_TYPE_GENERIC -}; - - - /** @class wxGenericAnimationCtrl @@ -117,6 +102,16 @@ public: long style = wxAC_DEFAULT_STYLE, const wxString& name = wxAnimationCtrlNameStr); + /** + Create a new animation object compatible with this control. + + A wxAnimation object created using this function is always compatible + with controls of this type, see wxAnimation::IsCompatibleWith(). + + @since 3.1.4 + */ + wxAnimation CreateAnimation() const; + /** Returns the animation associated with this control. */ @@ -267,38 +262,6 @@ public: }; -/** - @class wxAnimationImpl - - Abstract base class for native and generic animation classes. An instance - of one of these classes is used by @c wxAnimation to handle the details of - the interface between the animation file and the animation control. - - @See wxAnimationGenericImpl -*/ -class wxAnimationImpl : public wxObject, public wxRefCounter -{ -public: - wxAnimationImpl(); - - virtual wxAnimationImplType GetImplType() = 0; - - virtual bool IsOk() const = 0; - - virtual int GetDelay(unsigned int frame) const = 0; - - virtual unsigned int GetFrameCount() const = 0; - virtual wxImage GetFrame(unsigned int frame) const = 0; - virtual wxSize GetSize() const = 0; - - virtual bool LoadFile(const wxString& name, - wxAnimationType type = wxANIMATION_TYPE_ANY) = 0; - virtual bool Load(wxInputStream& stream, - wxAnimationType type = wxANIMATION_TYPE_ANY) = 0; - -}; - - /** @class wxAnimation @@ -314,15 +277,13 @@ class WXDLLIMPEXP_CORE wxAnimation : public wxObject { public: /** - Constructs a new animation object. + Constructs a new empty animation object. - @param implType - Specifies if the native or generic animation implementation should - be used. Most of the time this can be ignored, but if you want to - force the use of the generic back-end implementation on a platform - which has a native version, then pass ::wxANIMATION_IMPL_TYPE_GENERIC. + Call Load() to initialize it. + + @see wxAnimationCtrl::CreateAnimation() */ - wxAnimation(wxAnimationImplType implType = wxANIMATION_IMPL_TYPE_NATIVE); + wxAnimation(); /** Constructs a new animation object and load the animation data from the @@ -333,30 +294,34 @@ public: @param type One of the ::wxAnimationType values; wxANIMATION_TYPE_ANY means that the function should try to autodetect the filetype. - @param implType - Specifies if the native or generic animation implementation should - be used. Most of the time this can be ignored, but if you want to - force the use of the generic back-end implementation on a platform - which has a native version, then pass ::wxANIMATION_IMPL_TYPE_GENERIC. + + @see wxAnimationCtrl::CreateAnimation() */ - wxAnimation(const wxString &name, wxAnimationType type = wxANIMATION_TYPE_ANY, - wxAnimationImplType implType = wxANIMATION_IMPL_TYPE_NATIVE); + wxAnimation(const wxString &name, wxAnimationType type = wxANIMATION_TYPE_ANY); /** Copy constructor. */ wxAnimation(const wxAnimation& other); - /** - Returns a pointer to the backend animation implementation object. - */ - wxAnimationImpl* GetImpl() const; - /** Returns @true if animation data is present. */ bool IsOk() const; + /** + Returns @true if animation can be used with controls of the given type. + + This function checks if this animation object can be used with + wxAnimationCtrl of particular type. This will be always the case for + the platforms where only a single wxAnimationCtrl implementation is + available, but not necessarily under e.g. wxGTK where both native (but + limited) GTK implementation and generic implementation can be used. + + @since 3.1.4 + */ + bool IsCompatibleWith(wxClassInfo* ci) const; + /** Returns the delay for the i-th frame in milliseconds. If @c -1 is returned the frame is to be displayed forever. diff --git a/samples/animate/anitest.cpp b/samples/animate/anitest.cpp index fb4d948de3..03157888d4 100644 --- a/samples/animate/anitest.cpp +++ b/samples/animate/anitest.cpp @@ -316,14 +316,7 @@ void MyFrame::OnOpen(wxCommandEvent& WXUNUSED(event)) { wxString filename(dialog.GetPath()); - wxAnimation temp -#ifdef wxHAS_NATIVE_ANIMATIONCTRL - (GetMenuBar()->IsChecked(ID_USE_GENERIC) - ? wxANIMATION_IMPL_TYPE_GENERIC - : wxANIMATION_IMPL_TYPE_NATIVE) -#endif // wxHAS_NATIVE_ANIMATIONCTRL - ; - + wxAnimation temp(m_animationCtrl->CreateAnimation()); if (!temp.LoadFile(filename)) { wxLogError("Sorry, this animation is not a valid format for wxAnimation."); diff --git a/src/common/animatecmn.cpp b/src/common/animatecmn.cpp index 8fbb1da46d..20eba7f317 100644 --- a/src/common/animatecmn.cpp +++ b/src/common/animatecmn.cpp @@ -33,6 +33,8 @@ #include "wx/gifdecod.h" #include "wx/anidecod.h" +#include "wx/private/animate.h" + // global objects const char wxAnimationCtrlNameStr[] = "animationctrl"; wxAnimation wxNullAnimation; @@ -53,15 +55,19 @@ wxAnimationDecoderList wxAnimation::sm_handlers; // wxAnimation // ---------------------------------------------------------------------------- -wxAnimation::wxAnimation(wxAnimationImplType implType) +wxAnimation::wxAnimation() { - m_refData = wxAnimationCtrl::CreateAnimationImpl(implType); + m_refData = wxAnimationImpl::CreateDefault(); } -wxAnimation::wxAnimation(const wxString &name, wxAnimationType type, - wxAnimationImplType implType) +wxAnimation::wxAnimation(wxAnimationImpl* impl) { - m_refData = wxAnimationCtrl::CreateAnimationImpl(implType); + m_refData = impl; +} + +wxAnimation::wxAnimation(const wxString &name, wxAnimationType type) +{ + m_refData = wxAnimationImpl::CreateDefault(); LoadFile(name, type); } @@ -80,6 +86,23 @@ wxAnimation& wxAnimation::operator=(const wxAnimation& other) return *this; } +wxAnimationImpl* wxAnimation::GetImpl() const +{ + return static_cast(m_refData); +} + +bool wxAnimation::IsOk() const +{ + return GetImpl() && GetImpl()->IsOk(); +} + +bool wxAnimation::IsCompatibleWith(wxClassInfo* ci) const +{ + wxCHECK_MSG( IsOk(), false, wxT("invalid animation") ); + + return GetImpl()->IsCompatibleWith(ci); +} + int wxAnimation::GetDelay(unsigned int frame) const { wxCHECK_MSG( IsOk(), -1, wxT("invalid animation") ); diff --git a/src/generic/animateg.cpp b/src/generic/animateg.cpp index 176080b4cc..4947b064dd 100644 --- a/src/generic/animateg.cpp +++ b/src/generic/animateg.cpp @@ -32,6 +32,21 @@ // wxAnimation // ---------------------------------------------------------------------------- +#ifndef wxHAS_NATIVE_ANIMATIONCTRL + +/* static */ +wxAnimationImpl *wxAnimationImpl::CreateDefault() +{ + return new wxAnimationGenericImpl(); +} + +#endif // !wxHAS_NATIVE_ANIMATIONCTRL + +bool wxAnimationGenericImpl::IsCompatibleWith(wxClassInfo* ci) const +{ + return ci->IsKindOf(&wxGenericAnimationCtrl::ms_classInfo); +} + wxSize wxAnimationGenericImpl::GetSize() const { wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid animation") ); @@ -219,7 +234,7 @@ bool wxGenericAnimationCtrl::LoadFile(const wxString& filename, wxAnimationType bool wxGenericAnimationCtrl::Load(wxInputStream& stream, wxAnimationType type) { - wxAnimation anim(wxANIMATION_IMPL_TYPE_GENERIC); + wxAnimation anim(CreateAnimation()); if ( !anim.Load(stream, type) || !anim.IsOk() ) return false; @@ -227,6 +242,11 @@ bool wxGenericAnimationCtrl::Load(wxInputStream& stream, wxAnimationType type) return true; } +wxAnimationImpl* wxGenericAnimationCtrl::DoCreateAnimationImpl() const +{ + return new wxAnimationGenericImpl(); +} + wxSize wxGenericAnimationCtrl::DoGetBestSize() const { if (m_animation.IsOk() && !this->HasFlag(wxAC_NO_AUTORESIZE)) @@ -248,8 +268,8 @@ void wxGenericAnimationCtrl::SetAnimation(const wxAnimation& animation) return; } - wxCHECK_RET(animation.GetImpl()->GetImplType() == wxANIMATION_IMPL_TYPE_GENERIC, - wxT("incorrect animation implementation type provided") ); + wxCHECK_RET(animation.IsCompatibleWith(GetClassInfo()), + wxT("incompatible animation") ); if (AnimationImplGetBackgroundColour() == wxNullColour) SetUseWindowBackgroundColour(); @@ -600,19 +620,10 @@ void wxGenericAnimationCtrl::OnSize(wxSizeEvent &WXUNUSED(event)) } } -// ---------------------------------------------------------------------------- - -//static -wxAnimationImpl* wxGenericAnimationCtrl::CreateAnimationImpl(wxAnimationImplType WXUNUSED(implType)) -{ - // For the generic widget we always use the generic impl and ignore the given type - return new wxAnimationGenericImpl(); -} - // ---------------------------------------------------------------------------- // helpers to safely access wxAnimationGenericImpl methods // ---------------------------------------------------------------------------- -#define ANIMATION (static_cast(m_animation.GetImpl())) +#define ANIMATION (static_cast(GetAnimImpl(m_animation))) wxPoint wxGenericAnimationCtrl::AnimationImplGetFramePosition(unsigned int frame) const { diff --git a/src/gtk/animate.cpp b/src/gtk/animate.cpp index c62a390800..b8662acd86 100644 --- a/src/gtk/animate.cpp +++ b/src/gtk/animate.cpp @@ -53,6 +53,21 @@ void gdk_pixbuf_area_updated(GdkPixbufLoader *loader, // wxAnimationGTKImpl //----------------------------------------------------------------------------- +#ifdef wxHAS_NATIVE_ANIMATIONCTRL + +/* static */ +wxAnimationImpl *wxAnimationImpl::CreateDefault() +{ + return new wxAnimationGTKImpl(); +} + +#endif // wxHAS_NATIVE_ANIMATIONCTRL + +bool wxAnimationGTKImpl::IsCompatibleWith(wxClassInfo* ci) const +{ + return ci->IsKindOf(&wxAnimationCtrl::ms_classInfo); +} + bool wxAnimationGTKImpl::LoadFile(const wxString &name, wxAnimationType WXUNUSED(type)) { UnRef(); @@ -242,7 +257,7 @@ bool wxAnimationCtrl::LoadFile(const wxString &filename, wxAnimationType type) bool wxAnimationCtrl::Load(wxInputStream& stream, wxAnimationType type) { - wxAnimation anim(wxANIMATION_IMPL_TYPE_NATIVE); + wxAnimation anim(CreateAnimation()); if ( !anim.Load(stream, type) || !anim.IsOk() ) return false; @@ -250,6 +265,11 @@ bool wxAnimationCtrl::Load(wxInputStream& stream, wxAnimationType type) return true; } +wxAnimationImpl* wxAnimationCtrl::DoCreateAnimationImpl() const +{ + return new wxAnimationGTKImpl(); +} + void wxAnimationCtrl::SetAnimation(const wxAnimation &anim) { if (IsPlaying()) @@ -266,8 +286,8 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation &anim) return; } - wxCHECK_RET(anim.GetImpl()->GetImplType() == wxANIMATION_IMPL_TYPE_NATIVE, - wxT("incorrect animation implementation type provided") ); + wxCHECK_RET(anim.IsCompatibleWith(GetClassInfo()), + wxT("incompatible animation") ); // copy underlying GdkPixbuf object m_anim = AnimationImplGetPixbuf(); @@ -452,23 +472,8 @@ void wxAnimationCtrl::OnTimer(wxTimerEvent& WXUNUSED(ev)) } -// static -wxAnimationImpl* wxAnimationCtrl::CreateAnimationImpl(wxAnimationImplType implType) -{ - switch (implType) - { - case wxANIMATION_IMPL_TYPE_GENERIC: - return new wxAnimationGenericImpl(); - - case wxANIMATION_IMPL_TYPE_NATIVE: - return new wxAnimationGTKImpl(); - } - return NULL; -} - - // helpers to safely access wxAnimationGTKImpl methods -#define ANIMATION (static_cast(m_animation.GetImpl())) +#define ANIMATION (static_cast(GetAnimImpl(m_animation))) GdkPixbufAnimation* wxAnimationCtrl::AnimationImplGetPixbuf() const {