[ 1580776 ] wxAnimationCtrl::SetInactiveBitmap
Additionally call UnShare() in it. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42195 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -110,6 +110,14 @@ of the animation is displayed.
|
|||||||
Returns the animation associated with this control.
|
Returns the animation associated with this control.
|
||||||
|
|
||||||
|
|
||||||
|
\membersection{wxAnimationCtrl::GetInactiveBitmap}\label{wxanimationctrlgetinactivebitmap}
|
||||||
|
|
||||||
|
\constfunc{wxBitmap}{GetInactiveBitmap}{\void}
|
||||||
|
|
||||||
|
Returns the inactive bitmap shown in this control when the;
|
||||||
|
see \helpref{SetInactiveBitmap}{wxanimationctrlsetinactivebitmap} for more info.
|
||||||
|
|
||||||
|
|
||||||
\membersection{wxAnimationCtrl::IsPlaying}\label{wxanimationctrlisplaying}
|
\membersection{wxAnimationCtrl::IsPlaying}\label{wxanimationctrlisplaying}
|
||||||
|
|
||||||
\constfunc{bool}{IsPlaying}{\void}
|
\constfunc{bool}{IsPlaying}{\void}
|
||||||
@@ -143,17 +151,31 @@ displayed).
|
|||||||
Sets the animation to play in this control.
|
Sets the animation to play in this control.
|
||||||
If the previous animation is being played, it's \helpref{Stopped}{wxanimationctrlstop}.
|
If the previous animation is being played, it's \helpref{Stopped}{wxanimationctrlstop}.
|
||||||
|
|
||||||
Until \helpref{Play}{wxanimationctrlplay} isn't called, the first frame
|
Until \helpref{Play}{wxanimationctrlplay} isn't called, a static image, the first
|
||||||
of the animation is displayed.
|
frame of the given animation or the background colour will be shown
|
||||||
|
(see \helpref{SetInactiveBitmap}{wxanimationctrlsetinactivebitmap} for more info).
|
||||||
|
|
||||||
If {\tt wxNullAnimation} is given as animation, the control will be cleared to display
|
|
||||||
the background colour (see \helpref{wxWindow::GetBackgroundColour}{wxwindowgetbackgroundcolour}).
|
|
||||||
|
|
||||||
|
\membersection{wxAnimationCtrl::SetInactiveBitmap}\label{wxanimationctrlsetinactivebitmap}
|
||||||
|
|
||||||
|
\func{void}{SetInactiveBitmap}{\param{const wxBitmap\& }{bmp}}
|
||||||
|
|
||||||
|
Sets the bitmap to show on the control when it's not playing an animation.
|
||||||
|
If you set as inactive bitmap {\tt wxNullBitmap} (which is the default), then the
|
||||||
|
first frame of the animation is instead shown when the control is inactive; in this case,
|
||||||
|
if there's no valid animation associated with the control (see \helpref{SetAnimation}{wxanimationctrlsetanimation}),
|
||||||
|
then the background colour of the window is shown.
|
||||||
|
|
||||||
|
If the control is not playing the animation, the given bitmap will be immediately
|
||||||
|
shown, otherwise it will be shown as soon as \helpref{Stop}{wxanimationctrlstop}
|
||||||
|
is called.
|
||||||
|
|
||||||
\membersection{wxAnimationCtrl::Stop}\label{wxanimationctrlstop}
|
\membersection{wxAnimationCtrl::Stop}\label{wxanimationctrlstop}
|
||||||
|
|
||||||
\func{void}{Stop}{\void}
|
\func{void}{Stop}{\void}
|
||||||
|
|
||||||
Stops playing the animation.
|
Stops playing the animation.
|
||||||
The control will show the last frame rendered of the current animation until \helpref{Play}{wxanimationctrlplay} is called.
|
The control will show the first frame of the animation, a custom static image or
|
||||||
|
the window's background colour as specified by the
|
||||||
|
last \helpref{SetInactiveBitmap}{wxanimationctrlsetinactivebitmap} call.
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "wx/animdecod.h"
|
#include "wx/animdecod.h"
|
||||||
#include "wx/control.h"
|
#include "wx/control.h"
|
||||||
#include "wx/timer.h"
|
#include "wx/timer.h"
|
||||||
|
#include "wx/bitmap.h"
|
||||||
|
|
||||||
class WXDLLIMPEXP_ADV wxAnimation;
|
class WXDLLIMPEXP_ADV wxAnimation;
|
||||||
|
|
||||||
@@ -64,7 +65,6 @@ protected:
|
|||||||
// auto-resizes by default to fit the new animation when SetAnimation() is called
|
// auto-resizes by default to fit the new animation when SetAnimation() is called
|
||||||
#define wxAC_DEFAULT_STYLE (wxNO_BORDER)
|
#define wxAC_DEFAULT_STYLE (wxNO_BORDER)
|
||||||
|
|
||||||
|
|
||||||
class WXDLLIMPEXP_ADV wxAnimationCtrlBase : public wxControl
|
class WXDLLIMPEXP_ADV wxAnimationCtrlBase : public wxControl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -82,6 +82,13 @@ public: // public API
|
|||||||
|
|
||||||
virtual bool IsPlaying() const = 0;
|
virtual bool IsPlaying() const = 0;
|
||||||
|
|
||||||
|
virtual void SetInactiveBitmap(const wxBitmap &bmp);
|
||||||
|
wxBitmap GetInactiveBitmap() const
|
||||||
|
{ return m_bmpStatic; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxBitmap m_bmpStatic;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_ABSTRACT_CLASS(wxAnimationCtrlBase)
|
DECLARE_ABSTRACT_CLASS(wxAnimationCtrlBase)
|
||||||
};
|
};
|
||||||
|
@@ -108,6 +108,8 @@ public:
|
|||||||
wxAnimation GetAnimation() const
|
wxAnimation GetAnimation() const
|
||||||
{ return m_animation; }
|
{ return m_animation; }
|
||||||
|
|
||||||
|
void SetInactiveBitmap(const wxBitmap &bmp);
|
||||||
|
|
||||||
public: // event handlers
|
public: // event handlers
|
||||||
|
|
||||||
void OnPaint(wxPaintEvent& event);
|
void OnPaint(wxPaintEvent& event);
|
||||||
@@ -140,9 +142,11 @@ protected: // internal utilities
|
|||||||
void FitToAnimation();
|
void FitToAnimation();
|
||||||
|
|
||||||
// Draw the background; use this when e.g. previous frame had wxANIM_TOBACKGROUND disposal.
|
// Draw the background; use this when e.g. previous frame had wxANIM_TOBACKGROUND disposal.
|
||||||
|
void DisposeToBackground();
|
||||||
void DisposeToBackground(wxDC& dc);
|
void DisposeToBackground(wxDC& dc);
|
||||||
void DisposeToBackground(wxDC& dc, const wxPoint &pos, const wxSize &sz);
|
void DisposeToBackground(wxDC& dc, const wxPoint &pos, const wxSize &sz);
|
||||||
|
|
||||||
|
void UpdateBackingStoreWithStaticImage();
|
||||||
void IncrementalUpdateBackingStore();
|
void IncrementalUpdateBackingStore();
|
||||||
bool RebuildBackingStoreUpToFrame(size_t);
|
bool RebuildBackingStoreUpToFrame(size_t);
|
||||||
void DrawFrame(wxDC &dc, size_t);
|
void DrawFrame(wxDC &dc, size_t);
|
||||||
|
@@ -68,9 +68,6 @@ public: // used by GTK callbacks
|
|||||||
protected:
|
protected:
|
||||||
GdkPixbufAnimation *m_pixbuf;
|
GdkPixbufAnimation *m_pixbuf;
|
||||||
|
|
||||||
// used temporary by Load()
|
|
||||||
//bool m_bLoadComplete;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UnRef();
|
void UnRef();
|
||||||
|
|
||||||
@@ -132,12 +129,14 @@ public: // public API
|
|||||||
virtual bool IsPlaying() const;
|
virtual bool IsPlaying() const;
|
||||||
|
|
||||||
bool SetBackgroundColour( const wxColour &colour );
|
bool SetBackgroundColour( const wxColour &colour );
|
||||||
|
void SetInactiveBitmap(const wxBitmap &bmp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual wxSize DoGetBestSize() const;
|
virtual wxSize DoGetBestSize() const;
|
||||||
void FitToAnimation();
|
void FitToAnimation();
|
||||||
void ClearToBackgroundColour();
|
void ClearToBackgroundColour();
|
||||||
|
void DisplayStaticImage();
|
||||||
|
|
||||||
void ResetAnim();
|
void ResetAnim();
|
||||||
void ResetIter();
|
void ResetIter();
|
||||||
|
@@ -20,16 +20,21 @@
|
|||||||
#if wxUSE_ANIMATIONCTRL
|
#if wxUSE_ANIMATIONCTRL
|
||||||
|
|
||||||
#include "wx/animate.h"
|
#include "wx/animate.h"
|
||||||
|
#include "wx/bitmap.h"
|
||||||
|
|
||||||
const wxChar wxAnimationCtrlNameStr[] = wxT("animationctrl");
|
const wxChar wxAnimationCtrlNameStr[] = wxT("animationctrl");
|
||||||
|
|
||||||
// global object
|
// global object
|
||||||
wxAnimation wxNullAnimation;
|
wxAnimation wxNullAnimation;
|
||||||
|
|
||||||
//wxIMPLEMENT_HANDLER_LIST_MANAGER(wxAnimation,
|
|
||||||
IMPLEMENT_ABSTRACT_CLASS(wxAnimationBase, wxObject)
|
IMPLEMENT_ABSTRACT_CLASS(wxAnimationBase, wxObject)
|
||||||
IMPLEMENT_ABSTRACT_CLASS(wxAnimationCtrlBase, wxControl)
|
IMPLEMENT_ABSTRACT_CLASS(wxAnimationCtrlBase, wxControl)
|
||||||
|
|
||||||
|
void wxAnimationCtrlBase::SetInactiveBitmap(const wxBitmap &bmp)
|
||||||
|
{
|
||||||
|
m_bmpStatic = bmp;
|
||||||
|
m_bmpStatic.UnShare();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // wxUSE_ANIMATIONCTRL
|
#endif // wxUSE_ANIMATIONCTRL
|
||||||
|
@@ -335,27 +335,19 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation& animation)
|
|||||||
if (!this->HasFlag(wxAC_NO_AUTORESIZE))
|
if (!this->HasFlag(wxAC_NO_AUTORESIZE))
|
||||||
FitToAnimation();
|
FitToAnimation();
|
||||||
|
|
||||||
// display first frame
|
// reset frame counter
|
||||||
m_currentFrame = 0;
|
m_currentFrame = 0;
|
||||||
if (m_animation.IsOk())
|
|
||||||
{
|
|
||||||
if (!RebuildBackingStoreUpToFrame(0))
|
|
||||||
{
|
|
||||||
m_animation = wxNullAnimation;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// clear to
|
|
||||||
wxMemoryDC dc;
|
|
||||||
dc.SelectObject(m_backingStore);
|
|
||||||
|
|
||||||
// Draw the background
|
UpdateBackingStoreWithStaticImage();
|
||||||
DisposeToBackground(dc);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Refresh();
|
void wxAnimationCtrl::SetInactiveBitmap(const wxBitmap &bmp)
|
||||||
|
{
|
||||||
|
wxAnimationCtrlBase::SetInactiveBitmap(bmp);
|
||||||
|
|
||||||
|
// if not playing, update the backing store now
|
||||||
|
if (!IsPlaying())
|
||||||
|
UpdateBackingStoreWithStaticImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxAnimationCtrl::FitToAnimation()
|
void wxAnimationCtrl::FitToAnimation()
|
||||||
@@ -370,9 +362,10 @@ void wxAnimationCtrl::FitToAnimation()
|
|||||||
|
|
||||||
void wxAnimationCtrl::Stop()
|
void wxAnimationCtrl::Stop()
|
||||||
{
|
{
|
||||||
// leave current frame displayed until Play() is called again
|
|
||||||
m_timer.Stop();
|
m_timer.Stop();
|
||||||
m_isPlaying = false;
|
m_isPlaying = false;
|
||||||
|
|
||||||
|
UpdateBackingStoreWithStaticImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxAnimationCtrl::Play(bool looped)
|
bool wxAnimationCtrl::Play(bool looped)
|
||||||
@@ -392,6 +385,10 @@ bool wxAnimationCtrl::Play(bool looped)
|
|||||||
|
|
||||||
m_isPlaying = true;
|
m_isPlaying = true;
|
||||||
|
|
||||||
|
// do a ClearBackground() to avoid that e.g. the custom static bitmap which
|
||||||
|
// was eventually shown previously remains partially drawn
|
||||||
|
ClearBackground();
|
||||||
|
|
||||||
// DrawCurrentFrame() will use our updated backing store
|
// DrawCurrentFrame() will use our updated backing store
|
||||||
wxClientDC clientDC(this);
|
wxClientDC clientDC(this);
|
||||||
DrawCurrentFrame(clientDC);
|
DrawCurrentFrame(clientDC);
|
||||||
@@ -505,6 +502,29 @@ void wxAnimationCtrl::IncrementalUpdateBackingStore()
|
|||||||
dc.SelectObject(wxNullBitmap);
|
dc.SelectObject(wxNullBitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxAnimationCtrl::UpdateBackingStoreWithStaticImage()
|
||||||
|
{
|
||||||
|
wxASSERT(!IsPlaying());
|
||||||
|
|
||||||
|
if (m_bmpStatic.IsOk())
|
||||||
|
{
|
||||||
|
// copy the inactive bitmap in the backing store
|
||||||
|
m_backingStore = m_bmpStatic;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// put in the backing store the first frame of the animation
|
||||||
|
if (!m_animation.IsOk() ||
|
||||||
|
!RebuildBackingStoreUpToFrame(0))
|
||||||
|
{
|
||||||
|
m_animation = wxNullAnimation;
|
||||||
|
DisposeToBackground();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
void wxAnimationCtrl::DrawFrame(wxDC &dc, size_t frame)
|
void wxAnimationCtrl::DrawFrame(wxDC &dc, size_t frame)
|
||||||
{
|
{
|
||||||
// PERFORMANCE NOTE:
|
// PERFORMANCE NOTE:
|
||||||
@@ -523,7 +543,15 @@ void wxAnimationCtrl::DrawCurrentFrame(wxDC& dc)
|
|||||||
wxASSERT( m_backingStore.IsOk() );
|
wxASSERT( m_backingStore.IsOk() );
|
||||||
|
|
||||||
// m_backingStore always contains the current frame
|
// m_backingStore always contains the current frame
|
||||||
dc.DrawBitmap(m_backingStore, 0, 0);
|
dc.DrawBitmap(m_backingStore, 0, 0, true /* use mask in case it's present */);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxAnimationCtrl::DisposeToBackground()
|
||||||
|
{
|
||||||
|
// clear the backing store
|
||||||
|
wxMemoryDC dc;
|
||||||
|
dc.SelectObject(m_backingStore);
|
||||||
|
DisposeToBackground(dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxAnimationCtrl::DisposeToBackground(wxDC& dc)
|
void wxAnimationCtrl::DisposeToBackground(wxDC& dc)
|
||||||
@@ -556,10 +584,14 @@ void wxAnimationCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|||||||
// VERY IMPORTANT: the wxPaintDC *must* be created in any case
|
// VERY IMPORTANT: the wxPaintDC *must* be created in any case
|
||||||
wxPaintDC dc(this);
|
wxPaintDC dc(this);
|
||||||
|
|
||||||
// both if we are playing or not, we need to refresh the current frame
|
|
||||||
if ( m_backingStore.IsOk() )
|
if ( m_backingStore.IsOk() )
|
||||||
DrawCurrentFrame(dc);
|
DrawCurrentFrame(dc);
|
||||||
//else: m_animation is not valid and thus we don't have a valid backing store...
|
else
|
||||||
|
{
|
||||||
|
// m_animation is not valid and thus we don't have a valid backing store...
|
||||||
|
// clear then our area to the background colour
|
||||||
|
DisposeToBackground(dc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxAnimationCtrl::OnTimer(wxTimerEvent &WXUNUSED(event))
|
void wxAnimationCtrl::OnTimer(wxTimerEvent &WXUNUSED(event))
|
||||||
@@ -570,8 +602,7 @@ void wxAnimationCtrl::OnTimer(wxTimerEvent &WXUNUSED(event))
|
|||||||
// Should a non-looped animation display the last frame?
|
// Should a non-looped animation display the last frame?
|
||||||
if (!m_looped)
|
if (!m_looped)
|
||||||
{
|
{
|
||||||
m_timer.Stop();
|
Stop();
|
||||||
m_isPlaying = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@@ -117,7 +117,6 @@ bool wxAnimation::Load(wxInputStream &stream, wxAnimationType type)
|
|||||||
// connect to loader signals
|
// connect to loader signals
|
||||||
g_signal_connect(loader, "area-updated", G_CALLBACK(gdk_pixbuf_area_updated), this);
|
g_signal_connect(loader, "area-updated", G_CALLBACK(gdk_pixbuf_area_updated), this);
|
||||||
|
|
||||||
//m_bLoadComplete = false;
|
|
||||||
guchar buf[2048];
|
guchar buf[2048];
|
||||||
while (stream.IsOk())
|
while (stream.IsOk())
|
||||||
{
|
{
|
||||||
@@ -139,7 +138,6 @@ bool wxAnimation::Load(wxInputStream &stream, wxAnimationType type)
|
|||||||
wxLogDebug(wxT("Could not close the loader"));
|
wxLogDebug(wxT("Could not close the loader"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//m_bLoadComplete = true;
|
|
||||||
|
|
||||||
// wait until we get the last area_updated signal
|
// wait until we get the last area_updated signal
|
||||||
return true;
|
return true;
|
||||||
@@ -259,16 +257,9 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation &anim)
|
|||||||
|
|
||||||
if (!this->HasFlag(wxAC_NO_AUTORESIZE))
|
if (!this->HasFlag(wxAC_NO_AUTORESIZE))
|
||||||
FitToAnimation();
|
FitToAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
// display first frame
|
DisplayStaticImage();
|
||||||
gtk_image_set_from_pixbuf(GTK_IMAGE(m_widget),
|
|
||||||
gdk_pixbuf_animation_get_static_image(m_anim));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we need to clear the control to the background colour
|
|
||||||
ClearToBackgroundColour();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxAnimationCtrl::FitToAnimation()
|
void wxAnimationCtrl::FitToAnimation()
|
||||||
@@ -280,8 +271,6 @@ void wxAnimationCtrl::FitToAnimation()
|
|||||||
h = gdk_pixbuf_animation_get_height(m_anim);
|
h = gdk_pixbuf_animation_get_height(m_anim);
|
||||||
|
|
||||||
// update our size to fit animation
|
// update our size to fit animation
|
||||||
//if (w > 0 && h > 0)
|
|
||||||
// gtk_widget_set_size_request(m_widget, w, h);
|
|
||||||
SetSize(w, h);
|
SetSize(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,6 +313,49 @@ void wxAnimationCtrl::Stop()
|
|||||||
if (IsPlaying())
|
if (IsPlaying())
|
||||||
m_timer.Stop();
|
m_timer.Stop();
|
||||||
m_bPlaying = false;
|
m_bPlaying = false;
|
||||||
|
|
||||||
|
ResetIter();
|
||||||
|
DisplayStaticImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxAnimationCtrl::SetInactiveBitmap(const wxBitmap &bmp)
|
||||||
|
{
|
||||||
|
wxAnimationCtrlBase::SetInactiveBitmap(bmp);
|
||||||
|
|
||||||
|
// update the pixbuf associated with m_widget now...
|
||||||
|
if (!IsPlaying())
|
||||||
|
DisplayStaticImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxAnimationCtrl::DisplayStaticImage()
|
||||||
|
{
|
||||||
|
wxASSERT(!IsPlaying());
|
||||||
|
|
||||||
|
if (m_bmpStatic.IsOk())
|
||||||
|
{
|
||||||
|
// show inactive bitmap
|
||||||
|
GdkBitmap *mask = (GdkBitmap *) NULL;
|
||||||
|
if (m_bmpStatic.GetMask())
|
||||||
|
mask = m_bmpStatic.GetMask()->GetBitmap();
|
||||||
|
|
||||||
|
if (m_bmpStatic.HasPixbuf())
|
||||||
|
{
|
||||||
|
gtk_image_set_from_pixbuf(GTK_IMAGE(m_widget),
|
||||||
|
m_bmpStatic.GetPixbuf());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gtk_image_set_from_pixmap(GTK_IMAGE(m_widget),
|
||||||
|
m_bmpStatic.GetPixmap(), mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// even if not clearly documented, gdk_pixbuf_animation_get_static_image()
|
||||||
|
// always returns the first frame of the animation
|
||||||
|
gtk_image_set_from_pixbuf(GTK_IMAGE(m_widget),
|
||||||
|
gdk_pixbuf_animation_get_static_image(m_anim));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxAnimationCtrl::IsPlaying() const
|
bool wxAnimationCtrl::IsPlaying() const
|
||||||
@@ -358,8 +390,6 @@ void wxAnimationCtrl::ClearToBackgroundColour()
|
|||||||
guint32 col = (clr.Red() << 24) | (clr.Green() << 16) | (clr.Blue() << 8);
|
guint32 col = (clr.Red() << 24) | (clr.Green() << 16) | (clr.Blue() << 8);
|
||||||
gdk_pixbuf_fill(newpix, col);
|
gdk_pixbuf_fill(newpix, col);
|
||||||
|
|
||||||
wxLogDebug(wxT("Clearing to background %s"), clr.GetAsString().c_str());
|
|
||||||
|
|
||||||
gtk_image_set_from_pixbuf(GTK_IMAGE(m_widget), newpix);
|
gtk_image_set_from_pixbuf(GTK_IMAGE(m_widget), newpix);
|
||||||
g_object_unref(newpix);
|
g_object_unref(newpix);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user