X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ecd20d4a916884895dcd8873a9f1156e34f4ac89..7d6a4d96961eac84d05db8bb24c64d39003f6e54:/src/cocoa/mediactrl.mm diff --git a/src/cocoa/mediactrl.mm b/src/cocoa/mediactrl.mm index f350636a95..62348e0392 100644 --- a/src/cocoa/mediactrl.mm +++ b/src/cocoa/mediactrl.mm @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: mac/cocoa/mediactrl.cpp +// Name: src/cocoa/mediactrl.mm // Purpose: Built-in Media Backends for Cocoa // Author: Ryan Norton // Modified by: @@ -17,10 +17,6 @@ // Pre-compiled header stuff //--------------------------------------------------------------------------- -#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) -#pragma implementation "mediactrl.h" -#endif - // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -28,16 +24,17 @@ #pragma hdrstop #endif -//--------------------------------------------------------------------------- -// Includes -//--------------------------------------------------------------------------- -#include "wx/mediactrl.h" - //--------------------------------------------------------------------------- // Compilation guard //--------------------------------------------------------------------------- #if wxUSE_MEDIACTRL +#include "wx/mediactrl.h" + +#ifndef WX_PRECOMP + #include "wx/timer.h" +#endif + //=========================================================================== // BACKEND DECLARATIONS //=========================================================================== @@ -67,11 +64,11 @@ public: wxQTMediaBackend(); ~wxQTMediaBackend(); - virtual bool CreateControl(wxControl* ctrl, wxWindow* parent, + virtual bool CreateControl(wxControl* ctrl, wxWindow* parent, wxWindowID id, - const wxPoint& pos, + const wxPoint& pos, const wxSize& size, - long style, + long style, const wxValidator& validator, const wxString& name); @@ -98,10 +95,11 @@ public: void FinishLoad(); wxSize m_bestSize; //Original movie size - Movie m_movie; //QT Movie handle/instance + Movie m_movie; //QT Movie handle/instance NSMovieView* m_movieview; //NSMovieView instance wxControl* m_ctrl; //Parent control bool m_bVideo; //Whether or not we have video + class _wxQTTimer* m_timer; //Timer for streaming the movie DECLARE_DYNAMIC_CLASS(wxQTMediaBackend); }; @@ -110,17 +108,79 @@ public: //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // wxQTMediaBackend -// +// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend); +//Time between timer calls +#define MOVIE_DELAY 100 + +// -------------------------------------------------------------------------- +// wxQTTimer - Handle Asyncronous Playing +// -------------------------------------------------------------------------- +class _wxQTTimer : public wxTimer +{ +public: + _wxQTTimer(Movie movie, wxQTMediaBackend* parent) : + m_movie(movie), m_bPaused(false), m_parent(parent) + { + } + + ~_wxQTTimer() + { + } + + bool GetPaused() {return m_bPaused;} + void SetPaused(bool bPaused) {m_bPaused = bPaused;} + + //----------------------------------------------------------------------- + // _wxQTTimer::Notify + // + // 1) Checks to see if the movie is done, and if not continues + // streaming the movie + // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of + // the movie. + //----------------------------------------------------------------------- + void Notify() + { + if (!m_bPaused) + { + if(!IsMovieDone(m_movie)) + MoviesTask(m_movie, MOVIE_DELAY); + else + { + wxMediaEvent theEvent(wxEVT_MEDIA_STOP, + m_parent->m_ctrl->GetId()); + m_parent->m_ctrl->ProcessEvent(theEvent); + + if(theEvent.IsAllowed()) + { + Stop(); + m_parent->Stop(); + wxASSERT(::GetMoviesError() == noErr); + + //send the event to our child + wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED, + m_parent->m_ctrl->GetId()); + m_parent->m_ctrl->ProcessEvent(theEvent); + } + } + } + } + +protected: + Movie m_movie; //Our movie instance + bool m_bPaused; //Whether we are paused or not + wxQTMediaBackend* m_parent; //Backend pointer +}; + //--------------------------------------------------------------------------- // wxQTMediaBackend Constructor // // Sets m_timer to NULL signifying we havn't loaded anything yet //--------------------------------------------------------------------------- -wxQTMediaBackend::wxQTMediaBackend() +wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL) { } @@ -135,10 +195,11 @@ wxQTMediaBackend::wxQTMediaBackend() //--------------------------------------------------------------------------- wxQTMediaBackend::~wxQTMediaBackend() { - Cleanup(); + if(m_timer) + Cleanup(); - //Note that ExitMovies() is not neccessary... - ::ExitMovies(); + //Note that ExitMovies() is not necessary... + ExitMovies(); } //--------------------------------------------------------------------------- @@ -147,21 +208,21 @@ wxQTMediaBackend::~wxQTMediaBackend() // 1) Intializes QuickTime // 2) Creates the control window //--------------------------------------------------------------------------- -bool wxQTMediaBackend::CreateControl(wxControl* inctrl, wxWindow* parent, +bool wxQTMediaBackend::CreateControl(wxControl* inctrl, wxWindow* parent, wxWindowID wid, - const wxPoint& pos, + const wxPoint& pos, const wxSize& size, - long style, + long style, const wxValidator& validator, const wxString& name) { EnterMovies(); - + wxMediaCtrl* ctrl = (wxMediaCtrl*) inctrl; //Create the control base wxASSERT(ctrl->CreateBase(parent,wid,pos,size,style, validator, name)); - + //Create the NSMovieView ctrl->SetNSView(NULL); NSMovieView* theView = [[NSMovieView alloc] initWithFrame: ctrl->MakeDefaultNSRect(size)]; @@ -174,7 +235,7 @@ bool wxQTMediaBackend::CreateControl(wxControl* inctrl, wxWindow* parent, parent->CocoaAddChild(ctrl); ctrl->SetInitialFrameRect(pos,size); } - + [theView showController:false adjustingSize:true]; m_movieview = theView; m_ctrl = ctrl; @@ -190,7 +251,7 @@ bool wxQTMediaBackend::Load(const wxString& fileName) { return Load( wxURI( - wxString( wxT("file://") ) + fileName + wxString( wxT("file://") ) + fileName ) ); } @@ -203,7 +264,8 @@ bool wxQTMediaBackend::Load(const wxString& fileName) //--------------------------------------------------------------------------- bool wxQTMediaBackend::Load(const wxURI& location) { - Cleanup(); + if(m_timer) + Cleanup(); wxString theURI = location.BuildURI(); @@ -212,6 +274,16 @@ bool wxQTMediaBackend::Load(const wxURI& location) m_movie = (Movie) [[m_movieview movie] QTMovie]; + //preroll movie for streaming + //TODO:Async this using threads? + TimeValue timeNow; + Fixed playRate; + timeNow = GetMovieTime(m_movie, NULL); + playRate = GetMoviePreferredRate(m_movie); + PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL); + PrerollMovie(m_movie, timeNow, playRate); + SetMovieRate(m_movie, playRate); + FinishLoad(); return ::GetMoviesError() == noErr; @@ -219,9 +291,20 @@ bool wxQTMediaBackend::Load(const wxURI& location) //--------------------------------------------------------------------------- // wxQTMediaBackend::FinishLoad +// +// 1) Create the movie timer +// 2) Get real size of movie for GetBestSize/sizers +// 3) See if there is video in the movie, and if so then either +// SetMovieGWorld if < 10.2 or use Native CreateMovieControl +// 4) Set the movie time scale to something usable so that seeking +// etc. will work correctly +// 5) Refresh parent window //--------------------------------------------------------------------------- void wxQTMediaBackend::FinishLoad() { + m_timer = new _wxQTTimer(m_movie, (wxQTMediaBackend*) this); + wxASSERT(m_timer); + //get the real size of the movie Rect outRect; ::GetMovieNaturalBoundsRect (m_movie, &outRect); @@ -237,7 +320,7 @@ void wxQTMediaBackend::FinishLoad() // //Here, if the parent of the control has a sizer - we //tell it to recalculate the size of this control since - //the user opened a seperate media file + //the user opened a separate media file // m_ctrl->InvalidateBestSize(); m_ctrl->GetParent()->Layout(); @@ -253,7 +336,9 @@ void wxQTMediaBackend::FinishLoad() //--------------------------------------------------------------------------- bool wxQTMediaBackend::Play() { - [m_movieview start:NULL]; + ::StartMovie(m_movie); + m_timer->SetPaused(false); + m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS); return ::GetMoviesError() == noErr; } @@ -265,7 +350,9 @@ bool wxQTMediaBackend::Play() //--------------------------------------------------------------------------- bool wxQTMediaBackend::Pause() { - [m_movieview stop:NULL]; + ::StopMovie(m_movie); + m_timer->SetPaused(true); + m_timer->Stop(); return ::GetMoviesError() == noErr; } @@ -278,8 +365,14 @@ bool wxQTMediaBackend::Pause() //--------------------------------------------------------------------------- bool wxQTMediaBackend::Stop() { - [m_movieview stop:NULL]; - [m_movieview gotoBeginning:NULL]; + m_timer->SetPaused(false); + m_timer->Stop(); + + ::StopMovie(m_movie); + if(::GetMoviesError() != noErr) + return false; + + ::GoToBeginningOfMovie(m_movie); return ::GetMoviesError() == noErr; } @@ -353,11 +446,12 @@ wxLongLong wxQTMediaBackend::GetDuration() //--------------------------------------------------------------------------- wxMediaState wxQTMediaBackend::GetState() { - if ( [m_movieview isPlaying] ) - return wxMEDIASTATE_PLAYING; - - if( wxQTMediaBackend::GetPosition() == 0 ) + if ( !m_timer || (m_timer->IsRunning() == false && + m_timer->GetPaused() == false) ) return wxMEDIASTATE_STOPPED; + + if( m_timer->IsRunning() == true ) + return wxMEDIASTATE_PLAYING; else return wxMEDIASTATE_PAUSED; } @@ -370,11 +464,11 @@ wxMediaState wxQTMediaBackend::GetState() //--------------------------------------------------------------------------- void wxQTMediaBackend::Cleanup() { - if([m_movieview movie]) - { - [[m_movieview movie] release]; - [m_movieview setMovie:NULL]; - } + delete m_timer; + m_timer = NULL; + + [[m_movieview movie] release]; + [m_movieview setMovie:NULL]; } //--------------------------------------------------------------------------- @@ -398,12 +492,7 @@ void wxQTMediaBackend::Move(int x, int y, int w, int h) //in source file that contains stuff you don't directly use -#include +#include "wx/html/forcelnk.h" FORCE_LINK_ME(basewxmediabackends); #endif //wxUSE_MEDIACTRL - - - - -