]> git.saurik.com Git - wxWidgets.git/blob - src/cocoa/mediactrl.mm
make cocoa mediactrl usable. Some touchups to carbon mediactrl code. Add notebook...
[wxWidgets.git] / src / cocoa / mediactrl.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mac/cocoa/mediactrl.cpp
3 // Purpose: Built-in Media Backends for Cocoa
4 // Author: Ryan Norton <wxprojects@comcast.net>
5 // Modified by:
6 // Created: 02/03/05
7 // RCS-ID: $Id$
8 // Copyright: (c) 2004-2005 Ryan Norton, (c) 2005 David Elliot
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 //===========================================================================
13 // DECLARATIONS
14 //===========================================================================
15
16 //---------------------------------------------------------------------------
17 // Pre-compiled header stuff
18 //---------------------------------------------------------------------------
19
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "mediactrl.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 //---------------------------------------------------------------------------
32 // Includes
33 //---------------------------------------------------------------------------
34 #include "wx/mediactrl.h"
35
36 //---------------------------------------------------------------------------
37 // Compilation guard
38 //---------------------------------------------------------------------------
39 #if wxUSE_MEDIACTRL
40
41 //===========================================================================
42 // BACKEND DECLARATIONS
43 //===========================================================================
44
45 //---------------------------------------------------------------------------
46 //
47 // wxQTMediaBackend
48 //
49 //---------------------------------------------------------------------------
50
51 //---------------------------------------------------------------------------
52 // QT Includes
53 //---------------------------------------------------------------------------
54 #include <QuickTime/QuickTime.h>
55
56 #include "wx/cocoa/autorelease.h"
57 #include "wx/cocoa/string.h"
58
59 #import <AppKit/NSMovie.h>
60 #import <AppKit/NSMovieView.h>
61
62
63 class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackend
64 {
65 public:
66
67 wxQTMediaBackend();
68 ~wxQTMediaBackend();
69
70 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
71 wxWindowID id,
72 const wxPoint& pos,
73 const wxSize& size,
74 long style,
75 const wxValidator& validator,
76 const wxString& name);
77
78 virtual bool Play();
79 virtual bool Pause();
80 virtual bool Stop();
81
82 virtual bool Load(const wxString& fileName);
83 virtual bool Load(const wxURI& location);
84
85 virtual wxMediaState GetState();
86
87 virtual bool SetPosition(wxLongLong where);
88 virtual wxLongLong GetPosition();
89 virtual wxLongLong GetDuration();
90
91 virtual void Move(int x, int y, int w, int h);
92 wxSize GetVideoSize() const;
93
94 virtual double GetPlaybackRate();
95 virtual bool SetPlaybackRate(double dRate);
96
97 void Cleanup();
98 void FinishLoad();
99
100 wxSize m_bestSize; //Original movie size
101 Movie m_movie; //QT Movie handle/instance
102 NSMovieView* m_movieview; //NSMovieView instance
103 wxControl* m_ctrl; //Parent control
104 bool m_bVideo; //Whether or not we have video
105
106 DECLARE_DYNAMIC_CLASS(wxQTMediaBackend);
107 };
108
109
110 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
111 //
112 // wxQTMediaBackend
113 //
114 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
115
116 IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend);
117
118 //---------------------------------------------------------------------------
119 // wxQTMediaBackend Constructor
120 //
121 // Sets m_timer to NULL signifying we havn't loaded anything yet
122 //---------------------------------------------------------------------------
123 wxQTMediaBackend::wxQTMediaBackend()
124 {
125 }
126
127 //---------------------------------------------------------------------------
128 // wxQTMediaBackend Destructor
129 //
130 // 1) Cleans up the QuickTime movie instance
131 // 2) Decrements the QuickTime reference counter - if this reaches
132 // 0, QuickTime shuts down
133 // 3) Decrements the QuickTime Windows Media Layer reference counter -
134 // if this reaches 0, QuickTime shuts down the Windows Media Layer
135 //---------------------------------------------------------------------------
136 wxQTMediaBackend::~wxQTMediaBackend()
137 {
138 Cleanup();
139
140 //Note that ExitMovies() is not neccessary...
141 ::ExitMovies();
142 }
143
144 //---------------------------------------------------------------------------
145 // wxQTMediaBackend::CreateControl
146 //
147 // 1) Intializes QuickTime
148 // 2) Creates the control window
149 //---------------------------------------------------------------------------
150 bool wxQTMediaBackend::CreateControl(wxControl* inctrl, wxWindow* parent,
151 wxWindowID wid,
152 const wxPoint& pos,
153 const wxSize& size,
154 long style,
155 const wxValidator& validator,
156 const wxString& name)
157 {
158 EnterMovies();
159
160 wxMediaCtrl* ctrl = (wxMediaCtrl*) inctrl;
161
162 //Create the control base
163 wxASSERT(ctrl->CreateBase(parent,wid,pos,size,style, validator, name));
164
165 //Create the NSMovieView
166 ctrl->SetNSView(NULL);
167 NSMovieView* theView = [[NSMovieView alloc] initWithFrame: ctrl->MakeDefaultNSRect(size)];
168 ctrl->SetNSView(theView);
169 [theView release];
170
171 if (parent)
172 {
173 parent->AddChild(ctrl);
174 parent->CocoaAddChild(ctrl);
175 ctrl->SetInitialFrameRect(pos,size);
176 }
177
178 [theView showController:false adjustingSize:true];
179 m_movieview = theView;
180 m_ctrl = ctrl;
181 return true;
182 }
183
184 //---------------------------------------------------------------------------
185 // wxQTMediaBackend::Load (file version)
186 //
187 // Calls the URI version
188 //---------------------------------------------------------------------------
189 bool wxQTMediaBackend::Load(const wxString& fileName)
190 {
191 return Load(
192 wxURI(
193 wxString( wxT("file://") ) + fileName
194 )
195 );
196 }
197
198 //---------------------------------------------------------------------------
199 // wxQTMediaBackend::Load (URL Version)
200 //
201 // 1) Build an escaped URI from location
202 // ...
203 //---------------------------------------------------------------------------
204 bool wxQTMediaBackend::Load(const wxURI& location)
205 {
206 Cleanup();
207
208 wxString theURI = location.BuildURI();
209
210 [m_movieview setMovie:[[NSMovie alloc] initWithURL: [NSURL URLWithString: wxNSStringWithWxString(theURI)]
211 byReference: YES ] ];
212
213 m_movie = (Movie) [[m_movieview movie] QTMovie];
214
215 FinishLoad();
216
217 return ::GetMoviesError() == noErr;
218 }
219
220 //---------------------------------------------------------------------------
221 // wxQTMediaBackend::FinishLoad
222 //---------------------------------------------------------------------------
223 void wxQTMediaBackend::FinishLoad()
224 {
225 //get the real size of the movie
226 Rect outRect;
227 ::GetMovieNaturalBoundsRect (m_movie, &outRect);
228 wxASSERT(::GetMoviesError() == noErr);
229
230 m_bestSize.x = outRect.right - outRect.left;
231 m_bestSize.y = outRect.bottom - outRect.top;
232
233 //we want millisecond precision
234 ::SetMovieTimeScale(m_movie, 1000);
235 wxASSERT(::GetMoviesError() == noErr);
236
237 //
238 //Here, if the parent of the control has a sizer - we
239 //tell it to recalculate the size of this control since
240 //the user opened a seperate media file
241 //
242 m_ctrl->InvalidateBestSize();
243 m_ctrl->GetParent()->Layout();
244 m_ctrl->GetParent()->Refresh();
245 m_ctrl->GetParent()->Update();
246 }
247
248 //---------------------------------------------------------------------------
249 // wxQTMediaBackend::Play
250 //
251 // 1) Start the QT movie
252 // 2) Start the movie loading timer
253 //---------------------------------------------------------------------------
254 bool wxQTMediaBackend::Play()
255 {
256 [m_movieview start:NULL];
257 return ::GetMoviesError() == noErr;
258 }
259
260 //---------------------------------------------------------------------------
261 // wxQTMediaBackend::Pause
262 //
263 // 1) Stop the movie
264 // 2) Stop the movie timer
265 //---------------------------------------------------------------------------
266 bool wxQTMediaBackend::Pause()
267 {
268 [m_movieview stop:NULL];
269 return ::GetMoviesError() == noErr;
270 }
271
272 //---------------------------------------------------------------------------
273 // wxQTMediaBackend::Stop
274 //
275 // 1) Stop the movie
276 // 2) Stop the movie timer
277 // 3) Seek to the beginning of the movie
278 //---------------------------------------------------------------------------
279 bool wxQTMediaBackend::Stop()
280 {
281 [m_movieview stop:NULL];
282 [m_movieview gotoBeginning:NULL];
283 return ::GetMoviesError() == noErr;
284 }
285
286 //---------------------------------------------------------------------------
287 // wxQTMediaBackend::GetPlaybackRate
288 //
289 // 1) Get the movie playback rate from ::GetMovieRate
290 //---------------------------------------------------------------------------
291 double wxQTMediaBackend::GetPlaybackRate()
292 {
293 return ( ((double)::GetMovieRate(m_movie)) / 0x10000);
294 }
295
296 //---------------------------------------------------------------------------
297 // wxQTMediaBackend::SetPlaybackRate
298 //
299 // 1) Convert dRate to Fixed and Set the movie rate through SetMovieRate
300 //---------------------------------------------------------------------------
301 bool wxQTMediaBackend::SetPlaybackRate(double dRate)
302 {
303 ::SetMovieRate(m_movie, (Fixed) (dRate * 0x10000));
304 return ::GetMoviesError() == noErr;
305 }
306
307 //---------------------------------------------------------------------------
308 // wxQTMediaBackend::SetPosition
309 //
310 // 1) Create a time record struct (TimeRecord) with appropriate values
311 // 2) Pass struct to SetMovieTime
312 //---------------------------------------------------------------------------
313 bool wxQTMediaBackend::SetPosition(wxLongLong where)
314 {
315 TimeRecord theTimeRecord;
316 memset(&theTimeRecord, 0, sizeof(TimeRecord));
317 theTimeRecord.value.lo = where.GetValue();
318 theTimeRecord.scale = ::GetMovieTimeScale(m_movie);
319 theTimeRecord.base = ::GetMovieTimeBase(m_movie);
320 ::SetMovieTime(m_movie, &theTimeRecord);
321
322 if (::GetMoviesError() != noErr)
323 return false;
324
325 return true;
326 }
327
328 //---------------------------------------------------------------------------
329 // wxQTMediaBackend::GetPosition
330 //
331 // Calls GetMovieTime
332 //---------------------------------------------------------------------------
333 wxLongLong wxQTMediaBackend::GetPosition()
334 {
335 return ::GetMovieTime(m_movie, NULL);
336 }
337
338 //---------------------------------------------------------------------------
339 // wxQTMediaBackend::GetDuration
340 //
341 // Calls GetMovieDuration
342 //---------------------------------------------------------------------------
343 wxLongLong wxQTMediaBackend::GetDuration()
344 {
345 return ::GetMovieDuration(m_movie);
346 }
347
348 //---------------------------------------------------------------------------
349 // wxQTMediaBackend::GetState
350 //
351 // Determines the current state - the timer keeps track of whether or not
352 // we are paused or stopped (if the timer is running we are playing)
353 //---------------------------------------------------------------------------
354 wxMediaState wxQTMediaBackend::GetState()
355 {
356 if ( [m_movieview isPlaying] )
357 return wxMEDIASTATE_PLAYING;
358
359 if( wxQTMediaBackend::GetPosition() == 0 )
360 return wxMEDIASTATE_STOPPED;
361 else
362 return wxMEDIASTATE_PAUSED;
363 }
364
365 //---------------------------------------------------------------------------
366 // wxQTMediaBackend::Cleanup
367 //
368 // Diposes of the movie timer, Control if native, and stops and disposes
369 // of the QT movie
370 //---------------------------------------------------------------------------
371 void wxQTMediaBackend::Cleanup()
372 {
373 if([m_movieview movie])
374 {
375 [[m_movieview movie] release];
376 [m_movieview setMovie:NULL];
377 }
378 }
379
380 //---------------------------------------------------------------------------
381 // wxQTMediaBackend::GetVideoSize
382 //
383 // Returns the actual size of the QT movie
384 //---------------------------------------------------------------------------
385 wxSize wxQTMediaBackend::GetVideoSize() const
386 {
387 return m_bestSize;
388 }
389
390 //---------------------------------------------------------------------------
391 // wxQTMediaBackend::Move
392 //
393 // Nothin... cocoa takes care of this for us
394 //---------------------------------------------------------------------------
395 void wxQTMediaBackend::Move(int x, int y, int w, int h)
396 {
397 }
398
399
400 //in source file that contains stuff you don't directly use
401 #include <wx/html/forcelnk.h>
402 FORCE_LINK_ME(basewxmediabackends);
403
404 #endif //wxUSE_MEDIACTRL
405
406
407
408
409