]>
Commit | Line | Data |
---|---|---|
4638d697 JS |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: animate.cpp | |
3 | // Purpose: Implementation of wxAnimation classes | |
4 | // Author: Julian Smart and Guillermo Rodriguez Garcia | |
5 | // Modified by: | |
6 | // Created: 13/8/99 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Julian Smart and Guillermo Rodriguez Garcia | |
9 | // Licence: wxWindows licence | |
10 | /////////////////////////////////////////////////////////////////////////////// | |
11 | ||
4638d697 JS |
12 | #include "wx/wxprec.h" |
13 | ||
14 | #ifdef __BORLANDC__ | |
15 | #pragma hdrstop | |
16 | #endif //__BORLANDC__ | |
17 | ||
426195f9 | 18 | #include "wx/log.h" |
4638d697 JS |
19 | #include "wx/wfstream.h" |
20 | #include "wx/image.h" | |
21 | #include "wx/gifdecod.h" | |
cd2a4e16 | 22 | #include "wx/dcmemory.h" |
10217444 VS |
23 | #include "wx/dc.h" |
24 | #include "wx/dcclient.h" | |
426195f9 | 25 | #include "wx/animate/animate.h" |
4638d697 JS |
26 | |
27 | /* | |
28 | * wxAnimationPlayer | |
29 | */ | |
30 | ||
31 | IMPLEMENT_CLASS(wxAnimationPlayer, wxObject) | |
32 | ||
33 | wxAnimationPlayer::wxAnimationPlayer(wxAnimationBase *animation, bool destroyAnimation) | |
34 | { | |
35 | m_animation = animation; | |
36 | m_destroyAnimation = destroyAnimation; | |
426195f9 | 37 | m_customBackgroundColour = wxColour(0, 0, 0); |
4638d697 JS |
38 | m_currentFrame = 0; |
39 | m_window = (wxWindow*) NULL; | |
40 | m_position = wxPoint(0, 0); | |
426195f9 DS |
41 | m_looped = true; |
42 | m_isPlaying = false; | |
43 | m_useBackgroundColour = false; | |
44 | m_useCustomBackgroundColour = false; | |
45 | m_useParentBackground = false; | |
4638d697 JS |
46 | m_timer.SetPlayer(this); |
47 | } | |
48 | ||
49 | wxAnimationPlayer::~wxAnimationPlayer() | |
50 | { | |
51 | Stop(); | |
52 | ClearCache(); | |
53 | ||
54 | if (m_destroyAnimation) | |
55 | delete m_animation; | |
56 | } | |
57 | ||
58 | void wxAnimationPlayer::SetAnimation(wxAnimationBase* animation, bool destroyAnimation) | |
59 | { | |
60 | ClearCache(); | |
61 | if (m_destroyAnimation) | |
62 | delete m_animation; | |
63 | m_animation = animation; | |
64 | m_destroyAnimation = destroyAnimation; | |
65 | } | |
66 | ||
67 | // Play | |
87728739 | 68 | bool wxAnimationPlayer::Play(wxWindow& window, const wxPoint& pos, bool WXUNUSED(looped)) |
4638d697 JS |
69 | { |
70 | m_window = & window; | |
71 | ||
72 | if (!m_animation || !m_animation->IsValid()) | |
426195f9 | 73 | return false; |
4638d697 JS |
74 | |
75 | wxSize sz = GetLogicalScreenSize(); | |
76 | wxRect rect(pos, sz); | |
77 | SaveBackground(rect); | |
78 | ||
10217444 | 79 | if (m_frames.GetCount() == 0) |
4638d697 JS |
80 | { |
81 | if (!Build()) | |
82 | { | |
10217444 | 83 | wxLogWarning(_T("wxAnimationPlayer::Play: could not build the image cache.")); |
426195f9 DS |
84 | |
85 | return false; | |
4638d697 JS |
86 | } |
87 | } | |
426195f9 | 88 | |
4638d697 JS |
89 | m_currentFrame = 0; |
90 | ||
91 | // Create the backing store | |
92 | m_backingStore.Create(sz.x, sz.y); | |
93 | ||
94 | PlayFrame(); | |
95 | ||
426195f9 | 96 | return true; |
4638d697 JS |
97 | } |
98 | ||
99 | // Build animation (list of wxImages). If not called before Play | |
100 | // is called, Play will call this automatically. | |
101 | bool wxAnimationPlayer::Build() | |
102 | { | |
103 | ClearCache(); | |
426195f9 DS |
104 | if (!m_animation) |
105 | return false; | |
106 | ||
107 | int i, n; | |
108 | ||
109 | n = GetFrameCount(); | |
110 | for (i = 0; i < n; i++) | |
4638d697 | 111 | { |
426195f9 DS |
112 | wxImage* image = GetFrame(i); |
113 | if (image == NULL) | |
114 | return false; | |
115 | ||
116 | // If the frame has transparency, | |
117 | // set the colour so converting to a bitmap | |
118 | // will create a mask | |
119 | wxColour transparentColour; | |
120 | if (GetTransparentColour(transparentColour)) | |
121 | image->SetMaskColour(transparentColour.Red(), transparentColour.Green(), transparentColour.Blue()); | |
122 | ||
123 | wxBitmap* bitmap = new wxBitmap(*image); | |
124 | delete image; | |
125 | if (bitmap == NULL) | |
126 | return false; | |
127 | ||
128 | m_frames.Append(bitmap); | |
4638d697 | 129 | } |
426195f9 DS |
130 | |
131 | return true; | |
4638d697 JS |
132 | } |
133 | ||
134 | // Stop the animation | |
135 | void wxAnimationPlayer::Stop() | |
136 | { | |
137 | m_timer.Stop(); | |
426195f9 | 138 | m_isPlaying = false; |
4638d697 JS |
139 | } |
140 | ||
141 | // Draw the current view of the animation into this DC. | |
142 | // Call this from your OnPaint, for example. | |
143 | void wxAnimationPlayer::Draw(wxDC& dc) | |
144 | { | |
145 | dc.DrawBitmap(m_backingStore, m_position.x, m_position.y); | |
146 | } | |
147 | ||
4638d697 JS |
148 | int wxAnimationPlayer::GetFrameCount() const |
149 | { | |
150 | if (m_animation) | |
151 | return m_animation->GetFrameCount(); | |
152 | else | |
153 | return 0; | |
154 | } | |
155 | ||
156 | wxImage* wxAnimationPlayer::GetFrame(int i) const | |
157 | { | |
158 | if (m_animation) | |
159 | return m_animation->GetFrame(i); | |
160 | else | |
161 | return (wxImage*) NULL; | |
162 | } | |
163 | ||
164 | wxAnimationDisposal wxAnimationPlayer::GetDisposalMethod(int i) const | |
165 | { | |
166 | if (m_animation) | |
167 | return m_animation->GetDisposalMethod(i); | |
168 | else | |
169 | return wxANIM_UNSPECIFIED; | |
170 | } | |
171 | ||
172 | wxRect wxAnimationPlayer::GetFrameRect(int i) const | |
173 | { | |
174 | if (m_animation) | |
175 | return m_animation->GetFrameRect(i); | |
176 | else | |
177 | return wxRect(0, 0, 0, 0); | |
178 | } | |
179 | ||
180 | int wxAnimationPlayer::GetDelay(int i) const | |
181 | { | |
182 | if (m_animation) | |
183 | return m_animation->GetDelay(i); | |
184 | else | |
185 | return 0; | |
186 | } | |
187 | ||
188 | wxSize wxAnimationPlayer::GetLogicalScreenSize() const | |
189 | { | |
190 | if (m_animation) | |
191 | return m_animation->GetLogicalScreenSize(); | |
192 | else | |
193 | return wxSize(0, 0); | |
194 | } | |
195 | ||
196 | bool wxAnimationPlayer::GetBackgroundColour(wxColour& col) const | |
197 | { | |
198 | if (m_animation) | |
199 | return m_animation->GetBackgroundColour(col); | |
200 | else | |
426195f9 | 201 | return false; |
4638d697 JS |
202 | } |
203 | ||
204 | bool wxAnimationPlayer::GetTransparentColour(wxColour& col) const | |
205 | { | |
206 | if (m_animation) | |
207 | return m_animation->GetTransparentColour(col); | |
208 | else | |
426195f9 | 209 | return false; |
4638d697 JS |
210 | } |
211 | ||
212 | // Play the frame | |
87728739 | 213 | bool wxAnimationPlayer::PlayFrame(int frame, wxWindow& window, const wxPoint& WXUNUSED(pos)) |
4638d697 JS |
214 | { |
215 | wxMemoryDC dc; | |
216 | dc.SelectObject(m_backingStore); | |
217 | ||
218 | // Draw the background: colour or area beneath animation | |
219 | wxColour col(255, 255, 255); | |
220 | ||
221 | if (UsingBackgroundColour()) | |
222 | { | |
223 | if (UsingCustomBackgroundColour()) | |
224 | col = GetCustomBackgroundColour(); | |
225 | else | |
4638d697 | 226 | GetBackgroundColour(col); |
4638d697 JS |
227 | |
228 | // Draw the background colour loaded from the animation | |
229 | // (or set by the user) | |
230 | DrawBackground(dc, wxPoint(0, 0), col); | |
231 | } | |
232 | else | |
233 | { | |
234 | // Draw background we saved | |
235 | dc.DrawBitmap(m_savedBackground, 0, 0); | |
236 | } | |
237 | ||
426195f9 | 238 | // Draw all intermediate frames that haven't been removed from the animation |
4638d697 | 239 | int i; |
6b5403c8 | 240 | for (i = 0; i < frame; i++) |
4638d697 JS |
241 | { |
242 | if ((GetDisposalMethod(i) == wxANIM_DONOTREMOVE) || (GetDisposalMethod(i) == wxANIM_UNSPECIFIED)) | |
4638d697 | 243 | DrawFrame(i, dc, wxPoint(0, 0)); |
4638d697 | 244 | } |
426195f9 | 245 | |
4638d697 JS |
246 | DrawFrame(frame, dc, wxPoint(0, 0)); |
247 | ||
248 | dc.SelectObject(wxNullBitmap); | |
249 | ||
250 | // Draw from backing bitmap onto window | |
251 | wxClientDC clientDC(& window); | |
252 | Draw(clientDC); | |
253 | ||
426195f9 | 254 | return true; |
4638d697 JS |
255 | } |
256 | ||
257 | bool wxAnimationPlayer::PlayFrame() | |
258 | { | |
426195f9 | 259 | m_isPlaying = true; |
4638d697 JS |
260 | |
261 | PlayFrame(GetCurrentFrame(), * GetWindow(), GetPosition()); | |
262 | ||
263 | // Set the timer for the next frame | |
1c5f3f51 RD |
264 | int delay = GetDelay(GetCurrentFrame()); |
265 | if (delay == 0) | |
266 | delay = 1; // 0 is invalid timeout for wxTimer. | |
267 | ||
268 | m_timer.Start(delay); | |
4638d697 JS |
269 | |
270 | m_currentFrame ++; | |
271 | ||
272 | if (m_currentFrame == GetFrameCount()) | |
273 | { | |
274 | // Should a non-looped animation display the last frame? | |
275 | if (!m_looped) | |
276 | { | |
277 | m_timer.Stop(); | |
426195f9 | 278 | m_isPlaying = false; |
4638d697 JS |
279 | } |
280 | else | |
281 | m_currentFrame = 0; | |
282 | } | |
283 | ||
426195f9 | 284 | return true; |
4638d697 JS |
285 | } |
286 | ||
287 | // Clear the wxImage cache | |
288 | void wxAnimationPlayer::ClearCache() | |
289 | { | |
9c592b61 | 290 | wxList::compatibility_iterator node = m_frames.GetFirst(); |
4638d697 JS |
291 | while (node) |
292 | { | |
9c592b61 | 293 | wxList::compatibility_iterator next = node->GetNext(); |
10217444 | 294 | wxBitmap* bitmap = (wxBitmap*) node->GetData(); |
4638d697 | 295 | delete bitmap; |
9c592b61 | 296 | m_frames.Erase(node); |
426195f9 | 297 | |
4638d697 JS |
298 | node = next; |
299 | } | |
300 | } | |
301 | ||
302 | // Draw the background colour | |
303 | void wxAnimationPlayer::DrawBackground(wxDC& dc, const wxPoint& pos, const wxColour& colour) | |
304 | { | |
10217444 | 305 | wxASSERT_MSG( (m_animation != NULL), _T("Animation not present in wxAnimationPlayer")); |
426195f9 | 306 | wxASSERT_MSG( (m_frames.GetCount() > 0), _T("Animation cache not present in wxAnimationPlayer")); |
4638d697 JS |
307 | |
308 | // Optimization: if the first frame fills the whole area, and is non-transparent, | |
309 | // don't bother drawing the background | |
310 | ||
10217444 | 311 | wxBitmap* firstBitmap = (wxBitmap*) m_frames.GetFirst()->GetData() ; |
4638d697 JS |
312 | wxSize screenSize = GetLogicalScreenSize(); |
313 | if (!firstBitmap->GetMask() && (firstBitmap->GetWidth() == screenSize.x) && (firstBitmap->GetHeight() == screenSize.y)) | |
4638d697 | 314 | return; |
4638d697 JS |
315 | |
316 | wxBrush brush(colour, wxSOLID); | |
317 | wxPen pen(colour, 1, wxSOLID); | |
318 | dc.SetBrush(brush); | |
319 | dc.SetPen(pen); | |
320 | dc.SetLogicalFunction(wxCOPY); | |
321 | ||
322 | dc.DrawRectangle(pos.x, pos.y, screenSize.x, screenSize.y); | |
323 | } | |
324 | ||
325 | // Save the pertinent area of the window so we can restore | |
326 | // it if drawing transparently | |
327 | void wxAnimationPlayer::SaveBackground(const wxRect& rect) | |
328 | { | |
426195f9 | 329 | wxASSERT( (GetWindow() != NULL) ); |
4638d697 JS |
330 | |
331 | if (!GetWindow()) | |
332 | return; | |
333 | ||
334 | m_savedBackground.Create(rect.width, rect.height); | |
335 | ||
336 | wxMemoryDC memDC; | |
337 | memDC.SelectObject(m_savedBackground); | |
338 | ||
339 | if (m_useParentBackground && GetWindow()->GetParent()) | |
340 | { | |
341 | wxWindow* parent = GetWindow()->GetParent(); | |
342 | wxClientDC dc(parent); | |
343 | ||
344 | // Translate the point to coordinates in the | |
345 | // parent's client area, going via screen coordinates | |
346 | wxPoint pt(rect.x, rect.y); | |
347 | wxPoint screenPt = GetWindow()->ClientToScreen(pt); | |
348 | wxPoint parentPt = parent->ScreenToClient(screenPt); | |
349 | ||
350 | memDC.Blit(0, 0, rect.width, rect.height, & dc, parentPt.x, parentPt.y); | |
351 | } | |
352 | else | |
353 | { | |
354 | wxClientDC dc(GetWindow()); | |
355 | ||
356 | memDC.Blit(0, 0, rect.width, rect.height, & dc, rect.x, rect.y); | |
357 | } | |
426195f9 | 358 | |
4638d697 JS |
359 | memDC.SelectObject(wxNullBitmap); |
360 | } | |
361 | ||
362 | // Draw this frame | |
363 | void wxAnimationPlayer::DrawFrame(int frame, wxDC& dc, const wxPoint& pos) | |
364 | { | |
10217444 VS |
365 | wxASSERT_MSG( (m_animation != NULL), _T("Animation not present in wxAnimationPlayer")); |
366 | wxASSERT_MSG( (m_frames.GetCount() != 0), _T("Animation cache not present in wxAnimationPlayer")); | |
9c592b61 | 367 | wxASSERT_MSG( !!m_frames.Item(frame), _T("Image not present in wxAnimationPlayer::DrawFrame")); |
4638d697 | 368 | |
10217444 | 369 | wxBitmap* bitmap = (wxBitmap*) m_frames.Item(frame)->GetData() ; |
4638d697 JS |
370 | wxRect rect = GetFrameRect(frame); |
371 | ||
426195f9 | 372 | dc.DrawBitmap(*bitmap, pos.x + rect.x, pos.y + rect.y, (bitmap->GetMask() != NULL)); |
4638d697 JS |
373 | } |
374 | ||
375 | void wxAnimationTimer::Notify() | |
376 | { | |
377 | m_player->PlayFrame(); | |
378 | } | |
379 | ||
380 | /* | |
381 | * wxAnimationBase | |
382 | */ | |
383 | ||
384 | IMPLEMENT_ABSTRACT_CLASS(wxAnimationBase, wxObject) | |
385 | ||
386 | /* | |
387 | * wxGIFAnimation | |
388 | */ | |
389 | ||
390 | IMPLEMENT_CLASS(wxGIFAnimation, wxAnimationBase) | |
391 | ||
392 | wxGIFAnimation::wxGIFAnimation() | |
393 | { | |
394 | m_decoder = (wxGIFDecoder*) NULL; | |
395 | } | |
396 | ||
397 | wxGIFAnimation::~wxGIFAnimation() | |
398 | { | |
399 | delete m_decoder; | |
400 | } | |
401 | ||
402 | int wxGIFAnimation::GetFrameCount() const | |
403 | { | |
10217444 | 404 | wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); |
4638d697 JS |
405 | |
406 | return m_decoder->GetNumberOfFrames(); | |
407 | } | |
408 | ||
409 | wxImage* wxGIFAnimation::GetFrame(int i) const | |
410 | { | |
10217444 | 411 | wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); |
4638d697 | 412 | |
6b5403c8 | 413 | m_decoder->GoFrame(i + 1); |
4638d697 JS |
414 | |
415 | wxImage* image = new wxImage; | |
416 | m_decoder->ConvertToImage(image); | |
426195f9 | 417 | |
4638d697 JS |
418 | return image; |
419 | } | |
420 | ||
421 | wxAnimationDisposal wxGIFAnimation::GetDisposalMethod(int i) const | |
422 | { | |
10217444 | 423 | wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); |
4638d697 | 424 | |
6b5403c8 | 425 | m_decoder->GoFrame(i + 1); |
4638d697 JS |
426 | |
427 | int disposalMethod = m_decoder->GetDisposalMethod(); | |
428 | return (wxAnimationDisposal) disposalMethod; | |
429 | } | |
430 | ||
431 | wxRect wxGIFAnimation::GetFrameRect(int i) const | |
432 | { | |
10217444 | 433 | wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); |
4638d697 | 434 | |
6b5403c8 | 435 | m_decoder->GoFrame(i + 1); |
4638d697 JS |
436 | |
437 | wxRect rect(m_decoder->GetLeft(), m_decoder->GetTop(), m_decoder->GetWidth(), m_decoder->GetHeight()); | |
426195f9 | 438 | |
4638d697 JS |
439 | return rect; |
440 | } | |
441 | ||
442 | int wxGIFAnimation::GetDelay(int i) const | |
443 | { | |
10217444 | 444 | wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); |
4638d697 | 445 | |
6b5403c8 | 446 | m_decoder->GoFrame(i + 1); |
426195f9 | 447 | |
4638d697 JS |
448 | return m_decoder->GetDelay(); |
449 | } | |
450 | ||
451 | wxSize wxGIFAnimation::GetLogicalScreenSize() const | |
452 | { | |
10217444 | 453 | wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); |
4638d697 JS |
454 | |
455 | return wxSize(m_decoder->GetLogicalScreenWidth(), m_decoder->GetLogicalScreenHeight()); | |
456 | } | |
457 | ||
458 | bool wxGIFAnimation::GetBackgroundColour(wxColour& col) const | |
459 | { | |
10217444 | 460 | wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); |
4638d697 JS |
461 | |
462 | int i = m_decoder->GetBackgroundColour(); | |
463 | if (i == -1) | |
426195f9 | 464 | return false; |
4638d697 | 465 | |
426195f9 DS |
466 | const unsigned char *pal = m_decoder->GetPalette(); |
467 | bool result = (pal != NULL); | |
468 | ||
469 | if (result) | |
470 | col = wxColour(pal[3*i + 0], pal[3*i + 1], pal[3*i + 2]); | |
471 | ||
472 | return result; | |
4638d697 JS |
473 | } |
474 | ||
475 | bool wxGIFAnimation::GetTransparentColour(wxColour& col) const | |
476 | { | |
10217444 | 477 | wxASSERT_MSG( (m_decoder != (wxGIFDecoder*) NULL), _T("m_decoder must be non-NULL")); |
4638d697 JS |
478 | |
479 | int i = m_decoder->GetTransparentColour(); | |
480 | if (i == -1) | |
426195f9 | 481 | return false; |
4638d697 | 482 | |
426195f9 DS |
483 | const unsigned char *pal = m_decoder->GetPalette(); |
484 | bool result = (pal != NULL); | |
485 | ||
486 | if (result) | |
487 | col = wxColour(pal[3*i + 0], pal[3*i + 1], pal[3*i + 2]); | |
488 | ||
489 | return result; | |
4638d697 JS |
490 | } |
491 | ||
492 | bool wxGIFAnimation::IsValid() const | |
493 | { | |
494 | return ((m_decoder != NULL) && (m_decoder->IsAnimation())); | |
495 | } | |
496 | ||
497 | bool wxGIFAnimation::LoadFile(const wxString& filename) | |
498 | { | |
426195f9 DS |
499 | if (!wxFileExists(filename)) |
500 | return false; | |
501 | ||
502 | bool result = true; | |
503 | ||
4638d697 | 504 | if (m_decoder) |
426195f9 | 505 | { |
4638d697 | 506 | delete m_decoder; |
426195f9 DS |
507 | m_decoder = NULL; |
508 | } | |
4638d697 | 509 | |
4638d697 JS |
510 | { |
511 | wxFileInputStream stream(filename); | |
4638d697 | 512 | |
426195f9 DS |
513 | if (stream.GetLength() > 0) |
514 | m_decoder = new wxGIFDecoder(&stream, true); | |
4638d697 | 515 | |
426195f9 DS |
516 | result = ((m_decoder != NULL) && (m_decoder->ReadGIF() == wxGIF_OK)); |
517 | if (result) | |
518 | result = m_decoder->IsAnimation(); | |
519 | } | |
4638d697 | 520 | |
426195f9 DS |
521 | if (!result && (m_decoder != NULL)) |
522 | { | |
523 | delete m_decoder; | |
524 | m_decoder = NULL; | |
4638d697 | 525 | } |
426195f9 DS |
526 | |
527 | return result; | |
4638d697 JS |
528 | } |
529 | ||
530 | /* | |
531 | * wxAnimationCtrlBase | |
532 | * Abstract base class for format-specific animation controls. | |
533 | * This class implements most of the functionality; all a derived | |
534 | * class has to do is create the appropriate animation class on demand. | |
535 | */ | |
536 | ||
537 | IMPLEMENT_ABSTRACT_CLASS(wxAnimationCtrlBase, wxControl) | |
538 | ||
539 | BEGIN_EVENT_TABLE(wxAnimationCtrlBase, wxControl) | |
540 | EVT_PAINT(wxAnimationCtrlBase::OnPaint) | |
541 | END_EVENT_TABLE() | |
542 | ||
543 | bool wxAnimationCtrlBase::Create(wxWindow *parent, wxWindowID id, | |
544 | const wxString& filename, const wxPoint& pos, | |
545 | const wxSize& size, long style, const wxString& name) | |
546 | { | |
547 | m_animation = NULL; | |
548 | m_filename = filename; | |
549 | ||
550 | if (!wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name)) | |
426195f9 | 551 | return false; |
4638d697 JS |
552 | |
553 | SetBackgroundColour(parent->GetBackgroundColour()); | |
554 | ||
555 | m_animationPlayer.SetCustomBackgroundColour(GetBackgroundColour()); | |
556 | ||
426195f9 DS |
557 | // give the impression of transparency by painting |
558 | // with the parent background | |
4638d697 | 559 | // if (parent) |
426195f9 DS |
560 | // m_animationPlayer.UseParentBackground(true); |
561 | ||
4638d697 JS |
562 | m_animationPlayer.SetWindow(this); |
563 | m_animationPlayer.SetPosition(wxPoint(0, 0)); | |
426195f9 | 564 | m_animationPlayer.SetDestroyAnimation(false); |
4638d697 | 565 | |
770ddb3f RD |
566 | LoadFile(filename); |
567 | ||
426195f9 | 568 | return true; |
4638d697 JS |
569 | } |
570 | ||
571 | wxAnimationCtrlBase::~wxAnimationCtrlBase() | |
572 | { | |
573 | if (m_animationPlayer.IsPlaying()) | |
574 | m_animationPlayer.Stop(); | |
426195f9 DS |
575 | m_animationPlayer.SetAnimation(NULL, false); |
576 | ||
4638d697 JS |
577 | delete m_animation; |
578 | } | |
579 | ||
580 | bool wxAnimationCtrlBase::LoadFile(const wxString& filename) | |
581 | { | |
582 | if (m_animationPlayer.IsPlaying()) | |
583 | m_animationPlayer.Stop(); | |
584 | ||
585 | wxString filename1(filename); | |
586 | ||
587 | if (filename1.IsEmpty()) | |
426195f9 | 588 | { |
4638d697 | 589 | filename1 = m_filename; |
426195f9 DS |
590 | if (filename1.IsEmpty()) |
591 | return false; | |
592 | } | |
4638d697 JS |
593 | |
594 | if (m_animation) | |
595 | { | |
596 | delete m_animation; | |
597 | m_animation = NULL; | |
598 | } | |
599 | ||
600 | m_animation = DoCreateAnimation(filename1); | |
601 | if (!m_animation) | |
426195f9 | 602 | return false; |
4638d697 JS |
603 | |
604 | if (!m_animation->LoadFile(filename) || !m_animation->IsValid()) | |
605 | { | |
606 | delete m_animation; | |
607 | m_animation = NULL; | |
426195f9 DS |
608 | |
609 | return false; | |
4638d697 | 610 | } |
426195f9 DS |
611 | |
612 | m_animationPlayer.SetAnimation(m_animation, false); | |
4638d697 JS |
613 | |
614 | if (GetWindowStyle() & wxAN_FIT_ANIMATION) | |
615 | FitToAnimation(); | |
616 | ||
426195f9 | 617 | return true; |
4638d697 JS |
618 | } |
619 | ||
620 | bool wxAnimationCtrlBase::Play(bool looped) | |
621 | { | |
622 | return m_animationPlayer.Play(*this, wxPoint(0, 0), looped); | |
623 | } | |
624 | ||
625 | wxSize wxAnimationCtrlBase::DoGetBestSize() const | |
626 | { | |
627 | if (m_animationPlayer.HasAnimation() && (GetWindowStyle() & wxAN_FIT_ANIMATION)) | |
4638d697 | 628 | return m_animationPlayer.GetLogicalScreenSize(); |
4638d697 | 629 | else |
4638d697 | 630 | return GetSize(); |
4638d697 JS |
631 | } |
632 | ||
633 | void wxAnimationCtrlBase::FitToAnimation() | |
634 | { | |
635 | if (!m_animationPlayer.HasAnimation()) | |
636 | return; | |
637 | ||
638 | wxSize sz = m_animationPlayer.GetLogicalScreenSize(); | |
639 | SetClientSize(sz); | |
640 | } | |
641 | ||
87728739 | 642 | void wxAnimationCtrlBase::OnPaint(wxPaintEvent& WXUNUSED(event)) |
4638d697 JS |
643 | { |
644 | wxPaintDC dc(this); | |
645 | ||
646 | if (GetPlayer().IsPlaying()) | |
4638d697 | 647 | GetPlayer().Draw(dc); |
4638d697 JS |
648 | } |
649 | ||
650 | /* | |
651 | * wxGIFAnimationCtrl | |
652 | * Provides a GIF animation class when required. | |
653 | */ | |
654 | ||
655 | IMPLEMENT_ABSTRACT_CLASS(wxGIFAnimationCtrl, wxAnimationCtrlBase) | |
656 | ||
657 | wxAnimationBase* wxGIFAnimationCtrl::DoCreateAnimation(const wxString& WXUNUSED(filename)) | |
658 | { | |
659 | return new wxGIFAnimation; | |
660 | } | |
426195f9 | 661 |