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
This commit is contained in:
Ryan Norton
2004-11-07 10:56:06 +00:00
parent fe27303f7a
commit 0568fd59ca
4 changed files with 160 additions and 58 deletions

View File

@@ -14,6 +14,7 @@
#if wxUSE_MOVIECTRL #if wxUSE_MOVIECTRL
#include "wx/datetime.h" #include "wx/datetime.h"
#include "wx/control.h"
enum wxMovieCtrlState enum wxMovieCtrlState
{ {
@@ -45,12 +46,15 @@ public:
wxMovieCtrlState GetState(); wxMovieCtrlState GetState();
double GetPlaybackRate();
bool SetPlaybackRate(double dRate);
#if wxUSE_DATETIME #if wxUSE_DATETIME
bool Seek(const wxTimeSpan& where); bool Seek(const wxTimeSpan& where);
wxTimeSpan Tell();
wxTimeSpan Length();
#endif #endif
virtual void SetLabel(const wxString& label);
protected: protected:
void OnSize(wxSizeEvent& evt); void OnSize(wxSizeEvent& evt);
wxSize DoGetBestSize() const; wxSize DoGetBestSize() const;
@@ -60,8 +64,31 @@ protected:
wxSize m_bestSize; wxSize m_bestSize;
class _wxQTTimer* m_timer; class _wxQTTimer* m_timer;
friend class _wxQTTimer;
DECLARE_DYNAMIC_CLASS(wxMovieCtrl); 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 #endif // wxUSE_MOVIECTRL

View File

@@ -14,6 +14,7 @@
#if wxUSE_MOVIECTRL #if wxUSE_MOVIECTRL
#include "wx/datetime.h" #include "wx/datetime.h"
#include "wx/control.h"
enum wxMovieCtrlState enum wxMovieCtrlState
{ {
@@ -45,8 +46,13 @@ public:
wxMovieCtrlState GetState(); wxMovieCtrlState GetState();
double GetPlaybackRate();
bool SetPlaybackRate(double dRate);
#if wxUSE_DATETIME #if wxUSE_DATETIME
bool Seek(const wxTimeSpan& where); bool Seek(const wxTimeSpan& where);
wxTimeSpan Tell();
wxTimeSpan Length();
#endif #endif
virtual void SetLabel(const wxString& label); virtual void SetLabel(const wxString& label);
@@ -54,11 +60,10 @@ public:
protected: protected:
void OnSize(wxSizeEvent& evt); void OnSize(wxSizeEvent& evt);
wxSize DoGetBestSize() const; wxSize DoGetBestSize() const;
bool m_bVideo;
// void OnActivate(wxActivateEvent& evt);
//msw-specific - we need to overload the window proc //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_pGB;
void* m_pMC; void* m_pMC;
@@ -71,7 +76,28 @@ protected:
wxSize m_bestSize; wxSize m_bestSize;
DECLARE_DYNAMIC_CLASS(wxMovieCtrl); 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 #endif // wxUSE_MOVIECTRL

View File

@@ -29,10 +29,8 @@
#include "wx/timer.h" #include "wx/timer.h"
IMPLEMENT_CLASS(wxMovieCtrl, wxControl); IMPLEMENT_CLASS(wxMovieCtrl, wxControl);
IMPLEMENT_DYNAMIC_CLASS(wxMovieEvent, wxEvent);
BEGIN_EVENT_TABLE(wxMovieCtrl, wxControl) DEFINE_EVENT_TYPE(wxEVT_MOVIE_FINISHED);
EVT_SIZE(wxMovieCtrl::OnSize)
END_EVENT_TABLE()
//MESSY headers //MESSY headers
#ifdef __WXMAC__ #ifdef __WXMAC__
@@ -57,8 +55,8 @@ END_EVENT_TABLE()
class _wxQTTimer : public wxTimer class _wxQTTimer : public wxTimer
{ {
public: public:
_wxQTTimer(Movie movie) : _wxQTTimer(Movie movie, wxMovieCtrl* parent) :
m_movie(movie), m_bPaused(false) m_movie(movie), m_bPaused(false), m_parent(parent)
{ {
} }
@@ -76,13 +74,18 @@ public:
if(!IsMovieDone(m_movie)) if(!IsMovieDone(m_movie))
MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie
else else
{
Stop(); Stop();
wxMovieEvent theEvent(wxEVT_MOVIE_FINISHED, m_parent->GetId());
m_parent->GetParent()->ProcessEvent(theEvent);
}
} }
} }
protected: protected:
Movie m_movie; Movie m_movie;
bool m_bPaused; bool m_bPaused;
wxMovieCtrl* m_parent;
}; };
//Determines whether version 3 of QT is installed //Determines whether version 3 of QT is installed
@@ -166,7 +169,7 @@ bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileNa
return false; return false;
} }
m_timer = new _wxQTTimer(m_movie); m_timer = new _wxQTTimer(m_movie, (wxMovieCtrl*) this);
wxASSERT(m_timer); wxASSERT(m_timer);
//get the real size of the movie //get the real size of the movie
@@ -176,6 +179,11 @@ bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileNa
m_bestSize.x = outRect.right - outRect.left; m_bestSize.x = outRect.right - outRect.left;
m_bestSize.y = outRect.bottom - outRect.top; m_bestSize.y = outRect.bottom - outRect.top;
//soldier in OnSize
this->Connect( wxID_ANY,
wxEVT_SIZE,
(wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) &wxMovieCtrl::OnSize );
//do some window stuff //do some window stuff
if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER, wxDefaultValidator, name) ) if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER, wxDefaultValidator, name) )
return false; return false;
@@ -203,11 +211,6 @@ bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileNa
return true; return true;
} }
void wxMovieCtrl::SetLabel(const wxString& label)
{
wxControl::SetLabel(label);
}
bool wxMovieCtrl::Play() bool wxMovieCtrl::Play()
{ {
::StartMovie(m_movie); ::StartMovie(m_movie);
@@ -235,6 +238,17 @@ bool wxMovieCtrl::Stop()
return ::GetMoviesError() == noErr; 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 #if wxUSE_DATETIME
bool wxMovieCtrl::Seek(const wxTimeSpan& where) bool wxMovieCtrl::Seek(const wxTimeSpan& where)
@@ -251,6 +265,16 @@ bool wxMovieCtrl::Seek(const wxTimeSpan& where)
return true; return true;
} }
wxTimeSpan wxMovieCtrl::Tell()
{
return (wxTimeSpan) ::GetMovieTime(m_movie, NULL);
}
wxTimeSpan wxMovieCtrl::Length()
{
return (wxTimeSpan) ::GetMovieDuration(m_movie);
}
#endif // wxUSE_DATETIME #endif // wxUSE_DATETIME
wxMovieCtrlState wxMovieCtrl::GetState() wxMovieCtrlState wxMovieCtrl::GetState()
@@ -301,4 +325,5 @@ void wxMovieCtrl::OnSize(wxSizeEvent& evt)
wxASSERT(::GetMoviesError() == noErr); wxASSERT(::GetMoviesError() == noErr);
evt.Skip(); evt.Skip();
} }
#endif //wxUSE_MOVIECTRL #endif //wxUSE_MOVIECTRL

