From 1afdfc9debf357b7d53ce60c97bfa64c983cfa64 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 17 Nov 2006 18:14:42 +0000 Subject: [PATCH] - fix wxAnimationCtrl::SetBackgroundColour both for generic and native GTK version - fix wxAnimationCtrl::GetAnimation for GTK version (modifying correctly the constructor which takes a GdkPixbufAnimation) - fix the generic wxAnimationCtrl::SetAnimation() when it's used with a wxNullAnimation. - moves the frame counter reset in Stop() as it's more sensed to always have m_currentFrame cleared immediately when the animation has been stopped - fix a problem with transparent bitmaps drawing in wxAnimationCtrl::OnPaint (part of patch 1598005) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43475 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/generic/animate.h | 3 ++ include/wx/gtk/animate.h | 2 +- src/generic/animateg.cpp | 59 ++++++++++++++++++++++++++++++------ src/gtk/animate.cpp | 17 +++++++++-- 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/include/wx/generic/animate.h b/include/wx/generic/animate.h index fd7ee2a824..c053b172d6 100644 --- a/include/wx/generic/animate.h +++ b/include/wx/generic/animate.h @@ -107,6 +107,9 @@ public: void SetInactiveBitmap(const wxBitmap &bmp); + // override base class method + virtual bool SetBackgroundColour(const wxColour& col); + public: // event handlers void OnPaint(wxPaintEvent& event); diff --git a/include/wx/gtk/animate.h b/include/wx/gtk/animate.h index d9dbe1b72a..51d793766e 100644 --- a/include/wx/gtk/animate.h +++ b/include/wx/gtk/animate.h @@ -27,7 +27,7 @@ typedef struct _GdkPixbufAnimationIter GdkPixbufAnimationIter; class WXDLLIMPEXP_ADV wxAnimation : public wxAnimationBase { public: - wxAnimation(GdkPixbufAnimation *p = NULL) { m_pixbuf = p; } + wxAnimation(GdkPixbufAnimation *p = NULL); wxAnimation(const wxAnimation&); ~wxAnimation() { UnRef(); } diff --git a/src/generic/animateg.cpp b/src/generic/animateg.cpp index c7e55f4f92..2794e1a08f 100644 --- a/src/generic/animateg.cpp +++ b/src/generic/animateg.cpp @@ -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() ); @@ -330,16 +329,19 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation& animation) if (IsPlaying()) Stop(); + // set new animation even if it's wxNullAnimation m_animation = animation; + if (!m_animation.IsOk()) + { + UpdateBackingStoreWithStaticImage(); + return; + } if (m_animation.GetBackgroundColour() == wxNullColour) SetUseWindowBackgroundColour(); if (!this->HasFlag(wxAC_NO_AUTORESIZE)) FitToAnimation(); - // reset frame counter - m_currentFrame = 0; - UpdateBackingStoreWithStaticImage(); } @@ -347,8 +349,16 @@ 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()) + if ( !IsPlaying() ) UpdateBackingStoreWithStaticImage(); } @@ -357,6 +367,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() ) + UpdateBackingStoreWithStaticImage(); + + return true; +} + // ---------------------------------------------------------------------------- // wxAnimationCtrl - stop/play methods @@ -367,6 +390,9 @@ void wxAnimationCtrl::Stop() m_timer.Stop(); m_isPlaying = false; + // reset frame counter + m_currentFrame = 0; + UpdateBackingStoreWithStaticImage(); } @@ -507,7 +533,16 @@ void wxAnimationCtrl::UpdateBackingStoreWithStaticImage() if (m_bmpStatic.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_bmpStatic.GetMask() ) + { + wxMemoryDC temp; + temp.SelectObject(m_backingStore); + DisposeToBackground(temp); + temp.DrawBitmap(m_bmpStatic, 0, 0, true /* use mask */); + } + else + m_backingStore = m_bmpStatic; } else { @@ -557,6 +592,7 @@ void wxAnimationCtrl::DisposeToBackground(wxDC& dc) wxColour col = IsUsingWindowBackgroundColour() ? GetBackgroundColour() : m_animation.GetBackgroundColour(); + wxBrush brush(col); dc.SetBackground(brush); dc.Clear(); @@ -583,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... @@ -639,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 } } } diff --git a/src/gtk/animate.cpp b/src/gtk/animate.cpp index 05285756e6..ce570452ea 100644 --- a/src/gtk/animate.cpp +++ b/src/gtk/animate.cpp @@ -59,6 +59,13 @@ wxAnimation::wxAnimation(const wxAnimation& that) g_object_ref(m_pixbuf); } +wxAnimation::wxAnimation(GdkPixbufAnimation *p) +{ + m_pixbuf = p; + if ( m_pixbuf ) + g_object_ref(m_pixbuf); +} + wxAnimation& wxAnimation::operator=(const wxAnimation& that) { if (this != &that) @@ -271,7 +278,7 @@ void wxAnimationCtrl::FitToAnimation() h = gdk_pixbuf_animation_get_height(m_anim); // update our size to fit animation - SetSize(w, h); + SetSize(w, h); } void wxAnimationCtrl::ResetAnim() @@ -408,7 +415,13 @@ bool wxAnimationCtrl::SetBackgroundColour( const wxColour &colour ) // Thus we clear the GtkImage contents to the background colour... if (!wxControl::SetBackgroundColour(colour)) return false; - ClearToBackgroundColour(); + + // if not playing the change must take place immediately but + // remember that the inactive bitmap has higher priority over the background + // colour; DisplayStaticImage() will handle that + if ( !IsPlaying() ) + DisplayStaticImage(); + return true; } -- 2.45.2