#pragma hdrstop
#endif //__BORLANDC__
-#if wxUSE_ANIMATIONCTRL
+#if wxUSE_ANIMATIONCTRL && (!defined(__WXGTK20__) || defined(__WXUNIVERSAL__))
#include "wx/animate.h"
const wxAnimation& animation, const wxPoint& pos,
const wxSize& size, long style, const wxString& name)
{
- m_animation = animation;
m_timer.SetOwner(this);
if (!base_type::Create(parent, id, pos, size, style, wxDefaultValidator, name))
// by default we get the same background colour of our parent
SetBackgroundColour(parent->GetBackgroundColour());
+
+ SetAnimation(animation);
+
return true;
}
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)
+{
+ m_bmpStatic = bmp;
+
+ // if not playing, update the backing store now
+ if (!IsPlaying())
+ UpdateBackingStoreWithStaticImage();
}
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)
if (!m_animation.IsOk())
return false;
- int oldframe = m_currentFrame;
m_looped = looped;
m_currentFrame = 0;
- // small optimization: if the back store was already updated to the
- // first frame, don't rebuild it
- if (oldframe != 0)
- if (!RebuildBackingStoreUpToFrame(0))
- return false;
+ if (!RebuildBackingStoreUpToFrame(0))
+ return false;
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);
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:
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)
// 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))
// Should a non-looped animation display the last frame?
if (!m_looped)
{
- m_timer.Stop();
- m_isPlaying = false;
+ Stop();
return;
}
else
{
// NB: resizing an animation control may take a lot of time
// for big animations as the backing store must be
- // extended and rebuilt. Try to avoid it!!
+ // extended and rebuilt. Try to avoid it e.g. using
+ // a null proportion value for your wxAnimationCtrls
+ // when using them inside sizers.
if (m_animation.IsOk())
+ {
+ // be careful to change the backing store *only* if we are
+ // playing the animation as otherwise we may be displaying
+ // the inactive bitmap and overwriting the backing store
+ // with the last played frame is wrong in this case
+ if (IsPlaying())
+ {
if (!RebuildBackingStoreUpToFrame(m_currentFrame))
Stop(); // in case we are playing
+ }
+ }
}
#endif // wxUSE_ANIMATIONCTRL