View File

@@ -30,6 +30,8 @@
#include <dshow.h> #include <dshow.h>
IMPLEMENT_CLASS(wxMovieCtrl, wxControl); 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; } #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
@@ -41,11 +43,6 @@ IMPLEMENT_CLASS(wxMovieCtrl, wxControl);
#define wxDSVERIFY(x) (x) #define wxDSVERIFY(x) (x)
#endif #endif
BEGIN_EVENT_TABLE(wxMovieCtrl, wxControl)
EVT_SIZE(wxMovieCtrl::OnSize)
// EVT_ACTIVATE(wxMovieCtrl::OnActivate)
END_EVENT_TABLE()
//it's there someplace :) //it's there someplace :)
extern "C" WXDLLIMPEXP_BASE HWND extern "C" WXDLLIMPEXP_BASE HWND
wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc); 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 //get the _actual_ size of the movie & remember it
long nX, nY, nSX, nSY; 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.x = nSX;
m_bestSize.y = nSY; m_bestSize.y = nSY;
//do some window stuff - ORDER IS IMPORTANT //do some window stuff - ORDER IS IMPORTANT
//base create //base create
if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER | wxCLIP_CHILDREN, wxDefaultValidator, name) ) if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER | wxCLIP_CHILDREN, wxDefaultValidator, name) )
return false; return false;
//TODO: Connect() here instead of message maps
//Set our background color to black by default //Set our background color to black by default
SetBackgroundColour(*wxBLACK); SetBackgroundColour(*wxBLACK);
if (m_bVideo)
{
wxDSVERIFY( pVW->put_Owner((OAHWND)this->GetHandle()) ); wxDSVERIFY( pVW->put_Owner((OAHWND)this->GetHandle()) );
wxDSVERIFY( pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS) ); wxDSVERIFY( pVW->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS) );
// wxDSVERIFY( pME->SetNotifyWindow((OAHWND)this->GetHandle(), WM_GRAPHNOTIFY, 0) ); // wxDSVERIFY( pME->SetNotifyWindow((OAHWND)this->GetHandle(), WM_GRAPHNOTIFY, 0) );
wxDSVERIFY( pVW->put_Visible(OATRUE) ); //OATRUE actually == -1 :) wxDSVERIFY( pVW->put_Visible(OATRUE) ); //OATRUE actually == -1 :)
}
//set the time format //set the time format
wxDSVERIFY( pMS->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME) ); 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 //wxBasicString will have a null string on an
//empty wxString - gotta love those workarounds!! //empty wxString - gotta love those workarounds!!
if(!label.empty()) if(!label.empty() && m_bVideo)
{ {
wxBasicString theBasicString(label.mb_str()); wxBasicString theBasicString(label.mb_str());
wxDSVERIFY( pVW->put_Caption(theBasicString.Get()) ); 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 #endif // wxUSE_DATETIME
wxMovieCtrlState wxMovieCtrl::GetState() wxMovieCtrlState wxMovieCtrl::GetState()
@@ -174,23 +202,30 @@ wxMovieCtrlState wxMovieCtrl::GetState()
return (wxMovieCtrlState) theState; 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 //cast helpers
IMediaControl*& pMC = (IMediaControl*&) m_pMC; // IMediaControl*& pMC = (IMediaControl*&) m_pMC;
IMediaEventEx*& pME = (IMediaEventEx*&) m_pME; IMediaEventEx*& pME = (IMediaEventEx*&) m_pME;
IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS; // IMediaSeeking*& pMS = (IMediaSeeking*&) m_pMS;
if (nMsg == WM_GRAPHNOTIFY) if (nMsg == WM_GRAPHNOTIFY)
{ {
LONG evCode, evParam1, evParam2; LONG evCode, evParam1, evParam2;
HRESULT hr=S_OK; HRESULT hr=S_OK;
//make sure we exist
if (!pME)
return S_OK;
// Process all queued events // Process all queued events
while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR *) &evParam1, while(SUCCEEDED(pME->GetEvent(&evCode, (LONG_PTR *) &evParam1,
(LONG_PTR *) &evParam2, 0) (LONG_PTR *) &evParam2, 0)
@@ -200,9 +235,12 @@ wxMovieCtrlState wxMovieCtrl::GetState()
// Free memory associated with callback, since we're not using it // Free memory associated with callback, since we're not using it
hr = pME->FreeEventParams(evCode, evParam1, evParam2); 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) if(EC_COMPLETE == evCode)
{ {
wxMovieEvent theEvent(wxEVT_MOVIE_FINISHED, this->GetId());
GetParent()->ProcessEvent(theEvent);
/*
LONGLONG pos=0; LONGLONG pos=0;
// Reset to first frame of movie // Reset to first frame of movie
@@ -230,14 +268,14 @@ wxMovieCtrlState wxMovieCtrl::GetState()
break; break;
} }
} }
*/
} }
} }
return wxControl::MSWDefWindowProc(nMsg, wParam, lParam); return wxControl::MSWDefWindowProc(nMsg, wParam, lParam);
} }
*/
//pass the event to our parent //pass the event to our parent
// return wxControl::MSWWindowProc(nMsg, wParam, lParam); return wxControl::MSWWindowProc(nMsg, wParam, lParam);
//} }
wxMovieCtrl::~wxMovieCtrl() wxMovieCtrl::~wxMovieCtrl()
{ {
@@ -272,10 +310,6 @@ wxSize wxMovieCtrl::DoGetBestSize() const
return m_bestSize; return m_bestSize;
} }
//
//EVENT OVERRIDES
//
void wxMovieCtrl::OnSize(wxSizeEvent& evt) void wxMovieCtrl::OnSize(wxSizeEvent& evt)
{ {
IVideoWindow*& pVW = (IVideoWindow*&) m_pVW; IVideoWindow*& pVW = (IVideoWindow*&) m_pVW;
@@ -283,15 +317,5 @@ void wxMovieCtrl::OnSize(wxSizeEvent& evt)
evt.Skip(); evt.Skip();
} }
/*
void wxMovieCtrl::OnActivate(wxActivateEvent& evt)
{
if (evt.GetActive())
{
//HACK: Make the window show :)
SetSize(GetSize());
}
}
*/
#endif //wxUSE_MOVIECTRL #endif //wxUSE_MOVIECTRL