/ExtLibs/wxWidgets/src/common/mediactrlcmn.cpp
C++ | 554 lines | 349 code | 74 blank | 131 comment | 59 complexity | 69b512b35378e16b20db57e54bd44e85 MD5 | raw file
- /////////////////////////////////////////////////////////////////////////////
- // Name: src/common/mediactrlcmn.cpp
- // Purpose: wxMediaCtrl common code
- // Author: Ryan Norton <wxprojects@comcast.net>
- // Modified by:
- // Created: 11/07/04
- // RCS-ID: $Id$
- // Copyright: (c) Ryan Norton
- // Licence: wxWindows licence
- /////////////////////////////////////////////////////////////////////////////
- // TODO: Platform specific backend defaults?
- //===========================================================================
- // Declarations
- //===========================================================================
- //---------------------------------------------------------------------------
- // Includes
- //---------------------------------------------------------------------------
- #include "wx/wxprec.h"
- #ifdef __BORLANDC__
- #pragma hdrstop
- #endif
- #if wxUSE_MEDIACTRL
- #ifndef WX_PRECOMP
- #include "wx/hash.h"
- #include "wx/log.h"
- #endif
- #include "wx/mediactrl.h"
- //===========================================================================
- //
- // Implementation
- //
- //===========================================================================
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- // RTTI and Event implementations
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- IMPLEMENT_CLASS(wxMediaCtrl, wxControl)
- wxDEFINE_EVENT( wxEVT_MEDIA_STATECHANGED, wxMediaEvent );
- wxDEFINE_EVENT( wxEVT_MEDIA_PLAY, wxMediaEvent );
- wxDEFINE_EVENT( wxEVT_MEDIA_PAUSE, wxMediaEvent );
- IMPLEMENT_CLASS(wxMediaBackend, wxObject)
- IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent)
- wxDEFINE_EVENT( wxEVT_MEDIA_FINISHED, wxMediaEvent );
- wxDEFINE_EVENT( wxEVT_MEDIA_LOADED, wxMediaEvent );
- wxDEFINE_EVENT( wxEVT_MEDIA_STOP, wxMediaEvent );
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- //
- // wxMediaCtrl
- //
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- //---------------------------------------------------------------------------
- // wxMediaBackend Destructor
- //
- // This is here because the DARWIN gcc compiler badly screwed up and
- // needs the destructor implementation in the source
- //---------------------------------------------------------------------------
- wxMediaBackend::~wxMediaBackend()
- {
- }
- //---------------------------------------------------------------------------
- // wxMediaCtrl::Create (file version)
- // wxMediaCtrl::Create (URL version)
- //
- // Searches for a backend that is installed on the system (backends
- // starting with lower characters in the alphabet are given priority),
- // and creates the control from it
- //
- // This searches by searching the global RTTI hashtable, class by class,
- // attempting to call CreateControl on each one found that is a derivative
- // of wxMediaBackend - if it succeeded Create returns true, otherwise
- // it keeps iterating through the hashmap.
- //---------------------------------------------------------------------------
- bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
- const wxString& fileName,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxString& szBackend,
- const wxValidator& validator,
- const wxString& name)
- {
- if(!szBackend.empty())
- {
- wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
- if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
- pos, size, style, validator, name))
- {
- m_imp = NULL;
- return false;
- }
- if (!fileName.empty())
- {
- if (!Load(fileName))
- {
- wxDELETE(m_imp);
- return false;
- }
- }
- SetInitialSize(size);
- return true;
- }
- else
- {
- wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo();
- const wxClassInfo* classInfo;
- while((classInfo = NextBackend(&it)) != NULL)
- {
- if(!DoCreate(classInfo, parent, id,
- pos, size, style, validator, name))
- continue;
- if (!fileName.empty())
- {
- if (Load(fileName))
- {
- SetInitialSize(size);
- return true;
- }
- else
- delete m_imp;
- }
- else
- {
- SetInitialSize(size);
- return true;
- }
- }
- m_imp = NULL;
- return false;
- }
- }
- bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
- const wxURI& location,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxString& szBackend,
- const wxValidator& validator,
- const wxString& name)
- {
- if(!szBackend.empty())
- {
- wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
- if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
- pos, size, style, validator, name))
- {
- m_imp = NULL;
- return false;
- }
- if (!Load(location))
- {
- wxDELETE(m_imp);
- return false;
- }
- SetInitialSize(size);
- return true;
- }
- else
- {
- wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo();
- const wxClassInfo* classInfo;
- while((classInfo = NextBackend(&it)) != NULL)
- {
- if(!DoCreate(classInfo, parent, id,
- pos, size, style, validator, name))
- continue;
- if (Load(location))
- {
- SetInitialSize(size);
- return true;
- }
- else
- delete m_imp;
- }
- m_imp = NULL;
- return false;
- }
- }
- //---------------------------------------------------------------------------
- // wxMediaCtrl::DoCreate
- //
- // Attempts to create the control from a backend
- //---------------------------------------------------------------------------
- bool wxMediaCtrl::DoCreate(const wxClassInfo* classInfo,
- wxWindow* parent, wxWindowID id,
- const wxPoint& pos,
- const wxSize& size,
- long style,
- const wxValidator& validator,
- const wxString& name)
- {
- m_imp = (wxMediaBackend*)classInfo->CreateObject();
- if( m_imp->CreateControl(this, parent, id, pos, size,
- style, validator, name) )
- {
- return true;
- }
- delete m_imp;
- return false;
- }
- //---------------------------------------------------------------------------
- // wxMediaCtrl::NextBackend (static)
- //
- //
- // Search through the RTTI hashmap one at a
- // time, attempting to create each derivative
- // of wxMediaBackend
- //
- //
- // STL isn't compatible with and will have a compilation error
- // on a wxNode, however, wxHashTable::compatibility_iterator is
- // incompatible with the old 2.4 stable version - but since
- // we're in 2.5+ only we don't need to worry about the new version
- //---------------------------------------------------------------------------
- const wxClassInfo* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator* it)
- {
- for ( wxClassInfo::const_iterator end = wxClassInfo::end_classinfo();
- *it != end; ++(*it) )
- {
- const wxClassInfo* classInfo = **it;
- if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
- classInfo != CLASSINFO(wxMediaBackend) )
- {
- ++(*it);
- return classInfo;
- }
- }
- //
- // Nope - couldn't successfully find one... fail
- //
- return NULL;
- }
- //---------------------------------------------------------------------------
- // wxMediaCtrl Destructor
- //
- // Free up the backend if it exists
- //---------------------------------------------------------------------------
- wxMediaCtrl::~wxMediaCtrl()
- {
- if (m_imp)
- delete m_imp;
- }
- //---------------------------------------------------------------------------
- // wxMediaCtrl::Load (file version)
- // wxMediaCtrl::Load (URL version)
- // wxMediaCtrl::Load (URL & Proxy version)
- // wxMediaCtrl::Load (wxInputStream version)
- //
- // Here we call load of the backend - keeping
- // track of whether it was successful or not - which
- // will determine which later method calls work
- //---------------------------------------------------------------------------
- bool wxMediaCtrl::Load(const wxString& fileName)
- {
- if(m_imp)
- return (m_bLoaded = m_imp->Load(fileName));
- return false;
- }
- bool wxMediaCtrl::Load(const wxURI& location)
- {
- if(m_imp)
- return (m_bLoaded = m_imp->Load(location));
- return false;
- }
- bool wxMediaCtrl::Load(const wxURI& location, const wxURI& proxy)
- {
- if(m_imp)
- return (m_bLoaded = m_imp->Load(location, proxy));
- return false;
- }
- //---------------------------------------------------------------------------
- // wxMediaCtrl::Play
- // wxMediaCtrl::Pause
- // wxMediaCtrl::Stop
- // wxMediaCtrl::GetPlaybackRate
- // wxMediaCtrl::SetPlaybackRate
- // wxMediaCtrl::Seek --> SetPosition
- // wxMediaCtrl::Tell --> GetPosition
- // wxMediaCtrl::Length --> GetDuration
- // wxMediaCtrl::GetState
- // wxMediaCtrl::DoGetBestSize
- // wxMediaCtrl::SetVolume
- // wxMediaCtrl::GetVolume
- // wxMediaCtrl::ShowInterface
- // wxMediaCtrl::GetDownloadProgress
- // wxMediaCtrl::GetDownloadTotal
- //
- // 1) Check to see whether the backend exists and is loading
- // 2) Call the backend's version of the method, returning success
- // if the backend's version succeeds
- //---------------------------------------------------------------------------
- bool wxMediaCtrl::Play()
- {
- if(m_imp && m_bLoaded)
- return m_imp->Play();
- return 0;
- }
- bool wxMediaCtrl::Pause()
- {
- if(m_imp && m_bLoaded)
- return m_imp->Pause();
- return 0;
- }
- bool wxMediaCtrl::Stop()
- {
- if(m_imp && m_bLoaded)
- return m_imp->Stop();
- return 0;
- }
- double wxMediaCtrl::GetPlaybackRate()
- {
- if(m_imp && m_bLoaded)
- return m_imp->GetPlaybackRate();
- return 0;
- }
- bool wxMediaCtrl::SetPlaybackRate(double dRate)
- {
- if(m_imp && m_bLoaded)
- return m_imp->SetPlaybackRate(dRate);
- return false;
- }
- wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
- {
- wxFileOffset offset;
- switch (mode)
- {
- case wxFromStart:
- offset = where;
- break;
- case wxFromEnd:
- offset = Length() - where;
- break;
- // case wxFromCurrent:
- default:
- offset = Tell() + where;
- break;
- }
- if(m_imp && m_bLoaded && m_imp->SetPosition(offset))
- return offset;
- return wxInvalidOffset;
- }
- wxFileOffset wxMediaCtrl::Tell()
- {
- if(m_imp && m_bLoaded)
- return (wxFileOffset) m_imp->GetPosition().ToLong();
- return wxInvalidOffset;
- }
- wxFileOffset wxMediaCtrl::Length()
- {
- if(m_imp && m_bLoaded)
- return (wxFileOffset) m_imp->GetDuration().ToLong();
- return wxInvalidOffset;
- }
- wxMediaState wxMediaCtrl::GetState()
- {
- if(m_imp && m_bLoaded)
- return m_imp->GetState();
- return wxMEDIASTATE_STOPPED;
- }
- wxSize wxMediaCtrl::DoGetBestSize() const
- {
- if(m_imp)
- return m_imp->GetVideoSize();
- return wxSize(0,0);
- }
- double wxMediaCtrl::GetVolume()
- {
- if(m_imp && m_bLoaded)
- return m_imp->GetVolume();
- return 0.0;
- }
- bool wxMediaCtrl::SetVolume(double dVolume)
- {
- if(m_imp && m_bLoaded)
- return m_imp->SetVolume(dVolume);
- return false;
- }
- bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
- {
- if(m_imp)
- return m_imp->ShowPlayerControls(flags);
- return false;
- }
- wxFileOffset wxMediaCtrl::GetDownloadProgress()
- {
- if(m_imp && m_bLoaded)
- return (wxFileOffset) m_imp->GetDownloadProgress().ToLong();
- return wxInvalidOffset;
- }
- wxFileOffset wxMediaCtrl::GetDownloadTotal()
- {
- if(m_imp && m_bLoaded)
- return (wxFileOffset) m_imp->GetDownloadTotal().ToLong();
- return wxInvalidOffset;
- }
- //---------------------------------------------------------------------------
- // wxMediaCtrl::DoMoveWindow
- //
- // 1) Call parent's version so that our control's window moves where
- // it's supposed to
- // 2) If the backend exists and is loaded, move the video
- // of the media to where our control's window is now located
- //---------------------------------------------------------------------------
- void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
- {
- wxControl::DoMoveWindow(x,y,w,h);
- if(m_imp)
- m_imp->Move(x, y, w, h);
- }
- //---------------------------------------------------------------------------
- // wxMediaCtrl::MacVisibilityChanged
- //---------------------------------------------------------------------------
- #ifdef __WXOSX_CARBON__
- void wxMediaCtrl::MacVisibilityChanged()
- {
- wxControl::MacVisibilityChanged();
- if(m_imp)
- m_imp->MacVisibilityChanged();
- }
- #endif
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- //
- // wxMediaBackendCommonBase
- //
- //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
- {
- // our best size changed after opening a new file
- m_ctrl->InvalidateBestSize();
- m_ctrl->SetSize(m_ctrl->GetSize());
- // if the parent of the control has a sizer ask it to refresh our size
- wxWindow * const parent = m_ctrl->GetParent();
- if ( parent->GetSizer() )
- {
- m_ctrl->GetParent()->Layout();
- m_ctrl->GetParent()->Refresh();
- m_ctrl->GetParent()->Update();
- }
- }
- void wxMediaBackendCommonBase::NotifyMovieLoaded()
- {
- NotifyMovieSizeChanged();
- // notify about movie being fully loaded
- QueueEvent(wxEVT_MEDIA_LOADED);
- }
- bool wxMediaBackendCommonBase::SendStopEvent()
- {
- wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId());
- return !m_ctrl->GetEventHandler()->ProcessEvent(theEvent) || theEvent.IsAllowed();
- }
- void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType)
- {
- wxMediaEvent theEvent(evtType, m_ctrl->GetId());
- m_ctrl->GetEventHandler()->AddPendingEvent(theEvent);
- }
- void wxMediaBackendCommonBase::QueuePlayEvent()
- {
- QueueEvent(wxEVT_MEDIA_STATECHANGED);
- QueueEvent(wxEVT_MEDIA_PLAY);
- }
- void wxMediaBackendCommonBase::QueuePauseEvent()
- {
- QueueEvent(wxEVT_MEDIA_STATECHANGED);
- QueueEvent(wxEVT_MEDIA_PAUSE);
- }
- void wxMediaBackendCommonBase::QueueStopEvent()
- {
- QueueEvent(wxEVT_MEDIA_STATECHANGED);
- QueueEvent(wxEVT_MEDIA_STOP);
- }
- //
- // Force link default backends in -
- // see http://wiki.wxwidgets.org/wiki.pl?RTTI
- //
- #include "wx/html/forcelnk.h"
- #ifdef __WXMSW__ // MSW has huge backends so we do it seperately
- FORCE_LINK(wxmediabackend_am)
- FORCE_LINK(wxmediabackend_wmp10)
- #elif !defined(__WXOSX_COCOA__)
- FORCE_LINK(basewxmediabackends)
- #endif
- #endif //wxUSE_MEDIACTRL