]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/animateg.cpp
avoid assert in DoGetBestSize() for an empty tree
[wxWidgets.git] / src / generic / animateg.cpp
index 8daee51ebf0e145887a69ccc79c42853bf8069d3..f69ba2dd86936eca5fcdfa1455de0cbf0e15efe8 100644 (file)
@@ -185,7 +185,6 @@ void wxAnimation::AddHandler( wxAnimationDecoder *handler )
         // for preventing duplicate additions.  If someone ever has
         // a good reason to add and remove duplicate handlers (and they
         // may) we should probably refcount the duplicates.
-        //   also an issue in InsertHandler below.
 
         wxLogDebug( _T("Adding duplicate animation handler for '%d' type"),
                     handler->GetType() );
@@ -288,7 +287,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 +294,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;
 }
 
@@ -328,26 +329,33 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation& animation)
     if (IsPlaying())
         Stop();
 
+    // set new animation even if it's wxNullAnimation
     m_animation = animation;
+    if (!m_animation.IsOk())
+    {
+        DisplayStaticImage();
+        return;
+    }
 
     if (m_animation.GetBackgroundColour() == wxNullColour)
         SetUseWindowBackgroundColour();
     if (!this->HasFlag(wxAC_NO_AUTORESIZE))
         FitToAnimation();
 
-    // reset frame counter
-    m_currentFrame = 0;
-
-    UpdateBackingStoreWithStaticImage();
+    DisplayStaticImage();
 }
 
 void wxAnimationCtrl::SetInactiveBitmap(const wxBitmap &bmp)
 {
-    m_bmpStatic = bmp;
+    // if the bitmap has an associated mask, we need to set our background to
+    // the colour of our parent otherwise when calling DrawCurrentFrame()
+    // (which uses the bitmap's mask), our background colour would be used for
+    // transparent areas - and that's not what we want (at least for
+    // consistency with the GTK version)
+    if ( bmp.GetMask() != NULL && GetParent() != NULL )
+        SetBackgroundColour(GetParent()->GetBackgroundColour());
 
-    // if not playing, update the backing store now
-    if (!IsPlaying())
-        UpdateBackingStoreWithStaticImage();
+    wxAnimationCtrlBase::SetInactiveBitmap(bmp);
 }
 
 void wxAnimationCtrl::FitToAnimation()
@@ -355,6 +363,19 @@ void wxAnimationCtrl::FitToAnimation()
     SetSize(m_animation.GetSize());
 }
 
+bool wxAnimationCtrl::SetBackgroundColour(const wxColour& colour)
+{
+    if ( !wxWindow::SetBackgroundColour(colour) )
+        return false;
+
+    // if not playing, then this change must be seen immediately (unless
+    // there's an inactive bitmap set which has higher priority than bg colour)
+    if ( !IsPlaying() )
+        DisplayStaticImage();
+
+    return true;
+}
+
 
 // ----------------------------------------------------------------------------
 // wxAnimationCtrl - stop/play methods
@@ -365,7 +386,10 @@ void wxAnimationCtrl::Stop()
     m_timer.Stop();
     m_isPlaying = false;
 
-    UpdateBackingStoreWithStaticImage();
+    // reset frame counter
+    m_currentFrame = 0;
+
+    DisplayStaticImage();
 }
 
 bool wxAnimationCtrl::Play(bool looped)
@@ -373,15 +397,11 @@ 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;
 
@@ -502,14 +522,26 @@ void wxAnimationCtrl::IncrementalUpdateBackingStore()
     dc.SelectObject(wxNullBitmap);
 }
 
-void wxAnimationCtrl::UpdateBackingStoreWithStaticImage()
+void wxAnimationCtrl::DisplayStaticImage()
 {
     wxASSERT(!IsPlaying());
 
-    if (m_bmpStatic.IsOk())
+    // m_bmpStaticReal will be updated only if necessary...
+    UpdateStaticImage();
+
+    if (m_bmpStaticReal.IsOk())
     {
         // copy the inactive bitmap in the backing store
-        m_backingStore = m_bmpStatic;
+        // eventually using the mask if the static bitmap has one
+        if ( m_bmpStaticReal.GetMask() )
+        {
+            wxMemoryDC temp;
+            temp.SelectObject(m_backingStore);
+            DisposeToBackground(temp);
+            temp.DrawBitmap(m_bmpStaticReal, 0, 0, true /* use mask */);
+        }
+        else
+            m_backingStore = m_bmpStaticReal;
     }
     else
     {
@@ -551,7 +583,8 @@ void wxAnimationCtrl::DisposeToBackground()
     // clear the backing store
     wxMemoryDC dc;
     dc.SelectObject(m_backingStore);
-    DisposeToBackground(dc);
+    if ( dc.IsOk() )
+        DisposeToBackground(dc);
 }
 
 void wxAnimationCtrl::DisposeToBackground(wxDC& dc)
@@ -559,6 +592,7 @@ void wxAnimationCtrl::DisposeToBackground(wxDC& dc)
     wxColour col = IsUsingWindowBackgroundColour()
                     ? GetBackgroundColour()
                     : m_animation.GetBackgroundColour();
+
     wxBrush brush(col);
     dc.SetBackground(brush);
     dc.Clear();
@@ -585,7 +619,12 @@ void wxAnimationCtrl::OnPaint(wxPaintEvent& WXUNUSED(event))
     wxPaintDC dc(this);
 
     if ( m_backingStore.IsOk() )
-        DrawCurrentFrame(dc);
+    {
+        // NOTE: we draw the bitmap explicitely ignoring the mask (if any);
+        //       i.e. we don't want to combine the backing store with the 
+        //       possibly wrong preexisting contents of the window!
+        dc.DrawBitmap(m_backingStore, 0, 0, false /* no mask */);
+    }
     else
     {
         // m_animation is not valid and thus we don't have a valid backing store...
@@ -641,8 +680,8 @@ void wxAnimationCtrl::OnSize(wxSizeEvent &WXUNUSED(event))
         // with the last played frame is wrong in this case
         if (IsPlaying())
         {
-        if (!RebuildBackingStoreUpToFrame(m_currentFrame))
-            Stop();     // in case we are playing
+            if (!RebuildBackingStoreUpToFrame(m_currentFrame))
+                Stop();     // in case we are playing
         }
     }
 }