]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/mediactrl.mm
Add EnableHistory support to the OSX WebKit backend.
[wxWidgets.git] / src / osx / cocoa / mediactrl.mm
CommitLineData
38e4bfde
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/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: mediactrl.mm 39285 2006-05-23 11:04:37Z ABX $
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// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24#pragma hdrstop
25#endif
26
27//---------------------------------------------------------------------------
28// Compilation guard
29//---------------------------------------------------------------------------
30#if wxUSE_MEDIACTRL
31
32#include "wx/mediactrl.h"
33
34#ifndef WX_PRECOMP
35 #include "wx/timer.h"
36#endif
37
38#include "wx/osx/private.h"
39
40//===========================================================================
41// BACKEND DECLARATIONS
42//===========================================================================
43
44//---------------------------------------------------------------------------
45//
46// wxQTMediaBackend
47//
48//---------------------------------------------------------------------------
49
50//---------------------------------------------------------------------------
51// QT Includes
52//---------------------------------------------------------------------------
53#include <QTKit/QTKit.h>
54
55#include "wx/cocoa/autorelease.h"
56#include "wx/cocoa/string.h"
57
58#import <AppKit/NSMovie.h>
59#import <AppKit/NSMovieView.h>
60
c560088c 61class WXDLLIMPEXP_FWD_MEDIA wxQTMediaBackend;
38e4bfde 62
c560088c
SC
63@interface wxQTMovie : QTMovie {
64
65 wxQTMediaBackend* m_backend;
66}
67
68-(BOOL)isPlaying;
69
70@end
71
72class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackendCommonBase
38e4bfde
SC
73{
74public:
75
76 wxQTMediaBackend();
77 ~wxQTMediaBackend();
78
79 virtual bool CreateControl(wxControl* ctrl, wxWindow* parent,
80 wxWindowID id,
81 const wxPoint& pos,
82 const wxSize& size,
83 long style,
84 const wxValidator& validator,
85 const wxString& name);
86
87 virtual bool Play();
88 virtual bool Pause();
89 virtual bool Stop();
90
91 virtual bool Load(const wxString& fileName);
92 virtual bool Load(const wxURI& location);
93
94 virtual wxMediaState GetState();
95
96 virtual bool SetPosition(wxLongLong where);
97 virtual wxLongLong GetPosition();
98 virtual wxLongLong GetDuration();
99
100 virtual void Move(int x, int y, int w, int h);
101 wxSize GetVideoSize() const;
102
103 virtual double GetPlaybackRate();
104 virtual bool SetPlaybackRate(double dRate);
105
106 virtual double GetVolume();
107 virtual bool SetVolume(double dVolume);
108
109 void Cleanup();
110 void FinishLoad();
111
112 virtual bool ShowPlayerControls(wxMediaCtrlPlayerControls flags);
113private:
114 void DoShowPlayerControls(wxMediaCtrlPlayerControls flags);
115
116 wxSize m_bestSize; //Original movie size
c560088c 117 wxQTMovie* m_movie; //QTMovie handle/instance
38e4bfde 118 QTMovieView* m_movieview; //QTMovieView instance
38e4bfde
SC
119
120 wxMediaCtrlPlayerControls m_interfaceflags; // Saved interface flags
121
122 DECLARE_DYNAMIC_CLASS(wxQTMediaBackend);
123};
124
c560088c
SC
125// --------------------------------------------------------------------------
126// wxQTMovie
127// --------------------------------------------------------------------------
38e4bfde 128
c560088c 129@implementation wxQTMovie
38e4bfde 130
c560088c
SC
131- (id)initWithURL:(NSURL *)url error:(NSError **)errorPtr
132{
133 if ( [super initWithURL:url error:errorPtr] != nil )
134 {
135 m_backend = NULL;
136
137 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
138 [nc addObserver:self selector:@selector(movieDidEnd:)
139 name:QTMovieDidEndNotification object:nil];
140 [nc addObserver:self selector:@selector(movieRateChanged:)
141 name:QTMovieRateDidChangeNotification object:nil];
142 [nc addObserver:self selector:@selector(loadStateChanged:)
143 name:QTMovieLoadStateDidChangeNotification object:nil];
144
145 return self;
146 }
147 else
148 return nil;
149}
38e4bfde 150
c560088c
SC
151-(void)dealloc
152{
153 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
154 [nc removeObserver:self];
155
156 [super dealloc];
157}
38e4bfde 158
c560088c 159-(wxQTMediaBackend*) backend;
38e4bfde 160{
c560088c
SC
161 return m_backend;
162}
163
164-(void) setBackend:(wxQTMediaBackend*) backend
165{
166 m_backend = backend;
167}
168
169- (void)movieDidEnd:(NSNotification *)notification
170{
171 if ( m_backend )
38e4bfde 172 {
c560088c
SC
173 if ( m_backend->SendStopEvent() )
174 m_backend->QueueFinishEvent();
38e4bfde 175 }
c560088c 176}
38e4bfde 177
c560088c
SC
178- (void)movieRateChanged:(NSNotification *)notification
179{
180 NSDictionary *userInfo = [notification userInfo];
181
182 NSNumber *newRate = [userInfo objectForKey:QTMovieRateDidChangeNotificationParameter];
183
184 if ([newRate intValue] == 0)
185 {
186 m_backend->QueuePauseEvent();
187 }
188 else if ( [self isPlaying] == NO )
38e4bfde 189 {
c560088c 190 m_backend->QueuePlayEvent();
38e4bfde 191 }
c560088c 192}
38e4bfde 193
c560088c
SC
194-(void)loadStateChanged:(QTMovie *)movie
195{
196 long loadState = [[movie attributeForKey:QTMovieLoadStateAttribute] longValue];
197 if (loadState >= QTMovieLoadStatePlayable)
38e4bfde 198 {
c560088c
SC
199 // the movie has loaded enough media data to begin playing
200 }
201 else if (loadState >= QTMovieLoadStateLoaded)
202 {
203 m_backend->FinishLoad();
38e4bfde 204 }
c560088c
SC
205 else if (loadState == -1)
206 {
207 // error occurred
208 }
209}
38e4bfde 210
c560088c
SC
211-(BOOL)isPlaying
212{
213 if ([self rate] == 0)
214 {
215 return NO;
216 }
217
218 return YES;
219}
220
221@end
222
223// --------------------------------------------------------------------------
224// wxQTMediaBackend
225// --------------------------------------------------------------------------
226
227IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend);
38e4bfde 228
38e4bfde
SC
229wxQTMediaBackend::wxQTMediaBackend() :
230 m_interfaceflags(wxMEDIACTRLPLAYERCONTROLS_NONE),
c560088c 231 m_movie(nil), m_movieview(nil)
38e4bfde
SC
232{
233}
234
38e4bfde
SC
235wxQTMediaBackend::~wxQTMediaBackend()
236{
c560088c 237 Cleanup();
38e4bfde
SC
238}
239
38e4bfde
SC
240bool wxQTMediaBackend::CreateControl(wxControl* inctrl, wxWindow* parent,
241 wxWindowID wid,
242 const wxPoint& pos,
243 const wxSize& size,
244 long style,
245 const wxValidator& validator,
246 const wxString& name)
247{
248 wxMediaCtrl* mediactrl = (wxMediaCtrl*) inctrl;
249
c560088c
SC
250 mediactrl->DontCreatePeer();
251
38e4bfde
SC
252 if ( !mediactrl->wxControl::Create(
253 parent, wid, pos, size,
254 wxWindow::MacRemoveBordersFromStyle(style),
255 validator, name))
256 {
257 return false;
258 }
259
260 NSRect r = wxOSXGetFrameForControl( mediactrl, pos , size ) ;
261 QTMovieView* theView = [[QTMovieView alloc] initWithFrame: r];
262
263 wxWidgetCocoaImpl* impl = new wxWidgetCocoaImpl(mediactrl,theView);
264 mediactrl->SetPeer(impl);
265
266 m_movieview = theView;
267 // will be set up after load
268 [theView setControllerVisible:NO];
269
270 m_ctrl = mediactrl;
271 return true;
272}
273
274bool wxQTMediaBackend::Load(const wxString& fileName)
275{
276 return Load(
277 wxURI(
278 wxString( wxT("file://") ) + fileName
279 )
280 );
281}
282
283bool wxQTMediaBackend::Load(const wxURI& location)
284{
c560088c 285 wxCFStringRef uri(location.BuildURI());
38e4bfde
SC
286
287 [m_movie release];
c560088c 288 wxQTMovie* movie = [[wxQTMovie alloc] initWithURL: [NSURL URLWithString: uri.AsNSString()] error: nil ];
38e4bfde 289
c560088c
SC
290 m_movie = movie;
291 [m_movie setBackend:this];
38e4bfde
SC
292 [m_movieview setMovie:movie];
293
38e4bfde
SC
294 return movie != nil;
295}
296
297void wxQTMediaBackend::FinishLoad()
298{
c560088c
SC
299 DoShowPlayerControls(m_interfaceflags);
300
38e4bfde
SC
301 NSRect r =[m_movieview movieBounds];
302 m_bestSize.x = r.size.width;
303 m_bestSize.y = r.size.height;
c560088c
SC
304
305 NotifyMovieLoaded();
38e4bfde 306
38e4bfde
SC
307}
308
309bool wxQTMediaBackend::Play()
310{
311 [m_movieview play:nil];
312 return true;
313}
314
315bool wxQTMediaBackend::Pause()
316{
317 [m_movieview pause:nil];
318 return true;
319}
320
321bool wxQTMediaBackend::Stop()
322{
323 [m_movieview pause:nil];
324 [m_movieview gotoBeginning:nil];
325 return true;
326}
327
328double wxQTMediaBackend::GetVolume()
329{
330 return [m_movie volume];
331}
332
333bool wxQTMediaBackend::SetVolume(double dVolume)
334{
335 [m_movie setVolume:dVolume];
336 return true;
337}
338double wxQTMediaBackend::GetPlaybackRate()
339{
340 return [m_movie rate];
341}
342
343bool wxQTMediaBackend::SetPlaybackRate(double dRate)
344{
345 [m_movie setRate:dRate];
346 return true;
347}
348
349bool wxQTMediaBackend::SetPosition(wxLongLong where)
350{
351 QTTime position;
352 position = [m_movie currentTime];
353 position.timeValue = (where.GetValue() / 1000.0) * position.timeScale;
354 [m_movie setCurrentTime:position];
355 return true;
356}
357
358wxLongLong wxQTMediaBackend::GetPosition()
359{
360 QTTime position = [m_movie currentTime];
361 return ((double) position.timeValue) / position.timeScale * 1000;
362}
363
364wxLongLong wxQTMediaBackend::GetDuration()
365{
366 QTTime duration = [m_movie duration];
367 return ((double) duration.timeValue) / duration.timeScale * 1000;
368}
369
370wxMediaState wxQTMediaBackend::GetState()
371{
c560088c 372 if ( [m_movie isPlaying] )
38e4bfde
SC
373 return wxMEDIASTATE_PLAYING;
374 else
c560088c
SC
375 {
376 if ( GetPosition() == 0 )
377 return wxMEDIASTATE_STOPPED;
378 else
379 return wxMEDIASTATE_PAUSED;
380 }
38e4bfde
SC
381}
382
383void wxQTMediaBackend::Cleanup()
384{
38e4bfde 385 [m_movieview setMovie:NULL];
c560088c
SC
386 [m_movie release];
387 m_movie = nil;
38e4bfde
SC
388}
389
390wxSize wxQTMediaBackend::GetVideoSize() const
391{
392 return m_bestSize;
393}
394
395void wxQTMediaBackend::Move(int x, int y, int w, int h)
396{
397}
398
399bool wxQTMediaBackend::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
400{
401 if ( m_interfaceflags != flags )
402 DoShowPlayerControls(flags);
403
404 m_interfaceflags = flags;
405 return true;
406}
407
408void wxQTMediaBackend::DoShowPlayerControls(wxMediaCtrlPlayerControls flags)
409{
410 if (flags == wxMEDIACTRLPLAYERCONTROLS_NONE )
411 {
412 [m_movieview setControllerVisible:NO];
413 }
414 else
415 {
416 [m_movieview setStepButtonsVisible:(flags & wxMEDIACTRLPLAYERCONTROLS_STEP) ? YES:NO];
417 [m_movieview setVolumeButtonVisible:(flags & wxMEDIACTRLPLAYERCONTROLS_VOLUME) ? YES:NO];
418 }
419}
420
421//in source file that contains stuff you don't directly use
422#include "wx/html/forcelnk.h"
423FORCE_LINK_ME(basewxmediabackends);
424
425#endif //wxUSE_MEDIACTRL