[ 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:
parent
1a5e269be8
commit
8e458bb539
@ -110,6 +110,14 @@ of the animation is displayed.
|
||||
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}
|
||||
|
||||
\constfunc{bool}{IsPlaying}{\void}
|
||||
@ -143,17 +151,31 @@ displayed).
|
||||
Sets the animation to play in this control.
|
||||
If the previous animation is being played, it's \helpref{Stopped}{wxanimationctrlstop}.
|
||||
|
||||
Until \helpref{Play}{wxanimationctrlplay} isn't called, the first frame
|
||||
of the animation is displayed.
|
||||
Until \helpref{Play}{wxanimationctrlplay} isn't called, a static image, the first
|
||||
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}
|
||||
|
||||
\func{void}{Stop}{\void}
|
||||
|
||||
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/control.h"
|
||||
#include "wx/timer.h"
|
||||
#include "wx/bitmap.h"
|
||||
|
||||
class WXDLLIMPEXP_ADV wxAnimation;
|
||||
|
||||
@ -64,7 +65,6 @@ protected:
|
||||
// auto-resizes by default to fit the new animation when SetAnimation() is called
|
||||
#define wxAC_DEFAULT_STYLE (wxNO_BORDER)
|
||||
|
||||
|
||||
class WXDLLIMPEXP_ADV wxAnimationCtrlBase : public wxControl
|
||||
{
|
||||
public:
|
||||
@ -82,6 +82,13 @@ public: // public API
|
||||
|
||||
virtual bool IsPlaying() const = 0;
|
||||
|
||||
virtual void SetInactiveBitmap(const wxBitmap &bmp);
|
||||
wxBitmap GetInactiveBitmap() const
|
||||
{ return m_bmpStatic; }
|
||||
|
||||
protected:
|
||||
wxBitmap m_bmpStatic;
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_CLASS(wxAnimationCtrlBase)
|
||||
};
|
||||
|
@ -108,6 +108,8 @@ public:
|
||||
wxAnimation GetAnimation() const
|
||||
{ return m_animation; }
|
||||
|
||||
void SetInactiveBitmap(const wxBitmap &bmp);
|
||||
|
||||
public: // event handlers
|
||||
|
||||
void OnPaint(wxPaintEvent& event);
|
||||
@ -140,9 +142,11 @@ protected: // internal utilities
|
||||
void FitToAnimation();
|
||||
|
||||
// Draw the background; use this when e.g. previous frame had wxANIM_TOBACKGROUND disposal.
|
||||
void DisposeToBackground();
|
||||
void DisposeToBackground(wxDC& dc);
|
||||
void DisposeToBackground(wxDC& dc, const wxPoint &pos, const wxSize &sz);
|
||||
|
||||
void UpdateBackingStoreWithStaticImage();
|
||||
void IncrementalUpdateBackingStore();
|
||||
bool RebuildBackingStoreUpToFrame(size_t);
|
||||
void DrawFrame(wxDC &dc, size_t);
|
||||
|
@ -68,9 +68,6 @@ public: // used by GTK callbacks
|
||||
protected:
|
||||
GdkPixbufAnimation *m_pixbuf;
|
||||
|
||||
// used temporary by Load()
|
||||
//bool m_bLoadComplete;
|
||||
|
||||
private:
|
||||
void UnRef();
|
||||
|
||||
@ -132,12 +129,14 @@ public: // public API
|
||||
virtual bool IsPlaying() const;
|
||||
|
||||
bool SetBackgroundColour( const wxColour &colour );
|
||||
void SetInactiveBitmap(const wxBitmap &bmp);
|
||||
|
||||
protected:
|
||||
|
||||
virtual wxSize DoGetBestSize() const;
|
||||
void FitToAnimation();
|
||||
void ClearToBackgroundColour();
|
||||
void DisplayStaticImage();
|
||||
|
||||
void ResetAnim();
|
||||
void ResetIter();
|
||||
|
@ -20,16 +20,21 @@
|
||||
#if wxUSE_ANIMATIONCTRL
|
||||
|
||||
#include "wx/animate.h"
|
||||
#include "wx/bitmap.h"
|
||||
|
||||
const wxChar wxAnimationCtrlNameStr[] = wxT("animationctrl");
|
||||
|
||||
// global object
|
||||
wxAnimation wxNullAnimation;
|
||||
|
||||
//wxIMPLEMENT_HANDLER_LIST_MANAGER(wxAnimation,
|
||||
IMPLEMENT_ABSTRACT_CLASS(wxAnimationBase, wxObject)
|
||||
IMPLEMENT_ABSTRACT_CLASS(wxAnimationCtrlBase, wxControl)
|
||||
|
||||
void wxAnimationCtrlBase::SetInactiveBitmap(const wxBitmap &bmp)
|
||||
{
|
||||
m_bmpStatic = bmp;
|
||||
m_bmpStatic.UnShare();
|
||||
}
|
||||
|
||||
|
||||
#endif // wxUSE_ANIMATIONCTRL
|
||||
|
@ -335,27 +335,19 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation& animation)
|
||||
if (!this->HasFlag(wxAC_NO_AUTORESIZE))
|
||||
FitToAnimation();
|
||||
|
||||
// display first frame
|
||||
// reset frame counter
|
||||
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
|
||||
DisposeToBackground(dc);
|
||||
}
|
||||
UpdateBackingStoreWithStaticImage();
|
||||
}
|
||||
|
||||
Refresh();
|
||||
void wxAnimationCtrl::SetInactiveBitmap(const wxBitmap &bmp)
|
||||
{
|
||||
wxAnimationCtrlBase::SetInactiveBitmap(bmp);
|
||||
|
||||
// if not playing, update the backing store now
|
||||
if (!IsPlaying())
|
||||
UpdateBackingStoreWithStaticImage();
|
||||
}
|
||||
|
||||
void wxAnimationCtrl::FitToAnimation()
|
||||
@ -370,9 +362,10 @@ void wxAnimationCtrl::FitToAnimation()
|
||||
|
||||
void wxAnimationCtrl::Stop()
|
||||
{
|
||||
// leave current frame displayed until Play() is called again
|
||||
m_timer.Stop();
|
||||
m_isPlaying = false;
|
||||
|
||||
UpdateBackingStoreWithStaticImage();
|
||||
}
|
||||
|
||||
bool wxAnimationCtrl::Play(bool looped)
|
||||
@ -392,6 +385,10 @@ bool wxAnimationCtrl::Play(bool looped)
|
||||
|
||||
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
|
||||
wxClientDC clientDC(this);
|
||||
DrawCurrentFrame(clientDC);
|
||||
@ -505,6 +502,29 @@ void wxAnimationCtrl::IncrementalUpdateBackingStore()
|
||||
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)
|
||||
{
|
||||
// PERFORMANCE NOTE:
|
||||
@ -523,7 +543,15 @@ void wxAnimationCtrl::DrawCurrentFrame(wxDC& dc)
|
||||
wxASSERT( m_backingStore.IsOk() );
|
||||
|
||||
// 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)
|
||||
@ -556,10 +584,14 @@ void wxAnimationCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
|
||||
// VERY IMPORTANT: the wxPaintDC *must* be created in any case
|
||||
wxPaintDC dc(this);
|
||||
|
||||
// both if we are playing or not, we need to refresh the current frame
|
||||
if ( m_backingStore.IsOk() )
|
||||
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))
|
||||
@ -570,8 +602,7 @@ void wxAnimationCtrl::OnTimer(wxTimerEvent &WXUNUSED(event))
|
||||
// Should a non-looped animation display the last frame?
|
||||
if (!m_looped)
|
||||
{
|
||||
m_timer.Stop();
|
||||
m_isPlaying = false;
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -117,7 +117,6 @@ bool wxAnimation::Load(wxInputStream &stream, wxAnimationType type)
|
||||
// connect to loader signals
|
||||
g_signal_connect(loader, "area-updated", G_CALLBACK(gdk_pixbuf_area_updated), this);
|
||||
|
||||
//m_bLoadComplete = false;
|
||||
guchar buf[2048];
|
||||
while (stream.IsOk())
|
||||
{
|
||||
@ -139,7 +138,6 @@ bool wxAnimation::Load(wxInputStream &stream, wxAnimationType type)
|
||||
wxLogDebug(wxT("Could not close the loader"));
|
||||
return false;
|
||||
}
|
||||
//m_bLoadComplete = true;
|
||||
|
||||
// wait until we get the last area_updated signal
|
||||
return true;
|
||||
@ -259,16 +257,9 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation &anim)
|
||||
|
||||
if (!this->HasFlag(wxAC_NO_AUTORESIZE))
|
||||
FitToAnimation();
|
||||
}
|
||||
|
||||
// display first frame
|
||||
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();
|
||||
}
|
||||
DisplayStaticImage();
|
||||
}
|
||||
|
||||
void wxAnimationCtrl::FitToAnimation()
|
||||
@ -280,8 +271,6 @@ void wxAnimationCtrl::FitToAnimation()
|
||||
h = gdk_pixbuf_animation_get_height(m_anim);
|
||||
|
||||
// update our size to fit animation
|
||||
//if (w > 0 && h > 0)
|
||||
// gtk_widget_set_size_request(m_widget, w, h);
|
||||
SetSize(w, h);
|
||||
}
|
||||
|
||||
@ -324,6 +313,49 @@ void wxAnimationCtrl::Stop()
|
||||
if (IsPlaying())
|
||||
m_timer.Stop();
|
||||
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
|
||||
@ -358,8 +390,6 @@ void wxAnimationCtrl::ClearToBackgroundColour()
|
||||
guint32 col = (clr.Red() << 24) | (clr.Green() << 16) | (clr.Blue() << 8);
|
||||
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);
|
||||
g_object_unref(newpix);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user