1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/mediactrlcmn.cpp
3 // Purpose: wxMediaCtrl common code
4 // Author: Ryan Norton <wxprojects@comcast.net>
7 // Copyright: (c) Ryan Norton
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // TODO: Platform specific backend defaults?
13 //===========================================================================
15 //===========================================================================
17 //---------------------------------------------------------------------------
19 //---------------------------------------------------------------------------
21 #include "wx/wxprec.h"
34 #include "wx/mediactrl.h"
36 //===========================================================================
40 //===========================================================================
42 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
43 // RTTI and Event implementations
44 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
)
47 wxDEFINE_EVENT( wxEVT_MEDIA_STATECHANGED
, wxMediaEvent
);
48 wxDEFINE_EVENT( wxEVT_MEDIA_PLAY
, wxMediaEvent
);
49 wxDEFINE_EVENT( wxEVT_MEDIA_PAUSE
, wxMediaEvent
);
50 IMPLEMENT_CLASS(wxMediaBackend
, wxObject
)
51 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
)
52 wxDEFINE_EVENT( wxEVT_MEDIA_FINISHED
, wxMediaEvent
);
53 wxDEFINE_EVENT( wxEVT_MEDIA_LOADED
, wxMediaEvent
);
54 wxDEFINE_EVENT( wxEVT_MEDIA_STOP
, wxMediaEvent
);
56 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
60 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
62 //---------------------------------------------------------------------------
63 // wxMediaBackend Destructor
65 // This is here because the DARWIN gcc compiler badly screwed up and
66 // needs the destructor implementation in the source
67 //---------------------------------------------------------------------------
68 wxMediaBackend::~wxMediaBackend()
72 //---------------------------------------------------------------------------
73 // wxMediaCtrl::Create (file version)
74 // wxMediaCtrl::Create (URL version)
76 // Searches for a backend that is installed on the system (backends
77 // starting with lower characters in the alphabet are given priority),
78 // and creates the control from it
80 // This searches by searching the global RTTI hashtable, class by class,
81 // attempting to call CreateControl on each one found that is a derivative
82 // of wxMediaBackend - if it succeeded Create returns true, otherwise
83 // it keeps iterating through the hashmap.
84 //---------------------------------------------------------------------------
85 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
86 const wxString
& fileName
,
90 const wxString
& szBackend
,
91 const wxValidator
& validator
,
94 if(!szBackend
.empty())
96 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
98 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
99 pos
, size
, style
, validator
, name
))
105 if (!fileName
.empty())
114 SetInitialSize(size
);
119 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
121 const wxClassInfo
* classInfo
;
123 while((classInfo
= NextBackend(&it
)) != NULL
)
125 if(!DoCreate(classInfo
, parent
, id
,
126 pos
, size
, style
, validator
, name
))
129 if (!fileName
.empty())
133 SetInitialSize(size
);
141 SetInitialSize(size
);
151 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
152 const wxURI
& location
,
156 const wxString
& szBackend
,
157 const wxValidator
& validator
,
158 const wxString
& name
)
160 if(!szBackend
.empty())
162 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
163 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
164 pos
, size
, style
, validator
, name
))
176 SetInitialSize(size
);
181 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
183 const wxClassInfo
* classInfo
;
185 while((classInfo
= NextBackend(&it
)) != NULL
)
187 if(!DoCreate(classInfo
, parent
, id
,
188 pos
, size
, style
, validator
, name
))
193 SetInitialSize(size
);
205 //---------------------------------------------------------------------------
206 // wxMediaCtrl::DoCreate
208 // Attempts to create the control from a backend
209 //---------------------------------------------------------------------------
210 bool wxMediaCtrl::DoCreate(const wxClassInfo
* classInfo
,
211 wxWindow
* parent
, wxWindowID id
,
215 const wxValidator
& validator
,
216 const wxString
& name
)
218 m_imp
= (wxMediaBackend
*)classInfo
->CreateObject();
220 if( m_imp
->CreateControl(this, parent
, id
, pos
, size
,
221 style
, validator
, name
) )
230 //---------------------------------------------------------------------------
231 // wxMediaCtrl::NextBackend (static)
234 // Search through the RTTI hashmap one at a
235 // time, attempting to create each derivative
239 // STL isn't compatible with and will have a compilation error
240 // on a wxNode, however, wxHashTable::compatibility_iterator is
241 // incompatible with the old 2.4 stable version - but since
242 // we're in 2.5+ only we don't need to worry about the new version
243 //---------------------------------------------------------------------------
244 const wxClassInfo
* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator
* it
)
246 for ( wxClassInfo::const_iterator end
= wxClassInfo::end_classinfo();
247 *it
!= end
; ++(*it
) )
249 const wxClassInfo
* classInfo
= **it
;
250 if ( classInfo
->IsKindOf(wxCLASSINFO(wxMediaBackend
)) &&
251 classInfo
!= wxCLASSINFO(wxMediaBackend
) )
259 // Nope - couldn't successfully find one... fail
265 //---------------------------------------------------------------------------
266 // wxMediaCtrl Destructor
268 // Free up the backend if it exists
269 //---------------------------------------------------------------------------
270 wxMediaCtrl::~wxMediaCtrl()
276 //---------------------------------------------------------------------------
277 // wxMediaCtrl::Load (file version)
278 // wxMediaCtrl::Load (URL version)
279 // wxMediaCtrl::Load (URL & Proxy version)
280 // wxMediaCtrl::Load (wxInputStream version)
282 // Here we call load of the backend - keeping
283 // track of whether it was successful or not - which
284 // will determine which later method calls work
285 //---------------------------------------------------------------------------
286 bool wxMediaCtrl::Load(const wxString
& fileName
)
289 return (m_bLoaded
= m_imp
->Load(fileName
));
293 bool wxMediaCtrl::Load(const wxURI
& location
)
296 return (m_bLoaded
= m_imp
->Load(location
));
300 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
303 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
307 //---------------------------------------------------------------------------
309 // wxMediaCtrl::Pause
311 // wxMediaCtrl::GetPlaybackRate
312 // wxMediaCtrl::SetPlaybackRate
313 // wxMediaCtrl::Seek --> SetPosition
314 // wxMediaCtrl::Tell --> GetPosition
315 // wxMediaCtrl::Length --> GetDuration
316 // wxMediaCtrl::GetState
317 // wxMediaCtrl::DoGetBestSize
318 // wxMediaCtrl::SetVolume
319 // wxMediaCtrl::GetVolume
320 // wxMediaCtrl::ShowInterface
321 // wxMediaCtrl::GetDownloadProgress
322 // wxMediaCtrl::GetDownloadTotal
324 // 1) Check to see whether the backend exists and is loading
325 // 2) Call the backend's version of the method, returning success
326 // if the backend's version succeeds
327 //---------------------------------------------------------------------------
328 bool wxMediaCtrl::Play()
330 if(m_imp
&& m_bLoaded
)
331 return m_imp
->Play();
335 bool wxMediaCtrl::Pause()
337 if(m_imp
&& m_bLoaded
)
338 return m_imp
->Pause();
342 bool wxMediaCtrl::Stop()
344 if(m_imp
&& m_bLoaded
)
345 return m_imp
->Stop();
349 double wxMediaCtrl::GetPlaybackRate()
351 if(m_imp
&& m_bLoaded
)
352 return m_imp
->GetPlaybackRate();
356 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
358 if(m_imp
&& m_bLoaded
)
359 return m_imp
->SetPlaybackRate(dRate
);
363 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
373 offset
= Length() - where
;
375 // case wxFromCurrent:
377 offset
= Tell() + where
;
381 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
383 return wxInvalidOffset
;
386 wxFileOffset
wxMediaCtrl::Tell()
388 if(m_imp
&& m_bLoaded
)
389 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
390 return wxInvalidOffset
;
393 wxFileOffset
wxMediaCtrl::Length()
395 if(m_imp
&& m_bLoaded
)
396 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
397 return wxInvalidOffset
;
400 wxMediaState
wxMediaCtrl::GetState()
402 if(m_imp
&& m_bLoaded
)
403 return m_imp
->GetState();
404 return wxMEDIASTATE_STOPPED
;
407 wxSize
wxMediaCtrl::DoGetBestSize() const
410 return m_imp
->GetVideoSize();
414 double wxMediaCtrl::GetVolume()
416 if(m_imp
&& m_bLoaded
)
417 return m_imp
->GetVolume();
421 bool wxMediaCtrl::SetVolume(double dVolume
)
423 if(m_imp
&& m_bLoaded
)
424 return m_imp
->SetVolume(dVolume
);
428 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
431 return m_imp
->ShowPlayerControls(flags
);
435 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
437 if(m_imp
&& m_bLoaded
)
438 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
439 return wxInvalidOffset
;
442 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
444 if(m_imp
&& m_bLoaded
)
445 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
446 return wxInvalidOffset
;
449 //---------------------------------------------------------------------------
450 // wxMediaCtrl::DoMoveWindow
452 // 1) Call parent's version so that our control's window moves where
454 // 2) If the backend exists and is loaded, move the video
455 // of the media to where our control's window is now located
456 //---------------------------------------------------------------------------
457 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
459 wxControl::DoMoveWindow(x
,y
,w
,h
);
462 m_imp
->Move(x
, y
, w
, h
);
465 //---------------------------------------------------------------------------
466 // wxMediaCtrl::MacVisibilityChanged
467 //---------------------------------------------------------------------------
468 #ifdef __WXOSX_CARBON__
469 void wxMediaCtrl::MacVisibilityChanged()
471 wxControl::MacVisibilityChanged();
474 m_imp
->MacVisibilityChanged();
478 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
480 // wxMediaBackendCommonBase
482 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
484 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
486 // our best size changed after opening a new file
487 m_ctrl
->InvalidateBestSize();
488 m_ctrl
->SetSize(m_ctrl
->GetSize());
490 // if the parent of the control has a sizer ask it to refresh our size
491 wxWindow
* const parent
= m_ctrl
->GetParent();
492 if ( parent
->GetSizer() )
494 m_ctrl
->GetParent()->Layout();
495 m_ctrl
->GetParent()->Refresh();
496 m_ctrl
->GetParent()->Update();
500 void wxMediaBackendCommonBase::NotifyMovieLoaded()
502 NotifyMovieSizeChanged();
504 // notify about movie being fully loaded
505 QueueEvent(wxEVT_MEDIA_LOADED
);
508 bool wxMediaBackendCommonBase::SendStopEvent()
510 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
512 return !m_ctrl
->GetEventHandler()->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
515 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
517 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
518 m_ctrl
->GetEventHandler()->AddPendingEvent(theEvent
);
521 void wxMediaBackendCommonBase::QueuePlayEvent()
523 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
524 QueueEvent(wxEVT_MEDIA_PLAY
);
527 void wxMediaBackendCommonBase::QueuePauseEvent()
529 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
530 QueueEvent(wxEVT_MEDIA_PAUSE
);
533 void wxMediaBackendCommonBase::QueueStopEvent()
535 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
536 QueueEvent(wxEVT_MEDIA_STOP
);
541 // Force link default backends in -
542 // see http://wiki.wxwidgets.org/wiki.pl?RTTI
544 #include "wx/html/forcelnk.h"
546 #ifdef __WXMSW__ // MSW has huge backends so we do it separately
547 FORCE_LINK(wxmediabackend_am
)
548 FORCE_LINK(wxmediabackend_wmp10
)
550 FORCE_LINK(basewxmediabackends
)
553 #endif //wxUSE_MEDIACTRL