From 0568fd59ca381043065d745b7cbc03ad13eafa88 Mon Sep 17 00:00:00 2001 From: Ryan Norton Date: Sun, 7 Nov 2004 10:56:06 +0000 Subject: [PATCH] add Length, Tell, SetPlaybackRate and GetPlaybackRate - use Connect instead of message maps - on MSW don't assert if the file has no video and only sound - add event for when the movie finishes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@30336 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/mac/carbon/moviectrl.h | 33 +++++++++- include/wx/msw/moviectrl.h | 34 ++++++++-- src/mac/carbon/moviectrl.cpp | 51 +++++++++++---- src/msw/moviectrl.cpp | 100 ++++++++++++++++++------------ 4 files changed, 160 insertions(+), 58 deletions(-) diff --git a/include/wx/mac/carbon/moviectrl.h b/include/wx/mac/carbon/moviectrl.h index eac2847c6f..6102095df5 100644 --- a/include/wx/mac/carbon/moviectrl.h +++ b/include/wx/mac/carbon/moviectrl.h @@ -14,6 +14,7 @@ #if wxUSE_MOVIECTRL #include "wx/datetime.h" +#include "wx/control.h" enum wxMovieCtrlState { @@ -45,12 +46,15 @@ public: wxMovieCtrlState GetState(); + double GetPlaybackRate(); + bool SetPlaybackRate(double dRate); + #if wxUSE_DATETIME bool Seek(const wxTimeSpan& where); + wxTimeSpan Tell(); + wxTimeSpan Length(); #endif - virtual void SetLabel(const wxString& label); - protected: void OnSize(wxSizeEvent& evt); wxSize DoGetBestSize() const; @@ -59,9 +63,32 @@ protected: struct MovieRecord* m_movie; wxSize m_bestSize; class _wxQTTimer* m_timer; + + friend class _wxQTTimer; DECLARE_DYNAMIC_CLASS(wxMovieCtrl); - DECLARE_EVENT_TABLE() }; +//Event stuff +class WXDLLEXPORT wxMovieEvent : public wxNotifyEvent +{ +public: + wxMovieEvent(wxEventType commandType = wxEVT_NULL, int id = 0) + : wxNotifyEvent(commandType, id) + { } + + wxMovieEvent(const wxMovieEvent &clone) + : wxNotifyEvent(clone.GetEventType(), clone.GetId()) + { } + + wxEvent *Clone() { return new wxMovieEvent(*this); } + + DECLARE_DYNAMIC_CLASS(wxMovieEvent) +}; + +#define wxMOVIE_FINISHED_ID 13000 +DECLARE_EVENT_TYPE(wxEVT_MOVIE_FINISHED, wxMOVIE_FINISHED_ID) +typedef void (wxEvtHandler::*wxMovieEventFunction)(wxMovieEvent&); +#define EVT_MOVIE_FINISHED(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MOVIE_FINISHED, winid, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) (wxMovieEventFunction) & fn, (wxObject *) NULL ), + #endif // wxUSE_MOVIECTRL \ No newline at end of file diff --git a/include/wx/msw/moviectrl.h b/include/wx/msw/moviectrl.h index ceee950629..b7498552a3 100644 --- a/include/wx/msw/moviectrl.h +++ b/include/wx/msw/moviectrl.h @@ -14,6 +14,7 @@ #if wxUSE_MOVIECTRL #include "wx/datetime.h" +#include "wx/control.h" enum wxMovieCtrlState { @@ -45,8 +46,13 @@ public: wxMovieCtrlState GetState(); + double GetPlaybackRate(); + bool SetPlaybackRate(double dRate); + #if wxUSE_DATETIME bool Seek(const wxTimeSpan& where); + wxTimeSpan Tell(); + wxTimeSpan Length(); #endif virtual void SetLabel(const wxString& label); @@ -54,11 +60,10 @@ public: protected: void OnSize(wxSizeEvent& evt); wxSize DoGetBestSize() const; - -// void OnActivate(wxActivateEvent& evt); + bool m_bVideo; //msw-specific - we need to overload the window proc -// WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); + WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); void* m_pGB; void* m_pMC; @@ -71,7 +76,28 @@ protected: wxSize m_bestSize; DECLARE_DYNAMIC_CLASS(wxMovieCtrl); - DECLARE_EVENT_TABLE() }; +//Event stuff +class WXDLLEXPORT wxMovieEvent : public wxNotifyEvent +{ +public: + wxMovieEvent(wxEventType commandType = wxEVT_NULL, int id = 0) + : wxNotifyEvent(commandType, id) + { } + + wxMovieEvent(const wxMovieEvent &clone) + : wxNotifyEvent(clone.GetEventType(), clone.GetId()) + { } + + wxEvent *Clone() { return new wxMovieEvent(*this); } + + DECLARE_DYNAMIC_CLASS(wxMovieEvent) +}; + +#define wxMOVIE_FINISHED_ID 13000 +DECLARE_EVENT_TYPE(wxEVT_MOVIE_FINISHED, wxMOVIE_FINISHED_ID) +typedef void (wxEvtHandler::*wxMovieEventFunction)(wxMovieEvent&); +#define EVT_MOVIE_FINISHED(winid, fn) DECLARE_EVENT_TABLE_ENTRY( wxEVT_MOVIE_FINISHED, winid, wxID_ANY, (wxObjectEventFunction) (wxEventFunction) (wxMovieEventFunction) & fn, (wxObject *) NULL ), + #endif // wxUSE_MOVIECTRL \ No newline at end of file diff --git a/src/mac/carbon/moviectrl.cpp b/src/mac/carbon/moviectrl.cpp index db687e759c..86f296a90e 100644 --- a/src/mac/carbon/moviectrl.cpp +++ b/src/mac/carbon/moviectrl.cpp @@ -29,10 +29,8 @@ #include "wx/timer.h" IMPLEMENT_CLASS(wxMovieCtrl, wxControl); - -BEGIN_EVENT_TABLE(wxMovieCtrl, wxControl) - EVT_SIZE(wxMovieCtrl::OnSize) -END_EVENT_TABLE() +IMPLEMENT_DYNAMIC_CLASS(wxMovieEvent, wxEvent); +DEFINE_EVENT_TYPE(wxEVT_MOVIE_FINISHED); //MESSY headers #ifdef __WXMAC__ @@ -57,8 +55,8 @@ END_EVENT_TABLE() class _wxQTTimer : public wxTimer { public: - _wxQTTimer(Movie movie) : - m_movie(movie), m_bPaused(false) + _wxQTTimer(Movie movie, wxMovieCtrl* parent) : + m_movie(movie), m_bPaused(false), m_parent(parent) { } @@ -76,13 +74,18 @@ public: if(!IsMovieDone(m_movie)) MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie else + { Stop(); + wxMovieEvent theEvent(wxEVT_MOVIE_FINISHED, m_parent->GetId()); + m_parent->GetParent()->ProcessEvent(theEvent); + } } } protected: Movie m_movie; bool m_bPaused; + wxMovieCtrl* m_parent; }; //Determines whether version 3 of QT is installed @@ -166,7 +169,7 @@ bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileNa return false; } - m_timer = new _wxQTTimer(m_movie); + m_timer = new _wxQTTimer(m_movie, (wxMovieCtrl*) this); wxASSERT(m_timer); //get the real size of the movie @@ -176,7 +179,12 @@ bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileNa m_bestSize.x = outRect.right - outRect.left; m_bestSize.y = outRect.bottom - outRect.top; - //do some window stuff + //soldier in OnSize + this->Connect( wxID_ANY, + wxEVT_SIZE, + (wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) &wxMovieCtrl::OnSize ); + + //do some window stuff if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER, wxDefaultValidator, name) ) return false; @@ -203,11 +211,6 @@ bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileNa return true; } -void wxMovieCtrl::SetLabel(const wxString& label) -{ - wxControl::SetLabel(label); -} - bool wxMovieCtrl::Play() { ::StartMovie(m_movie); @@ -235,6 +238,17 @@ bool wxMovieCtrl::Stop() return ::GetMoviesError() == noErr; } +double wxMovieCtrl::GetPlaybackRate() +{ + return (double) (::GetMovieTimeScale(m_movie) / 0x10000f); +} + +bool wxMovieCtrl::SetPlaybackRate(double dRate) +{ + ::SetMovieTimeScale(m_movie, (Fixed) (dRate * 0x10000)); + return ::GetMoviesError() == noErr; +} + #if wxUSE_DATETIME bool wxMovieCtrl::Seek(const wxTimeSpan& where) @@ -251,6 +265,16 @@ bool wxMovieCtrl::Seek(const wxTimeSpan& where) return true; } +wxTimeSpan wxMovieCtrl::Tell() +{ + return (wxTimeSpan) ::GetMovieTime(m_movie, NULL); +} + +wxTimeSpan wxMovieCtrl::Length() +{ + return (wxTimeSpan) ::GetMovieDuration(m_movie); +} + #endif // wxUSE_DATETIME wxMovieCtrlState wxMovieCtrl::GetState() @@ -301,4 +325,5 @@ void wxMovieCtrl::OnSize(wxSizeEvent& evt) wxASSERT(::GetMoviesError() == noErr); evt.Skip(); } + #endif //wxUSE_MOVIECTRL diff --git a/src/msw/moviectrl.cpp b/src/msw/moviectrl.cpp index dabee83352..6b2de258f2 100644 --- a/src/msw/moviectrl.cpp +++ b/src/msw/moviectrl.cpp @@ -30,6 +30,8 @@ #include IMPLEMENT_CLASS(wxMovieCtrl, wxControl); +IMPLEMENT_DYNAMIC_CLASS(wxMovieEvent, wxEvent); +DEFINE_EVENT_TYPE(wxEVT_MOVIE_FINISHED); #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; } @@ -41,11 +43,6 @@ IMPLEMENT_CLASS(wxMovieCtrl, wxControl); #define wxDSVERIFY(x) (x) #endif -BEGIN_EVENT_TABLE(wxMovieCtrl, wxControl) - EVT_SIZE(wxMovieCtrl::OnSize) -// EVT_ACTIVATE(wxMovieCtrl::OnActivate) -END_EVENT_TABLE() - //it's there someplace :) extern "C" WXDLLIMPEXP_BASE HWND wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc); @@ -84,23 +81,38 @@ bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileNa //get the _actual_ size of the movie & remember it long nX, nY, nSX, nSY; - pVW->GetWindowPosition(&nX,&nY,&nSX,&nSY); + if (FAILED(pVW->GetWindowPosition(&nX,&nY,&nSX,&nSY))) + m_bVideo = false; + else + { + m_bVideo = true; + + this->Connect( wxID_ANY, + wxEVT_SIZE, + (wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) &wxMovieCtrl::OnSize ); + } m_bestSize.x = nSX; m_bestSize.y = nSY; + //do some window stuff - ORDER IS IMPORTANT //base create if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER | wxCLIP_CHILDREN, wxDefaultValidator, name) ) return false; + //TODO: Connect() here instead of message maps + //Set our background color to black by default SetBackgroundColour(*wxBLACK); - wxDSVERIFY( pVW->put_Owner((OAHWND)this->GetHandle()) ); - wxDSVERIFY( pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS) ); -// wxDSVERIFY( pME->SetNotifyWindow((OAHWND)this->GetHandle(), WM_GRAPHNOTIFY, 0) ); - wxDSVERIFY( pVW->put_Visible(OATRUE) ); //OATRUE actually == -1 :) + if (m_bVideo) + { + wxDSVERIFY( pVW->put_Owner((OAHWND)this->GetHandle()) ); + wxDSVERIFY( pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS) ); + // wxDSVERIFY( pME->SetNotifyWindow((OAHWND)this->GetHandle(), WM_GRAPHNOTIFY, 0) ); + wxDSVERIFY( pVW->put_Visible(OATRUE) ); //OATRUE actually == -1 :) + } //set the time format wxDSVERIFY( pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME) ); @@ -119,7 +131,7 @@ void wxMovieCtrl::SetLabel(const wxString& label) //wxBasicString will have a null string on an //empty wxString - gotta love those workarounds!! - if(!label.empty()) + if(!label.empty() && m_bVideo) { wxBasicString theBasicString(label.mb_str()); wxDSVERIFY( pVW->put_Caption(theBasicString.Get()) ); @@ -156,6 +168,22 @@ bool wxMovieCtrl::Seek(const wxTimeSpan& where) ) ); } +wxTimeSpan wxMovieCtrl::Tell() +{ + LONGLONG outCur, outStop; + wxDSVERIFY( ((IMediaSeeking*&)m_pMS)->GetPositions(&outCur, &outStop) ); + + return outCur; +} + +wxTimeSpan wxMovieCtrl::Length() +{ + LONGLONG outDuration; + wxDSVERIFY( ((IMediaSeeking*&)m_pMS)->GetDuration(&outDuration) ); + + return outDuration; +} + #endif // wxUSE_DATETIME wxMovieCtrlState wxMovieCtrl::GetState() @@ -174,23 +202,30 @@ wxMovieCtrlState wxMovieCtrl::GetState() return (wxMovieCtrlState) theState; } -//WXLRESULT wxMovieCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) -//{ -/* +double wxMovieCtrl::GetPlaybackRate() +{ + double dRate; + wxDSVERIFY( ((IMediaSeeking*&)m_pMS)->GetRate(&dRate) ); + return dRate; +} + +bool wxMovieCtrl::SetPlaybackRate(double dRate) +{ + return SUCCEEDED( ((IMediaSeeking*&)m_pMS)->SetRate(dRate) ); +} + +WXLRESULT wxMovieCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) +{ //cast helpers - IMediaControl*& pMC = (IMediaControl*&) m_pMC; +// IMediaControl*& pMC = (IMediaControl*&) m_pMC; IMediaEventEx*& pME = (IMediaEventEx*&) m_pME; - IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS; +// IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS; if (nMsg == WM_GRAPHNOTIFY) { LONG evCode, evParam1, evParam2; HRESULT hr=S_OK; - //make sure we exist - if (!pME) - return S_OK; - // Process all queued events while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR *) &evParam1, (LONG_PTR *) &evParam2, 0) @@ -200,9 +235,12 @@ wxMovieCtrlState wxMovieCtrl::GetState() // Free memory associated with callback, since we're not using it hr = pME->FreeEventParams(evCode, evParam1, evParam2); - // If this is the end of the clip, reset to beginning + // If this is the end of the clip, notify handler if(EC_COMPLETE == evCode) { + wxMovieEvent theEvent(wxEVT_MOVIE_FINISHED, this->GetId()); + GetParent()->ProcessEvent(theEvent); +/* LONGLONG pos=0; // Reset to first frame of movie @@ -230,14 +268,14 @@ wxMovieCtrlState wxMovieCtrl::GetState() break; } } +*/ } } return wxControl::MSWDefWindowProc(nMsg, wParam, lParam); } -*/ //pass the event to our parent -// return wxControl::MSWWindowProc(nMsg, wParam, lParam); -//} + return wxControl::MSWWindowProc(nMsg, wParam, lParam); +} wxMovieCtrl::~wxMovieCtrl() { @@ -272,10 +310,6 @@ wxSize wxMovieCtrl::DoGetBestSize() const return m_bestSize; } -// -//EVENT OVERRIDES -// - void wxMovieCtrl::OnSize(wxSizeEvent& evt) { IVideoWindow*& pVW = (IVideoWindow*&) m_pVW; @@ -283,15 +317,5 @@ void wxMovieCtrl::OnSize(wxSizeEvent& evt) evt.Skip(); } -/* -void wxMovieCtrl::OnActivate(wxActivateEvent& evt) -{ - if (evt.GetActive()) - { - //HACK: Make the window show :) - SetSize(GetSize()); - } -} -*/ #endif //wxUSE_MOVIECTRL \ No newline at end of file -- 2.45.2