1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/mediactrlcmn.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 if(!DoCreate(classInfo
, parent
, id
,
127 pos
, size
, style
, validator
, name
))
130 if (!fileName
.empty())
134 SetInitialSize(size
);
142 SetInitialSize(size
);
152 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
153 const wxURI
& location
,
157 const wxString
& szBackend
,
158 const wxValidator
& validator
,
159 const wxString
& name
)
161 if(!szBackend
.empty())
163 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
164 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
165 pos
, size
, style
, validator
, name
))
177 SetInitialSize(size
);
182 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
184 const wxClassInfo
* classInfo
;
186 while((classInfo
= NextBackend(&it
)) != NULL
)
188 if(!DoCreate(classInfo
, parent
, id
,
189 pos
, size
, style
, validator
, name
))
194 SetInitialSize(size
);
206 //---------------------------------------------------------------------------
207 // wxMediaCtrl::DoCreate
209 // Attempts to create the control from a backend
210 //---------------------------------------------------------------------------
211 bool wxMediaCtrl::DoCreate(const wxClassInfo
* classInfo
,
212 wxWindow
* parent
, wxWindowID id
,
216 const wxValidator
& validator
,
217 const wxString
& name
)
219 m_imp
= (wxMediaBackend
*)classInfo
->CreateObject();
221 if( m_imp
->CreateControl(this, parent
, id
, pos
, size
,
222 style
, validator
, name
) )
231 //---------------------------------------------------------------------------
232 // wxMediaCtrl::NextBackend (static)
235 // Search through the RTTI hashmap one at a
236 // time, attempting to create each derivative
240 // STL isn't compatible with and will have a compilation error
241 // on a wxNode, however, wxHashTable::compatibility_iterator is
242 // incompatible with the old 2.4 stable version - but since
243 // we're in 2.5+ only we don't need to worry about the new version
244 //---------------------------------------------------------------------------
245 const wxClassInfo
* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator
* it
)
247 for ( wxClassInfo::const_iterator end
= wxClassInfo::end_classinfo();
248 *it
!= end
; ++(*it
) )
250 const wxClassInfo
* classInfo
= **it
;
251 if ( classInfo
->IsKindOf(wxCLASSINFO(wxMediaBackend
)) &&
252 classInfo
!= wxCLASSINFO(wxMediaBackend
) )
260 // Nope - couldn't successfully find one... fail
266 //---------------------------------------------------------------------------
267 // wxMediaCtrl Destructor
269 // Free up the backend if it exists
270 //---------------------------------------------------------------------------
271 wxMediaCtrl::~wxMediaCtrl()
277 //---------------------------------------------------------------------------
278 // wxMediaCtrl::Load (file version)
279 // wxMediaCtrl::Load (URL version)
280 // wxMediaCtrl::Load (URL & Proxy version)
281 // wxMediaCtrl::Load (wxInputStream version)
283 // Here we call load of the backend - keeping
284 // track of whether it was successful or not - which
285 // will determine which later method calls work
286 //---------------------------------------------------------------------------
287 bool wxMediaCtrl::Load(const wxString
& fileName
)
290 return (m_bLoaded
= m_imp
->Load(fileName
));
294 bool wxMediaCtrl::Load(const wxURI
& location
)
297 return (m_bLoaded
= m_imp
->Load(location
));
301 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
304 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
308 //---------------------------------------------------------------------------
310 // wxMediaCtrl::Pause
312 // wxMediaCtrl::GetPlaybackRate
313 // wxMediaCtrl::SetPlaybackRate
314 // wxMediaCtrl::Seek --> SetPosition
315 // wxMediaCtrl::Tell --> GetPosition
316 // wxMediaCtrl::Length --> GetDuration
317 // wxMediaCtrl::GetState
318 // wxMediaCtrl::DoGetBestSize
319 // wxMediaCtrl::SetVolume
320 // wxMediaCtrl::GetVolume
321 // wxMediaCtrl::ShowInterface
322 // wxMediaCtrl::GetDownloadProgress
323 // wxMediaCtrl::GetDownloadTotal
325 // 1) Check to see whether the backend exists and is loading
326 // 2) Call the backend's version of the method, returning success
327 // if the backend's version succeeds
328 //---------------------------------------------------------------------------
329 bool wxMediaCtrl::Play()
331 if(m_imp
&& m_bLoaded
)
332 return m_imp
->Play();
336 bool wxMediaCtrl::Pause()
338 if(m_imp
&& m_bLoaded
)
339 return m_imp
->Pause();
343 bool wxMediaCtrl::Stop()
345 if(m_imp
&& m_bLoaded
)
346 return m_imp
->Stop();
350 double wxMediaCtrl::GetPlaybackRate()
352 if(m_imp
&& m_bLoaded
)
353 return m_imp
->GetPlaybackRate();
357 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
359 if(m_imp
&& m_bLoaded
)
360 return m_imp
->SetPlaybackRate(dRate
);
364 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
374 offset
= Length() - where
;
376 // case wxFromCurrent:
378 offset
= Tell() + where
;
382 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
384 return wxInvalidOffset
;
387 wxFileOffset
wxMediaCtrl::Tell()
389 if(m_imp
&& m_bLoaded
)
390 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
391 return wxInvalidOffset
;
394 wxFileOffset
wxMediaCtrl::Length()
396 if(m_imp
&& m_bLoaded
)
397 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
398 return wxInvalidOffset
;
401 wxMediaState
wxMediaCtrl::GetState()
403 if(m_imp
&& m_bLoaded
)
404 return m_imp
->GetState();
405 return wxMEDIASTATE_STOPPED
;
408 wxSize
wxMediaCtrl::DoGetBestSize() const
411 return m_imp
->GetVideoSize();
415 double wxMediaCtrl::GetVolume()
417 if(m_imp
&& m_bLoaded
)
418 return m_imp
->GetVolume();
422 bool wxMediaCtrl::SetVolume(double dVolume
)
424 if(m_imp
&& m_bLoaded
)
425 return m_imp
->SetVolume(dVolume
);
429 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
432 return m_imp
->ShowPlayerControls(flags
);
436 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
438 if(m_imp
&& m_bLoaded
)
439 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
440 return wxInvalidOffset
;
443 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
445 if(m_imp
&& m_bLoaded
)
446 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
447 return wxInvalidOffset
;
450 //---------------------------------------------------------------------------
451 // wxMediaCtrl::DoMoveWindow
453 // 1) Call parent's version so that our control's window moves where
455 // 2) If the backend exists and is loaded, move the video
456 // of the media to where our control's window is now located
457 //---------------------------------------------------------------------------
458 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
460 wxControl::DoMoveWindow(x
,y
,w
,h
);
463 m_imp
->Move(x
, y
, w
, h
);
466 //---------------------------------------------------------------------------
467 // wxMediaCtrl::MacVisibilityChanged
468 //---------------------------------------------------------------------------
469 #ifdef __WXOSX_CARBON__
470 void wxMediaCtrl::MacVisibilityChanged()
472 wxControl::MacVisibilityChanged();
475 m_imp
->MacVisibilityChanged();
479 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
481 // wxMediaBackendCommonBase
483 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
485 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
487 // our best size changed after opening a new file
488 m_ctrl
->InvalidateBestSize();
489 m_ctrl
->SetSize(m_ctrl
->GetSize());
491 // if the parent of the control has a sizer ask it to refresh our size
492 wxWindow
* const parent
= m_ctrl
->GetParent();
493 if ( parent
->GetSizer() )
495 m_ctrl
->GetParent()->Layout();
496 m_ctrl
->GetParent()->Refresh();
497 m_ctrl
->GetParent()->Update();
501 void wxMediaBackendCommonBase::NotifyMovieLoaded()
503 NotifyMovieSizeChanged();
505 // notify about movie being fully loaded
506 QueueEvent(wxEVT_MEDIA_LOADED
);
509 bool wxMediaBackendCommonBase::SendStopEvent()
511 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
513 return !m_ctrl
->GetEventHandler()->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
516 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
518 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
519 m_ctrl
->GetEventHandler()->AddPendingEvent(theEvent
);
522 void wxMediaBackendCommonBase::QueuePlayEvent()
524 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
525 QueueEvent(wxEVT_MEDIA_PLAY
);
528 void wxMediaBackendCommonBase::QueuePauseEvent()
530 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
531 QueueEvent(wxEVT_MEDIA_PAUSE
);
534 void wxMediaBackendCommonBase::QueueStopEvent()
536 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
537 QueueEvent(wxEVT_MEDIA_STOP
);
542 // Force link default backends in -
543 // see http://wiki.wxwidgets.org/wiki.pl?RTTI
545 #include "wx/html/forcelnk.h"
547 #ifdef __WXMSW__ // MSW has huge backends so we do it separately
548 FORCE_LINK(wxmediabackend_am
)
549 FORCE_LINK(wxmediabackend_wmp10
)
550 #elif !defined(__WXOSX_COCOA__)
551 FORCE_LINK(basewxmediabackends
)
554 #endif //wxUSE_MEDIACTRL