1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/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 #include "wx/wxprec.h"
34 //---------------------------------------------------------------------------
36 //---------------------------------------------------------------------------
37 #include "wx/mediactrl.h"
39 //===========================================================================
43 //===========================================================================
45 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 // RTTI and Event implementations
47 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
49 IMPLEMENT_CLASS(wxMediaCtrl
, wxControl
)
50 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STATECHANGED
)
51 DEFINE_EVENT_TYPE(wxEVT_MEDIA_PLAY
)
52 DEFINE_EVENT_TYPE(wxEVT_MEDIA_PAUSE
)
53 IMPLEMENT_CLASS(wxMediaBackend
, wxObject
)
54 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent
, wxEvent
)
55 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED
)
56 DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED
)
57 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP
)
59 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
63 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
65 //---------------------------------------------------------------------------
66 // wxMediaBackend Destructor
68 // This is here because the DARWIN gcc compiler badly screwed up and
69 // needs the destructor implementation in the source
70 //---------------------------------------------------------------------------
71 wxMediaBackend::~wxMediaBackend()
75 //---------------------------------------------------------------------------
76 // wxMediaCtrl::Create (file version)
77 // wxMediaCtrl::Create (URL version)
79 // Searches for a backend that is installed on the system (backends
80 // starting with lower characters in the alphabet are given priority),
81 // and creates the control from it
83 // This searches by searching the global RTTI hashtable, class by class,
84 // attempting to call CreateControl on each one found that is a derivative
85 // of wxMediaBackend - if it succeeded Create returns true, otherwise
86 // it keeps iterating through the hashmap.
87 //---------------------------------------------------------------------------
88 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
89 const wxString
& fileName
,
93 const wxString
& szBackend
,
94 const wxValidator
& validator
,
97 if(!szBackend
.empty())
99 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
101 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
102 pos
, size
, style
, validator
, name
))
108 if (!fileName
.empty())
118 SetInitialSize(size
);
123 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
125 const wxClassInfo
* classInfo
;
127 while((classInfo
= NextBackend(&it
)) != NULL
)
129 wxLogMessage( classInfo
->GetClassName() );
130 if(!DoCreate(classInfo
, parent
, id
,
131 pos
, size
, style
, validator
, name
))
134 if (!fileName
.empty())
138 SetInitialSize(size
);
146 SetInitialSize(size
);
156 bool wxMediaCtrl::Create(wxWindow
* parent
, wxWindowID id
,
157 const wxURI
& location
,
161 const wxString
& szBackend
,
162 const wxValidator
& validator
,
163 const wxString
& name
)
165 if(!szBackend
.empty())
167 wxClassInfo
* pClassInfo
= wxClassInfo::FindClass(szBackend
);
168 if(!pClassInfo
|| !DoCreate(pClassInfo
, parent
, id
,
169 pos
, size
, style
, validator
, name
))
182 SetInitialSize(size
);
187 wxClassInfo::const_iterator it
= wxClassInfo::begin_classinfo();
189 const wxClassInfo
* classInfo
;
191 while((classInfo
= NextBackend(&it
)) != NULL
)
193 if(!DoCreate(classInfo
, parent
, id
,
194 pos
, size
, style
, validator
, name
))
199 SetInitialSize(size
);
211 //---------------------------------------------------------------------------
212 // wxMediaCtrl::DoCreate
214 // Attempts to create the control from a backend
215 //---------------------------------------------------------------------------
216 bool wxMediaCtrl::DoCreate(const wxClassInfo
* classInfo
,
217 wxWindow
* parent
, wxWindowID id
,
221 const wxValidator
& validator
,
222 const wxString
& name
)
224 m_imp
= (wxMediaBackend
*)classInfo
->CreateObject();
226 if( m_imp
->CreateControl(this, parent
, id
, pos
, size
,
227 style
, validator
, name
) )
236 //---------------------------------------------------------------------------
237 // wxMediaCtrl::NextBackend (static)
240 // Search through the RTTI hashmap one at a
241 // time, attempting to create each derivative
245 // STL isn't compatible with and will have a compilation error
246 // on a wxNode, however, wxHashTable::compatibility_iterator is
247 // incompatible with the old 2.4 stable version - but since
248 // we're in 2.5+ only we don't need to worry about the new version
249 //---------------------------------------------------------------------------
250 const wxClassInfo
* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator
* it
)
252 for ( wxClassInfo::const_iterator end
= wxClassInfo::end_classinfo();
253 *it
!= end
; ++(*it
) )
255 const wxClassInfo
* classInfo
= **it
;
256 if ( classInfo
->IsKindOf(CLASSINFO(wxMediaBackend
)) &&
257 classInfo
!= CLASSINFO(wxMediaBackend
) )
264 // Nope - couldn't successfully find one... fail
270 //---------------------------------------------------------------------------
271 // wxMediaCtrl Destructor
273 // Free up the backend if it exists
274 //---------------------------------------------------------------------------
275 wxMediaCtrl::~wxMediaCtrl()
281 //---------------------------------------------------------------------------
282 // wxMediaCtrl::Load (file version)
283 // wxMediaCtrl::Load (URL version)
284 // wxMediaCtrl::Load (URL & Proxy version)
285 // wxMediaCtrl::Load (wxInputStream version)
287 // Here we call load of the backend - keeping
288 // track of whether it was successful or not - which
289 // will determine which later method calls work
290 //---------------------------------------------------------------------------
291 bool wxMediaCtrl::Load(const wxString
& fileName
)
294 return (m_bLoaded
= m_imp
->Load(fileName
));
298 bool wxMediaCtrl::Load(const wxURI
& location
)
301 return (m_bLoaded
= m_imp
->Load(location
));
305 bool wxMediaCtrl::Load(const wxURI
& location
, const wxURI
& proxy
)
308 return (m_bLoaded
= m_imp
->Load(location
, proxy
));
312 //---------------------------------------------------------------------------
314 // wxMediaCtrl::Pause
316 // wxMediaCtrl::GetPlaybackRate
317 // wxMediaCtrl::SetPlaybackRate
318 // wxMediaCtrl::Seek --> SetPosition
319 // wxMediaCtrl::Tell --> GetPosition
320 // wxMediaCtrl::Length --> GetDuration
321 // wxMediaCtrl::GetState
322 // wxMediaCtrl::DoGetBestSize
323 // wxMediaCtrl::SetVolume
324 // wxMediaCtrl::GetVolume
325 // wxMediaCtrl::ShowInterface
326 // wxMediaCtrl::GetDownloadProgress
327 // wxMediaCtrl::GetDownloadTotal
329 // 1) Check to see whether the backend exists and is loading
330 // 2) Call the backend's version of the method, returning success
331 // if the backend's version succeeds
332 //---------------------------------------------------------------------------
333 bool wxMediaCtrl::Play()
335 if(m_imp
&& m_bLoaded
)
336 return m_imp
->Play();
340 bool wxMediaCtrl::Pause()
342 if(m_imp
&& m_bLoaded
)
343 return m_imp
->Pause();
347 bool wxMediaCtrl::Stop()
349 if(m_imp
&& m_bLoaded
)
350 return m_imp
->Stop();
354 double wxMediaCtrl::GetPlaybackRate()
356 if(m_imp
&& m_bLoaded
)
357 return m_imp
->GetPlaybackRate();
361 bool wxMediaCtrl::SetPlaybackRate(double dRate
)
363 if(m_imp
&& m_bLoaded
)
364 return m_imp
->SetPlaybackRate(dRate
);
368 wxFileOffset
wxMediaCtrl::Seek(wxFileOffset where
, wxSeekMode mode
)
378 offset
= Length() - where
;
380 // case wxFromCurrent:
382 offset
= Tell() + where
;
386 if(m_imp
&& m_bLoaded
&& m_imp
->SetPosition(offset
))
388 return wxInvalidOffset
;
391 wxFileOffset
wxMediaCtrl::Tell()
393 if(m_imp
&& m_bLoaded
)
394 return (wxFileOffset
) m_imp
->GetPosition().ToLong();
395 return wxInvalidOffset
;
398 wxFileOffset
wxMediaCtrl::Length()
400 if(m_imp
&& m_bLoaded
)
401 return (wxFileOffset
) m_imp
->GetDuration().ToLong();
402 return wxInvalidOffset
;
405 wxMediaState
wxMediaCtrl::GetState()
407 if(m_imp
&& m_bLoaded
)
408 return m_imp
->GetState();
409 return wxMEDIASTATE_STOPPED
;
412 wxSize
wxMediaCtrl::DoGetBestSize() const
415 return m_imp
->GetVideoSize();
419 double wxMediaCtrl::GetVolume()
421 if(m_imp
&& m_bLoaded
)
422 return m_imp
->GetVolume();
426 bool wxMediaCtrl::SetVolume(double dVolume
)
428 if(m_imp
&& m_bLoaded
)
429 return m_imp
->SetVolume(dVolume
);
433 bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags
)
436 return m_imp
->ShowPlayerControls(flags
);
440 wxFileOffset
wxMediaCtrl::GetDownloadProgress()
442 if(m_imp
&& m_bLoaded
)
443 return (wxFileOffset
) m_imp
->GetDownloadProgress().ToLong();
444 return wxInvalidOffset
;
447 wxFileOffset
wxMediaCtrl::GetDownloadTotal()
449 if(m_imp
&& m_bLoaded
)
450 return (wxFileOffset
) m_imp
->GetDownloadTotal().ToLong();
451 return wxInvalidOffset
;
454 //---------------------------------------------------------------------------
455 // wxMediaCtrl::DoMoveWindow
457 // 1) Call parent's version so that our control's window moves where
459 // 2) If the backend exists and is loaded, move the video
460 // of the media to where our control's window is now located
461 //---------------------------------------------------------------------------
462 void wxMediaCtrl::DoMoveWindow(int x
, int y
, int w
, int h
)
464 wxControl::DoMoveWindow(x
,y
,w
,h
);
467 m_imp
->Move(x
, y
, w
, h
);
470 //---------------------------------------------------------------------------
471 // wxMediaCtrl::MacVisibilityChanged
472 //---------------------------------------------------------------------------
474 void wxMediaCtrl::MacVisibilityChanged()
476 wxControl::MacVisibilityChanged();
479 m_imp
->MacVisibilityChanged();
483 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
485 // wxMediaBackendCommonBase
487 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
489 void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
491 // our best size changed after opening a new file
492 m_ctrl
->InvalidateBestSize();
493 m_ctrl
->SetSize(m_ctrl
->GetSize());
495 // if the parent of the control has a sizer ask it to refresh our size
496 wxWindow
* const parent
= m_ctrl
->GetParent();
497 if ( parent
->GetSizer() )
499 m_ctrl
->GetParent()->Layout();
500 m_ctrl
->GetParent()->Refresh();
501 m_ctrl
->GetParent()->Update();
505 void wxMediaBackendCommonBase::NotifyMovieLoaded()
507 NotifyMovieSizeChanged();
509 // notify about movie being fully loaded
510 QueueEvent(wxEVT_MEDIA_LOADED
);
513 bool wxMediaBackendCommonBase::SendStopEvent()
515 wxMediaEvent
theEvent(wxEVT_MEDIA_STOP
, m_ctrl
->GetId());
517 return !m_ctrl
->ProcessEvent(theEvent
) || theEvent
.IsAllowed();
520 void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType
)
522 wxMediaEvent
theEvent(evtType
, m_ctrl
->GetId());
523 m_ctrl
->AddPendingEvent(theEvent
);
526 void wxMediaBackendCommonBase::QueuePlayEvent()
528 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
529 QueueEvent(wxEVT_MEDIA_PLAY
);
532 void wxMediaBackendCommonBase::QueuePauseEvent()
534 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
535 QueueEvent(wxEVT_MEDIA_PAUSE
);
538 void wxMediaBackendCommonBase::QueueStopEvent()
540 QueueEvent(wxEVT_MEDIA_STATECHANGED
);
541 QueueEvent(wxEVT_MEDIA_STOP
);
546 // Force link default backends in -
547 // see http://wiki.wxwidgets.org/wiki.pl?RTTI
549 #include "wx/html/forcelnk.h"
551 #ifdef __WXMSW__ // MSW has huge backends so we do it seperately
552 FORCE_LINK(wxmediabackend_am
)
553 FORCE_LINK(wxmediabackend_wmp10
)
555 FORCE_LINK(basewxmediabackends
)
558 #endif //wxUSE_MEDIACTRL