#if wxUSE_MOVIECTRL
#include "wx/datetime.h"
+#include "wx/control.h"
enum wxMovieCtrlState
{
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;
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
#if wxUSE_MOVIECTRL
#include "wx/datetime.h"
+#include "wx/control.h"
enum wxMovieCtrlState
{
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;
-
-// 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;
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
#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__
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)
{
}
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
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
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;
return true;
}
-void wxMovieCtrl::SetLabel(const wxString& label)
-{
- wxControl::SetLabel(label);
-}
-
bool wxMovieCtrl::Play()
{
::StartMovie(m_movie);
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)
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()
wxASSERT(::GetMoviesError() == noErr);
evt.Skip();
}
+
#endif //wxUSE_MOVIECTRL
#include <dshow.h>
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 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);
//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) );
//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()) );
) );
}
+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()
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)
// 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
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()
{
return m_bestSize;
}
-//
-//EVENT OVERRIDES
-//
-
void wxMovieCtrl::OnSize(wxSizeEvent& evt)
{
IVideoWindow*& pVW = (IVideoWindow*&) m_pVW;
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