]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/moviectrl.cpp
correct Stopping - go to start of movie if stopped - add in preliminary docs
[wxWidgets.git] / src / mac / carbon / moviectrl.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mac/carbon/moviectrl.cpp
3 // Purpose: wxMovieCtrl MAC CARBON QT
4 // Author: Ryan Norton <wxprojects@comcast.net>
5 // Modified by:
6 // Created: 11/07/04
7 // RCS-ID: $Id$
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 //#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
13 //#pragma implementation "moviectrl.h"
14 //#endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #define wxUSE_MOVIECTRL 1
24
25 #if wxUSE_MOVIECTRL
26
27 #include "wx/moviectrl.h"
28 #include "wx/sound.h"
29 #include "wx/timer.h"
30
31 IMPLEMENT_CLASS(wxMovieCtrl, wxControl);
32 IMPLEMENT_DYNAMIC_CLASS(wxMovieEvent, wxEvent);
33 DEFINE_EVENT_TYPE(wxEVT_MOVIE_FINISHED);
34
35 //MESSY headers
36 #ifdef __WXMAC__
37 #include "wx/mac/uma.h"
38 #include <Movies.h>
39 #include <Gestalt.h>
40 #endif
41
42 //quicktime media layer only required for mac emulation on pc
43 #ifndef __WXMAC__
44 #include <qtml.h>
45 #endif
46
47 #include <QuickTimeComponents.h>
48
49 //Time between timer calls
50 #define MOVIE_DELAY 100
51
52 // ------------------------------------------------------------------
53 // wxQTTimer - Handle Asyncronous Playing
54 // ------------------------------------------------------------------
55 class _wxQTTimer : public wxTimer
56 {
57 public:
58 _wxQTTimer(Movie movie, wxMovieCtrl* parent) :
59 m_movie(movie), m_bPaused(false), m_parent(parent)
60 {
61 }
62
63 ~_wxQTTimer()
64 {
65 }
66
67 bool GetPaused() {return m_bPaused;}
68 void SetPaused(bool bPaused) {m_bPaused = bPaused;}
69
70 void Notify()
71 {
72 if (!m_bPaused)
73 {
74 if(!IsMovieDone(m_movie))
75 MoviesTask(m_movie, MOVIE_DELAY); //Give QT time to play movie
76 else
77 {
78 Stop();
79 ::GoToBeginningOfMovie(m_movie);
80 wxASSERT( ::GetMoviesError() == noErr );
81 wxMovieEvent theEvent(wxEVT_MOVIE_FINISHED, m_parent->GetId());
82 m_parent->GetParent()->ProcessEvent(theEvent);
83 }
84 }
85 }
86
87 protected:
88 Movie m_movie;
89 bool m_bPaused;
90 wxMovieCtrl* m_parent;
91 };
92
93 //Determines whether version 3 of QT is installed
94 Boolean wxIsQuickTime3Installed (void)
95 {
96 #ifdef __WXMAC__
97 short error;
98 long result;
99
100 error = Gestalt (gestaltQuickTime, &result);
101 return (error == noErr) && (((result >> 16) & 0xffff) >= 0x0300);
102 #else
103 return true;
104 #endif
105 }
106
107 bool wxMovieCtrl::InitQT ()
108 {
109 if (wxIsQuickTime3Installed())
110 {
111 #ifndef __WXMAC__
112 int nError;
113 //-2093 no dll
114 if ((nError = InitializeQTML(0)) != noErr)
115 {
116 wxFAIL_MSG(wxString::Format(wxT("Couldn't Initialize Quicktime-%i"), nError));
117 }
118 #endif
119 EnterMovies();
120 return true;
121 }
122 else
123 {
124 wxFAIL_MSG(wxT("Quicktime is not installed, or Your Version of Quicktime is <= 4."));
125 return false;
126 }
127 }
128
129 bool wxMovieCtrl::Create(wxWindow* parent, wxWindowID id, const wxString& fileName,
130 const wxString& label, const wxPoint& pos, const wxSize& size,
131 long WXUNUSED(style), const wxString& name)
132 {
133 if ( !InitQT() )
134 return false;
135
136 OSErr err = noErr;
137 short movieResFile;
138 FSSpec sfFile;
139 #ifdef __WXMAC__
140 wxMacFilename2FSSpec( m_sndname , &sfFile ) ;
141 #else
142 int nError;
143 if ((nError = NativePathNameToFSSpec ((char*) fileName.c_str(), &sfFile, 0)) != noErr)
144 {
145 wxFAIL_MSG(wxString::Format(wxT("File:%s does not exist\nError:%i"),
146 fileName.c_str(), nError));
147 return false;
148 }
149 #endif
150 if (OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr)
151 {
152 wxFAIL_MSG(wxT("Quicktime couldn't open the file"));
153 return false;
154 }
155 short movieResID = 0;
156 Str255 movieName;
157
158 err = NewMovieFromFile (
159 &m_movie,
160 movieResFile,
161 &movieResID,
162 movieName,
163 newMovieActive,
164 NULL); //wasChanged
165
166 CloseMovieFile (movieResFile);
167
168 if (err != noErr)
169 {
170 wxFAIL_MSG(wxT("Could not create movie"));
171 return false;
172 }
173
174 m_timer = new _wxQTTimer(m_movie, (wxMovieCtrl*) this);
175 wxASSERT(m_timer);
176
177 //get the real size of the movie
178 Rect outRect;
179 ::GetMovieNaturalBoundsRect (m_movie, &outRect);
180
181 m_bestSize.x = outRect.right - outRect.left;
182 m_bestSize.y = outRect.bottom - outRect.top;
183
184 //soldier in OnSize
185 this->Connect( wxID_ANY,
186 wxEVT_SIZE,
187 (wxObjectEventFunction) (wxEventFunction) (wxSizeEventFunction) &wxMovieCtrl::OnSize );
188
189 //do some window stuff
190 if ( !wxControl::Create(parent, id, pos, size, wxNO_BORDER, wxDefaultValidator, name) )
191 return false;
192
193 //Set our background color to black by default
194 SetBackgroundColour(*wxBLACK);
195
196 //reparent movie
197 #ifdef __WXMSW__
198 CreatePortAssociation(this->GetHWND(), NULL, 0L);
199 #endif
200 SetMovieGWorld(m_movie, (CGrafPtr)
201
202 #ifdef __WXMSW__
203 GetNativeWindowPort(this->GetHWND())
204 #else
205 this->GetHandle()
206 #endif
207 , nil);
208
209 //go!
210 SetLabel(label);
211 Play();
212
213 return true;
214 }
215
216 bool wxMovieCtrl::Play()
217 {
218 ::StartMovie(m_movie);
219 m_timer->SetPaused(false);
220 m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
221 return ::GetMoviesError() == noErr;
222 }
223
224 bool wxMovieCtrl::Pause()
225 {
226 ::StopMovie(m_movie);
227 m_timer->SetPaused(true);
228 return ::GetMoviesError() == noErr;
229 }
230
231 bool wxMovieCtrl::Stop()
232 {
233 m_timer->SetPaused(false);
234
235 ::StopMovie(m_movie);
236 if(::GetMoviesError() != noErr)
237 return false;
238
239 ::GoToBeginningOfMovie(m_movie);
240 return ::GetMoviesError() == noErr;
241 }
242
243 double wxMovieCtrl::GetPlaybackRate()
244 {
245 return (double) (::GetMovieTimeScale(m_movie) / 0x10000f);
246 }
247
248 bool wxMovieCtrl::SetPlaybackRate(double dRate)
249 {
250 ::SetMovieTimeScale(m_movie, (Fixed) (dRate * 0x10000));
251 return ::GetMoviesError() == noErr;
252 }
253
254 #if wxUSE_DATETIME
255
256 bool wxMovieCtrl::Seek(const wxTimeSpan& where)
257 {
258 TimeRecord theTimeRecord;
259 theTimeRecord.value.lo = ((size_t)where.GetMilliseconds().ToLong()) * 10;
260 theTimeRecord.scale = ::GetMovieTimeScale(m_movie);
261 theTimeRecord.base = ::GetMovieTimeBase(m_movie);
262 ::SetMovieTime(m_movie, &theTimeRecord);
263
264 if (::GetMoviesError() != noErr)
265 return false;
266
267 return true;
268 }
269
270 wxTimeSpan wxMovieCtrl::Tell()
271 {
272 return (wxTimeSpan) ::GetMovieTime(m_movie, NULL);
273 }
274
275 wxTimeSpan wxMovieCtrl::Length()
276 {
277 return (wxTimeSpan) ::GetMovieDuration(m_movie);
278 }
279
280 #endif // wxUSE_DATETIME
281
282 wxMovieCtrlState wxMovieCtrl::GetState()
283 {
284 if( m_timer->IsRunning() == true )
285 return wxMOVIECTRL_STOPPED;
286
287 if ( m_timer->GetPaused() == false )
288 return wxMOVIECTRL_PLAYING;
289 else
290 return wxMOVIECTRL_PAUSED;
291 }
292
293 wxMovieCtrl::~wxMovieCtrl()
294 {
295 if (m_timer)
296 {
297 delete m_timer;
298
299 StopMovie(m_movie);
300 DisposeMovie(m_movie);
301
302 //Note that ExitMovies() is not neccessary, but
303 //the docs are fuzzy on whether or not TerminateQTML is
304 ExitMovies();
305
306 #ifndef __WXMAC__
307 TerminateQTML();
308 #endif
309 }
310 }
311
312 wxSize wxMovieCtrl::DoGetBestSize() const
313 {
314 return m_bestSize;
315 }
316
317 void wxMovieCtrl::OnSize(wxSizeEvent& evt)
318 {
319 Rect theRect;
320 theRect.left = 0;
321 theRect.top = 0;
322 theRect.bottom = evt.GetSize().y;
323 theRect.right = evt.GetSize().x;
324
325 ::SetMovieBox(m_movie, &theRect);
326
327 wxASSERT(::GetMoviesError() == noErr);
328 evt.Skip();
329 }
330
331 #endif //wxUSE_MOVIECTRL