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())
116 SetInitialSize(size
);
121 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
123 const wxClassInfo
* classInfo
;
125 while((classInfo
= NextBackend(&it
)) != NULL
)
127 wxLogMessage( classInfo
->GetClassName() );
128 if(!DoCreate(classInfo
, parent
, id
,
129 pos
, size
, style
, validator
, name
))
132 if (!fileName
.empty())
136 SetInitialSize(size
);
144 SetInitialSize(size
);
154 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
155 const wxURI
& location
,
159 const wxString
& szBackend
,
160 const wxValidator
& validator
,
161 const wxString
& name
)
163 if(!szBackend
.empty())
165 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
166 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
167 pos
, size
, style
, validator
, name
))
180 SetInitialSize(size
);
185 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
187 const wxClassInfo
* classInfo
;
189 while((classInfo
= NextBackend(&it
)) != NULL
)
191 if(!DoCreate(classInfo
, parent
, id
,
192 pos
, size
, style
, validator
, name
))
197 SetInitialSize(size
);
209 //---------------------------------------------------------------------------
210 // wxMediaCtrl::DoCreate
212 // Attempts to create the control from a backend
213 //---------------------------------------------------------------------------
214 bool wxMediaCtrl::DoCreate(const wxClassInfo
* classInfo
,
215 wxWindow
* parent
, wxWindowID id
,
219 const wxValidator
& validator
,
220 const wxString
& name
)
222 m_imp
= (wxMediaBackend
*)classInfo
->CreateObject();
224 if( m_imp
->CreateControl(this, parent
, id
, pos
, size
,
225 style
, validator
, name
) )
234 //---------------------------------------------------------------------------
235 // wxMediaCtrl::NextBackend (static)
238 // Search through the RTTI hashmap one at a
239 // time, attempting to create each derivative
243 // STL isn't compatible with and will have a compilation error
244 // on a wxNode, however, wxHashTable::compatibility_iterator is
245 // incompatible with the old 2.4 stable version - but since
246 // we're in 2.5+ only we don't need to worry about the new version
247 //---------------------------------------------------------------------------
248 const wxClassInfo
* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator
* it
)
250 for ( wxClassInfo::const_iterator end
= wxClassInfo::end_classinfo();
251 *it
!= end
; ++(*it
) )
253 const wxClassInfo
* classInfo
= **it
;
254 if ( classInfo
->IsKindOf(CLASSINFO(wxMediaBackend
)) &&
255 classInfo
!= CLASSINFO(wxMediaBackend
) )
263 // Nope - couldn't successfully find one... fail
269 //---------------------------------------------------------------------------
270 // wxMediaCtrl Destructor
272 // Free up the backend if it exists
273 //---------------------------------------------------------------------------
274 wxMediaCtrl::~wxMediaCtrl()
280 //---------------------------------------------------------------------------
281 // wxMediaCtrl::Load (file version)
282 // wxMediaCtrl::Load (URL version)
283 // wxMediaCtrl::Load (URL & Proxy version)
284 // wxMediaCtrl::Load (wxInputStream version)
286 // Here we call load of the backend - keeping
287 // track of whether it was successful or not - which
288 // will determine which later method calls work
289 //---------------------------------------------------------------------------
290 bool wxMediaCtrl::Load(const wxString
& fileName
)
293 return (m_bLoaded
= m_imp
->Load(fileName
));
297 bool wxMediaCtrl::Load(const wxURI
& location
)
300 return (m_bLoaded
= m_imp
->Load(location
));
304 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
307 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
311 //---------------------------------------------------------------------------
313 // wxMediaCtrl::Pause
315 // wxMediaCtrl::GetPlaybackRate
316 // wxMediaCtrl::SetPlaybackRate
317 // wxMediaCtrl::Seek --> SetPosition
318 // wxMediaCtrl::Tell --> GetPosition
319 // wxMediaCtrl::Length --> GetDuration
320 // wxMediaCtrl::GetState
321 // wxMediaCtrl::DoGetBestSize
322 // wxMediaCtrl::SetVolume
323 // wxMediaCtrl::GetVolume
324 // wxMediaCtrl::ShowInterface
325 // wxMediaCtrl::GetDownloadProgress
326 // wxMediaCtrl::GetDownloadTotal
328 // 1) Check to see whether the backend exists and is loading
329 // 2) Call the backend's version of the method, returning success
330 // if the backend's version succeeds
331 //---------------------------------------------------------------------------
332 bool wxMediaCtrl::Play()
334 if(m_imp
&& m_bLoaded
)
335 return m_imp
->Play();
339 bool wxMediaCtrl::Pause()
341 if(m_imp
&& m_bLoaded
)
342 return m_imp
->Pause();
346 bool wxMediaCtrl::Stop()
348 if(m_imp
&& m_bLoaded
)
349 return m_imp
->Stop();
353 double wxMediaCtrl::GetPlaybackRate()
355 if(m_imp
&& m_bLoaded
)
356 return m_imp
->GetPlaybackRate();
360 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
362 if(m_imp
&& m_bLoaded
)
363 return m_imp
->SetPlaybackRate(dRate
);
367 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
377 offset
= Length() - where
;
379 // case wxFromCurrent:
381 offset
= Tell() + where
;
385 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
387 return wxInvalidOffset
;
390 wxFileOffset
wxMediaCtrl::Tell()
392 if(m_imp
&& m_bLoaded
)
393 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
394 return wxInvalidOffset
;
397 wxFileOffset
wxMediaCtrl::Length()
399 if(m_imp
&& m_bLoaded
)
400 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
401 return wxInvalidOffset
;
404 wxMediaState
wxMediaCtrl::GetState()
406 if(m_imp
&& m_bLoaded
)
407 return m_imp
->GetState();
408 return wxMEDIASTATE_STOPPED
;
411 wxSize
wxMediaCtrl::DoGetBestSize() const
414 return m_imp
->GetVideoSize();
418 double wxMediaCtrl::GetVolume()
420 if(m_imp
&& m_bLoaded
)
421 return m_imp
->GetVolume();
425 bool wxMediaCtrl::SetVolume(double dVolume
)
427 if(m_imp
&& m_bLoaded
)
428 return m_imp
->SetVolume(dVolume
);
432 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
435 return m_imp
->ShowPlayerControls(flags
);
439 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
441 if(m_imp
&& m_bLoaded
)
442 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
443 return wxInvalidOffset
;
446 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
448 if(m_imp
&& m_bLoaded
)
449 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
450 return wxInvalidOffset
;
453 //---------------------------------------------------------------------------
454 // wxMediaCtrl::DoMoveWindow
456 // 1) Call parent's version so that our control's window moves where
458 // 2) If the backend exists and is loaded, move the video
459 // of the media to where our control's window is now located
460 //---------------------------------------------------------------------------
461 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
463 wxControl::DoMoveWindow(x
,y
,w
,h
);
466 m_imp
->Move(x
, y
, w
, h
);
469 //---------------------------------------------------------------------------
470 // wxMediaCtrl::MacVisibilityChanged
471 //---------------------------------------------------------------------------
472 #ifdef __WXOSX_CARBON__
473 void wxMediaCtrl::MacVisibilityChanged()
475 wxControl::MacVisibilityChanged();
478 m_imp
->MacVisibilityChanged();
482 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
484 // wxMediaBackendCommonBase
486 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
488 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
490 // our best size changed after opening a new file
491 m_ctrl
->InvalidateBestSize();
492 m_ctrl
->SetSize(m_ctrl
->GetSize());
494 // if the parent of the control has a sizer ask it to refresh our size
495 wxWindow
* const parent
= m_ctrl
->GetParent();
496 if ( parent
->GetSizer() )
498 m_ctrl
->GetParent()->Layout();
499 m_ctrl
->GetParent()->Refresh();
500 m_ctrl
->GetParent()->Update();
504 void wxMediaBackendCommonBase::NotifyMovieLoaded()
506 NotifyMovieSizeChanged();
508 // notify about movie being fully loaded
509 QueueEvent(wxEVT_MEDIA_LOADED
);
512 bool wxMediaBackendCommonBase::SendStopEvent()
514 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
516 return !m_ctrl
->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
519 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
521 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
522 m_ctrl
->AddPendingEvent(theEvent
);
525 void wxMediaBackendCommonBase::QueuePlayEvent()
527 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
528 QueueEvent(wxEVT_MEDIA_PLAY
);
531 void wxMediaBackendCommonBase::QueuePauseEvent()
533 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
534 QueueEvent(wxEVT_MEDIA_PAUSE
);
537 void wxMediaBackendCommonBase::QueueStopEvent()
539 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
540 QueueEvent(wxEVT_MEDIA_STOP
);
545 // Force link default backends in -
546 // see http://wiki.wxwidgets.org/wiki.pl?RTTI
548 #include "wx/html/forcelnk.h"
550 #ifdef __WXMSW__ // MSW has huge backends so we do it seperately
551 FORCE_LINK(wxmediabackend_am
)
552 FORCE_LINK(wxmediabackend_wmp10
)
553 #elif !defined(__WXOSX_COCOA__)
554 FORCE_LINK(basewxmediabackends
)
557 #endif //wxUSE_MEDIACTRL