]> git.saurik.com Git - wxWidgets.git/commitdiff
Fix part of [ 1570325 ] wxAnimationCtrl for wxAdv library
authorRobert Roebling <robert@roebling.de>
Wed, 11 Oct 2006 16:09:39 +0000 (16:09 +0000)
committerRobert Roebling <robert@roebling.de>
Wed, 11 Oct 2006 16:09:39 +0000 (16:09 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41940 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/anidecod.h
include/wx/animdecod.h
include/wx/generic/animate.h
include/wx/gifdecod.h
include/wx/gtk/animate.h
src/common/anidecod.cpp
src/common/gifdecod.cpp
src/generic/animateg.cpp
src/gtk/animate.cpp

index 723c35239891a5feac6ecf05f796add2b1f95a8d..176a631904c23ea1738925f8a1f786e44c55730d 100644 (file)
@@ -49,6 +49,7 @@ public:
     virtual wxPoint GetFramePosition(size_t frame) const;
     virtual wxAnimationDisposal GetDisposalMethod(size_t frame) const;
     virtual long GetDelay(size_t frame) const;
+    virtual wxColour GetTransparentColour(size_t frame) const;
 
 public:
     // constructor, destructor, etc.
index 4e89b4f9e9245947b04b65da9f9f14d04924dc77..af82c389ec45d4bc6632cb5693b4eec6307f91d3 100644 (file)
@@ -112,6 +112,9 @@ public:     // frame specific data getters
     // if returns -1 then the frame must be displayed forever.
     virtual long GetDelay(size_t frame) const = 0;
 
+    // the transparent colour for this frame if any or wxNullColour.
+    virtual wxColour GetTransparentColour(size_t frame) const = 0;
+
     // get global data
     wxSize GetAnimationSize() const { return m_szAnimation; }
     wxColour GetBackgroundColour() const { return m_background; }
index ef79045471209fd465370c808e8b20c3c0bcb625..09b22bd59370727995857afd0c13eb8610e7a900 100644 (file)
@@ -42,7 +42,9 @@ public:
 public:     // extended interface used by the generic implementation of wxAnimationCtrl
 
     wxPoint GetFramePosition(size_t frame) const;
+    wxSize GetFrameSize(size_t frame) const;
     wxAnimationDisposal GetDisposalMethod(size_t frame) const;
+    wxColour GetTransparentColour(size_t frame) const;
     wxColour GetBackgroundColour() const;
 
 protected:
@@ -68,7 +70,7 @@ public:
 class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase
 {
 public:
-    wxAnimationCtrl();
+    wxAnimationCtrl() { Init(); }
     wxAnimationCtrl(wxWindow *parent,
             wxWindowID id,
             const wxAnimation& anim = wxNullAnimation,
@@ -77,9 +79,13 @@ public:
             long style = wxAC_DEFAULT_STYLE,
             const wxString& name = wxAnimationCtrlNameStr)
     {
+        Init();
+
         Create(parent, id, anim, pos, size, style, name);
     }
 
+    void Init();
+
     bool Create(wxWindow *parent, wxWindowID id,
                 const wxAnimation& anim = wxNullAnimation,
                 const wxPoint& pos = wxDefaultPosition,
@@ -135,9 +141,10 @@ protected:      // internal utilities
 
     // Draw the background; use this when e.g. previous frame had wxANIM_TOBACKGROUND disposal.
     void DisposeToBackground(wxDC& dc);
+    void DisposeToBackground(wxDC& dc, const wxPoint &pos, const wxSize &sz);
 
     void IncrementalUpdateBackingStore();
-    void RebuildBackingStoreUpToFrame(size_t);
+    bool RebuildBackingStoreUpToFrame(size_t);
     void DrawFrame(wxDC &dc, size_t);
 
     virtual wxSize DoGetBestSize() const;
index 346ae800b940602f16680efc8ccebf87c62ad536..8761fa749c52a594a1f3d3e4c229d8b07471c7d1 100644 (file)
@@ -71,7 +71,8 @@ public:
     unsigned char* GetData(size_t frame) const;
     unsigned char* GetPalette(size_t frame) const;
     unsigned int GetNcolours(size_t frame) const;
-    int GetTransparentColour(size_t frame) const;
+    int GetTransparentColourIndex(size_t frame) const;
+    wxColour GetTransparentColour(size_t frame) const;
 
     virtual wxSize GetFrameSize(size_t frame) const;
     virtual wxPoint GetFramePosition(size_t frame) const;
index b58865029e220186d08697f023f5d8378239dcd4..fcd39a378413297d863624745003e16472210c87 100644 (file)
@@ -89,7 +89,7 @@ private:
 class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase
 {
 public:
-    wxAnimationCtrl();
+    wxAnimationCtrl() { Init(); }
     wxAnimationCtrl(wxWindow *parent,
                         wxWindowID id,
                         const wxAnimation& anim = wxNullAnimation,
@@ -98,9 +98,13 @@ public:
                         long style = wxAC_DEFAULT_STYLE,
                         const wxString& name = wxAnimationCtrlNameStr)
     {
+        Init();
+
         Create(parent, id, anim, pos, size, style, name);
     }
 
+    void Init();
+
     bool Create(wxWindow *parent, wxWindowID id,
                 const wxAnimation& anim = wxNullAnimation,
                 const wxPoint& pos = wxDefaultPosition,
index 7f90c8fdeb2d6d1a8607bea8751d9ff8afb8ea19..7d502ae52a4ed898c83572ad25ed848422421725 100644 (file)
@@ -96,6 +96,18 @@ long wxANIDecoder::GetDelay(size_t frame) const
     return m_info[frame].m_delay;
 }
 
+wxColour wxANIDecoder::GetTransparentColour(size_t frame) const
+{
+    size_t idx = m_info[frame].m_imageIndex;
+
+    if (!m_images[idx].HasMask())
+        return wxNullColour;
+
+    return wxColour(m_images[idx].GetMaskRed(),
+                    m_images[idx].GetMaskGreen(),
+                    m_images[idx].GetMaskBlue());
+}
+
 
 //---------------------------------------------------------------------------
 // ANI reading and decoding
index ab507b8d7f860fc7211306bba7185f8f52b54af1..a96e64b18d6e1e1f7e7f181d0118239689486e6d 100644 (file)
@@ -125,7 +125,7 @@ bool wxGIFDecoder::ConvertToImage(size_t frame, wxImage *image) const
     pal = GetPalette(frame);
     src = GetData(frame);
     dst = image->GetData();
-    transparent = GetTransparentColour(frame);
+    transparent = GetTransparentColourIndex(frame);
 
     /* set transparent colour mask */
     if (transparent != -1)
@@ -206,10 +206,22 @@ long wxGIFDecoder::GetDelay(size_t frame) const
     return GetFrame(frame)->delay;
 }
 
+wxColour wxGIFDecoder::GetTransparentColour(size_t frame) const
+{
+    unsigned char *pal = GetFrame(frame)->pal;
+    int n = GetFrame(frame)->transparent;
+    if (n == -1)
+        return wxNullColour;
+
+    return wxColour(pal[n*3 + 0],
+                    pal[n*3 + 1],
+                    pal[n*3 + 2]);
+}
+
 unsigned char* wxGIFDecoder::GetData(size_t frame) const    { return (GetFrame(frame)->p); }
 unsigned char* wxGIFDecoder::GetPalette(size_t frame) const { return (GetFrame(frame)->pal); }
 unsigned int wxGIFDecoder::GetNcolours(size_t frame) const  { return (GetFrame(frame)->ncolours); }
-int wxGIFDecoder::GetTransparentColour(size_t frame) const  { return (GetFrame(frame)->transparent); }
+int wxGIFDecoder::GetTransparentColourIndex(size_t frame) const  { return (GetFrame(frame)->transparent); }
 
 
 
index 062855d92687b61085f458e093faaeef9cff053d..7c156123b4d1699302b0da25d2b4f8fc33e4a8bc 100644 (file)
@@ -82,6 +82,13 @@ wxPoint wxAnimation::GetFramePosition(size_t frame) const
     return M_ANIMDATA->GetFramePosition(frame);
 }
 
+wxSize wxAnimation::GetFrameSize(size_t frame) const
+{
+    wxCHECK_MSG( IsOk(), wxDefaultSize, wxT("invalid animation") );
+
+    return M_ANIMDATA->GetFrameSize(frame);
+}
+
 wxAnimationDisposal wxAnimation::GetDisposalMethod(size_t frame) const
 {
     wxCHECK_MSG( IsOk(), wxANIM_UNSPECIFIED, wxT("invalid animation") );
@@ -89,6 +96,13 @@ wxAnimationDisposal wxAnimation::GetDisposalMethod(size_t frame) const
     return M_ANIMDATA->GetDisposalMethod(frame);
 }
 
+wxColour wxAnimation::GetTransparentColour(size_t frame) const
+{
+    wxCHECK_MSG( IsOk(), wxNullColour, wxT("invalid animation") );
+
+    return M_ANIMDATA->GetTransparentColour(frame);
+}
+
 wxColour wxAnimation::GetBackgroundColour() const
 {
     wxCHECK_MSG( IsOk(), wxNullColour, wxT("invalid animation") );
@@ -259,12 +273,15 @@ BEGIN_EVENT_TABLE(wxAnimationCtrl, wxAnimationCtrlBase)
     EVT_TIMER(wxID_ANY, wxAnimationCtrl::OnTimer)
 END_EVENT_TABLE()
 
-wxAnimationCtrl::wxAnimationCtrl()
+void wxAnimationCtrl::Init()
 {
     m_currentFrame = 0;
     m_looped = false;
     m_isPlaying = false;
-    m_useWinBackgroundColour = false;
+
+    // use the window background colour by default to be consistent
+    // with the GTK+ native version
+    m_useWinBackgroundColour = true;
 }
 
 bool wxAnimationCtrl::Create(wxWindow *parent, wxWindowID id,
@@ -272,10 +289,6 @@ bool wxAnimationCtrl::Create(wxWindow *parent, wxWindowID id,
             const wxSize& size, long style, const wxString& name)
 {
     m_animation = animation;
-    m_currentFrame = 0;
-    m_looped = true;
-    m_isPlaying = false;
-    m_useWinBackgroundColour = false;
     m_timer.SetOwner(this);
 
     if (!base_type::Create(parent, id, pos, size, style, wxDefaultValidator, name))
@@ -325,7 +338,13 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation& animation)
     // display first frame
     m_currentFrame = 0;
     if (m_animation.IsOk())
-        RebuildBackingStoreUpToFrame(0);
+    {
+        if (!RebuildBackingStoreUpToFrame(0))
+        {
+            m_animation = wxNullAnimation;
+            return;
+        }
+    }
     else
     {
         // clear to
@@ -364,12 +383,14 @@ bool wxAnimationCtrl::Play(bool looped)
     int oldframe = m_currentFrame;
     m_looped = looped;
     m_currentFrame = 0;
-    m_isPlaying = true;
 
     // small optimization: if the back store was already updated to the
     // first frame, don't rebuild it
     if (oldframe != 0)
-        RebuildBackingStoreUpToFrame(0);
+        if (!RebuildBackingStoreUpToFrame(0))
+            return false;
+
+    m_isPlaying = true;
 
     // DrawCurrentFrame() will use our updated backing store
     wxClientDC clientDC(this);
@@ -390,7 +411,7 @@ bool wxAnimationCtrl::Play(bool looped)
 // wxAnimationCtrl - rendering methods
 // ----------------------------------------------------------------------------
 
-void wxAnimationCtrl::RebuildBackingStoreUpToFrame(size_t frame)
+bool wxAnimationCtrl::RebuildBackingStoreUpToFrame(size_t frame)
 {
     // if we've not created the backing store yet or it's too
     // small, then recreate it
@@ -402,7 +423,8 @@ void wxAnimationCtrl::RebuildBackingStoreUpToFrame(size_t frame)
     if ( !m_backingStore.IsOk() ||
             m_backingStore.GetWidth() < w || m_backingStore.GetHeight() < h )
     {
-        m_backingStore.Create(w, h);
+        if (!m_backingStore.Create(w, h))
+            return false;
     }
 
     wxMemoryDC dc;
@@ -419,11 +441,16 @@ void wxAnimationCtrl::RebuildBackingStoreUpToFrame(size_t frame)
         {
             DrawFrame(dc, i);
         }
+        else if (m_animation.GetDisposalMethod(i) == wxANIM_TOBACKGROUND)
+            DisposeToBackground(dc, m_animation.GetFramePosition(i),
+                                    m_animation.GetFrameSize(i));
     }
 
     // finally draw this frame
     DrawFrame(dc, frame);
     dc.SelectObject(wxNullBitmap);
+
+    return true;
 }
 
 void wxAnimationCtrl::IncrementalUpdateBackingStore()
@@ -447,7 +474,8 @@ void wxAnimationCtrl::IncrementalUpdateBackingStore()
         switch (m_animation.GetDisposalMethod(m_currentFrame-1))
         {
         case wxANIM_TOBACKGROUND:
-            DisposeToBackground(dc);
+            DisposeToBackground(dc, m_animation.GetFramePosition(m_currentFrame-1),
+                                    m_animation.GetFrameSize(m_currentFrame-1));
             break;
 
         case wxANIM_TOPREVIOUS:
@@ -462,7 +490,8 @@ void wxAnimationCtrl::IncrementalUpdateBackingStore()
                 DisposeToBackground(dc);
             }
             else
-                RebuildBackingStoreUpToFrame(m_currentFrame-2);
+                if (!RebuildBackingStoreUpToFrame(m_currentFrame-2))
+                    Stop();
             break;
 
         case wxANIM_DONOTREMOVE:
@@ -501,12 +530,23 @@ void wxAnimationCtrl::DisposeToBackground(wxDC& dc)
 { 
     wxColour col = IsUsingWindowBackgroundColour()
                     ? GetBackgroundColour()
-                    : m_animation.GetBackgroundColour() ;
+                    : m_animation.GetBackgroundColour();
     wxBrush brush(col);
     dc.SetBackground(brush);
     dc.Clear();
 }
 
+void wxAnimationCtrl::DisposeToBackground(wxDC& dc, const wxPoint &pos, const wxSize &sz)
+{
+    wxColour col = IsUsingWindowBackgroundColour()
+                    ? GetBackgroundColour()
+                    : m_animation.GetBackgroundColour();
+    wxBrush brush(col);
+    dc.SetBrush(brush);         // SetBrush and not SetBackground !!
+    dc.SetPen(*wxTRANSPARENT_PEN);
+    dc.DrawRectangle(pos, sz);
+}
+
 // ----------------------------------------------------------------------------
 // wxAnimationCtrl - event handlers
 // ----------------------------------------------------------------------------
@@ -561,7 +601,8 @@ void wxAnimationCtrl::OnSize(wxSizeEvent &WXUNUSED(event))
     //     for big animations as the backing store must be
     //     extended and rebuilt. Try to avoid it!!
     if (m_animation.IsOk())
-        RebuildBackingStoreUpToFrame(m_currentFrame);
+        if (!RebuildBackingStoreUpToFrame(m_currentFrame))
+            Stop();     // in case we are playing
 }
 
 #endif      // wxUSE_ANIMATIONCTRL
index 1eb6239e95387d22cf043efd382cf8f33a0781f1..cf7fa686a382b4ff35d9d9b402f44648f12482eb 100644 (file)
@@ -180,7 +180,7 @@ BEGIN_EVENT_TABLE(wxAnimationCtrl, wxAnimationCtrlBase)
     EVT_TIMER(wxID_ANY, wxAnimationCtrl::OnTimer)
 END_EVENT_TABLE()
 
-wxAnimationCtrl::wxAnimationCtrl()
+void wxAnimationCtrl::Init()
 {
     m_anim = NULL;
     m_iter = NULL;
@@ -215,9 +215,6 @@ bool wxAnimationCtrl::Create( wxWindow *parent, wxWindowID id,
     PostCreation(size);
     SetBestSize(size);
 
-    m_anim = NULL;
-    m_iter = NULL;
-    m_bPlaying = false;
     if (anim != wxNullAnimation)
         SetAnimation(anim);