]> git.saurik.com Git - wxWidgets.git/blame_incremental - src/common/mediactrlcmn.cpp
getting rid of redundant redraws
[wxWidgets.git] / src / common / mediactrlcmn.cpp
... / ...
CommitLineData
1/////////////////////////////////////////////////////////////////////////////
2// Name: common/mediactrl.cpp
3// Purpose: wxMediaCtrl common code
4// Author: Ryan Norton <wxprojects@comcast.net>
5// Modified by:
6// Created: 11/07/04
7// RCS-ID: $Id$
8// Copyright: (c) Ryan Norton
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12//===========================================================================
13// Definitions
14//===========================================================================
15
16//---------------------------------------------------------------------------
17// Pre-compiled header stuff
18//---------------------------------------------------------------------------
19
20#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21#pragma implementation "mediactrl.h"
22#endif
23
24#include "wx/wxprec.h"
25
26#ifdef __BORLANDC__
27#pragma hdrstop
28#endif
29
30//---------------------------------------------------------------------------
31// Includes
32//---------------------------------------------------------------------------
33#include "wx/mediactrl.h"
34#include "wx/hash.h"
35
36//---------------------------------------------------------------------------
37// Compilation guard
38//---------------------------------------------------------------------------
39#if wxUSE_MEDIACTRL
40
41//===========================================================================
42//
43// Implementation
44//
45//===========================================================================
46
47//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
48// RTTI and Event implementations
49//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50
51IMPLEMENT_CLASS(wxMediaCtrl, wxControl);
52IMPLEMENT_CLASS(wxMediaBackend, wxObject);
53IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
54DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
55DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP);
56
57//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58//
59// wxMediaCtrl
60//
61//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
62
63//---------------------------------------------------------------------------
64// wxMediaCtrl::Create (file version)
65// wxMediaCtrl::Create (URL version)
66//
67// Searches for a backend that is installed on the system (backends
68// starting with lower characters in the alphabet are given priority),
69// and creates the control from it
70//
71// This searches by searching the global RTTI hashtable, class by class,
72// attempting to call CreateControl on each one found that is a derivative
73// of wxMediaBackend - if it succeeded Create returns true, otherwise
74// it keeps iterating through the hashmap.
75//---------------------------------------------------------------------------
76bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
77 const wxString& fileName,
78 const wxPoint& pos,
79 const wxSize& size,
80 long style,
81 const wxString& szBackend,
82 const wxValidator& validator,
83 const wxString& name)
84{
85 if(!szBackend.empty())
86 {
87 if(!DoCreate(wxClassInfo::FindClass(szBackend), parent, id,
88 pos, size, style, validator, name))
89 {
90 m_imp = NULL;
91 return false;
92 }
93
94 if (!fileName.empty())
95 {
96 if (!Load(fileName))
97 {
98 delete m_imp;
99 m_imp = NULL;
100 return false;
101 }
102 }
103
104 SetBestFittingSize(size);
105 return true;
106 }
107 else
108 {
109 wxClassInfo::sm_classTable->BeginFind();
110
111 wxClassInfo* classInfo = NextBackend();
112
113 while(classInfo)
114 {
115 if(!DoCreate(classInfo, parent, id,
116 pos, size, style, validator, name))
117 continue;
118
119 if (!fileName.empty())
120 {
121 if (Load(fileName))
122 {
123 SetBestFittingSize(size);
124 return true;
125 }
126 else
127 delete m_imp;
128 }
129 else
130 {
131 SetBestFittingSize(size);
132 return true;
133 }
134
135 classInfo = NextBackend();
136 }
137
138 m_imp = NULL;
139 return false;
140 }
141}
142
143bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
144 const wxURI& location,
145 const wxPoint& pos,
146 const wxSize& size,
147 long style,
148 const wxString& szBackend,
149 const wxValidator& validator,
150 const wxString& name)
151{
152 if(!szBackend.empty())
153 {
154 if(!DoCreate(wxClassInfo::FindClass(szBackend), parent, id,
155 pos, size, style, validator, name))
156 {
157 m_imp = NULL;
158 return false;
159 }
160
161 if (!Load(location))
162 {
163 delete m_imp;
164 m_imp = NULL;
165 return false;
166 }
167
168 SetBestFittingSize(size);
169 return true;
170 }
171 else
172 {
173 wxClassInfo::sm_classTable->BeginFind();
174
175 wxClassInfo* classInfo = NextBackend();
176
177 while(classInfo)
178 {
179 if(!DoCreate(classInfo, parent, id,
180 pos, size, style, validator, name))
181 continue;
182
183 if (Load(location))
184 {
185 SetBestFittingSize(size);
186 return true;
187 }
188 else
189 delete m_imp;
190
191 classInfo = NextBackend();
192 }
193
194 m_imp = NULL;
195 return false;
196 }
197}
198
199//---------------------------------------------------------------------------
200// wxMediaCtrl::DoCreate
201//
202// Attempts to create the control from a backend
203//---------------------------------------------------------------------------
204bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
205 wxWindow* parent, wxWindowID id,
206 const wxPoint& pos,
207 const wxSize& size,
208 long style,
209 const wxValidator& validator,
210 const wxString& name)
211{
212 m_imp = (wxMediaBackend*)classInfo->CreateObject();
213
214 if( m_imp->CreateControl(this, parent, id, pos, size,
215 style, validator, name) )
216 {
217 return true;
218 }
219
220 delete m_imp;
221 return false;
222}
223
224//---------------------------------------------------------------------------
225// wxMediaCtrl::NextBackend
226//
227//
228// Search through the RTTI hashmap one at a
229// time, attempting to create each derivative
230// of wxMediaBackend
231//
232//
233// STL isn't compatable with and will have a compilation error
234// on a wxNode, however, wxHashTable::compatibility_iterator is
235// incompatible with the old 2.4 stable version - but since
236// we're in 2.5 only we don't need to worry about this
237// static
238//---------------------------------------------------------------------------
239wxClassInfo* wxMediaCtrl::NextBackend()
240{
241 wxHashTable::compatibility_iterator
242 node = wxClassInfo::sm_classTable->Next();
243 while (node)
244 {
245 wxClassInfo* classInfo = (wxClassInfo *)node->GetData();
246 if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
247 classInfo != CLASSINFO(wxMediaBackend) )
248 {
249 return classInfo;
250 }
251 node = wxClassInfo::sm_classTable->Next();
252 }
253
254 //
255 // Nope - couldn't successfully find one... fail
256 //
257 return NULL;
258}
259
260
261//---------------------------------------------------------------------------
262// wxMediaCtrl Destructor
263//
264// Free up the backend if it exists
265//---------------------------------------------------------------------------
266wxMediaCtrl::~wxMediaCtrl()
267{
268 if (m_imp)
269 delete m_imp;
270}
271
272//---------------------------------------------------------------------------
273// wxMediaCtrl::Load (file version)
274// wxMediaCtrl::Load (URL version)
275//
276// Here we call load of the backend - keeping
277// track of whether it was successful or not - which
278// will determine which later method calls work
279//---------------------------------------------------------------------------
280bool wxMediaCtrl::Load(const wxString& fileName)
281{
282 if(m_imp)
283 return (m_bLoaded = m_imp->Load(fileName));
284 return false;
285}
286
287bool wxMediaCtrl::Load(const wxURI& location)
288{
289 if(m_imp)
290 return (m_bLoaded = m_imp->Load(location));
291 return false;
292}
293
294//---------------------------------------------------------------------------
295// wxMediaCtrl::Play
296// wxMediaCtrl::Pause
297// wxMediaCtrl::Stop
298// wxMediaCtrl::GetPlaybackRate
299// wxMediaCtrl::SetPlaybackRate
300// wxMediaCtrl::Seek --> SetPosition
301// wxMediaCtrl::Tell --> GetPosition
302// wxMediaCtrl::Length --> GetDuration
303// wxMediaCtrl::GetState
304// wxMediaCtrl::DoGetBestSize
305//
306// 1) Check to see whether the backend exists and is loading
307// 2) Call the backend's version of the method, returning success
308// if the backend's version succeeds
309//---------------------------------------------------------------------------
310bool wxMediaCtrl::Play()
311{
312 if(m_imp && m_bLoaded)
313 return m_imp->Play();
314 return 0;
315}
316
317bool wxMediaCtrl::Pause()
318{
319 if(m_imp && m_bLoaded)
320 return m_imp->Pause();
321 return 0;
322}
323
324bool wxMediaCtrl::Stop()
325{
326 if(m_imp && m_bLoaded)
327 return m_imp->Stop();
328 return 0;
329}
330
331double wxMediaCtrl::GetPlaybackRate()
332{
333 if(m_imp && m_bLoaded)
334 return m_imp->GetPlaybackRate();
335 return 0;
336}
337
338bool wxMediaCtrl::SetPlaybackRate(double dRate)
339{
340 if(m_imp && m_bLoaded)
341 return m_imp->SetPlaybackRate(dRate);
342 return false;
343}
344
345wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
346{
347 wxFileOffset offset;
348
349 switch (mode)
350 {
351 case wxFromStart:
352 offset = where;
353 break;
354 case wxFromEnd:
355 offset = Length() - where;
356 break;
357// case wxFromCurrent:
358 default:
359 offset = Tell() + where;
360 break;
361 }
362
363 if(m_imp && m_bLoaded && m_imp->SetPosition(offset))
364 return offset;
365 return wxInvalidOffset;
366}
367
368wxFileOffset wxMediaCtrl::Tell()
369{
370 //FIXME
371 if(m_imp && m_bLoaded)
372 return (wxFileOffset) m_imp->GetPosition().ToLong();
373 return wxInvalidOffset;
374}
375
376wxFileOffset wxMediaCtrl::Length()
377{
378 //FIXME
379 if(m_imp && m_bLoaded)
380 return (wxFileOffset) m_imp->GetDuration().ToLong();
381 return wxInvalidOffset;
382}
383
384wxMediaState wxMediaCtrl::GetState()
385{
386 if(m_imp && m_bLoaded)
387 return m_imp->GetState();
388 return wxMEDIASTATE_STOPPED;
389}
390
391wxSize wxMediaCtrl::DoGetBestSize() const
392{
393 if(m_imp)
394 return m_imp->GetVideoSize();
395 return wxSize();
396}
397
398//---------------------------------------------------------------------------
399// wxMediaCtrl::DoMoveWindow
400//
401// 1) Call parent's version so that our control's window moves where
402// it's supposed to
403// 2) If the backend exists and is loaded, move the video
404// of the media to where our control's window is now located
405//---------------------------------------------------------------------------
406void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
407{
408 wxControl::DoMoveWindow(x,y,w,h);
409
410 if(m_imp)
411 m_imp->Move(x, y, w, h);
412}
413
414//DARWIN gcc compiler badly screwed up - needs destructor impl in source
415wxMediaBackend::~wxMediaBackend()
416{ }
417#include "wx/html/forcelnk.h"
418FORCE_LINK(basewxmediabackends);
419
420//---------------------------------------------------------------------------
421// End of compilation guard and of file
422//---------------------------------------------------------------------------
423#endif //wxUSE_MEDIACTRL
424
425