/////////////////////////////////////////////////////////////////////////////
-// Name: common/mediactrl.cpp
+// Name: src/common/mediactrl.cpp
// Purpose: wxMediaCtrl common code
// Author: Ryan Norton <wxprojects@comcast.net>
// Modified by:
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
+// TODO: Platform specific backend defaults?
+
//===========================================================================
-// Definitions
+// Declarations
//===========================================================================
//---------------------------------------------------------------------------
-// Pre-compiled header stuff
+// Includes
//---------------------------------------------------------------------------
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-#pragma implementation "mediactrl.h"
-#endif
-
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
-//---------------------------------------------------------------------------
-// Includes
-//---------------------------------------------------------------------------
-#include "wx/mediactrl.h"
-#include "wx/hash.h"
-
-//---------------------------------------------------------------------------
-// Compilation guard
-//---------------------------------------------------------------------------
#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);
-IMPLEMENT_CLASS(wxMediaBackend, wxObject);
-IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
-DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
-DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP);
+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 );
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//---------------------------------------------------------------------------
+// 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 succeededs Create returns true, otherwise
+// 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 wxPoint& pos,
const wxSize& size,
- long style,
+ 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))
+ 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 (!m_imp->Load(fileName))
+ if (!Load(fileName))
{
- delete m_imp;
- m_imp = NULL;
+ wxDELETE(m_imp);
return false;
}
}
+ SetInitialSize(size);
return true;
}
else
{
- wxClassInfo::sm_classTable->BeginFind();
+ wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo();
- wxClassInfo* classInfo = NextBackend();
+ const wxClassInfo* classInfo;
- while(classInfo)
+ while((classInfo = NextBackend(&it)) != NULL)
{
if(!DoCreate(classInfo, parent, id,
pos, size, style, validator, name))
- continue;
+ continue;
if (!fileName.empty())
{
- if (m_imp->Load(fileName))
+ if (Load(fileName))
+ {
+ SetInitialSize(size);
return true;
+ }
else
delete m_imp;
}
else
+ {
+ SetInitialSize(size);
return true;
-
- classInfo = NextBackend();
+ }
}
m_imp = NULL;
}
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)
+ 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))
+ wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
+ if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
+ pos, size, style, validator, name))
{
m_imp = NULL;
return false;
}
- if (!m_imp->Load(location))
+ if (!Load(location))
{
- delete m_imp;
- m_imp = NULL;
+ wxDELETE(m_imp);
return false;
}
+ SetInitialSize(size);
return true;
}
else
{
- wxClassInfo::sm_classTable->BeginFind();
+ wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo();
- wxClassInfo* classInfo = NextBackend();
+ const wxClassInfo* classInfo;
- while(classInfo)
+ while((classInfo = NextBackend(&it)) != NULL)
{
if(!DoCreate(classInfo, parent, id,
pos, size, style, validator, name))
- continue;
+ continue;
- if (m_imp->Load(location))
+ if (Load(location))
+ {
+ SetInitialSize(size);
return true;
+ }
else
delete m_imp;
-
- classInfo = NextBackend();
}
m_imp = NULL;
//
// Attempts to create the control from a backend
//---------------------------------------------------------------------------
-bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
+bool wxMediaCtrl::DoCreate(const wxClassInfo* classInfo,
wxWindow* parent, wxWindowID id,
- const wxPoint& pos,
+ const wxPoint& pos,
const wxSize& size,
- long style,
+ 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
+// wxMediaCtrl::NextBackend (static)
//
//
// 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
+//
+// 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 this
-// static
+// we're in 2.5+ only we don't need to worry about the new version
//---------------------------------------------------------------------------
-wxClassInfo* wxMediaCtrl::NextBackend()
+const wxClassInfo* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator* it)
{
- wxHashTable::compatibility_iterator
- node = wxClassInfo::sm_classTable->Next();
- while (node)
+ for ( wxClassInfo::const_iterator end = wxClassInfo::end_classinfo();
+ *it != end; ++(*it) )
{
- wxClassInfo* classInfo = (wxClassInfo *)node->GetData();
+ const wxClassInfo* classInfo = **it;
if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
classInfo != CLASSINFO(wxMediaBackend) )
{
+ ++(*it);
return classInfo;
}
- node = wxClassInfo::sm_classTable->Next();
}
//
//---------------------------------------------------------------------------
// 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
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::SetPosition
-// wxMediaCtrl::GetPosition
-// wxMediaCtrl::GetDuration
+// 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
return false;
}
-bool wxMediaCtrl::SetPosition(wxLongLong where)
+wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
{
- if(m_imp && m_bLoaded)
- return m_imp->SetPosition(where);
- return false;
+ 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;
}
-wxLongLong wxMediaCtrl::GetPosition()
+wxFileOffset wxMediaCtrl::Tell()
{
if(m_imp && m_bLoaded)
- return m_imp->GetPosition();
- return 0;
+ return (wxFileOffset) m_imp->GetPosition().ToLong();
+ return wxInvalidOffset;
}
-wxLongLong wxMediaCtrl::GetDuration()
+wxFileOffset wxMediaCtrl::Length()
{
if(m_imp && m_bLoaded)
- return m_imp->GetDuration();
- return 0;
+ return (wxFileOffset) m_imp->GetDuration().ToLong();
+ return wxInvalidOffset;
}
wxMediaState wxMediaCtrl::GetState()
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
m_imp->Move(x, y, w, h);
}
-void wxMediaCtrl::Loop(bool bLoop)
+//---------------------------------------------------------------------------
+// wxMediaCtrl::MacVisibilityChanged
+//---------------------------------------------------------------------------
+#ifdef __WXOSX_CARBON__
+void wxMediaCtrl::MacVisibilityChanged()
{
- m_bLoop = bLoop;
-}
+ wxControl::MacVisibilityChanged();
-bool wxMediaCtrl::IsLooped()
-{
- return m_bLoop;
+ if(m_imp)
+ m_imp->MacVisibilityChanged();
}
+#endif
-void wxMediaCtrl::OnMediaFinished(const wxMediaEvent& WXUNUSED(evt))
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// wxMediaBackendCommonBase
+//
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
{
- if(m_bLoop)
+ // 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() )
{
-#ifdef __WXDEBUG__
- wxASSERT( Play() );
-#else
- Play();
-#endif
+ m_ctrl->GetParent()->Layout();
+ m_ctrl->GetParent()->Refresh();
+ m_ctrl->GetParent()->Update();
}
}
-//DARWIN gcc compiler badly screwed up - needs destructor impl in source
-wxMediaBackend::~wxMediaBackend()
-{ }
-#include <wx/html/forcelnk.h>
-FORCE_LINK(basewxmediabackends);
+void wxMediaBackendCommonBase::NotifyMovieLoaded()
+{
+ NotifyMovieSizeChanged();
-//---------------------------------------------------------------------------
-// End of compilation guard and of file
-//---------------------------------------------------------------------------
-#endif //wxUSE_MEDIACTRL
+ // 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