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 //---------------------------------------------------------------------------
19 // Pre-compiled header stuff
20 //---------------------------------------------------------------------------
22 #include "wx/wxprec.h"
34 //---------------------------------------------------------------------------
36 //---------------------------------------------------------------------------
37 #include "wx/mediactrl.h"
39 //===========================================================================
43 //===========================================================================
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 // RTTI and Event implementations
47 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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
)
59 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
63 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
65 //---------------------------------------------------------------------------
66 // wxMediaBackend Destructor
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()
75 //---------------------------------------------------------------------------
76 // wxMediaCtrl::Create (file version)
77 // wxMediaCtrl::Create (URL version)
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
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
,
93 const wxString
& szBackend
,
94 const wxValidator
& validator
,
97 if(!szBackend
.empty())
99 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
101 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
102 pos
, size
, style
, validator
, name
))
108 if (!fileName
.empty())
118 SetBestFittingSize(size
);
123 wxClassInfo::sm_classTable
->BeginFind();
125 wxClassInfo
* classInfo
;
127 while((classInfo
= NextBackend()) != NULL
)
129 if(!DoCreate(classInfo
, parent
, id
,
130 pos
, size
, style
, validator
, name
))
133 if (!fileName
.empty())
137 SetBestFittingSize(size
);
145 SetBestFittingSize(size
);
155 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
156 const wxURI
& location
,
160 const wxString
& szBackend
,
161 const wxValidator
& validator
,
162 const wxString
& name
)
164 if(!szBackend
.empty())
166 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
167 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
168 pos
, size
, style
, validator
, name
))
181 SetBestFittingSize(size
);
186 wxClassInfo::sm_classTable
->BeginFind();
188 wxClassInfo
* classInfo
;
190 while((classInfo
= NextBackend()) != NULL
)
192 if(!DoCreate(classInfo
, parent
, id
,
193 pos
, size
, style
, validator
, name
))
198 SetBestFittingSize(size
);
210 //---------------------------------------------------------------------------
211 // wxMediaCtrl::DoCreate
213 // Attempts to create the control from a backend
214 //---------------------------------------------------------------------------
215 bool wxMediaCtrl::DoCreate(wxClassInfo
* classInfo
,
216 wxWindow
* parent
, wxWindowID id
,
220 const wxValidator
& validator
,
221 const wxString
& name
)
223 m_imp
= (wxMediaBackend
*)classInfo
->CreateObject();
225 if( m_imp
->CreateControl(this, parent
, id
, pos
, size
,
226 style
, validator
, name
) )
235 //---------------------------------------------------------------------------
236 // wxMediaCtrl::NextBackend (static)
239 // Search through the RTTI hashmap one at a
240 // time, attempting to create each derivative
244 // STL isn't compatible with and will have a compilation error
245 // on a wxNode, however, wxHashTable::compatibility_iterator is
246 // incompatible with the old 2.4 stable version - but since
247 // we're in 2.5+ only we don't need to worry about the new version
248 //---------------------------------------------------------------------------
249 wxClassInfo
* wxMediaCtrl::NextBackend()
251 wxHashTable::compatibility_iterator
252 node
= wxClassInfo::sm_classTable
->Next();
255 wxClassInfo
* classInfo
= (wxClassInfo
*)node
->GetData();
256 if ( classInfo
->IsKindOf(CLASSINFO(wxMediaBackend
)) &&
257 classInfo
!= CLASSINFO(wxMediaBackend
) )
261 node
= wxClassInfo::sm_classTable
->Next();
265 // Nope - couldn't successfully find one... fail
271 //---------------------------------------------------------------------------
272 // wxMediaCtrl Destructor
274 // Free up the backend if it exists
275 //---------------------------------------------------------------------------
276 wxMediaCtrl::~wxMediaCtrl()
282 //---------------------------------------------------------------------------
283 // wxMediaCtrl::Load (file version)
284 // wxMediaCtrl::Load (URL version)
285 // wxMediaCtrl::Load (URL & Proxy version)
286 // wxMediaCtrl::Load (wxInputStream version)
288 // Here we call load of the backend - keeping
289 // track of whether it was successful or not - which
290 // will determine which later method calls work
291 //---------------------------------------------------------------------------
292 bool wxMediaCtrl::Load(const wxString
& fileName
)
295 return (m_bLoaded
= m_imp
->Load(fileName
));
299 bool wxMediaCtrl::Load(const wxURI
& location
)
302 return (m_bLoaded
= m_imp
->Load(location
));
306 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
309 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
313 //---------------------------------------------------------------------------
315 // wxMediaCtrl::Pause
317 // wxMediaCtrl::GetPlaybackRate
318 // wxMediaCtrl::SetPlaybackRate
319 // wxMediaCtrl::Seek --> SetPosition
320 // wxMediaCtrl::Tell --> GetPosition
321 // wxMediaCtrl::Length --> GetDuration
322 // wxMediaCtrl::GetState
323 // wxMediaCtrl::DoGetBestSize
324 // wxMediaCtrl::SetVolume
325 // wxMediaCtrl::GetVolume
326 // wxMediaCtrl::ShowInterface
327 // wxMediaCtrl::GetDownloadProgress
328 // wxMediaCtrl::GetDownloadTotal
330 // 1) Check to see whether the backend exists and is loading
331 // 2) Call the backend's version of the method, returning success
332 // if the backend's version succeeds
333 //---------------------------------------------------------------------------
334 bool wxMediaCtrl::Play()
336 if(m_imp
&& m_bLoaded
)
337 return m_imp
->Play();
341 bool wxMediaCtrl::Pause()
343 if(m_imp
&& m_bLoaded
)
344 return m_imp
->Pause();
348 bool wxMediaCtrl::Stop()
350 if(m_imp
&& m_bLoaded
)
351 return m_imp
->Stop();
355 double wxMediaCtrl::GetPlaybackRate()
357 if(m_imp
&& m_bLoaded
)
358 return m_imp
->GetPlaybackRate();
362 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
364 if(m_imp
&& m_bLoaded
)
365 return m_imp
->SetPlaybackRate(dRate
);
369 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
379 offset
= Length() - where
;
381 // case wxFromCurrent:
383 offset
= Tell() + where
;
387 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
389 return wxInvalidOffset
;
392 wxFileOffset
wxMediaCtrl::Tell()
394 if(m_imp
&& m_bLoaded
)
395 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
396 return wxInvalidOffset
;
399 wxFileOffset
wxMediaCtrl::Length()
401 if(m_imp
&& m_bLoaded
)
402 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
403 return wxInvalidOffset
;
406 wxMediaState
wxMediaCtrl::GetState()
408 if(m_imp
&& m_bLoaded
)
409 return m_imp
->GetState();
410 return wxMEDIASTATE_STOPPED
;
413 wxSize
wxMediaCtrl::DoGetBestSize() const
416 return m_imp
->GetVideoSize();
420 double wxMediaCtrl::GetVolume()
422 if(m_imp
&& m_bLoaded
)
423 return m_imp
->GetVolume();
427 bool wxMediaCtrl::SetVolume(double dVolume
)
429 if(m_imp
&& m_bLoaded
)
430 return m_imp
->SetVolume(dVolume
);
434 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
437 return m_imp
->ShowPlayerControls(flags
);
441 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
443 if(m_imp
&& m_bLoaded
)
444 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
445 return wxInvalidOffset
;
448 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
450 if(m_imp
&& m_bLoaded
)
451 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
452 return wxInvalidOffset
;
455 //---------------------------------------------------------------------------
456 // wxMediaCtrl::DoMoveWindow
458 // 1) Call parent's version so that our control's window moves where
460 // 2) If the backend exists and is loaded, move the video
461 // of the media to where our control's window is now located
462 //---------------------------------------------------------------------------
463 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
465 wxControl::DoMoveWindow(x
,y
,w
,h
);
468 m_imp
->Move(x
, y
, w
, h
);
471 //---------------------------------------------------------------------------
472 // wxMediaCtrl::MacVisibilityChanged
473 //---------------------------------------------------------------------------
475 void wxMediaCtrl::MacVisibilityChanged()
477 wxControl::MacVisibilityChanged();
480 m_imp
->MacVisibilityChanged();
484 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
486 // wxMediaBackendCommonBase
488 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
490 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
492 // our best size changed after opening a new file
493 m_ctrl
->InvalidateBestSize();
494 m_ctrl
->SetSize(m_ctrl
->GetSize());
496 // if the parent of the control has a sizer ask it to refresh our size
497 wxWindow
* const parent
= m_ctrl
->GetParent();
498 if ( parent
->GetSizer() )
500 m_ctrl
->GetParent()->Layout();
501 m_ctrl
->GetParent()->Refresh();
502 m_ctrl
->GetParent()->Update();
506 void wxMediaBackendCommonBase::NotifyMovieLoaded()
508 NotifyMovieSizeChanged();
510 // notify about movie being fully loaded
511 QueueEvent(wxEVT_MEDIA_LOADED
);
514 bool wxMediaBackendCommonBase::SendStopEvent()
516 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
518 return !m_ctrl
->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
521 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
523 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
524 m_ctrl
->AddPendingEvent(theEvent
);
527 void wxMediaBackendCommonBase::QueuePlayEvent()
529 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
530 QueueEvent(wxEVT_MEDIA_PLAY
);
533 void wxMediaBackendCommonBase::QueuePauseEvent()
535 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
536 QueueEvent(wxEVT_MEDIA_PAUSE
);
539 void wxMediaBackendCommonBase::QueueStopEvent()
541 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
542 QueueEvent(wxEVT_MEDIA_STOP
);
547 // Force link default backends in -
548 // see http://wiki.wxwidgets.org/wiki.pl?RTTI
550 #include "wx/html/forcelnk.h"
552 #ifdef __WXMSW__ // MSW has huge backends so we do it seperately
553 FORCE_LINK(wxmediabackend_am
)
554 FORCE_LINK(wxmediabackend_wmp10
)
556 FORCE_LINK(basewxmediabackends
)
559 #endif //wxUSE_MEDIACTRL