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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "mediactrl.h"
24 #include "wx/wxprec.h"
30 //---------------------------------------------------------------------------
32 //---------------------------------------------------------------------------
33 #include "wx/mediactrl.h"
36 //---------------------------------------------------------------------------
38 //---------------------------------------------------------------------------
41 //===========================================================================
45 //===========================================================================
47 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
48 // RTTI and Event implementations
49 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
51 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
);
52 IMPLEMENT_CLASS(wxMediaBackend
, wxObject
);
53 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
);
54 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED
);
55 DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED
);
56 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP
);
58 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
62 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
64 //---------------------------------------------------------------------------
65 // wxMediaBackend Destructor
67 // This is here because the DARWIN gcc compiler badly screwed up and
68 // needs the destructor implementation in the source
69 //---------------------------------------------------------------------------
70 wxMediaBackend::~wxMediaBackend()
74 //---------------------------------------------------------------------------
75 // wxMediaCtrl::Create (file version)
76 // wxMediaCtrl::Create (URL version)
78 // Searches for a backend that is installed on the system (backends
79 // starting with lower characters in the alphabet are given priority),
80 // and creates the control from it
82 // This searches by searching the global RTTI hashtable, class by class,
83 // attempting to call CreateControl on each one found that is a derivative
84 // of wxMediaBackend - if it succeeded Create returns true, otherwise
85 // it keeps iterating through the hashmap.
86 //---------------------------------------------------------------------------
87 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
88 const wxString
& fileName
,
92 const wxString
& szBackend
,
93 const wxValidator
& validator
,
96 if(!szBackend
.empty())
98 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
100 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
101 pos
, size
, style
, validator
, name
))
107 if (!fileName
.empty())
117 SetBestFittingSize(size
);
122 wxClassInfo::sm_classTable
->BeginFind();
124 wxClassInfo
* classInfo
;
126 while((classInfo
= NextBackend()) != NULL
)
128 if(!DoCreate(classInfo
, parent
, id
,
129 pos
, size
, style
, validator
, name
))
132 if (!fileName
.empty())
136 SetBestFittingSize(size
);
144 SetBestFittingSize(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 SetBestFittingSize(size
);
185 wxClassInfo::sm_classTable
->BeginFind();
187 wxClassInfo
* classInfo
;
189 while((classInfo
= NextBackend()) != NULL
)
191 if(!DoCreate(classInfo
, parent
, id
,
192 pos
, size
, style
, validator
, name
))
197 SetBestFittingSize(size
);
209 //---------------------------------------------------------------------------
210 // wxMediaCtrl::DoCreate
212 // Attempts to create the control from a backend
213 //---------------------------------------------------------------------------
214 bool wxMediaCtrl::DoCreate(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
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 this
248 //---------------------------------------------------------------------------
249 wxClassInfo
* wxMediaCtrl::NextBackend()
251 wxHashTable::compatibility_iterator
252 node
= wxClassInfo::sm_classTable
->Next();
255 wxClassInfo
* classInfo
= (wxClassInfo
*)node
->GetData();
256 if ( classInfo
->IsKindOf(CLASSINFO(wxMediaBackend
)) &&
257 classInfo
!= CLASSINFO(wxMediaBackend
) )
261 node
= wxClassInfo::sm_classTable
->Next();
265 // Nope - couldn't successfully find one... fail
271 //---------------------------------------------------------------------------
272 // wxMediaCtrl Destructor
274 // Free up the backend if it exists
275 //---------------------------------------------------------------------------
276 wxMediaCtrl::~wxMediaCtrl()
282 //---------------------------------------------------------------------------
283 // wxMediaCtrl::Load (file version)
284 // wxMediaCtrl::Load (URL version)
285 // wxMediaCtrl::Load (URL & Proxy version)
286 // wxMediaCtrl::Load (wxInputStream version)
288 // Here we call load of the backend - keeping
289 // track of whether it was successful or not - which
290 // will determine which later method calls work
291 //---------------------------------------------------------------------------
292 bool wxMediaCtrl::Load(const wxString
& fileName
)
295 return (m_bLoaded
= m_imp
->Load(fileName
));
299 bool wxMediaCtrl::Load(const wxURI
& location
)
302 return (m_bLoaded
= m_imp
->Load(location
));
306 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
309 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
313 //---------------------------------------------------------------------------
315 // wxMediaCtrl::Pause
317 // wxMediaCtrl::GetPlaybackRate
318 // wxMediaCtrl::SetPlaybackRate
319 // wxMediaCtrl::Seek --> SetPosition
320 // wxMediaCtrl::Tell --> GetPosition
321 // wxMediaCtrl::Length --> GetDuration
322 // wxMediaCtrl::GetState
323 // wxMediaCtrl::DoGetBestSize
324 // wxMediaCtrl::SetVolume
325 // wxMediaCtrl::GetVolume
326 // wxMediaCtrl::ShowInterface
327 // wxMediaCtrl::GetDownloadProgress
328 // wxMediaCtrl::GetDownloadTotal
330 // 1) Check to see whether the backend exists and is loading
331 // 2) Call the backend's version of the method, returning success
332 // if the backend's version succeeds
333 //---------------------------------------------------------------------------
334 bool wxMediaCtrl::Play()
336 if(m_imp
&& m_bLoaded
)
337 return m_imp
->Play();
341 bool wxMediaCtrl::Pause()
343 if(m_imp
&& m_bLoaded
)
344 return m_imp
->Pause();
348 bool wxMediaCtrl::Stop()
350 if(m_imp
&& m_bLoaded
)
351 return m_imp
->Stop();
355 double wxMediaCtrl::GetPlaybackRate()
357 if(m_imp
&& m_bLoaded
)
358 return m_imp
->GetPlaybackRate();
362 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
364 if(m_imp
&& m_bLoaded
)
365 return m_imp
->SetPlaybackRate(dRate
);
369 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
379 offset
= Length() - where
;
381 // case wxFromCurrent:
383 offset
= Tell() + where
;
387 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
389 return wxInvalidOffset
;
392 wxFileOffset
wxMediaCtrl::Tell()
394 if(m_imp
&& m_bLoaded
)
395 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
396 return wxInvalidOffset
;
399 wxFileOffset
wxMediaCtrl::Length()
401 if(m_imp
&& m_bLoaded
)
402 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
403 return wxInvalidOffset
;
406 wxMediaState
wxMediaCtrl::GetState()
408 if(m_imp
&& m_bLoaded
)
409 return m_imp
->GetState();
410 return wxMEDIASTATE_STOPPED
;
413 wxSize
wxMediaCtrl::DoGetBestSize() const
416 return m_imp
->GetVideoSize();
420 double wxMediaCtrl::GetVolume()
422 if(m_imp
&& m_bLoaded
)
423 return m_imp
->GetVolume();
427 bool wxMediaCtrl::SetVolume(double dVolume
)
429 if(m_imp
&& m_bLoaded
)
430 return m_imp
->SetVolume(dVolume
);
434 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
437 return m_imp
->ShowPlayerControls(flags
);
441 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
443 if(m_imp
&& m_bLoaded
)
444 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
445 return wxInvalidOffset
;
448 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
450 if(m_imp
&& m_bLoaded
)
451 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
452 return wxInvalidOffset
;
455 //---------------------------------------------------------------------------
456 // wxMediaCtrl::DoMoveWindow
458 // 1) Call parent's version so that our control's window moves where
460 // 2) If the backend exists and is loaded, move the video
461 // of the media to where our control's window is now located
462 //---------------------------------------------------------------------------
463 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
465 wxControl::DoMoveWindow(x
,y
,w
,h
);
468 m_imp
->Move(x
, y
, w
, h
);
471 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
473 // wxMediaBackendCommonBase
475 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
477 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
479 // our best size changed after opening a new file
480 m_ctrl
->InvalidateBestSize();
481 m_ctrl
->SetSize(m_ctrl
->GetSize());
483 // if the parent of the control has a sizer ask it to refresh our size
484 wxWindow
* const parent
= m_ctrl
->GetParent();
485 if ( parent
->GetSizer() )
487 m_ctrl
->GetParent()->Layout();
488 m_ctrl
->GetParent()->Refresh();
489 m_ctrl
->GetParent()->Update();
493 void wxMediaBackendCommonBase::NotifyMovieLoaded()
495 NotifyMovieSizeChanged();
497 // notify about movie being fully loaded
498 QueueEvent(wxEVT_MEDIA_LOADED
);
501 bool wxMediaBackendCommonBase::SendStopEvent()
503 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
505 return !m_ctrl
->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
508 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
510 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
511 m_ctrl
->AddPendingEvent(theEvent
);
514 #include "wx/html/forcelnk.h"
515 FORCE_LINK(basewxmediabackends
);
517 //---------------------------------------------------------------------------
518 // End of compilation guard and of file
519 //---------------------------------------------------------------------------
520 #endif //wxUSE_MEDIACTRL