1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
23 #pragma implementation "mediactrl.h"
26 #include "wx/wxprec.h"
32 //---------------------------------------------------------------------------
34 //---------------------------------------------------------------------------
35 #include "wx/mediactrl.h"
38 //---------------------------------------------------------------------------
40 //---------------------------------------------------------------------------
43 //===========================================================================
47 //===========================================================================
49 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50 // RTTI and Event implementations
51 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
53 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
);
54 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STATECHANGED
)
55 DEFINE_EVENT_TYPE(wxEVT_MEDIA_PLAY
)
56 DEFINE_EVENT_TYPE(wxEVT_MEDIA_PAUSE
)
57 IMPLEMENT_CLASS(wxMediaBackend
, wxObject
);
58 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
);
59 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED
);
60 DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED
);
61 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP
);
63 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
67 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
69 //---------------------------------------------------------------------------
70 // wxMediaBackend Destructor
72 // This is here because the DARWIN gcc compiler badly screwed up and
73 // needs the destructor implementation in the source
74 //---------------------------------------------------------------------------
75 wxMediaBackend::~wxMediaBackend()
79 //---------------------------------------------------------------------------
80 // wxMediaCtrl::Create (file version)
81 // wxMediaCtrl::Create (URL version)
83 // Searches for a backend that is installed on the system (backends
84 // starting with lower characters in the alphabet are given priority),
85 // and creates the control from it
87 // This searches by searching the global RTTI hashtable, class by class,
88 // attempting to call CreateControl on each one found that is a derivative
89 // of wxMediaBackend - if it succeeded Create returns true, otherwise
90 // it keeps iterating through the hashmap.
91 //---------------------------------------------------------------------------
92 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
93 const wxString
& fileName
,
97 const wxString
& szBackend
,
98 const wxValidator
& validator
,
101 if(!szBackend
.empty())
103 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
105 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
106 pos
, size
, style
, validator
, name
))
112 if (!fileName
.empty())
122 SetBestFittingSize(size
);
127 wxClassInfo::sm_classTable
->BeginFind();
129 wxClassInfo
* classInfo
;
131 while((classInfo
= NextBackend()) != NULL
)
133 if(!DoCreate(classInfo
, parent
, id
,
134 pos
, size
, style
, validator
, name
))
137 if (!fileName
.empty())
141 SetBestFittingSize(size
);
149 SetBestFittingSize(size
);
159 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
160 const wxURI
& location
,
164 const wxString
& szBackend
,
165 const wxValidator
& validator
,
166 const wxString
& name
)
168 if(!szBackend
.empty())
170 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
171 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
172 pos
, size
, style
, validator
, name
))
185 SetBestFittingSize(size
);
190 wxClassInfo::sm_classTable
->BeginFind();
192 wxClassInfo
* classInfo
;
194 while((classInfo
= NextBackend()) != NULL
)
196 if(!DoCreate(classInfo
, parent
, id
,
197 pos
, size
, style
, validator
, name
))
202 SetBestFittingSize(size
);
214 //---------------------------------------------------------------------------
215 // wxMediaCtrl::DoCreate
217 // Attempts to create the control from a backend
218 //---------------------------------------------------------------------------
219 bool wxMediaCtrl::DoCreate(wxClassInfo
* classInfo
,
220 wxWindow
* parent
, wxWindowID id
,
224 const wxValidator
& validator
,
225 const wxString
& name
)
227 m_imp
= (wxMediaBackend
*)classInfo
->CreateObject();
229 if( m_imp
->CreateControl(this, parent
, id
, pos
, size
,
230 style
, validator
, name
) )
239 //---------------------------------------------------------------------------
240 // wxMediaCtrl::NextBackend (static)
243 // Search through the RTTI hashmap one at a
244 // time, attempting to create each derivative
248 // STL isn't compatible with and will have a compilation error
249 // on a wxNode, however, wxHashTable::compatibility_iterator is
250 // incompatible with the old 2.4 stable version - but since
251 // we're in 2.5+ only we don't need to worry about the new version
252 //---------------------------------------------------------------------------
253 wxClassInfo
* wxMediaCtrl::NextBackend()
255 wxHashTable::compatibility_iterator
256 node
= wxClassInfo::sm_classTable
->Next();
259 wxClassInfo
* classInfo
= (wxClassInfo
*)node
->GetData();
260 if ( classInfo
->IsKindOf(CLASSINFO(wxMediaBackend
)) &&
261 classInfo
!= CLASSINFO(wxMediaBackend
) )
265 node
= wxClassInfo::sm_classTable
->Next();
269 // Nope - couldn't successfully find one... fail
275 //---------------------------------------------------------------------------
276 // wxMediaCtrl Destructor
278 // Free up the backend if it exists
279 //---------------------------------------------------------------------------
280 wxMediaCtrl::~wxMediaCtrl()
286 //---------------------------------------------------------------------------
287 // wxMediaCtrl::Load (file version)
288 // wxMediaCtrl::Load (URL version)
289 // wxMediaCtrl::Load (URL & Proxy version)
290 // wxMediaCtrl::Load (wxInputStream version)
292 // Here we call load of the backend - keeping
293 // track of whether it was successful or not - which
294 // will determine which later method calls work
295 //---------------------------------------------------------------------------
296 bool wxMediaCtrl::Load(const wxString
& fileName
)
299 return (m_bLoaded
= m_imp
->Load(fileName
));
303 bool wxMediaCtrl::Load(const wxURI
& location
)
306 return (m_bLoaded
= m_imp
->Load(location
));
310 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
313 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
317 //---------------------------------------------------------------------------
319 // wxMediaCtrl::Pause
321 // wxMediaCtrl::GetPlaybackRate
322 // wxMediaCtrl::SetPlaybackRate
323 // wxMediaCtrl::Seek --> SetPosition
324 // wxMediaCtrl::Tell --> GetPosition
325 // wxMediaCtrl::Length --> GetDuration
326 // wxMediaCtrl::GetState
327 // wxMediaCtrl::DoGetBestSize
328 // wxMediaCtrl::SetVolume
329 // wxMediaCtrl::GetVolume
330 // wxMediaCtrl::ShowInterface
331 // wxMediaCtrl::GetDownloadProgress
332 // wxMediaCtrl::GetDownloadTotal
334 // 1) Check to see whether the backend exists and is loading
335 // 2) Call the backend's version of the method, returning success
336 // if the backend's version succeeds
337 //---------------------------------------------------------------------------
338 bool wxMediaCtrl::Play()
340 if(m_imp
&& m_bLoaded
)
341 return m_imp
->Play();
345 bool wxMediaCtrl::Pause()
347 if(m_imp
&& m_bLoaded
)
348 return m_imp
->Pause();
352 bool wxMediaCtrl::Stop()
354 if(m_imp
&& m_bLoaded
)
355 return m_imp
->Stop();
359 double wxMediaCtrl::GetPlaybackRate()
361 if(m_imp
&& m_bLoaded
)
362 return m_imp
->GetPlaybackRate();
366 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
368 if(m_imp
&& m_bLoaded
)
369 return m_imp
->SetPlaybackRate(dRate
);
373 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
383 offset
= Length() - where
;
385 // case wxFromCurrent:
387 offset
= Tell() + where
;
391 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
393 return wxInvalidOffset
;
396 wxFileOffset
wxMediaCtrl::Tell()
398 if(m_imp
&& m_bLoaded
)
399 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
400 return wxInvalidOffset
;
403 wxFileOffset
wxMediaCtrl::Length()
405 if(m_imp
&& m_bLoaded
)
406 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
407 return wxInvalidOffset
;
410 wxMediaState
wxMediaCtrl::GetState()
412 if(m_imp
&& m_bLoaded
)
413 return m_imp
->GetState();
414 return wxMEDIASTATE_STOPPED
;
417 wxSize
wxMediaCtrl::DoGetBestSize() const
420 return m_imp
->GetVideoSize();
424 double wxMediaCtrl::GetVolume()
426 if(m_imp
&& m_bLoaded
)
427 return m_imp
->GetVolume();
431 bool wxMediaCtrl::SetVolume(double dVolume
)
433 if(m_imp
&& m_bLoaded
)
434 return m_imp
->SetVolume(dVolume
);
438 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
441 return m_imp
->ShowPlayerControls(flags
);
445 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
447 if(m_imp
&& m_bLoaded
)
448 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
449 return wxInvalidOffset
;
452 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
454 if(m_imp
&& m_bLoaded
)
455 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
456 return wxInvalidOffset
;
459 //---------------------------------------------------------------------------
460 // wxMediaCtrl::DoMoveWindow
462 // 1) Call parent's version so that our control's window moves where
464 // 2) If the backend exists and is loaded, move the video
465 // of the media to where our control's window is now located
466 //---------------------------------------------------------------------------
467 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
469 wxControl::DoMoveWindow(x
,y
,w
,h
);
472 m_imp
->Move(x
, y
, w
, h
);
475 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
477 // wxMediaBackendCommonBase
479 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
481 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
483 // our best size changed after opening a new file
484 m_ctrl
->InvalidateBestSize();
485 m_ctrl
->SetSize(m_ctrl
->GetSize());
487 // if the parent of the control has a sizer ask it to refresh our size
488 wxWindow
* const parent
= m_ctrl
->GetParent();
489 if ( parent
->GetSizer() )
491 m_ctrl
->GetParent()->Layout();
492 m_ctrl
->GetParent()->Refresh();
493 m_ctrl
->GetParent()->Update();
497 void wxMediaBackendCommonBase::NotifyMovieLoaded()
499 NotifyMovieSizeChanged();
501 // notify about movie being fully loaded
502 QueueEvent(wxEVT_MEDIA_LOADED
);
505 bool wxMediaBackendCommonBase::SendStopEvent()
507 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
509 return !m_ctrl
->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
512 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
514 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
515 m_ctrl
->AddPendingEvent(theEvent
);
518 void wxMediaBackendCommonBase::QueuePlayEvent()
520 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
521 QueueEvent(wxEVT_MEDIA_PLAY
);
524 void wxMediaBackendCommonBase::QueuePauseEvent()
526 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
527 QueueEvent(wxEVT_MEDIA_PAUSE
);
530 void wxMediaBackendCommonBase::QueueStopEvent()
532 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
533 QueueEvent(wxEVT_MEDIA_STOP
);
538 // Force link default backends in -
539 // see http://wiki.wxwidgets.org/wiki.pl?RTTI
541 #include "wx/html/forcelnk.h"
543 #ifdef __WXMSW__ // MSW has huge backends so we do it seperately
544 FORCE_LINK(wxmediabackend_am
);
545 FORCE_LINK(wxmediabackend_wmp10
);
547 FORCE_LINK(basewxmediabackends
);
549 //---------------------------------------------------------------------------
550 // End of compilation guard and of file
551 //---------------------------------------------------------------------------
552 #endif //wxUSE_MEDIACTRL