From 1bd2ceb57b0cc9f2b07b8bbb7d38d0e0d2381d3a Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Sat, 18 Nov 2006 17:46:29 +0000 Subject: [PATCH] [ 1598659 ] make wxAnimationCtrl::SetInactiveBitmap center given bitmap git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@43494 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/animatctrl.tex | 4 +++ include/wx/animate.h | 15 +++++++- include/wx/generic/animate.h | 4 +-- include/wx/gtk/animate.h | 3 +- src/common/animatecmn.cpp | 69 ++++++++++++++++++++++++++++++++++++ src/generic/animateg.cpp | 27 +++++++------- src/gtk/animate.cpp | 24 +++++-------- 7 files changed, 112 insertions(+), 34 deletions(-) diff --git a/docs/latex/wx/animatctrl.tex b/docs/latex/wx/animatctrl.tex index 7d0148a155..446efe41de 100644 --- a/docs/latex/wx/animatctrl.tex +++ b/docs/latex/wx/animatctrl.tex @@ -170,6 +170,10 @@ If the control is not playing the animation, the given bitmap will be immediatel shown, otherwise it will be shown as soon as \helpref{Stop}{wxanimationctrlstop} is called. +Note that the inactive bitmap, if smaller than the control's size, will be centered in +the control; if bigger, it will be stretched to fit it. + + \membersection{wxAnimationCtrl::Stop}\label{wxanimationctrlstop} \func{void}{Stop}{\void} diff --git a/include/wx/animate.h b/include/wx/animate.h index d228b37f19..5a0a5ad632 100644 --- a/include/wx/animate.h +++ b/include/wx/animate.h @@ -82,13 +82,26 @@ public: // public API virtual bool IsPlaying() const = 0; - virtual void SetInactiveBitmap(const wxBitmap &bmp) = 0; + virtual void SetInactiveBitmap(const wxBitmap &bmp); + + // always return the original bitmap set in this control wxBitmap GetInactiveBitmap() const { return m_bmpStatic; } protected: + // the inactive bitmap as it was set by the user wxBitmap m_bmpStatic; + // the inactive bitmap currently shown in the control + // (may differ in the size from m_bmpStatic) + wxBitmap m_bmpStaticReal; + + // updates m_bmpStaticReal from m_bmpStatic if needed + virtual void UpdateStaticImage(); + + // called by SetInactiveBitmap + virtual void DisplayStaticImage() = 0; + private: DECLARE_ABSTRACT_CLASS(wxAnimationCtrlBase) }; diff --git a/include/wx/generic/animate.h b/include/wx/generic/animate.h index c053b172d6..c46d1c2755 100644 --- a/include/wx/generic/animate.h +++ b/include/wx/generic/animate.h @@ -105,7 +105,7 @@ public: wxAnimation GetAnimation() const { return m_animation; } - void SetInactiveBitmap(const wxBitmap &bmp); + virtual void SetInactiveBitmap(const wxBitmap &bmp); // override base class method virtual bool SetBackgroundColour(const wxColour& col); @@ -146,11 +146,11 @@ protected: // internal utilities 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); + virtual void DisplayStaticImage(); virtual wxSize DoGetBestSize() const; protected: diff --git a/include/wx/gtk/animate.h b/include/wx/gtk/animate.h index 51d793766e..99ddd11f28 100644 --- a/include/wx/gtk/animate.h +++ b/include/wx/gtk/animate.h @@ -124,14 +124,13 @@ public: // public API virtual bool IsPlaying() const; bool SetBackgroundColour( const wxColour &colour ); - void SetInactiveBitmap(const wxBitmap &bmp); protected: + virtual void DisplayStaticImage(); virtual wxSize DoGetBestSize() const; void FitToAnimation(); void ClearToBackgroundColour(); - void DisplayStaticImage(); void ResetAnim(); void ResetIter(); diff --git a/src/common/animatecmn.cpp b/src/common/animatecmn.cpp index 512c309942..e18c6e8d34 100644 --- a/src/common/animatecmn.cpp +++ b/src/common/animatecmn.cpp @@ -21,6 +21,10 @@ #include "wx/animate.h" #include "wx/bitmap.h" +#include "wx/log.h" +#include "wx/brush.h" +#include "wx/image.h" +#include "wx/dcmemory.h" const wxChar wxAnimationCtrlNameStr[] = wxT("animationctrl"); @@ -31,4 +35,69 @@ IMPLEMENT_ABSTRACT_CLASS(wxAnimationBase, wxObject) IMPLEMENT_ABSTRACT_CLASS(wxAnimationCtrlBase, wxControl) +// ---------------------------------------------------------------------------- +// wxAnimationCtrlBase +// ---------------------------------------------------------------------------- + +void wxAnimationCtrlBase::UpdateStaticImage() +{ + if (!m_bmpStaticReal.IsOk() || !m_bmpStatic.IsOk()) + return; + + // if given bitmap is not of the right size, recreate m_bmpStaticReal accordingly + const wxSize &sz = GetClientSize(); + if (sz.GetWidth() != m_bmpStaticReal.GetWidth() || + sz.GetHeight() != m_bmpStaticReal.GetHeight()) + { + if (!m_bmpStaticReal.IsOk() || + m_bmpStaticReal.GetWidth() != sz.GetWidth() || + m_bmpStaticReal.GetHeight() != sz.GetHeight()) + { + // need to (re)create m_bmpStaticReal + if (!m_bmpStaticReal.Create(sz.GetWidth(), sz.GetHeight(), + m_bmpStatic.GetDepth())) + { + wxLogDebug(wxT("Cannot create the static bitmap")); + m_bmpStatic = wxNullBitmap; + return; + } + } + + if (m_bmpStatic.GetWidth() <= sz.GetWidth() && + m_bmpStatic.GetHeight() <= sz.GetHeight()) + { + // clear the background of m_bmpStaticReal + wxBrush brush(GetBackgroundColour()); + wxMemoryDC dc; + dc.SelectObject(m_bmpStaticReal); + dc.SetBackground(brush); + dc.Clear(); + + // center the user-provided bitmap in m_bmpStaticReal + dc.DrawBitmap(m_bmpStatic, + (sz.GetWidth()-m_bmpStatic.GetWidth())/2, + (sz.GetHeight()-m_bmpStatic.GetHeight())/2, + true /* use mask */ ); + } + else + { + // the user-provided bitmap is bigger than our control, strech it + wxImage temp(m_bmpStatic.ConvertToImage()); + temp.Rescale(sz.GetWidth(), sz.GetHeight(), wxIMAGE_QUALITY_HIGH); + m_bmpStaticReal = wxBitmap(temp); + } + } +} + +void wxAnimationCtrlBase::SetInactiveBitmap(const wxBitmap &bmp) +{ + m_bmpStatic = bmp; + m_bmpStaticReal = bmp; + + // if not playing, update the control now + // NOTE: DisplayStaticImage() will call UpdateStaticImage automatically + if ( !IsPlaying() ) + DisplayStaticImage(); +} + #endif // wxUSE_ANIMATIONCTRL diff --git a/src/generic/animateg.cpp b/src/generic/animateg.cpp index 2794e1a08f..dbdc6665d1 100644 --- a/src/generic/animateg.cpp +++ b/src/generic/animateg.cpp @@ -333,7 +333,7 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation& animation) m_animation = animation; if (!m_animation.IsOk()) { - UpdateBackingStoreWithStaticImage(); + DisplayStaticImage(); return; } @@ -342,13 +342,11 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation& animation) if (!this->HasFlag(wxAC_NO_AUTORESIZE)) FitToAnimation(); - 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 @@ -357,9 +355,7 @@ void wxAnimationCtrl::SetInactiveBitmap(const wxBitmap &bmp) 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() @@ -375,7 +371,7 @@ bool wxAnimationCtrl::SetBackgroundColour(const wxColour& colour) // 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(); + DisplayStaticImage(); return true; } @@ -393,7 +389,7 @@ void wxAnimationCtrl::Stop() // reset frame counter m_currentFrame = 0; - UpdateBackingStoreWithStaticImage(); + DisplayStaticImage(); } bool wxAnimationCtrl::Play(bool looped) @@ -526,23 +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 // eventually using the mask if the static bitmap has one - if ( m_bmpStatic.GetMask() ) + if ( m_bmpStaticReal.GetMask() ) { wxMemoryDC temp; temp.SelectObject(m_backingStore); DisposeToBackground(temp); - temp.DrawBitmap(m_bmpStatic, 0, 0, true /* use mask */); + temp.DrawBitmap(m_bmpStaticReal, 0, 0, true /* use mask */); } else - m_backingStore = m_bmpStatic; + m_backingStore = m_bmpStaticReal; } else { diff --git a/src/gtk/animate.cpp b/src/gtk/animate.cpp index ce570452ea..e3c6b9dc00 100644 --- a/src/gtk/animate.cpp +++ b/src/gtk/animate.cpp @@ -325,35 +325,29 @@ void wxAnimationCtrl::Stop() DisplayStaticImage(); } -void wxAnimationCtrl::SetInactiveBitmap(const wxBitmap &bmp) -{ - m_bmpStatic = bmp; - - // update the pixbuf associated with m_widget now... - if (!IsPlaying()) - DisplayStaticImage(); -} - void wxAnimationCtrl::DisplayStaticImage() { wxASSERT(!IsPlaying()); - if (m_bmpStatic.IsOk()) + // m_bmpStaticReal will be updated only if necessary... + UpdateStaticImage(); + + if (m_bmpStaticReal.IsOk()) { // show inactive bitmap GdkBitmap *mask = (GdkBitmap *) NULL; - if (m_bmpStatic.GetMask()) - mask = m_bmpStatic.GetMask()->GetBitmap(); + if (m_bmpStaticReal.GetMask()) + mask = m_bmpStaticReal.GetMask()->GetBitmap(); - if (m_bmpStatic.HasPixbuf()) + if (m_bmpStaticReal.HasPixbuf()) { gtk_image_set_from_pixbuf(GTK_IMAGE(m_widget), - m_bmpStatic.GetPixbuf()); + m_bmpStaticReal.GetPixbuf()); } else { gtk_image_set_from_pixmap(GTK_IMAGE(m_widget), - m_bmpStatic.GetPixmap(), mask); + m_bmpStaticReal.GetPixmap(), mask); } } else