]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/animateg.cpp
another GradientFillLinear fix
[wxWidgets.git] / src / generic / animateg.cpp
index 7c156123b4d1699302b0da25d2b4f8fc33e4a8bc..c7e55f4f92e862dbd0d582e85f10f229dcf6fca7 100644 (file)
@@ -15,7 +15,7 @@
   #pragma hdrstop
 #endif  //__BORLANDC__
 
-#if wxUSE_ANIMATIONCTRL
+#if wxUSE_ANIMATIONCTRL && (!defined(__WXGTK20__) || defined(__WXUNIVERSAL__))
 
 #include "wx/animate.h"
 
@@ -288,7 +288,6 @@ bool wxAnimationCtrl::Create(wxWindow *parent, wxWindowID id,
             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))
@@ -296,6 +295,9 @@ bool wxAnimationCtrl::Create(wxWindow *parent, wxWindowID id,
 
     // by default we get the same background colour of our parent
     SetBackgroundColour(parent->GetBackgroundColour());
+
+    SetAnimation(animation);
+
     return true;
 }
 
@@ -335,27 +337,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)
+{
+    m_bmpStatic = bmp;
+
+    // if not playing, update the backing store now
+    if (!IsPlaying())
+        UpdateBackingStoreWithStaticImage();
 }
 
 void wxAnimationCtrl::FitToAnimation()
@@ -370,9 +364,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)
@@ -380,18 +375,18 @@ 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);
@@ -505,6 +500,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 +541,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 +582,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 +600,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
@@ -599,10 +628,21 @@ void wxAnimationCtrl::OnSize(wxSizeEvent &WXUNUSED(event))
 {
     // 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