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
This commit is contained in:
Robert Roebling
2006-10-11 16:09:39 +00:00
parent a51cb1e67b
commit 05a98b6d5d
9 changed files with 103 additions and 25 deletions

View File

@@ -49,6 +49,7 @@ public:
virtual wxPoint GetFramePosition(size_t frame) const; virtual wxPoint GetFramePosition(size_t frame) const;
virtual wxAnimationDisposal GetDisposalMethod(size_t frame) const; virtual wxAnimationDisposal GetDisposalMethod(size_t frame) const;
virtual long GetDelay(size_t frame) const; virtual long GetDelay(size_t frame) const;
virtual wxColour GetTransparentColour(size_t frame) const;
public: public:
// constructor, destructor, etc. // constructor, destructor, etc.

View File

@@ -112,6 +112,9 @@ public: // frame specific data getters
// if returns -1 then the frame must be displayed forever. // if returns -1 then the frame must be displayed forever.
virtual long GetDelay(size_t frame) const = 0; 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 // get global data
wxSize GetAnimationSize() const { return m_szAnimation; } wxSize GetAnimationSize() const { return m_szAnimation; }
wxColour GetBackgroundColour() const { return m_background; } wxColour GetBackgroundColour() const { return m_background; }

View File

@@ -42,7 +42,9 @@ public:
public: // extended interface used by the generic implementation of wxAnimationCtrl public: // extended interface used by the generic implementation of wxAnimationCtrl
wxPoint GetFramePosition(size_t frame) const; wxPoint GetFramePosition(size_t frame) const;
wxSize GetFrameSize(size_t frame) const;
wxAnimationDisposal GetDisposalMethod(size_t frame) const; wxAnimationDisposal GetDisposalMethod(size_t frame) const;
wxColour GetTransparentColour(size_t frame) const;
wxColour GetBackgroundColour() const; wxColour GetBackgroundColour() const;
protected: protected:
@@ -68,7 +70,7 @@ public:
class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase
{ {
public: public:
wxAnimationCtrl(); wxAnimationCtrl() { Init(); }
wxAnimationCtrl(wxWindow *parent, wxAnimationCtrl(wxWindow *parent,
wxWindowID id, wxWindowID id,
const wxAnimation& anim = wxNullAnimation, const wxAnimation& anim = wxNullAnimation,
@@ -77,9 +79,13 @@ public:
long style = wxAC_DEFAULT_STYLE, long style = wxAC_DEFAULT_STYLE,
const wxString& name = wxAnimationCtrlNameStr) const wxString& name = wxAnimationCtrlNameStr)
{ {
Init();
Create(parent, id, anim, pos, size, style, name); Create(parent, id, anim, pos, size, style, name);
} }
void Init();
bool Create(wxWindow *parent, wxWindowID id, bool Create(wxWindow *parent, wxWindowID id,
const wxAnimation& anim = wxNullAnimation, const wxAnimation& anim = wxNullAnimation,
const wxPoint& pos = wxDefaultPosition, 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. // Draw the background; use this when e.g. previous frame had wxANIM_TOBACKGROUND disposal.
void DisposeToBackground(wxDC& dc); void DisposeToBackground(wxDC& dc);
void DisposeToBackground(wxDC& dc, const wxPoint &pos, const wxSize &sz);
void IncrementalUpdateBackingStore(); void IncrementalUpdateBackingStore();
void RebuildBackingStoreUpToFrame(size_t); bool RebuildBackingStoreUpToFrame(size_t);
void DrawFrame(wxDC &dc, size_t); void DrawFrame(wxDC &dc, size_t);
virtual wxSize DoGetBestSize() const; virtual wxSize DoGetBestSize() const;

View File

@@ -71,7 +71,8 @@ public:
unsigned char* GetData(size_t frame) const; unsigned char* GetData(size_t frame) const;
unsigned char* GetPalette(size_t frame) const; unsigned char* GetPalette(size_t frame) const;
unsigned int GetNcolours(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 wxSize GetFrameSize(size_t frame) const;
virtual wxPoint GetFramePosition(size_t frame) const; virtual wxPoint GetFramePosition(size_t frame) const;

View File

@@ -89,7 +89,7 @@ private:
class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase class WXDLLIMPEXP_ADV wxAnimationCtrl: public wxAnimationCtrlBase
{ {
public: public:
wxAnimationCtrl(); wxAnimationCtrl() { Init(); }
wxAnimationCtrl(wxWindow *parent, wxAnimationCtrl(wxWindow *parent,
wxWindowID id, wxWindowID id,
const wxAnimation& anim = wxNullAnimation, const wxAnimation& anim = wxNullAnimation,
@@ -98,9 +98,13 @@ public:
long style = wxAC_DEFAULT_STYLE, long style = wxAC_DEFAULT_STYLE,
const wxString& name = wxAnimationCtrlNameStr) const wxString& name = wxAnimationCtrlNameStr)
{ {
Init();
Create(parent, id, anim, pos, size, style, name); Create(parent, id, anim, pos, size, style, name);
} }
void Init();
bool Create(wxWindow *parent, wxWindowID id, bool Create(wxWindow *parent, wxWindowID id,
const wxAnimation& anim = wxNullAnimation, const wxAnimation& anim = wxNullAnimation,
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,

View File

@@ -96,6 +96,18 @@ long wxANIDecoder::GetDelay(size_t frame) const
return m_info[frame].m_delay; 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 // ANI reading and decoding

View File

@@ -125,7 +125,7 @@ bool wxGIFDecoder::ConvertToImage(size_t frame, wxImage *image) const
pal = GetPalette(frame); pal = GetPalette(frame);
src = GetData(frame); src = GetData(frame);
dst = image->GetData(); dst = image->GetData();
transparent = GetTransparentColour(frame); transparent = GetTransparentColourIndex(frame);
/* set transparent colour mask */ /* set transparent colour mask */
if (transparent != -1) if (transparent != -1)
@@ -206,10 +206,22 @@ long wxGIFDecoder::GetDelay(size_t frame) const
return GetFrame(frame)->delay; 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::GetData(size_t frame) const { return (GetFrame(frame)->p); }
unsigned char* wxGIFDecoder::GetPalette(size_t frame) const { return (GetFrame(frame)->pal); } unsigned char* wxGIFDecoder::GetPalette(size_t frame) const { return (GetFrame(frame)->pal); }
unsigned int wxGIFDecoder::GetNcolours(size_t frame) const { return (GetFrame(frame)->ncolours); } 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); }

View File

@@ -82,6 +82,13 @@ wxPoint wxAnimation::GetFramePosition(size_t frame) const
return M_ANIMDATA->GetFramePosition(frame); 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 wxAnimationDisposal wxAnimation::GetDisposalMethod(size_t frame) const
{ {
wxCHECK_MSG( IsOk(), wxANIM_UNSPECIFIED, wxT("invalid animation") ); wxCHECK_MSG( IsOk(), wxANIM_UNSPECIFIED, wxT("invalid animation") );
@@ -89,6 +96,13 @@ wxAnimationDisposal wxAnimation::GetDisposalMethod(size_t frame) const
return M_ANIMDATA->GetDisposalMethod(frame); 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 wxColour wxAnimation::GetBackgroundColour() const
{ {
wxCHECK_MSG( IsOk(), wxNullColour, wxT("invalid animation") ); wxCHECK_MSG( IsOk(), wxNullColour, wxT("invalid animation") );
@@ -259,12 +273,15 @@ BEGIN_EVENT_TABLE(wxAnimationCtrl, wxAnimationCtrlBase)
EVT_TIMER(wxID_ANY, wxAnimationCtrl::OnTimer) EVT_TIMER(wxID_ANY, wxAnimationCtrl::OnTimer)
END_EVENT_TABLE() END_EVENT_TABLE()
wxAnimationCtrl::wxAnimationCtrl() void wxAnimationCtrl::Init()
{ {
m_currentFrame = 0; m_currentFrame = 0;
m_looped = false; m_looped = false;
m_isPlaying = 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, 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) const wxSize& size, long style, const wxString& name)
{ {
m_animation = animation; m_animation = animation;
m_currentFrame = 0;
m_looped = true;
m_isPlaying = false;
m_useWinBackgroundColour = false;
m_timer.SetOwner(this); m_timer.SetOwner(this);
if (!base_type::Create(parent, id, pos, size, style, wxDefaultValidator, name)) if (!base_type::Create(parent, id, pos, size, style, wxDefaultValidator, name))
@@ -325,7 +338,13 @@ void wxAnimationCtrl::SetAnimation(const wxAnimation& animation)
// display first frame // display first frame
m_currentFrame = 0; m_currentFrame = 0;
if (m_animation.IsOk()) if (m_animation.IsOk())
RebuildBackingStoreUpToFrame(0); {
if (!RebuildBackingStoreUpToFrame(0))
{
m_animation = wxNullAnimation;
return;
}
}
else else
{ {
// clear to // clear to
@@ -364,12 +383,14 @@ bool wxAnimationCtrl::Play(bool looped)
int oldframe = m_currentFrame; int oldframe = m_currentFrame;
m_looped = looped; m_looped = looped;
m_currentFrame = 0; m_currentFrame = 0;
m_isPlaying = true;
// small optimization: if the back store was already updated to the // small optimization: if the back store was already updated to the
// first frame, don't rebuild it // first frame, don't rebuild it
if (oldframe != 0) if (oldframe != 0)
RebuildBackingStoreUpToFrame(0); if (!RebuildBackingStoreUpToFrame(0))
return false;
m_isPlaying = true;
// DrawCurrentFrame() will use our updated backing store // DrawCurrentFrame() will use our updated backing store
wxClientDC clientDC(this); wxClientDC clientDC(this);
@@ -390,7 +411,7 @@ bool wxAnimationCtrl::Play(bool looped)
// wxAnimationCtrl - rendering methods // 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 // if we've not created the backing store yet or it's too
// small, then recreate it // small, then recreate it
@@ -402,7 +423,8 @@ void wxAnimationCtrl::RebuildBackingStoreUpToFrame(size_t frame)
if ( !m_backingStore.IsOk() || if ( !m_backingStore.IsOk() ||
m_backingStore.GetWidth() < w || m_backingStore.GetHeight() < h ) m_backingStore.GetWidth() < w || m_backingStore.GetHeight() < h )
{ {
m_backingStore.Create(w, h); if (!m_backingStore.Create(w, h))
return false;
} }
wxMemoryDC dc; wxMemoryDC dc;
@@ -419,11 +441,16 @@ void wxAnimationCtrl::RebuildBackingStoreUpToFrame(size_t frame)
{ {
DrawFrame(dc, i); 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 // finally draw this frame
DrawFrame(dc, frame); DrawFrame(dc, frame);
dc.SelectObject(wxNullBitmap); dc.SelectObject(wxNullBitmap);
return true;
} }
void wxAnimationCtrl::IncrementalUpdateBackingStore() void wxAnimationCtrl::IncrementalUpdateBackingStore()
@@ -447,7 +474,8 @@ void wxAnimationCtrl::IncrementalUpdateBackingStore()
switch (m_animation.GetDisposalMethod(m_currentFrame-1)) switch (m_animation.GetDisposalMethod(m_currentFrame-1))
{ {
case wxANIM_TOBACKGROUND: case wxANIM_TOBACKGROUND:
DisposeToBackground(dc); DisposeToBackground(dc, m_animation.GetFramePosition(m_currentFrame-1),
m_animation.GetFrameSize(m_currentFrame-1));
break; break;
case wxANIM_TOPREVIOUS: case wxANIM_TOPREVIOUS:
@@ -462,7 +490,8 @@ void wxAnimationCtrl::IncrementalUpdateBackingStore()
DisposeToBackground(dc); DisposeToBackground(dc);
} }
else else
RebuildBackingStoreUpToFrame(m_currentFrame-2); if (!RebuildBackingStoreUpToFrame(m_currentFrame-2))
Stop();
break; break;
case wxANIM_DONOTREMOVE: case wxANIM_DONOTREMOVE:
@@ -507,6 +536,17 @@ void wxAnimationCtrl::DisposeToBackground(wxDC& dc)
dc.Clear(); 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 // wxAnimationCtrl - event handlers
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -561,7 +601,8 @@ void wxAnimationCtrl::OnSize(wxSizeEvent &WXUNUSED(event))
// for big animations as the backing store must be // for big animations as the backing store must be
// extended and rebuilt. Try to avoid it!! // extended and rebuilt. Try to avoid it!!
if (m_animation.IsOk()) if (m_animation.IsOk())
RebuildBackingStoreUpToFrame(m_currentFrame); if (!RebuildBackingStoreUpToFrame(m_currentFrame))
Stop(); // in case we are playing
} }
#endif // wxUSE_ANIMATIONCTRL #endif // wxUSE_ANIMATIONCTRL

View File

@@ -180,7 +180,7 @@ BEGIN_EVENT_TABLE(wxAnimationCtrl, wxAnimationCtrlBase)
EVT_TIMER(wxID_ANY, wxAnimationCtrl::OnTimer) EVT_TIMER(wxID_ANY, wxAnimationCtrl::OnTimer)
END_EVENT_TABLE() END_EVENT_TABLE()
wxAnimationCtrl::wxAnimationCtrl() void wxAnimationCtrl::Init()
{ {
m_anim = NULL; m_anim = NULL;
m_iter = NULL; m_iter = NULL;
@@ -215,9 +215,6 @@ bool wxAnimationCtrl::Create( wxWindow *parent, wxWindowID id,
PostCreation(size); PostCreation(size);
SetBestSize(size); SetBestSize(size);
m_anim = NULL;
m_iter = NULL;
m_bPlaying = false;
if (anim != wxNullAnimation) if (anim != wxNullAnimation)
SetAnimation(anim); SetAnimation(anim);