From 05a98b6d5d201eb8edea04b1ab022e4a9a46e9f0 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Wed, 11 Oct 2006 16:09:39 +0000 Subject: [PATCH] Fix part of [ 1570325 ] wxAnimationCtrl for wxAdv library git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@41940 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/anidecod.h | 1 + include/wx/animdecod.h | 3 ++ include/wx/generic/animate.h | 11 +++++- include/wx/gifdecod.h | 3 +- include/wx/gtk/animate.h | 6 ++- src/common/anidecod.cpp | 12 ++++++ src/common/gifdecod.cpp | 16 +++++++- src/generic/animateg.cpp | 71 ++++++++++++++++++++++++++++-------- src/gtk/animate.cpp | 5 +-- 9 files changed, 103 insertions(+), 25 deletions(-) diff --git a/include/wx/anidecod.h b/include/wx/anidecod.h index 723c352398..176a631904 100644 --- a/include/wx/anidecod.h +++ b/include/wx/anidecod.h @@ -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. diff --git a/include/wx/animdecod.h b/include/wx/animdecod.h index 4e89b4f9e9..af82c389ec 100644 --- a/include/wx/animdecod.h +++ b/include/wx/animdecod.h @@ -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; } diff --git a/include/wx/generic/animate.h b/include/wx/generic/animate.h index ef79045471..09b22bd593 100644 --- a/include/wx/generic/animate.h +++ b/include/wx/generic/animate.h @@ -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; diff --git a/include/wx/gifdecod.h b/include/wx/gifdecod.h index 346ae800b9..8761fa749c 100644 --- a/include/wx/gifdecod.h +++ b/include/wx/gifdecod.h @@ -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; diff --git a/include/wx/gtk/animate.h b/include/wx/gtk/animate.h index b58865029e..fcd39a3784 100644 --- a/include/wx/gtk/animate.h +++ b/include/wx/gtk/animate.h @@ -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, diff --git a/src/common/anidecod.cpp b/src/common/anidecod.cpp index 7f90c8fdeb..7d502ae52a 100644 --- a/src/common/anidecod.cpp +++ b/src/common/anidecod.cpp @@ -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 diff --git a/src/common/gifdecod.cpp b/src/common/gifdecod.cpp index ab507b8d7f..a96e64b18d 100644 --- a/src/common/gifdecod.cpp +++ b/src/common/gifdecod.cpp @@ -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); } diff --git a/src/generic/animateg.cpp b/src/generic/animateg.cpp index 062855d926..7c156123b4 100644 --- a/src/generic/animateg.cpp +++ b/src/generic/animateg.cpp @@ -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 diff --git a/src/gtk/animate.cpp b/src/gtk/animate.cpp index 1eb6239e95..cf7fa686a3 100644 --- a/src/gtk/animate.cpp +++ b/src/gtk/animate.cpp @@ -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); -- 2.45.2