Massive reworking of wxMediaCtrl code - backend everything, search for backends via RTTI lookup, and more
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30527 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
422
src/common/mediactrlcmn.cpp
Normal file
422
src/common/mediactrlcmn.cpp
Normal file
@@ -0,0 +1,422 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: common/mediactrl.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
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//===========================================================================
|
||||
// Definitions
|
||||
//===========================================================================
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Pre-compiled header stuff
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
|
||||
#pragma implementation "mediactrl.h"
|
||||
#endif
|
||||
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Includes
|
||||
//---------------------------------------------------------------------------
|
||||
#include "wx/mediactrl.h"
|
||||
#include "wx/hash.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Compilation guard
|
||||
//---------------------------------------------------------------------------
|
||||
#if wxUSE_MEDIACTRL
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// RTTI and Event implementations
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
IMPLEMENT_CLASS(wxMediaCtrl, wxControl);
|
||||
IMPLEMENT_CLASS(wxMediaBackend, wxObject);
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
|
||||
DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
|
||||
DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP);
|
||||
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
//
|
||||
// wxMediaCtrl
|
||||
//
|
||||
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// 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 succeededs 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())
|
||||
{
|
||||
if(!DoCreate(wxClassInfo::FindClass(szBackend), parent, id,
|
||||
pos, size, style, validator, name))
|
||||
{
|
||||
m_imp = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!fileName.empty())
|
||||
{
|
||||
if (!m_imp->Load(fileName))
|
||||
{
|
||||
delete m_imp;
|
||||
m_imp = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxClassInfo::sm_classTable->BeginFind();
|
||||
|
||||
wxClassInfo* classInfo = NextBackend();
|
||||
|
||||
while(classInfo)
|
||||
{
|
||||
if(!DoCreate(classInfo, parent, id,
|
||||
pos, size, style, validator, name))
|
||||
continue;
|
||||
|
||||
if (!fileName.empty())
|
||||
{
|
||||
if (m_imp->Load(fileName))
|
||||
return true;
|
||||
else
|
||||
delete m_imp;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
|
||||
classInfo = NextBackend();
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
if(!DoCreate(wxClassInfo::FindClass(szBackend), parent, id,
|
||||
pos, size, style, validator, name))
|
||||
{
|
||||
m_imp = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_imp->Load(location))
|
||||
{
|
||||
delete m_imp;
|
||||
m_imp = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxClassInfo::sm_classTable->BeginFind();
|
||||
|
||||
wxClassInfo* classInfo = NextBackend();
|
||||
|
||||
while(classInfo)
|
||||
{
|
||||
if(!DoCreate(classInfo, parent, id,
|
||||
pos, size, style, validator, name))
|
||||
continue;
|
||||
|
||||
if (m_imp->Load(location))
|
||||
return true;
|
||||
else
|
||||
delete m_imp;
|
||||
|
||||
classInfo = NextBackend();
|
||||
}
|
||||
|
||||
m_imp = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// wxMediaCtrl::DoCreate
|
||||
//
|
||||
// Attempts to create the control from a backend
|
||||
//---------------------------------------------------------------------------
|
||||
bool wxMediaCtrl::DoCreate(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) )
|
||||
{
|
||||
this->Connect(GetId(), wxEVT_MEDIA_FINISHED,
|
||||
(wxObjectEventFunction) (wxEventFunction)
|
||||
(wxMediaEventFunction)
|
||||
&wxMediaCtrl::OnMediaFinished);
|
||||
return true;
|
||||
}
|
||||
|
||||
delete m_imp;
|
||||
return false;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// wxMediaCtrl::NextBackend
|
||||
//
|
||||
//
|
||||
// Search through the RTTI hashmap one at a
|
||||
// time, attempting to create each derivative
|
||||
// of wxMediaBackend
|
||||
//
|
||||
//
|
||||
// STL isn't compatable 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 this
|
||||
// static
|
||||
//---------------------------------------------------------------------------
|
||||
wxClassInfo* wxMediaCtrl::NextBackend()
|
||||
{
|
||||
wxHashTable::compatibility_iterator
|
||||
node = wxClassInfo::sm_classTable->Next();
|
||||
while (node)
|
||||
{
|
||||
wxClassInfo* classInfo = (wxClassInfo *)node->GetData();
|
||||
if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
|
||||
classInfo != CLASSINFO(wxMediaBackend) )
|
||||
{
|
||||
return classInfo;
|
||||
}
|
||||
node = wxClassInfo::sm_classTable->Next();
|
||||
}
|
||||
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// wxMediaCtrl::Play
|
||||
// wxMediaCtrl::Pause
|
||||
// wxMediaCtrl::Stop
|
||||
// wxMediaCtrl::GetPlaybackRate
|
||||
// wxMediaCtrl::SetPlaybackRate
|
||||
// wxMediaCtrl::SetPosition
|
||||
// wxMediaCtrl::GetPosition
|
||||
// wxMediaCtrl::GetDuration
|
||||
// wxMediaCtrl::GetState
|
||||
// wxMediaCtrl::DoGetBestSize
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
bool wxMediaCtrl::SetPosition(wxLongLong where)
|
||||
{
|
||||
if(m_imp && m_bLoaded)
|
||||
return m_imp->SetPosition(where);
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLongLong wxMediaCtrl::GetPosition()
|
||||
{
|
||||
if(m_imp && m_bLoaded)
|
||||
return m_imp->GetPosition();
|
||||
return 0;
|
||||
}
|
||||
|
||||
wxLongLong wxMediaCtrl::GetDuration()
|
||||
{
|
||||
if(m_imp && m_bLoaded)
|
||||
return m_imp->GetDuration();
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// 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);
|
||||
}
|
||||
|
||||
void wxMediaCtrl::Loop(bool bLoop)
|
||||
{
|
||||
m_bLoop = bLoop;
|
||||
}
|
||||
|
||||
bool wxMediaCtrl::IsLooped()
|
||||
{
|
||||
return m_bLoop;
|
||||
}
|
||||
|
||||
void wxMediaCtrl::OnMediaFinished(const wxMediaEvent& WXUNUSED(evt))
|
||||
{
|
||||
if(m_bLoop)
|
||||
{
|
||||
#ifdef __WXDEBUG__
|
||||
wxASSERT( Play() );
|
||||
#else
|
||||
Play();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//DARWIN gcc compiler badly screwed up - needs destructor impl in source
|
||||
wxMediaBackend::~wxMediaBackend()
|
||||
{ }
|
||||
#include <wx/html/forcelnk.h>
|
||||
FORCE_LINK(basewxmediabackends);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// End of compilation guard and of file
|
||||
//---------------------------------------------------------------------------
|
||||
#endif //wxUSE_MEDIACTRL
|
||||
|
||||
|
||||
Reference in New Issue
Block a user