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}
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)
};
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);
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:
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();
#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");
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
m_animation = animation;
if (!m_animation.IsOk())
{
- UpdateBackingStoreWithStaticImage();
+ DisplayStaticImage();
return;
}
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
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()
// 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;
}
// reset frame counter
m_currentFrame = 0;
- UpdateBackingStoreWithStaticImage();
+ DisplayStaticImage();
}
bool wxAnimationCtrl::Play(bool looped)
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
{
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