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.
// 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; }
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:
class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase
{
public:
- wxAnimationCtrl();
+ wxAnimationCtrl() { Init(); }
wxAnimationCtrl(wxWindow *parent,
wxWindowID id,
const wxAnimation& anim = wxNullAnimation,
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,
// 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;
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;
class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase
{
public:
- wxAnimationCtrl();
+ wxAnimationCtrl() { Init(); }
wxAnimationCtrl(wxWindow *parent,
wxWindowID id,
const wxAnimation& anim = wxNullAnimation,
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,
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
pal = GetPalette(frame);
src = GetData(frame);
dst = image->GetData();
- transparent = GetTransparentColour(frame);
+ transparent = GetTransparentColourIndex(frame);
/* set transparent colour mask */
if (transparent != -1)
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); }
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") );
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") );
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,
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))
// display first frame
m_currentFrame = 0;
if (m_animation.IsOk())
- RebuildBackingStoreUpToFrame(0);
+ {
+ if (!RebuildBackingStoreUpToFrame(0))
+ {
+ m_animation = wxNullAnimation;
+ return;
+ }
+ }
else
{
// clear to
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);
// 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
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;
{
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()
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:
DisposeToBackground(dc);
}
else
- RebuildBackingStoreUpToFrame(m_currentFrame-2);
+ if (!RebuildBackingStoreUpToFrame(m_currentFrame-2))
+ Stop();
break;
case wxANIM_DONOTREMOVE:
{
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
// ----------------------------------------------------------------------------
// 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
EVT_TIMER(wxID_ANY, wxAnimationCtrl::OnTimer)
END_EVENT_TABLE()
-wxAnimationCtrl::wxAnimationCtrl()
+void wxAnimationCtrl::Init()
{
m_anim = NULL;
m_iter = NULL;
PostCreation(size);
SetBestSize(size);
- m_anim = NULL;
- m_iter = NULL;
- m_bPlaying = false;
if (anim != wxNullAnimation)
SetAnimation(anim);