Make wxAnimationImpl private and get rid of wxAnimationImplType

Simplify and streamline animation classes relationship: wxAnimation is
the only public class representing an animation and it can be created by
both the native wxAnimationCtrl and wxGenericAnimationCtrl using the new
public CreateAnimation() method.

Replace wxAnimationImplType enum with more flexible type info based
check.
This commit is contained in:
Vadim Zeitlin 2020-04-06 01:00:15 +02:00
parent 86d6cb8d1f
commit b08db49bf6
11 changed files with 184 additions and 165 deletions

View File

@ -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<wxAnimationImpl*>(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;

View File

@ -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();

View File

@ -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;

View File

@ -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;

View File

@ -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:

View File

@ -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__

View File

@ -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.

View File

@ -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.");

View File

@ -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<wxAnimationImpl*>(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") );

View File

@ -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<wxAnimationGenericImpl*>(m_animation.GetImpl()))
#define ANIMATION (static_cast<wxAnimationGenericImpl*>(GetAnimImpl(m_animation)))
wxPoint wxGenericAnimationCtrl::AnimationImplGetFramePosition(unsigned int frame) const
{

View File

@ -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<wxAnimationGTKImpl*>(m_animation.GetImpl()))
#define ANIMATION (static_cast<wxAnimationGTKImpl*>(GetAnimImpl(m_animation)))
GdkPixbufAnimation* wxAnimationCtrl::AnimationImplGetPixbuf() const
{