From 735ab537a890915040fa23dc17aeebab8900400a Mon Sep 17 00:00:00 2001 From: Rom Walton Date: Thu, 22 Jun 2006 18:54:42 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=10465 --- checkin_notes | 13 + clientgui/common/wxAnimate.cpp | 653 ++++++++++++++++++++++++++++ clientgui/common/wxAnimate.h | 336 ++++++++++++++ clientgui/common/wxFlatNotebook.cpp | 11 +- clientgui/common/wxFlatNotebook.h | 19 +- 5 files changed, 1012 insertions(+), 20 deletions(-) create mode 100644 clientgui/common/wxAnimate.cpp create mode 100644 clientgui/common/wxAnimate.h diff --git a/checkin_notes b/checkin_notes index 7d70d49c3a..e99a33ac8a 100755 --- a/checkin_notes +++ b/checkin_notes @@ -6508,6 +6508,19 @@ David 21 June 2006 sched/ file_upload_handler.C +Milos 21 June 2006 + - Initial checkin on the simple GUI + + clientgui/ + sg_BoincSimpleGUI.cpp, .h (Added) + sg_DlgPreferences.cpp, .h (Added) + sg_ImageLoader.cpp, .h (Added) + sg_SkinClass.cpp, .h (Added) + sg_StatImageLoader.cpp, .h (Added) + clientgui/common/ + wxFlatNotebook.cpp, .h (Added) + wxFNBDropTarget.h (Added) + wxAnimate.cpp (Added) Rom 21 June 2006 - Bug Fix: Two setup failure logs that were sent to me indicate that diff --git a/clientgui/common/wxAnimate.cpp b/clientgui/common/wxAnimate.cpp new file mode 100644 index 0000000000..ce993b8d08 --- /dev/null +++ b/clientgui/common/wxAnimate.cpp @@ -0,0 +1,653 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: animate.cpp +// Purpose: Implementation of wxAnimation classes +// Author: Julian Smart and Guillermo Rodriguez Garcia +// Modified by: +// Created: 13/8/99 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart and Guillermo Rodriguez Garcia +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma implementation "common/wxAnimate.h" +#endif + +#include "stdwx.h" +#include "common/wxAnimate.h" + +/* + * wxAnimationPlayer + */ + +IMPLEMENT_CLASS(wxAnimationPlayer, wxObject) + +wxAnimationPlayer::wxAnimationPlayer(wxAnimationBase *animation, bool destroyAnimation) +{ + m_animation = animation; + m_destroyAnimation = destroyAnimation; + m_currentFrame = 0; + m_window = (wxWindow*) NULL; + m_position = wxPoint(0, 0); + m_looped = TRUE; + m_isPlaying = FALSE; + m_useBackgroundColour = FALSE; + m_customBackgroundColour = wxColour(0, 0, 0); + m_useCustomBackgroundColour = FALSE; + m_useParentBackground = FALSE; + m_timer.SetPlayer(this); +} + +wxAnimationPlayer::~wxAnimationPlayer() +{ + Stop(); + ClearCache(); + + if (m_destroyAnimation) + delete m_animation; +} + +void wxAnimationPlayer::SetAnimation(wxAnimationBase* animation, bool destroyAnimation) +{ + ClearCache(); + if (m_destroyAnimation) + delete m_animation; + m_animation = animation; + m_destroyAnimation = destroyAnimation; +} + +// Play +bool wxAnimationPlayer::Play(wxWindow& window, const wxPoint& pos, bool WXUNUSED(looped)) +{ + m_window = & window; + + if (!m_animation || !m_animation->IsValid()) + return FALSE; + + wxSize sz = GetLogicalScreenSize(); + wxRect rect(pos, sz); + SaveBackground(rect); + + if (m_frames.GetCount() == 0) + { + if (!Build()) + { + wxLogWarning(_T("wxAnimationPlayer::Play: could not build the image cache.")); + return FALSE; + } + } + m_currentFrame = 0; + + // Create the backing store + m_backingStore.Create(sz.x, sz.y); + + PlayFrame(); + + return TRUE; +} + +// Build animation (list of wxImages). If not called before Play +// is called, Play will call this automatically. +bool wxAnimationPlayer::Build() +{ + ClearCache(); + if (!m_animation) + return false; + + int i, n; + + n = GetFrameCount(); + for (i = 0; i < n; i++) + { + wxImage* image = GetFrame(i); + if (image == NULL) + return false; + + // If the frame has transparency, + // set the colour so converting to a bitmap + // will create a mask + wxColour transparentColour; + if (GetTransparentColour(transparentColour)) + image->SetMaskColour(transparentColour.Red(), transparentColour.Green(), transparentColour.Blue()); + + wxBitmap* bitmap = new wxBitmap(*image); + delete image; + if (bitmap == NULL) + return false; + + m_frames.Append(bitmap); + } + + return true; +} + +// Stop the animation +void wxAnimationPlayer::Stop() +{ + m_timer.Stop(); + m_isPlaying = FALSE; +} + +// Draw the current view of the animation into this DC. +// Call this from your OnPaint, for example. +void wxAnimationPlayer::Draw(wxDC& dc) +{ + dc.DrawBitmap(m_backingStore, m_position.x, m_position.y); +} + +int wxAnimationPlayer::GetFrameCount() const +{ + if (m_animation) + return m_animation->GetFrameCount(); + else + return 0; +} + +wxImage* wxAnimationPlayer::GetFrame(int i) const +{ + if (m_animation) + return m_animation->GetFrame(i); + else + return (wxImage*) NULL; +} + +wxAnimationDisposal wxAnimationPlayer::GetDisposalMethod(int i) const +{ + if (m_animation) + return m_animation->GetDisposalMethod(i); + else + return wxANIM_UNSPECIFIED; +} + +wxRect wxAnimationPlayer::GetFrameRect(int i) const +{ + if (m_animation) + return m_animation->GetFrameRect(i); + else + return wxRect(0, 0, 0, 0); +} + +int wxAnimationPlayer::GetDelay(int i) const +{ + if (m_animation) + return m_animation->GetDelay(i); + else + return 0; +} + +wxSize wxAnimationPlayer::GetLogicalScreenSize() const +{ + if (m_animation) + return m_animation->GetLogicalScreenSize(); + else + return wxSize(0, 0); +} + +bool wxAnimationPlayer::GetBackgroundColour(wxColour& col) const +{ + if (m_animation) + return m_animation->GetBackgroundColour(col); + else + return FALSE; +} + +bool wxAnimationPlayer::GetTransparentColour(wxColour& col) const +{ + if (m_animation) + return m_animation->GetTransparentColour(col); + else + return FALSE; +} + +// Play the frame +bool wxAnimationPlayer::PlayFrame(int frame, wxWindow& window, const wxPoint& WXUNUSED(pos)) +{ + wxMemoryDC dc; + dc.SelectObject(m_backingStore); + + // Draw the background: colour or area beneath animation + wxColour col(255, 255, 255); + + if (UsingBackgroundColour()) + { + if (UsingCustomBackgroundColour()) + col = GetCustomBackgroundColour(); + else + { + GetBackgroundColour(col); + } + + // Draw the background colour loaded from the animation + // (or set by the user) + DrawBackground(dc, wxPoint(0, 0), col); + } + else + { + // Draw background we saved + dc.DrawBitmap(m_savedBackground, 0, 0); + } + + // Draw all intermediate frames that haven't been removed from the + // animation + int i; + for (i = 0; i < frame; i++) + { + if ((GetDisposalMethod(i) == wxANIM_DONOTREMOVE) || (GetDisposalMethod(i) == wxANIM_UNSPECIFIED)) + { + DrawFrame(i, dc, wxPoint(0, 0)); + } + } + DrawFrame(frame, dc, wxPoint(0, 0)); + + dc.SelectObject(wxNullBitmap); + + // Draw from backing bitmap onto window + wxClientDC clientDC(& window); + Draw(clientDC); + + return TRUE; +} + +bool wxAnimationPlayer::PlayFrame() +{ + m_isPlaying = TRUE; + + PlayFrame(GetCurrentFrame(), * GetWindow(), GetPosition()); + + // Set the timer for the next frame + int delay = GetDelay(GetCurrentFrame()); + if (delay == 0) + delay = 1; // 0 is invalid timeout for wxTimer. + + m_timer.Start(delay); + + m_currentFrame ++; + + if (m_currentFrame == GetFrameCount()) + { + // Should a non-looped animation display the last frame? + if (!m_looped) + { + m_timer.Stop(); + m_isPlaying = FALSE; + } + else + m_currentFrame = 0; + } + + return TRUE; +} + +// Clear the wxImage cache +void wxAnimationPlayer::ClearCache() +{ + wxList::compatibility_iterator node = m_frames.GetFirst(); + while (node) + { + wxList::compatibility_iterator next = node->GetNext(); + wxBitmap* bitmap = (wxBitmap*) node->GetData(); + delete bitmap; + m_frames.Erase(node); + node = next; + } +} + +// Draw the background colour +void wxAnimationPlayer::DrawBackground(wxDC& dc, const wxPoint& pos, const wxColour& colour) +{ + wxASSERT_MSG( (m_animation != NULL), _T("Animation not present in wxAnimationPlayer")); + wxASSERT_MSG( (m_frames.GetCount() != 0), _T("Animation cache not present in wxAnimationPlayer")); + + // Optimization: if the first frame fills the whole area, and is non-transparent, + // don't bother drawing the background + + wxBitmap* firstBitmap = (wxBitmap*) m_frames.GetFirst()->GetData() ; + wxSize screenSize = GetLogicalScreenSize(); + if (!firstBitmap->GetMask() && (firstBitmap->GetWidth() == screenSize.x) && (firstBitmap->GetHeight() == screenSize.y)) + { + return; + } + + wxBrush brush(colour, wxSOLID); + wxPen pen(colour, 1, wxSOLID); + dc.SetBrush(brush); + dc.SetPen(pen); + dc.SetLogicalFunction(wxCOPY); + + dc.DrawRectangle(pos.x, pos.y, screenSize.x, screenSize.y); +} + +// Save the pertinent area of the window so we can restore +// it if drawing transparently +void wxAnimationPlayer::SaveBackground(const wxRect& rect) +{ + wxASSERT( GetWindow() ); + + if (!GetWindow()) + return; + + m_savedBackground.Create(rect.width, rect.height); + + wxMemoryDC memDC; + memDC.SelectObject(m_savedBackground); + + if (m_useParentBackground && GetWindow()->GetParent()) + { + wxWindow* parent = GetWindow()->GetParent(); + wxClientDC dc(parent); + + // Translate the point to coordinates in the + // parent's client area, going via screen coordinates + wxPoint pt(rect.x, rect.y); + wxPoint screenPt = GetWindow()->ClientToScreen(pt); + wxPoint parentPt = parent->ScreenToClient(screenPt); + + memDC.Blit(0, 0, rect.width, rect.height, & dc, parentPt.x, parentPt.y); + } + else + { + wxClientDC dc(GetWindow()); + + memDC.Blit(0, 0, rect.width, rect.height, & dc, rect.x, rect.y); + } + memDC.SelectObject(wxNullBitmap); +} + +// Draw this frame +void wxAnimationPlayer::DrawFrame(int frame, wxDC& dc, const wxPoint& pos) +{ + wxASSERT_MSG( (m_animation != NULL), _T("Animation not present in wxAnimationPlayer")); + wxASSERT_MSG( (m_frames.GetCount() != 0), _T("Animation cache not present in wxAnimationPlayer")); + wxASSERT_MSG( !!m_frames.Item(frame), _T("Image not present in wxAnimationPlayer::DrawFrame")); + + wxBitmap* bitmap = (wxBitmap*) m_frames.Item(frame)->GetData() ; + + wxRect rect = GetFrameRect(frame); + + dc.DrawBitmap(* bitmap, pos.x + rect.x, pos.y + rect.y, (bitmap->GetMask() != NULL)); +} + +void wxAnimationTimer::Notify() +{ + m_player->PlayFrame(); +} + +/* + * wxAnimationBase + */ + +IMPLEMENT_ABSTRACT_CLASS(wxAnimationBase, wxObject) + +/* + * wxGIFAnimation + */ + +IMPLEMENT_CLASS(wxGIFAnimation, wxAnimationBase) + +wxGIFAnimation::wxGIFAnimation() +{ + m_decoder = (wxGIFDecoder*) NULL; +} + +wxGIFAnimation::~wxGIFAnimation() +{ + delete m_decoder; +} + +int wxGIFAnimation::GetFrameCount() const +{ + wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); + + return m_decoder->GetNumberOfFrames(); +} + +wxImage* wxGIFAnimation::GetFrame(int i) const +{ + wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); + + m_decoder->GoFrame(i + 1); + + wxImage* image = new wxImage; + m_decoder->ConvertToImage(image); + return image; +} + +wxAnimationDisposal wxGIFAnimation::GetDisposalMethod(int i) const +{ + wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); + + m_decoder->GoFrame(i + 1); + + int disposalMethod = m_decoder->GetDisposalMethod(); + return (wxAnimationDisposal) disposalMethod; +} + +wxRect wxGIFAnimation::GetFrameRect(int i) const +{ + wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); + + m_decoder->GoFrame(i + 1); + + wxRect rect(m_decoder->GetLeft(), m_decoder->GetTop(), m_decoder->GetWidth(), m_decoder->GetHeight()); + return rect; +} + +int wxGIFAnimation::GetDelay(int i) const +{ + wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); + + m_decoder->GoFrame(i + 1); + return m_decoder->GetDelay(); +} + +wxSize wxGIFAnimation::GetLogicalScreenSize() const +{ + wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); + + return wxSize(m_decoder->GetLogicalScreenWidth(), m_decoder->GetLogicalScreenHeight()); +} + +bool wxGIFAnimation::GetBackgroundColour(wxColour& col) const +{ + wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); + + int i = m_decoder->GetBackgroundColour(); + if (i == -1) + return false; + + const unsigned char *pal = m_decoder->GetPalette(); + bool result = (pal != NULL); + + if (result) + col = wxColour(pal[3*i + 0], pal[3*i + 1], pal[3*i + 2]); + + return result; +} + +bool wxGIFAnimation::GetTransparentColour(wxColour& col) const +{ + wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); + + int i = m_decoder->GetTransparentColour(); + if (i == -1) + return false; + + const unsigned char *pal = m_decoder->GetPalette(); + bool result = (pal != NULL); + + if (result) + col = wxColour(pal[3*i + 0], pal[3*i + 1], pal[3*i + 2]); + + return result; +} + +bool wxGIFAnimation::IsValid() const +{ + return ((m_decoder != NULL) && (m_decoder->IsAnimation())); +} + +bool wxGIFAnimation::LoadFile(const wxString& filename) +{ + if (!wxFileExists(filename)) + return false; + + bool result = true; + + if (m_decoder) + { + delete m_decoder; + m_decoder = NULL; + } + + { + wxFileInputStream stream(filename); + + if (stream.GetLength() > 0) + m_decoder = new wxGIFDecoder(&stream, true); + + result = ((m_decoder != NULL) && (m_decoder->ReadGIF() == wxGIF_OK)); + if (result) + result = m_decoder->IsAnimation(); + } + + if (!result && (m_decoder != NULL)) + { + delete m_decoder; + m_decoder = NULL; + } + + return result; +} + +/* + * wxAnimationCtrlBase + * Abstract base class for format-specific animation controls. + * This class implements most of the functionality; all a derived + * class has to do is create the appropriate animation class on demand. + */ + +IMPLEMENT_ABSTRACT_CLASS(wxAnimationCtrlBase, wxControl) + +BEGIN_EVENT_TABLE(wxAnimationCtrlBase, wxControl) + EVT_PAINT(wxAnimationCtrlBase::OnPaint) +END_EVENT_TABLE() + +bool wxAnimationCtrlBase::Create(wxWindow *parent, wxWindowID id, + const wxString& filename, const wxPoint& pos, + const wxSize& size, long style, const wxString& name) +{ + m_animation = NULL; + m_filename = filename; + + if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name)) + return FALSE; + + SetBackgroundColour(parent->GetBackgroundColour()); + + m_animationPlayer.SetCustomBackgroundColour(GetBackgroundColour()); + + // give the impression of transparency by painting + // with the parent background +// if (parent) +// m_animationPlayer.UseParentBackground(TRUE); + m_animationPlayer.SetWindow(this); + m_animationPlayer.SetPosition(wxPoint(0, 0)); + m_animationPlayer.SetDestroyAnimation(FALSE); + + LoadFile(filename); + + return TRUE; +} + +wxAnimationCtrlBase::~wxAnimationCtrlBase() +{ + if (m_animationPlayer.IsPlaying()) + m_animationPlayer.Stop(); + m_animationPlayer.SetAnimation(NULL, FALSE); + delete m_animation; +} + +bool wxAnimationCtrlBase::LoadFile(const wxString& filename) +{ + if (m_animationPlayer.IsPlaying()) + m_animationPlayer.Stop(); + + wxString filename1(filename); + + if (filename1.IsEmpty()) + filename1 = m_filename; + + if (filename1.IsEmpty()) + return FALSE; + + if (m_animation) + { + delete m_animation; + m_animation = NULL; + } + + m_animation = DoCreateAnimation(filename1); + if (!m_animation) + return FALSE; + + if (!m_animation->LoadFile(filename) || !m_animation->IsValid()) + { + delete m_animation; + m_animation = NULL; + return FALSE; + } + m_animationPlayer.SetAnimation(m_animation, FALSE); + + if (GetWindowStyle() & wxAN_FIT_ANIMATION) + FitToAnimation(); + + return TRUE; +} + +bool wxAnimationCtrlBase::Play(bool looped) +{ + return m_animationPlayer.Play(*this, wxPoint(0, 0), looped); +} + +wxSize wxAnimationCtrlBase::DoGetBestSize() const +{ + if (m_animationPlayer.HasAnimation() && (GetWindowStyle() & wxAN_FIT_ANIMATION)) + { + return m_animationPlayer.GetLogicalScreenSize(); + } + else + { + return GetSize(); + } +} + +void wxAnimationCtrlBase::FitToAnimation() +{ + if (!m_animationPlayer.HasAnimation()) + return; + + wxSize sz = m_animationPlayer.GetLogicalScreenSize(); + SetClientSize(sz); +} + +void wxAnimationCtrlBase::OnPaint(wxPaintEvent& WXUNUSED(event)) +{ + wxPaintDC dc(this); + + if (GetPlayer().IsPlaying()) + { + GetPlayer().Draw(dc); + } +} + +/* + * wxGIFAnimationCtrl + * Provides a GIF animation class when required. + */ + +IMPLEMENT_ABSTRACT_CLASS(wxGIFAnimationCtrl, wxAnimationCtrlBase) + +wxAnimationBase* wxGIFAnimationCtrl::DoCreateAnimation(const wxString& WXUNUSED(filename)) +{ + return new wxGIFAnimation; +} diff --git a/clientgui/common/wxAnimate.h b/clientgui/common/wxAnimate.h new file mode 100644 index 0000000000..579cc65885 --- /dev/null +++ b/clientgui/common/wxAnimate.h @@ -0,0 +1,336 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: animate.h +// Purpose: Animation classes +// Author: Julian Smart and Guillermo Rodriguez Garcia +// Modified by: +// Created: 13/8/99 +// RCS-ID: $Id$ +// Copyright: (c) Julian Smart and Guillermo Rodriguez Garcia +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_ANIMATEH__ +#define _WX_ANIMATEH__ + +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma interface "common/wxAnimate.cpp" +#endif + + +#ifdef WXMAKINGDLL_ANIMATE + #define WXDLLIMPEXP_ANIMATE WXEXPORT +#elif defined(WXUSINGDLL) + #define WXDLLIMPEXP_ANIMATE WXIMPORT +#else // not making nor using DLL + #define WXDLLIMPEXP_ANIMATE +#endif + +class WXDLLIMPEXP_ANIMATE wxAnimationBase; +class WXDLLIMPEXP_ANIMATE wxAnimationPlayer; +class WXDLLEXPORT wxImage; + +enum wxAnimationDisposal +{ + wxANIM_UNSPECIFIED = -1, + wxANIM_DONOTREMOVE = 0, + wxANIM_TOBACKGROUND = 1, + wxANIM_TOPREVIOUS = 2 +} ; + +class WXDLLIMPEXP_ANIMATE wxAnimationTimer: public wxTimer +{ +public: + wxAnimationTimer() { m_player = (wxAnimationPlayer*) NULL; } + + virtual void Notify(); + void SetPlayer(wxAnimationPlayer* player) { m_player = player; } + +protected: + wxAnimationPlayer* m_player; +}; + +/* wxAnimationPlayer + * Create an object of this class, and either pass an wxXXXAnimation object in + * the constructor, or call SetAnimation. Then call Play(). The wxAnimation + * object is only destroyed in the destructor if destroyAnimation is TRUE in + * the constructor. + */ + +class WXDLLIMPEXP_ANIMATE wxAnimationPlayer : public wxObject +{ + DECLARE_CLASS(wxAnimationPlayer) + +public: + wxAnimationPlayer(wxAnimationBase *animation = (wxAnimationBase *) NULL, bool destroyAnimation = FALSE); + ~wxAnimationPlayer(); +//// Accessors + + void SetAnimation(wxAnimationBase* animation, bool destroyAnimation = FALSE); + wxAnimationBase* GetAnimation() const { return m_animation; } + + void SetDestroyAnimation(bool destroyAnimation) { m_destroyAnimation = destroyAnimation; }; + bool GetDestroyAnimation() const { return m_destroyAnimation; } + + void SetCurrentFrame(int currentFrame) { m_currentFrame = currentFrame; }; + int GetCurrentFrame() const { return m_currentFrame; } + + void SetWindow(wxWindow* window) { m_window = window; }; + wxWindow* GetWindow() const { return m_window; } + + void SetPosition(const wxPoint& pos) { m_position = pos; }; + wxPoint GetPosition() const { return m_position; } + + void SetLooped(bool looped) { m_looped = looped; }; + bool GetLooped() const { return m_looped; } + + bool HasAnimation() const { return (m_animation != (wxAnimationBase*) NULL); } + + bool IsPlaying() const { return m_isPlaying; } + + // Specify whether the GIF's background colour is to be shown, + // or whether the window background should show through (the default) + void UseBackgroundColour(bool useBackground) { m_useBackgroundColour = useBackground; } + bool UsingBackgroundColour() const { return m_useBackgroundColour; } + + // Set and use a user-specified background colour (valid for transparent + // animations only) + void SetCustomBackgroundColour(const wxColour& col, bool useCustomBackgroundColour = TRUE) + { m_customBackgroundColour = col; m_useCustomBackgroundColour = useCustomBackgroundColour; } + + bool UsingCustomBackgroundColour() const { return m_useCustomBackgroundColour; } + const wxColour& GetCustomBackgroundColour() const { return m_customBackgroundColour; } + + // Another refinement - suppose we're drawing the animation in a separate + // control or window. We may wish to use the background of the parent + // window as the background of our animation. This allows us to specify + // whether to grab from the parent or from this window. + void UseParentBackground(bool useParent) { m_useParentBackground = useParent; } + bool UsingParentBackground() const { return m_useParentBackground; } + +//// Operations + + // Play + virtual bool Play(wxWindow& window, const wxPoint& pos = wxPoint(0, 0), bool looped = TRUE); + + // Build animation (list of wxImages). If not called before Play + // is called, Play will call this automatically. + virtual bool Build(); + + // Stop the animation + virtual void Stop(); + + // Draw the current view of the animation into this DC. + // Call this from your OnPaint, for example. + virtual void Draw(wxDC& dc); + +//// Accessing the current animation + + virtual int GetFrameCount() const; + virtual wxImage* GetFrame(int i) const; // Creates a new wxImage + virtual wxAnimationDisposal GetDisposalMethod(int i) const; + virtual wxRect GetFrameRect(int i) const; // Position and size of frame + virtual int GetDelay(int i) const; // Delay for this frame + + virtual wxSize GetLogicalScreenSize() const; + virtual bool GetBackgroundColour(wxColour& col) const ; + virtual bool GetTransparentColour(wxColour& col) const ; + +//// Implementation + + // Play the frame + virtual bool PlayFrame(int frame, wxWindow& window, const wxPoint& pos); + virtual bool PlayFrame(); + virtual void DrawFrame(int frame, wxDC& dc, const wxPoint& pos); + virtual void DrawBackground(wxDC& dc, const wxPoint& pos, const wxColour& colour); + + // Clear the wxImage cache + virtual void ClearCache(); + + // Save the pertinent area of the window so we can restore + // it if drawing transparently + void SaveBackground(const wxRect& rect); + + wxBitmap& GetBackingStore() { return m_backingStore; } + +//// Data members +protected: + wxAnimationBase* m_animation; + bool m_destroyAnimation; // Destroy m_animation on deletion of this object + wxList m_frames; // List of cached wxBitmap frames. + int m_currentFrame; // Current frame + wxWindow* m_window; // Window to draw into + wxPoint m_position; // Position to draw at + bool m_looped; // Looped, or not + wxAnimationTimer m_timer; // The timer + bool m_isPlaying; // Is the animation playing? + wxBitmap m_savedBackground; // Saved background of window portion + wxBitmap m_backingStore; // The player draws into this + bool m_useBackgroundColour; // Use colour or background + wxColour m_customBackgroundColour; // Override animation background + bool m_useCustomBackgroundColour; + bool m_useParentBackground; // Grab background from parent? +}; + +/* wxAnimationBase + * Base class for animations. + * A wxXXXAnimation only stores the animation, providing accessors to + * wxAnimationPlayer. Currently an animation is read-only, but we could + * extend the API for adding frames programmatically, and perhaps have a + * wxMemoryAnimation class that stores its frames in memory, and is able to + * save all files with suitable filenames. You could then use e.g. Ulead GIF + * Animator to load the image files into a GIF animation. + */ + +class WXDLLIMPEXP_ANIMATE wxAnimationBase : public wxObject +{ + DECLARE_ABSTRACT_CLASS(wxAnimationBase) + +public: + wxAnimationBase() {}; + ~wxAnimationBase() {}; + +//// Accessors. Should be overridden by each derived class. + + virtual int GetFrameCount() const = 0; + virtual wxImage* GetFrame(int i) const = 0; // Creates a new wxImage + virtual wxAnimationDisposal GetDisposalMethod(int i) const = 0; + virtual wxRect GetFrameRect(int i) const = 0; // Position and size of frame + virtual int GetDelay(int i) const = 0; // Delay for this frame + + virtual wxSize GetLogicalScreenSize() const = 0; + virtual bool GetBackgroundColour(wxColour& col) const = 0; + virtual bool GetTransparentColour(wxColour& col) const = 0; + + // Is the animation OK? + virtual bool IsValid() const = 0; + +//// Operations + + virtual bool LoadFile(const wxString& WXUNUSED(filename)) { return FALSE; } +}; + +/* wxGIFAnimation + * This will be moved to a separate file in due course. + */ + +class WXDLLIMPEXP_ANIMATE wxGIFDecoder; + +class WXDLLIMPEXP_ANIMATE wxGIFAnimation : public wxAnimationBase +{ + DECLARE_CLASS(wxGIFAnimation) + +public: + wxGIFAnimation() ; + ~wxGIFAnimation() ; + +//// Accessors + + virtual int GetFrameCount() const; + virtual wxImage* GetFrame(int i) const; + virtual wxAnimationDisposal GetDisposalMethod(int i) const; + virtual wxRect GetFrameRect(int i) const; // Position and size of frame + virtual int GetDelay(int i) const; // Delay for this frame + + virtual wxSize GetLogicalScreenSize() const ; + virtual bool GetBackgroundColour(wxColour& col) const ; + virtual bool GetTransparentColour(wxColour& col) const ; + + virtual bool IsValid() const; + +//// Operations + + virtual bool LoadFile(const wxString& filename); + +protected: + + wxGIFDecoder* m_decoder; +}; + +/* + * wxAnimationCtrlBase + * Abstract base class for format-specific animation controls. + * This class implements most of the functionality; all a derived + * class has to do is create the appropriate animation class on demand. + */ + +// Resize to animation size if this is set +#define wxAN_FIT_ANIMATION 0x0010 + +class WXDLLIMPEXP_ANIMATE wxAnimationCtrlBase: public wxControl +{ +public: + wxAnimationCtrlBase() { } + wxAnimationCtrlBase(wxWindow *parent, wxWindowID id, + const wxString& filename = wxEmptyString, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = wxAN_FIT_ANIMATION|wxNO_BORDER, + const wxString& name = wxT("animationControl")) + { + Create(parent, id, filename, pos, size, style, name); + } + ~wxAnimationCtrlBase(); + + bool Create(wxWindow *parent, wxWindowID id, + const wxString& filename = wxEmptyString, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = wxAN_FIT_ANIMATION|wxNO_BORDER, + const wxString& name = wxT("animationControl")); + + //// Operations + virtual bool LoadFile(const wxString& filename = wxEmptyString); + virtual bool Play(bool looped = TRUE) ; + virtual void Stop() { m_animationPlayer.Stop(); } + virtual void FitToAnimation(); + + //// Accessors + virtual bool IsPlaying() const { return m_animationPlayer.IsPlaying(); } + virtual wxAnimationPlayer& GetPlayer() { return m_animationPlayer; } + virtual wxAnimationBase* GetAnimation() { return m_animation; } + + const wxString& GetFilename() const { return m_filename; } + void SetFilename(const wxString& filename) { m_filename = filename; } + + //// Event handlers + void OnPaint(wxPaintEvent& event); + +protected: + virtual wxSize DoGetBestSize() const; + + // Override this in derived classes + virtual wxAnimationBase* DoCreateAnimation(const wxString& filename) = 0; + + wxAnimationPlayer m_animationPlayer; + wxAnimationBase* m_animation; + wxString m_filename; + +private: + DECLARE_ABSTRACT_CLASS(wxAnimationCtrlBase) + DECLARE_EVENT_TABLE() +}; + +/* + * wxGIFAnimationCtrl + * Provides a GIF animation class when required. + */ + +class WXDLLIMPEXP_ANIMATE wxGIFAnimationCtrl: public wxAnimationCtrlBase +{ +public: + wxGIFAnimationCtrl() { } + wxGIFAnimationCtrl(wxWindow *parent, wxWindowID id, + const wxString& filename = wxEmptyString, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, long style = wxAN_FIT_ANIMATION|wxNO_BORDER, + const wxString& name = wxT("animationControl")) + { + Create(parent, id, filename, pos, size, style, name); + } + +protected: + virtual wxAnimationBase* DoCreateAnimation(const wxString& filename) ; +private: + DECLARE_DYNAMIC_CLASS(wxGIFAnimationCtrl) +}; + +#endif // _WX_ANIMATEH__ + diff --git a/clientgui/common/wxFlatNotebook.cpp b/clientgui/common/wxFlatNotebook.cpp index f223cef1bc..ff27784e23 100644 --- a/clientgui/common/wxFlatNotebook.cpp +++ b/clientgui/common/wxFlatNotebook.cpp @@ -10,10 +10,13 @@ /////////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma implementation "common/wxFlatNotebook.h" +#endif + +#include "stdwx.h" +#include "common/wxFlatNotebook.h" + IMPLEMENT_DYNAMIC_CLASS(wxFlatNotebookEvent, wxNotifyEvent) DEFINE_EVENT_TYPE(wxEVT_COMMAND_FLATNOTEBOOK_PAGE_CHANGED) diff --git a/clientgui/common/wxFlatNotebook.h b/clientgui/common/wxFlatNotebook.h index c1032029a7..9bbdb685a2 100644 --- a/clientgui/common/wxFlatNotebook.h +++ b/clientgui/common/wxFlatNotebook.h @@ -12,24 +12,12 @@ #ifndef WXFLATNOTEBOOK_H #define WXFLATNOTEBOOK_H -#include - -#ifdef __VISUALC__ -#pragma warning( push ) -#pragma warning(disable: 4702) +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma interface "common/wxFlatNotebook.cpp" #endif -#include -#ifdef __VISUALC__ -#pragma warning(pop) -#endif - -#include -#include -#include - -#include +#include "common/wxFNBDropTarget.h" class wxPageContainerBase; @@ -37,7 +25,6 @@ class wxPageContainerBase; #define M_PI 3.14159265358979 #endif - typedef std::vector wxFlatNotebookImageList;