]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/mediactrlcmn.cpp
Use floating point arithmetic in wxDC::GradientFillConcentric().
[wxWidgets.git] / src / common / mediactrlcmn.cpp
index 53ba95509ab9ec1f116a3df50eac7e95afabb002..c1cf31c007ddd507a0bfbbe1abf74407c0131a83 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        common/mediactrl.cpp
+// Name:        src/common/mediactrl.cpp
 // Purpose:     wxMediaCtrl common code
 // Author:      Ryan Norton <wxprojects@comcast.net>
 // Modified by:
@@ -9,50 +9,50 @@
 // 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 );
 
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 //
@@ -60,6 +60,16 @@ DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP);
 //
 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
+//---------------------------------------------------------------------------
+// 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)
@@ -67,25 +77,27 @@ DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP);
 // 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;
@@ -93,39 +105,43 @@ bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
 
         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;
@@ -134,50 +150,52 @@ bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
 }
 
 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;
@@ -190,58 +208,52 @@ bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
 //
 // 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();
     }
 
     //
@@ -265,6 +277,8 @@ wxMediaCtrl::~wxMediaCtrl()
 //---------------------------------------------------------------------------
 // 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
@@ -284,18 +298,30 @@ bool wxMediaCtrl::Load(const wxURI& 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::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
@@ -335,25 +361,41 @@ bool wxMediaCtrl::SetPlaybackRate(double dRate)
     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()
@@ -370,9 +412,44 @@ wxSize wxMediaCtrl::DoGetBestSize() const
     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
@@ -386,37 +463,92 @@ void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
         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