More DLL build fixes for wxMediaCtrl
[wxWidgets.git] / src / common / mediactrlcmn.cpp
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
51 IMPLEMENT_CLASS(wxMediaCtrl, wxControl);
52 IMPLEMENT_CLASS(wxMediaBackend, wxObject);
53 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
54 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
55 DEFINE_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 succeededs Create returns true, otherwise
74 // it keeps iterating through the hashmap.
75 //---------------------------------------------------------------------------
76 bool 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 (!m_imp->Load(fileName))
97 {
98 delete m_imp;
99 m_imp = NULL;
100 return false;
101 }
102 }
103
104 return true;
105 }
106 else
107 {
108 wxClassInfo::sm_classTable->BeginFind();
109
110 wxClassInfo* classInfo = NextBackend();
111
112 while(classInfo)
113 {
114 if(!DoCreate(classInfo, parent, id,
115 pos, size, style, validator, name))
116 continue;
117
118 if (!fileName.empty())
119 {
120 if (m_imp->Load(fileName))
121 return true;
122 else
123 delete m_imp;
124 }
125 else
126 return true;
127
128 classInfo = NextBackend();
129 }
130
131 m_imp = NULL;
132 return false;
133 }
134 }
135
136 bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
137 const wxURI& location,
138 const wxPoint& pos,
139 const wxSize& size,
140 long style,
141 const wxString& szBackend,
142 const wxValidator& validator,
143 const wxString& name)
144 {
145 if(!szBackend.empty())
146 {
147 if(!DoCreate(wxClassInfo::FindClass(szBackend), parent, id,
148 pos, size, style, validator, name))
149 {
150 m_imp = NULL;
151 return false;
152 }
153
154 if (!m_imp->Load(location))
155 {
156 delete m_imp;
157 m_imp = NULL;
158 return false;
159 }
160
161 return true;
162 }
163 else
164 {
165 wxClassInfo::sm_classTable->BeginFind();
166
167 wxClassInfo* classInfo = NextBackend();
168
169 while(classInfo)
170 {
171 if(!DoCreate(classInfo, parent, id,
172 pos, size, style, validator, name))
173 continue;
174
175 if (m_imp->Load(location))
176 return true;
177 else
178 delete m_imp;
179
180 classInfo = NextBackend();
181 }
182
183 m_imp = NULL;
184 return false;
185 }
186 }
187
188 //---------------------------------------------------------------------------
189 // wxMediaCtrl::DoCreate
190 //
191 // Attempts to create the control from a backend
192 //---------------------------------------------------------------------------
193 bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
194 wxWindow* parent, wxWindowID id,
195 const wxPoint& pos,
196 const wxSize& size,
197 long style,
198 const wxValidator& validator,
199 const wxString& name)
200 {
201 m_imp = (wxMediaBackend*)classInfo->CreateObject();
202
203 if( m_imp->CreateControl(this, parent, id, pos, size,
204 style, validator, name) )
205 {
206 this->Connect(GetId(), wxEVT_MEDIA_FINISHED,
207 (wxObjectEventFunction) (wxEventFunction)
208 (wxMediaEventFunction)
209 &wxMediaCtrl::OnMediaFinished);
210 return true;
211 }
212
213 delete m_imp;
214 return false;
215 }
216
217 //---------------------------------------------------------------------------
218 // wxMediaCtrl::NextBackend
219 //
220 //
221 // Search through the RTTI hashmap one at a
222 // time, attempting to create each derivative
223 // of wxMediaBackend
224 //
225 //
226 // STL isn't compatable with and will have a compilation error
227 // on a wxNode, however, wxHashTable::compatibility_iterator is
228 // incompatible with the old 2.4 stable version - but since
229 // we're in 2.5 only we don't need to worry about this
230 // static
231 //---------------------------------------------------------------------------
232 wxClassInfo* wxMediaCtrl::NextBackend()
233 {
234 wxHashTable::compatibility_iterator
235 node = wxClassInfo::sm_classTable->Next();
236 while (node)
237 {
238 wxClassInfo* classInfo = (wxClassInfo *)node->GetData();
239 if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
240 classInfo != CLASSINFO(wxMediaBackend) )
241 {
242 return classInfo;
243 }
244 node = wxClassInfo::sm_classTable->Next();
245 }
246
247 //
248 // Nope - couldn't successfully find one... fail
249 //
250 return NULL;
251 }
252
253
254 //---------------------------------------------------------------------------
255 // wxMediaCtrl Destructor
256 //
257 // Free up the backend if it exists
258 //---------------------------------------------------------------------------
259 wxMediaCtrl::~wxMediaCtrl()
260 {
261 if (m_imp)
262 delete m_imp;
263 }
264
265 //---------------------------------------------------------------------------
266 // wxMediaCtrl::Load (file version)
267 // wxMediaCtrl::Load (URL version)
268 //
269 // Here we call load of the backend - keeping
270 // track of whether it was successful or not - which
271 // will determine which later method calls work
272 //---------------------------------------------------------------------------
273 bool wxMediaCtrl::Load(const wxString& fileName)
274 {
275 if(m_imp)
276 return (m_bLoaded = m_imp->Load(fileName));
277 return false;
278 }
279
280 bool wxMediaCtrl::Load(const wxURI& location)
281 {
282 if(m_imp)
283 return (m_bLoaded = m_imp->Load(location));
284 return false;
285 }
286
287 //---------------------------------------------------------------------------
288 // wxMediaCtrl::Play
289 // wxMediaCtrl::Pause
290 // wxMediaCtrl::Stop
291 // wxMediaCtrl::GetPlaybackRate
292 // wxMediaCtrl::SetPlaybackRate
293 // wxMediaCtrl::SetPosition
294 // wxMediaCtrl::GetPosition
295 // wxMediaCtrl::GetDuration
296 // wxMediaCtrl::GetState
297 // wxMediaCtrl::DoGetBestSize
298 //
299 // 1) Check to see whether the backend exists and is loading
300 // 2) Call the backend's version of the method, returning success
301 // if the backend's version succeeds
302 //---------------------------------------------------------------------------
303 bool wxMediaCtrl::Play()
304 {
305 if(m_imp && m_bLoaded)
306 return m_imp->Play();
307 return 0;
308 }
309
310 bool wxMediaCtrl::Pause()
311 {
312 if(m_imp && m_bLoaded)
313 return m_imp->Pause();
314 return 0;
315 }
316
317 bool wxMediaCtrl::Stop()
318 {
319 if(m_imp && m_bLoaded)
320 return m_imp->Stop();
321 return 0;
322 }
323
324 double wxMediaCtrl::GetPlaybackRate()
325 {
326 if(m_imp && m_bLoaded)
327 return m_imp->GetPlaybackRate();
328 return 0;
329 }
330
331 bool wxMediaCtrl::SetPlaybackRate(double dRate)
332 {
333 if(m_imp && m_bLoaded)
334 return m_imp->SetPlaybackRate(dRate);
335 return false;
336 }
337
338 bool wxMediaCtrl::SetPosition(wxLongLong where)
339 {
340 if(m_imp && m_bLoaded)
341 return m_imp->SetPosition(where);
342 return false;
343 }
344
345 wxLongLong wxMediaCtrl::GetPosition()
346 {
347 if(m_imp && m_bLoaded)
348 return m_imp->GetPosition();
349 return 0;
350 }
351
352 wxLongLong wxMediaCtrl::GetDuration()
353 {
354 if(m_imp && m_bLoaded)
355 return m_imp->GetDuration();
356 return 0;
357 }
358
359 wxMediaState wxMediaCtrl::GetState()
360 {
361 if(m_imp && m_bLoaded)
362 return m_imp->GetState();
363 return wxMEDIASTATE_STOPPED;
364 }
365
366 wxSize wxMediaCtrl::DoGetBestSize() const
367 {
368 if(m_imp)
369 return m_imp->GetVideoSize();
370 return wxSize(0,0);
371 }
372
373 //---------------------------------------------------------------------------
374 // wxMediaCtrl::DoMoveWindow
375 //
376 // 1) Call parent's version so that our control's window moves where
377 // it's supposed to
378 // 2) If the backend exists and is loaded, move the video
379 // of the media to where our control's window is now located
380 //---------------------------------------------------------------------------
381 void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
382 {
383 wxControl::DoMoveWindow(x,y,w,h);
384
385 if(m_imp)
386 m_imp->Move(x, y, w, h);
387 }
388
389 void wxMediaCtrl::Loop(bool bLoop)
390 {
391 m_bLoop = bLoop;
392 }
393
394 bool wxMediaCtrl::IsLooped()
395 {
396 return m_bLoop;
397 }
398
399 void wxMediaCtrl::OnMediaFinished(wxMediaEvent& WXUNUSED(evt))
400 {
401 if(m_bLoop)
402 {
403 #ifdef __WXDEBUG__
404 wxASSERT( Play() );
405 #else
406 Play();
407 #endif
408 }
409 }
410
411 //DARWIN gcc compiler badly screwed up - needs destructor impl in source
412 wxMediaBackend::~wxMediaBackend()
413 { }
414 #include <wx/html/forcelnk.h>
415 FORCE_LINK(basewxmediabackends);
416
417 //---------------------------------------------------------------------------
418 // End of compilation guard and of file
419 //---------------------------------------------------------------------------
420 #endif //wxUSE_MEDIACTRL
421
422