]> git.saurik.com Git - wxWidgets.git/blob - src/common/mediactrlcmn.cpp
Make wxClassInfo attributes private. Replace
[wxWidgets.git] / src / common / mediactrlcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/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 // TODO: Platform specific backend defaults?
13
14 //===========================================================================
15 // Definitions
16 //===========================================================================
17
18 //---------------------------------------------------------------------------
19 // Pre-compiled header stuff
20 //---------------------------------------------------------------------------
21
22 #include "wx/wxprec.h"
23
24 #ifdef __BORLANDC__
25 #pragma hdrstop
26 #endif
27
28 #if wxUSE_MEDIACTRL
29
30 #ifndef WX_PRECOMP
31 #include "wx/hash.h"
32 #endif
33
34 //---------------------------------------------------------------------------
35 // Includes
36 //---------------------------------------------------------------------------
37 #include "wx/mediactrl.h"
38
39 //===========================================================================
40 //
41 // Implementation
42 //
43 //===========================================================================
44
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 // RTTI and Event implementations
47 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
48
49 IMPLEMENT_CLASS(wxMediaCtrl, wxControl)
50 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STATECHANGED)
51 DEFINE_EVENT_TYPE(wxEVT_MEDIA_PLAY)
52 DEFINE_EVENT_TYPE(wxEVT_MEDIA_PAUSE)
53 IMPLEMENT_CLASS(wxMediaBackend, wxObject)
54 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent)
55 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED)
56 DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED)
57 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP)
58
59 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
60 //
61 // wxMediaCtrl
62 //
63 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
64
65 //---------------------------------------------------------------------------
66 // wxMediaBackend Destructor
67 //
68 // This is here because the DARWIN gcc compiler badly screwed up and
69 // needs the destructor implementation in the source
70 //---------------------------------------------------------------------------
71 wxMediaBackend::~wxMediaBackend()
72 {
73 }
74
75 //---------------------------------------------------------------------------
76 // wxMediaCtrl::Create (file version)
77 // wxMediaCtrl::Create (URL version)
78 //
79 // Searches for a backend that is installed on the system (backends
80 // starting with lower characters in the alphabet are given priority),
81 // and creates the control from it
82 //
83 // This searches by searching the global RTTI hashtable, class by class,
84 // attempting to call CreateControl on each one found that is a derivative
85 // of wxMediaBackend - if it succeeded Create returns true, otherwise
86 // it keeps iterating through the hashmap.
87 //---------------------------------------------------------------------------
88 bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
89 const wxString& fileName,
90 const wxPoint& pos,
91 const wxSize& size,
92 long style,
93 const wxString& szBackend,
94 const wxValidator& validator,
95 const wxString& name)
96 {
97 if(!szBackend.empty())
98 {
99 wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
100
101 if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
102 pos, size, style, validator, name))
103 {
104 m_imp = NULL;
105 return false;
106 }
107
108 if (!fileName.empty())
109 {
110 if (!Load(fileName))
111 {
112 delete m_imp;
113 m_imp = NULL;
114 return false;
115 }
116 }
117
118 SetInitialSize(size);
119 return true;
120 }
121 else
122 {
123 wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo();
124
125 const wxClassInfo* classInfo;
126
127 while((classInfo = NextBackend(&it)) != NULL)
128 {
129 wxLogMessage( classInfo->GetClassName() );
130 if(!DoCreate(classInfo, parent, id,
131 pos, size, style, validator, name))
132 continue;
133
134 if (!fileName.empty())
135 {
136 if (Load(fileName))
137 {
138 SetInitialSize(size);
139 return true;
140 }
141 else
142 delete m_imp;
143 }
144 else
145 {
146 SetInitialSize(size);
147 return true;
148 }
149 }
150
151 m_imp = NULL;
152 return false;
153 }
154 }
155
156 bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
157 const wxURI& location,
158 const wxPoint& pos,
159 const wxSize& size,
160 long style,
161 const wxString& szBackend,
162 const wxValidator& validator,
163 const wxString& name)
164 {
165 if(!szBackend.empty())
166 {
167 wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
168 if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
169 pos, size, style, validator, name))
170 {
171 m_imp = NULL;
172 return false;
173 }
174
175 if (!Load(location))
176 {
177 delete m_imp;
178 m_imp = NULL;
179 return false;
180 }
181
182 SetInitialSize(size);
183 return true;
184 }
185 else
186 {
187 wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo();
188
189 const wxClassInfo* classInfo;
190
191 while((classInfo = NextBackend(&it)) != NULL)
192 {
193 if(!DoCreate(classInfo, parent, id,
194 pos, size, style, validator, name))
195 continue;
196
197 if (Load(location))
198 {
199 SetInitialSize(size);
200 return true;
201 }
202 else
203 delete m_imp;
204 }
205
206 m_imp = NULL;
207 return false;
208 }
209 }
210
211 //---------------------------------------------------------------------------
212 // wxMediaCtrl::DoCreate
213 //
214 // Attempts to create the control from a backend
215 //---------------------------------------------------------------------------
216 bool wxMediaCtrl::DoCreate(const wxClassInfo* classInfo,
217 wxWindow* parent, wxWindowID id,
218 const wxPoint& pos,
219 const wxSize& size,
220 long style,
221 const wxValidator& validator,
222 const wxString& name)
223 {
224 m_imp = (wxMediaBackend*)classInfo->CreateObject();
225
226 if( m_imp->CreateControl(this, parent, id, pos, size,
227 style, validator, name) )
228 {
229 return true;
230 }
231
232 delete m_imp;
233 return false;
234 }
235
236 //---------------------------------------------------------------------------
237 // wxMediaCtrl::NextBackend (static)
238 //
239 //
240 // Search through the RTTI hashmap one at a
241 // time, attempting to create each derivative
242 // of wxMediaBackend
243 //
244 //
245 // STL isn't compatible with and will have a compilation error
246 // on a wxNode, however, wxHashTable::compatibility_iterator is
247 // incompatible with the old 2.4 stable version - but since
248 // we're in 2.5+ only we don't need to worry about the new version
249 //---------------------------------------------------------------------------
250 const wxClassInfo* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator* it)
251 {
252 for ( wxClassInfo::const_iterator end = wxClassInfo::end_classinfo();
253 *it != end; ++(*it) )
254 {
255 const wxClassInfo* classInfo = **it;
256 if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
257 classInfo != CLASSINFO(wxMediaBackend) )
258 {
259 return classInfo;
260 }
261 }
262
263 //
264 // Nope - couldn't successfully find one... fail
265 //
266 return NULL;
267 }
268
269
270 //---------------------------------------------------------------------------
271 // wxMediaCtrl Destructor
272 //
273 // Free up the backend if it exists
274 //---------------------------------------------------------------------------
275 wxMediaCtrl::~wxMediaCtrl()
276 {
277 if (m_imp)
278 delete m_imp;
279 }
280
281 //---------------------------------------------------------------------------
282 // wxMediaCtrl::Load (file version)
283 // wxMediaCtrl::Load (URL version)
284 // wxMediaCtrl::Load (URL & Proxy version)
285 // wxMediaCtrl::Load (wxInputStream version)
286 //
287 // Here we call load of the backend - keeping
288 // track of whether it was successful or not - which
289 // will determine which later method calls work
290 //---------------------------------------------------------------------------
291 bool wxMediaCtrl::Load(const wxString& fileName)
292 {
293 if(m_imp)
294 return (m_bLoaded = m_imp->Load(fileName));
295 return false;
296 }
297
298 bool wxMediaCtrl::Load(const wxURI& location)
299 {
300 if(m_imp)
301 return (m_bLoaded = m_imp->Load(location));
302 return false;
303 }
304
305 bool wxMediaCtrl::Load(const wxURI& location, const wxURI& proxy)
306 {
307 if(m_imp)
308 return (m_bLoaded = m_imp->Load(location, proxy));
309 return false;
310 }
311
312 //---------------------------------------------------------------------------
313 // wxMediaCtrl::Play
314 // wxMediaCtrl::Pause
315 // wxMediaCtrl::Stop
316 // wxMediaCtrl::GetPlaybackRate
317 // wxMediaCtrl::SetPlaybackRate
318 // wxMediaCtrl::Seek --> SetPosition
319 // wxMediaCtrl::Tell --> GetPosition
320 // wxMediaCtrl::Length --> GetDuration
321 // wxMediaCtrl::GetState
322 // wxMediaCtrl::DoGetBestSize
323 // wxMediaCtrl::SetVolume
324 // wxMediaCtrl::GetVolume
325 // wxMediaCtrl::ShowInterface
326 // wxMediaCtrl::GetDownloadProgress
327 // wxMediaCtrl::GetDownloadTotal
328 //
329 // 1) Check to see whether the backend exists and is loading
330 // 2) Call the backend's version of the method, returning success
331 // if the backend's version succeeds
332 //---------------------------------------------------------------------------
333 bool wxMediaCtrl::Play()
334 {
335 if(m_imp && m_bLoaded)
336 return m_imp->Play();
337 return 0;
338 }
339
340 bool wxMediaCtrl::Pause()
341 {
342 if(m_imp && m_bLoaded)
343 return m_imp->Pause();
344 return 0;
345 }
346
347 bool wxMediaCtrl::Stop()
348 {
349 if(m_imp && m_bLoaded)
350 return m_imp->Stop();
351 return 0;
352 }
353
354 double wxMediaCtrl::GetPlaybackRate()
355 {
356 if(m_imp && m_bLoaded)
357 return m_imp->GetPlaybackRate();
358 return 0;
359 }
360
361 bool wxMediaCtrl::SetPlaybackRate(double dRate)
362 {
363 if(m_imp && m_bLoaded)
364 return m_imp->SetPlaybackRate(dRate);
365 return false;
366 }
367
368 wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
369 {
370 wxFileOffset offset;
371
372 switch (mode)
373 {
374 case wxFromStart:
375 offset = where;
376 break;
377 case wxFromEnd:
378 offset = Length() - where;
379 break;
380 // case wxFromCurrent:
381 default:
382 offset = Tell() + where;
383 break;
384 }
385
386 if(m_imp && m_bLoaded && m_imp->SetPosition(offset))
387 return offset;
388 return wxInvalidOffset;
389 }
390
391 wxFileOffset wxMediaCtrl::Tell()
392 {
393 if(m_imp && m_bLoaded)
394 return (wxFileOffset) m_imp->GetPosition().ToLong();
395 return wxInvalidOffset;
396 }
397
398 wxFileOffset wxMediaCtrl::Length()
399 {
400 if(m_imp && m_bLoaded)
401 return (wxFileOffset) m_imp->GetDuration().ToLong();
402 return wxInvalidOffset;
403 }
404
405 wxMediaState wxMediaCtrl::GetState()
406 {
407 if(m_imp && m_bLoaded)
408 return m_imp->GetState();
409 return wxMEDIASTATE_STOPPED;
410 }
411
412 wxSize wxMediaCtrl::DoGetBestSize() const
413 {
414 if(m_imp)
415 return m_imp->GetVideoSize();
416 return wxSize(0,0);
417 }
418
419 double wxMediaCtrl::GetVolume()
420 {
421 if(m_imp && m_bLoaded)
422 return m_imp->GetVolume();
423 return 0.0;
424 }
425
426 bool wxMediaCtrl::SetVolume(double dVolume)
427 {
428 if(m_imp && m_bLoaded)
429 return m_imp->SetVolume(dVolume);
430 return false;
431 }
432
433 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
434 {
435 if(m_imp)
436 return m_imp->ShowPlayerControls(flags);
437 return false;
438 }
439
440 wxFileOffset wxMediaCtrl::GetDownloadProgress()
441 {
442 if(m_imp && m_bLoaded)
443 return (wxFileOffset) m_imp->GetDownloadProgress().ToLong();
444 return wxInvalidOffset;
445 }
446
447 wxFileOffset wxMediaCtrl::GetDownloadTotal()
448 {
449 if(m_imp && m_bLoaded)
450 return (wxFileOffset) m_imp->GetDownloadTotal().ToLong();
451 return wxInvalidOffset;
452 }
453
454 //---------------------------------------------------------------------------
455 // wxMediaCtrl::DoMoveWindow
456 //
457 // 1) Call parent's version so that our control's window moves where
458 // it's supposed to
459 // 2) If the backend exists and is loaded, move the video
460 // of the media to where our control's window is now located
461 //---------------------------------------------------------------------------
462 void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
463 {
464 wxControl::DoMoveWindow(x,y,w,h);
465
466 if(m_imp)
467 m_imp->Move(x, y, w, h);
468 }
469
470 //---------------------------------------------------------------------------
471 // wxMediaCtrl::MacVisibilityChanged
472 //---------------------------------------------------------------------------
473 #ifdef __WXMAC__
474 void wxMediaCtrl::MacVisibilityChanged()
475 {
476 wxControl::MacVisibilityChanged();
477
478 if(m_imp)
479 m_imp->MacVisibilityChanged();
480 }
481 #endif
482
483 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
484 //
485 // wxMediaBackendCommonBase
486 //
487 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
488
489 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
490 {
491 // our best size changed after opening a new file
492 m_ctrl->InvalidateBestSize();
493 m_ctrl->SetSize(m_ctrl->GetSize());
494
495 // if the parent of the control has a sizer ask it to refresh our size
496 wxWindow * const parent = m_ctrl->GetParent();
497 if ( parent->GetSizer() )
498 {
499 m_ctrl->GetParent()->Layout();
500 m_ctrl->GetParent()->Refresh();
501 m_ctrl->GetParent()->Update();
502 }
503 }
504
505 void wxMediaBackendCommonBase::NotifyMovieLoaded()
506 {
507 NotifyMovieSizeChanged();
508
509 // notify about movie being fully loaded
510 QueueEvent(wxEVT_MEDIA_LOADED);
511 }
512
513 bool wxMediaBackendCommonBase::SendStopEvent()
514 {
515 wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId());
516
517 return !m_ctrl->ProcessEvent(theEvent) || theEvent.IsAllowed();
518 }
519
520 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType)
521 {
522 wxMediaEvent theEvent(evtType, m_ctrl->GetId());
523 m_ctrl->AddPendingEvent(theEvent);
524 }
525
526 void wxMediaBackendCommonBase::QueuePlayEvent()
527 {
528 QueueEvent(wxEVT_MEDIA_STATECHANGED);
529 QueueEvent(wxEVT_MEDIA_PLAY);
530 }
531
532 void wxMediaBackendCommonBase::QueuePauseEvent()
533 {
534 QueueEvent(wxEVT_MEDIA_STATECHANGED);
535 QueueEvent(wxEVT_MEDIA_PAUSE);
536 }
537
538 void wxMediaBackendCommonBase::QueueStopEvent()
539 {
540 QueueEvent(wxEVT_MEDIA_STATECHANGED);
541 QueueEvent(wxEVT_MEDIA_STOP);
542 }
543
544
545 //
546 // Force link default backends in -
547 // see http://wiki.wxwidgets.org/wiki.pl?RTTI
548 //
549 #include "wx/html/forcelnk.h"
550
551 #ifdef __WXMSW__ // MSW has huge backends so we do it seperately
552 FORCE_LINK(wxmediabackend_am)
553 FORCE_LINK(wxmediabackend_wmp10)
554 #else
555 FORCE_LINK(basewxmediabackends)
556 #endif
557
558 #endif //wxUSE_MEDIACTRL