]> git.saurik.com Git - wxWidgets.git/commitdiff
[ 1580776 ] wxAnimationCtrl::SetInactiveBitmap
authorRobert Roebling <robert@roebling.de>
Sat, 21 Oct 2006 13:51:38 +0000 (13:51 +0000)
committerRobert Roebling <robert@roebling.de>
Sat, 21 Oct 2006 13:51:38 +0000 (13:51 +0000)
  Additionally call UnShare() in it.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42195 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/latex/wx/animatctrl.tex
include/wx/animate.h
include/wx/generic/animate.h
include/wx/gtk/animate.h
src/common/animatecmn.cpp
src/generic/animateg.cpp
src/gtk/animate.cpp

index 37036af48ded48e8cd7a47452bdd7e8e0a1a868d..ba36f1f97650f16dba5ef65da783aefc8ce282d4 100644 (file)
@@ -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).
+
+
+\membersection{wxAnimationCtrl::SetInactiveBitmap}\label{wxanimationctrlsetinactivebitmap}
+
+\func{void}{SetInactiveBitmap}{\param{const wxBitmap\& }{bmp}}
 
-If {\tt wxNullAnimation} is given as animation, the control will be cleared to display
-the background colour (see \helpref{wxWindow::GetBackgroundColour}{wxwindowgetbackgroundcolour}).
+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.
 
index 1e0d6fc039b5346a8421568f88f438077619b1e4..583b1afc74eab829baa1f5844bdfde3a8e282500 100644 (file)
@@ -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)
 };
index 09b22bd59370727995857afd0c13eb8610e7a900..f56056e5956087c88bb571f1a96687fb5cc3797f 100644 (file)
@@ -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);
index fcd39a378413297d863624745003e16472210c87..56dd791cf9a44191d0f2c837368460e5d9c9b803 100644 (file)
@@ -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();
index d3b69867f56762ea408d661f15e97f41b48dd933..e9c0b8678a2d85753c23d81f47ee3cbe921081e7 100644 (file)
 #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
index 1bda5864672ae4de05eeac00772664cdf65140d1..2035cbb4f4b665900d77c7a0972600e2d1561801 100644 (file)
@@ -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
index cb596e7bd5d9dcf7ec4a3287ed0e444414cc2cfa..a2e17e22aa537e458199520bad660382cec3a1be 100644 (file)
@@ -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);
 }