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 //===========================================================================
14 //===========================================================================
16 //---------------------------------------------------------------------------
17 // Pre-compiled header stuff
18 //---------------------------------------------------------------------------
20 #include "wx/wxprec.h"
26 //---------------------------------------------------------------------------
28 //---------------------------------------------------------------------------
29 #include "wx/mediactrl.h"
32 //---------------------------------------------------------------------------
34 //---------------------------------------------------------------------------
37 //===========================================================================
41 //===========================================================================
43 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
44 // RTTI and Event implementations
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
);
48 IMPLEMENT_CLASS(wxMediaBackend
, wxObject
);
49 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
);
50 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED
);
51 DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED
);
52 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP
);
54 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
60 //---------------------------------------------------------------------------
61 // wxMediaBackend Destructor
63 // This is here because the DARWIN gcc compiler badly screwed up and
64 // needs the destructor implementation in the source
65 //---------------------------------------------------------------------------
66 wxMediaBackend::~wxMediaBackend()
70 //---------------------------------------------------------------------------
71 // wxMediaCtrl::Create (file version)
72 // wxMediaCtrl::Create (URL version)
74 // Searches for a backend that is installed on the system (backends
75 // starting with lower characters in the alphabet are given priority),
76 // and creates the control from it
78 // This searches by searching the global RTTI hashtable, class by class,
79 // attempting to call CreateControl on each one found that is a derivative
80 // of wxMediaBackend - if it succeeded Create returns true, otherwise
81 // it keeps iterating through the hashmap.
82 //---------------------------------------------------------------------------
83 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
84 const wxString
& fileName
,
88 const wxString
& szBackend
,
89 const wxValidator
& validator
,
92 if(!szBackend
.empty())
94 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
96 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
97 pos
, size
, style
, validator
, name
))
103 if (!fileName
.empty())
113 SetBestFittingSize(size
);
118 wxClassInfo::sm_classTable
->BeginFind();
120 wxClassInfo
* classInfo
;
122 while((classInfo
= NextBackend()) != NULL
)
124 if(!DoCreate(classInfo
, parent
, id
,
125 pos
, size
, style
, validator
, name
))
128 if (!fileName
.empty())
132 SetBestFittingSize(size
);
140 SetBestFittingSize(size
);
150 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
151 const wxURI
& location
,
155 const wxString
& szBackend
,
156 const wxValidator
& validator
,
157 const wxString
& name
)
159 if(!szBackend
.empty())
161 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
162 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
163 pos
, size
, style
, validator
, name
))
176 SetBestFittingSize(size
);
181 wxClassInfo::sm_classTable
->BeginFind();
183 wxClassInfo
* classInfo
;
185 while((classInfo
= NextBackend()) != NULL
)
187 if(!DoCreate(classInfo
, parent
, id
,
188 pos
, size
, style
, validator
, name
))
193 SetBestFittingSize(size
);
205 //---------------------------------------------------------------------------
206 // wxMediaCtrl::DoCreate
208 // Attempts to create the control from a backend
209 //---------------------------------------------------------------------------
210 bool wxMediaCtrl::DoCreate(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
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 this
244 //---------------------------------------------------------------------------
245 wxClassInfo
* wxMediaCtrl::NextBackend()
247 wxHashTable::compatibility_iterator
248 node
= wxClassInfo::sm_classTable
->Next();
251 wxClassInfo
* classInfo
= (wxClassInfo
*)node
->GetData();
252 if ( classInfo
->IsKindOf(CLASSINFO(wxMediaBackend
)) &&
253 classInfo
!= CLASSINFO(wxMediaBackend
) )
257 node
= wxClassInfo::sm_classTable
->Next();
261 // Nope - couldn't successfully find one... fail
267 //---------------------------------------------------------------------------
268 // wxMediaCtrl Destructor
270 // Free up the backend if it exists
271 //---------------------------------------------------------------------------
272 wxMediaCtrl::~wxMediaCtrl()
278 //---------------------------------------------------------------------------
279 // wxMediaCtrl::Load (file version)
280 // wxMediaCtrl::Load (URL version)
281 // wxMediaCtrl::Load (URL & Proxy version)
282 // wxMediaCtrl::Load (wxInputStream version)
284 // Here we call load of the backend - keeping
285 // track of whether it was successful or not - which
286 // will determine which later method calls work
287 //---------------------------------------------------------------------------
288 bool wxMediaCtrl::Load(const wxString
& fileName
)
291 return (m_bLoaded
= m_imp
->Load(fileName
));
295 bool wxMediaCtrl::Load(const wxURI
& location
)
298 return (m_bLoaded
= m_imp
->Load(location
));
302 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
305 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
309 //---------------------------------------------------------------------------
311 // wxMediaCtrl::Pause
313 // wxMediaCtrl::GetPlaybackRate
314 // wxMediaCtrl::SetPlaybackRate
315 // wxMediaCtrl::Seek --> SetPosition
316 // wxMediaCtrl::Tell --> GetPosition
317 // wxMediaCtrl::Length --> GetDuration
318 // wxMediaCtrl::GetState
319 // wxMediaCtrl::DoGetBestSize
320 // wxMediaCtrl::SetVolume
321 // wxMediaCtrl::GetVolume
322 // wxMediaCtrl::ShowInterface
323 // wxMediaCtrl::GetDownloadProgress
324 // wxMediaCtrl::GetDownloadTotal
326 // 1) Check to see whether the backend exists and is loading
327 // 2) Call the backend's version of the method, returning success
328 // if the backend's version succeeds
329 //---------------------------------------------------------------------------
330 bool wxMediaCtrl::Play()
332 if(m_imp
&& m_bLoaded
)
333 return m_imp
->Play();
337 bool wxMediaCtrl::Pause()
339 if(m_imp
&& m_bLoaded
)
340 return m_imp
->Pause();
344 bool wxMediaCtrl::Stop()
346 if(m_imp
&& m_bLoaded
)
347 return m_imp
->Stop();
351 double wxMediaCtrl::GetPlaybackRate()
353 if(m_imp
&& m_bLoaded
)
354 return m_imp
->GetPlaybackRate();
358 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
360 if(m_imp
&& m_bLoaded
)
361 return m_imp
->SetPlaybackRate(dRate
);
365 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
375 offset
= Length() - where
;
377 // case wxFromCurrent:
379 offset
= Tell() + where
;
383 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
385 return wxInvalidOffset
;
388 wxFileOffset
wxMediaCtrl::Tell()
390 if(m_imp
&& m_bLoaded
)
391 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
392 return wxInvalidOffset
;
395 wxFileOffset
wxMediaCtrl::Length()
397 if(m_imp
&& m_bLoaded
)
398 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
399 return wxInvalidOffset
;
402 wxMediaState
wxMediaCtrl::GetState()
404 if(m_imp
&& m_bLoaded
)
405 return m_imp
->GetState();
406 return wxMEDIASTATE_STOPPED
;
409 wxSize
wxMediaCtrl::DoGetBestSize() const
412 return m_imp
->GetVideoSize();
416 double wxMediaCtrl::GetVolume()
418 if(m_imp
&& m_bLoaded
)
419 return m_imp
->GetVolume();
423 bool wxMediaCtrl::SetVolume(double dVolume
)
425 if(m_imp
&& m_bLoaded
)
426 return m_imp
->SetVolume(dVolume
);
430 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
433 return m_imp
->ShowPlayerControls(flags
);
437 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
439 if(m_imp
&& m_bLoaded
)
440 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
441 return wxInvalidOffset
;
444 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
446 if(m_imp
&& m_bLoaded
)
447 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
448 return wxInvalidOffset
;
451 //---------------------------------------------------------------------------
452 // wxMediaCtrl::DoMoveWindow
454 // 1) Call parent's version so that our control's window moves where
456 // 2) If the backend exists and is loaded, move the video
457 // of the media to where our control's window is now located
458 //---------------------------------------------------------------------------
459 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
461 wxControl::DoMoveWindow(x
,y
,w
,h
);
464 m_imp
->Move(x
, y
, w
, h
);
467 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
469 // wxMediaBackendCommonBase
471 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
473 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
475 // our best size changed after opening a new file
476 m_ctrl
->InvalidateBestSize();
477 m_ctrl
->SetSize(m_ctrl
->GetSize());
479 // if the parent of the control has a sizer ask it to refresh our size
480 wxWindow
* const parent
= m_ctrl
->GetParent();
481 if ( parent
->GetSizer() )
483 m_ctrl
->GetParent()->Layout();
484 m_ctrl
->GetParent()->Refresh();
485 m_ctrl
->GetParent()->Update();
489 void wxMediaBackendCommonBase::NotifyMovieLoaded()
491 NotifyMovieSizeChanged();
493 // notify about movie being fully loaded
494 QueueEvent(wxEVT_MEDIA_LOADED
);
497 bool wxMediaBackendCommonBase::SendStopEvent()
499 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
501 return !m_ctrl
->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
504 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
506 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
507 m_ctrl
->AddPendingEvent(theEvent
);
510 #include "wx/html/forcelnk.h"
511 FORCE_LINK(basewxmediabackends
);
513 //---------------------------------------------------------------------------
514 // End of compilation guard and of file
515 //---------------------------------------------------------------------------
516 #endif //wxUSE_MEDIACTRL