1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/mediactrl.cpp
3 // Purpose: wxMediaCtrl common code
4 // Author: Ryan Norton <wxprojects@comcast.net>
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // TODO: Platform specific backend defaults?
14 //===========================================================================
16 //===========================================================================
18 //---------------------------------------------------------------------------
20 //---------------------------------------------------------------------------
22 #include "wx/wxprec.h"
35 #include "wx/mediactrl.h"
37 //===========================================================================
41 //===========================================================================
43 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44 // RTTI and Event implementations
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
)
48 wxDEFINE_EVENT( wxEVT_MEDIA_STATECHANGED
, wxMediaEvent
);
49 wxDEFINE_EVENT( wxEVT_MEDIA_PLAY
, wxMediaEvent
);
50 wxDEFINE_EVENT( wxEVT_MEDIA_PAUSE
, wxMediaEvent
);
51 IMPLEMENT_CLASS(wxMediaBackend
, wxObject
)
52 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
)
53 wxDEFINE_EVENT( wxEVT_MEDIA_FINISHED
, wxMediaEvent
);
54 wxDEFINE_EVENT( wxEVT_MEDIA_LOADED
, wxMediaEvent
);
55 wxDEFINE_EVENT( wxEVT_MEDIA_STOP
, wxMediaEvent
);
57 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
61 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
63 //---------------------------------------------------------------------------
64 // wxMediaBackend Destructor
66 // This is here because the DARWIN gcc compiler badly screwed up and
67 // needs the destructor implementation in the source
68 //---------------------------------------------------------------------------
69 wxMediaBackend::~wxMediaBackend()
73 //---------------------------------------------------------------------------
74 // wxMediaCtrl::Create (file version)
75 // wxMediaCtrl::Create (URL version)
77 // Searches for a backend that is installed on the system (backends
78 // starting with lower characters in the alphabet are given priority),
79 // and creates the control from it
81 // This searches by searching the global RTTI hashtable, class by class,
82 // attempting to call CreateControl on each one found that is a derivative
83 // of wxMediaBackend - if it succeeded Create returns true, otherwise
84 // it keeps iterating through the hashmap.
85 //---------------------------------------------------------------------------
86 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
87 const wxString
& fileName
,
91 const wxString
& szBackend
,
92 const wxValidator
& validator
,
95 if(!szBackend
.empty())
97 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
99 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
100 pos
, size
, style
, validator
, name
))
106 if (!fileName
.empty())
115 SetInitialSize(size
);
120 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
122 const wxClassInfo
* classInfo
;
124 while((classInfo
= NextBackend(&it
)) != NULL
)
126 wxLogMessage( classInfo
->GetClassName() );
127 if(!DoCreate(classInfo
, parent
, id
,
128 pos
, size
, style
, validator
, name
))
131 if (!fileName
.empty())
135 SetInitialSize(size
);
143 SetInitialSize(size
);
153 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
154 const wxURI
& location
,
158 const wxString
& szBackend
,
159 const wxValidator
& validator
,
160 const wxString
& name
)
162 if(!szBackend
.empty())
164 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
165 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
166 pos
, size
, style
, validator
, name
))
178 SetInitialSize(size
);
183 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
185 const wxClassInfo
* classInfo
;
187 while((classInfo
= NextBackend(&it
)) != NULL
)
189 if(!DoCreate(classInfo
, parent
, id
,
190 pos
, size
, style
, validator
, name
))
195 SetInitialSize(size
);
207 //---------------------------------------------------------------------------
208 // wxMediaCtrl::DoCreate
210 // Attempts to create the control from a backend
211 //---------------------------------------------------------------------------
212 bool wxMediaCtrl::DoCreate(const wxClassInfo
* classInfo
,
213 wxWindow
* parent
, wxWindowID id
,
217 const wxValidator
& validator
,
218 const wxString
& name
)
220 m_imp
= (wxMediaBackend
*)classInfo
->CreateObject();
222 if( m_imp
->CreateControl(this, parent
, id
, pos
, size
,
223 style
, validator
, name
) )
232 //---------------------------------------------------------------------------
233 // wxMediaCtrl::NextBackend (static)
236 // Search through the RTTI hashmap one at a
237 // time, attempting to create each derivative
241 // STL isn't compatible with and will have a compilation error
242 // on a wxNode, however, wxHashTable::compatibility_iterator is
243 // incompatible with the old 2.4 stable version - but since
244 // we're in 2.5+ only we don't need to worry about the new version
245 //---------------------------------------------------------------------------
246 const wxClassInfo
* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator
* it
)
248 for ( wxClassInfo::const_iterator end
= wxClassInfo::end_classinfo();
249 *it
!= end
; ++(*it
) )
251 const wxClassInfo
* classInfo
= **it
;
252 if ( classInfo
->IsKindOf(CLASSINFO(wxMediaBackend
)) &&
253 classInfo
!= CLASSINFO(wxMediaBackend
) )
261 // Nope - couldn't successfully find one... fail
267 //---------------------------------------------------------------------------
268 // wxMediaCtrl Destructor
270 // Free up the backend if it exists
271 //---------------------------------------------------------------------------
272 wxMediaCtrl::~wxMediaCtrl()
278 //---------------------------------------------------------------------------
279 // wxMediaCtrl::Load (file version)
280 // wxMediaCtrl::Load (URL version)
281 // wxMediaCtrl::Load (URL & Proxy version)
282 // wxMediaCtrl::Load (wxInputStream version)
284 // Here we call load of the backend - keeping
285 // track of whether it was successful or not - which
286 // will determine which later method calls work
287 //---------------------------------------------------------------------------
288 bool wxMediaCtrl::Load(const wxString
& fileName
)
291 return (m_bLoaded
= m_imp
->Load(fileName
));
295 bool wxMediaCtrl::Load(const wxURI
& location
)
298 return (m_bLoaded
= m_imp
->Load(location
));
302 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
305 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
309 //---------------------------------------------------------------------------
311 // wxMediaCtrl::Pause
313 // wxMediaCtrl::GetPlaybackRate
314 // wxMediaCtrl::SetPlaybackRate
315 // wxMediaCtrl::Seek --> SetPosition
316 // wxMediaCtrl::Tell --> GetPosition
317 // wxMediaCtrl::Length --> GetDuration
318 // wxMediaCtrl::GetState
319 // wxMediaCtrl::DoGetBestSize
320 // wxMediaCtrl::SetVolume
321 // wxMediaCtrl::GetVolume
322 // wxMediaCtrl::ShowInterface
323 // wxMediaCtrl::GetDownloadProgress
324 // wxMediaCtrl::GetDownloadTotal
326 // 1) Check to see whether the backend exists and is loading
327 // 2) Call the backend's version of the method, returning success
328 // if the backend's version succeeds
329 //---------------------------------------------------------------------------
330 bool wxMediaCtrl::Play()
332 if(m_imp
&& m_bLoaded
)
333 return m_imp
->Play();
337 bool wxMediaCtrl::Pause()
339 if(m_imp
&& m_bLoaded
)
340 return m_imp
->Pause();
344 bool wxMediaCtrl::Stop()
346 if(m_imp
&& m_bLoaded
)
347 return m_imp
->Stop();
351 double wxMediaCtrl::GetPlaybackRate()
353 if(m_imp
&& m_bLoaded
)
354 return m_imp
->GetPlaybackRate();
358 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
360 if(m_imp
&& m_bLoaded
)
361 return m_imp
->SetPlaybackRate(dRate
);
365 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
375 offset
= Length() - where
;
377 // case wxFromCurrent:
379 offset
= Tell() + where
;
383 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
385 return wxInvalidOffset
;
388 wxFileOffset
wxMediaCtrl::Tell()
390 if(m_imp
&& m_bLoaded
)
391 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
392 return wxInvalidOffset
;
395 wxFileOffset
wxMediaCtrl::Length()
397 if(m_imp
&& m_bLoaded
)
398 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
399 return wxInvalidOffset
;
402 wxMediaState
wxMediaCtrl::GetState()
404 if(m_imp
&& m_bLoaded
)
405 return m_imp
->GetState();
406 return wxMEDIASTATE_STOPPED
;
409 wxSize
wxMediaCtrl::DoGetBestSize() const
412 return m_imp
->GetVideoSize();
416 double wxMediaCtrl::GetVolume()
418 if(m_imp
&& m_bLoaded
)
419 return m_imp
->GetVolume();
423 bool wxMediaCtrl::SetVolume(double dVolume
)
425 if(m_imp
&& m_bLoaded
)
426 return m_imp
->SetVolume(dVolume
);
430 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
433 return m_imp
->ShowPlayerControls(flags
);
437 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
439 if(m_imp
&& m_bLoaded
)
440 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
441 return wxInvalidOffset
;
444 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
446 if(m_imp
&& m_bLoaded
)
447 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
448 return wxInvalidOffset
;
451 //---------------------------------------------------------------------------
452 // wxMediaCtrl::DoMoveWindow
454 // 1) Call parent's version so that our control's window moves where
456 // 2) If the backend exists and is loaded, move the video
457 // of the media to where our control's window is now located
458 //---------------------------------------------------------------------------
459 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
461 wxControl::DoMoveWindow(x
,y
,w
,h
);
464 m_imp
->Move(x
, y
, w
, h
);
467 //---------------------------------------------------------------------------
468 // wxMediaCtrl::MacVisibilityChanged
469 //---------------------------------------------------------------------------
470 #ifdef __WXOSX_CARBON__
471 void wxMediaCtrl::MacVisibilityChanged()
473 wxControl::MacVisibilityChanged();
476 m_imp
->MacVisibilityChanged();
480 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
482 // wxMediaBackendCommonBase
484 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
486 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
488 // our best size changed after opening a new file
489 m_ctrl
->InvalidateBestSize();
490 m_ctrl
->SetSize(m_ctrl
->GetSize());
492 // if the parent of the control has a sizer ask it to refresh our size
493 wxWindow
* const parent
= m_ctrl
->GetParent();
494 if ( parent
->GetSizer() )
496 m_ctrl
->GetParent()->Layout();
497 m_ctrl
->GetParent()->Refresh();
498 m_ctrl
->GetParent()->Update();
502 void wxMediaBackendCommonBase::NotifyMovieLoaded()
504 NotifyMovieSizeChanged();
506 // notify about movie being fully loaded
507 QueueEvent(wxEVT_MEDIA_LOADED
);
510 bool wxMediaBackendCommonBase::SendStopEvent()
512 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
514 return !m_ctrl
->GetEventHandler()->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
517 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
519 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
520 m_ctrl
->GetEventHandler()->AddPendingEvent(theEvent
);
523 void wxMediaBackendCommonBase::QueuePlayEvent()
525 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
526 QueueEvent(wxEVT_MEDIA_PLAY
);
529 void wxMediaBackendCommonBase::QueuePauseEvent()
531 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
532 QueueEvent(wxEVT_MEDIA_PAUSE
);
535 void wxMediaBackendCommonBase::QueueStopEvent()
537 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
538 QueueEvent(wxEVT_MEDIA_STOP
);
543 // Force link default backends in -
544 // see http://wiki.wxwidgets.org/wiki.pl?RTTI
546 #include "wx/html/forcelnk.h"
548 #ifdef __WXMSW__ // MSW has huge backends so we do it seperately
549 FORCE_LINK(wxmediabackend_am
)
550 FORCE_LINK(wxmediabackend_wmp10
)
551 #elif !defined(__WXOSX_COCOA__)
552 FORCE_LINK(basewxmediabackends
)
555 #endif //wxUSE_MEDIACTRL