Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTMovieWindowController.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 66 - (hide annotations) (download)
Mon Sep 15 01:14:27 2008 UTC (15 years, 7 months ago) by masaki
Original Path: XspfQT/XspfMovieWindowController.m
File size: 10931 byte(s)
NSTimerのオーナーシップがないのにreleaseしていた。
代わりにinvalidateするようにした。
1 masaki 2 //
2     // XspfMovieWindowController.m
3     // XspfQT
4     //
5     // Created by Hori,Masaki on 08/08/31.
6     // Copyright 2008 masakih. All rights reserved.
7     //
8    
9     #import "XspfMovieWindowController.h"
10     #import "XspfDocument.h"
11 masaki 29 #import "XspfComponent.h"
12 masaki 2 #import "XspfFullScreenWindow.h"
13    
14    
15     @interface XspfMovieWindowController (Private)
16 masaki 45 - (NSSize)windowSizeWithoutQTView;
17 masaki 17 - (void)sizeTofitWidnow;
18 masaki 2 - (NSSize)fitSizeToSize:(NSSize)toSize;
19     - (NSWindow *)fullscreenWindow;
20     @end
21    
22     @implementation XspfMovieWindowController
23    
24 masaki 10 #pragma mark ### Static variables ###
25 masaki 2 static const float sVolumeDelta = 0.2;
26 masaki 38 static NSString *const kQTMovieKeyPath = @"trackList.qtMovie";
27 masaki 40 static NSString *const kIsPlayedKeyPath = @"trackList.isPlayed";
28 masaki 2
29 masaki 10 - (id)init
30 masaki 2 {
31     if(self = [super initWithWindowNibName:@"XspfDocument"]) {
32     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
33     [nc addObserver:self
34     selector:@selector(applicationWillTerminate:)
35     name:NSApplicationWillTerminateNotification
36     object:NSApp];
37    
38     updateTime = [NSTimer scheduledTimerWithTimeInterval:0.3
39     target:self
40     selector:@selector(updateTimeIfNeeded:)
41     userInfo:NULL
42     repeats:YES];
43     }
44    
45     return self;
46     }
47    
48     - (void)dealloc
49     {
50     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
51     [nc removeObserver:self];
52 masaki 49
53     [self setQtMovie:nil];
54 masaki 2
55     [fullscreenWindow release];
56 masaki 66 [updateTime invalidate];
57 masaki 10 [prevMouseMovedDate release];
58 masaki 2
59     [super dealloc];
60     }
61     - (void)awakeFromNib
62     {
63 masaki 3 prevMouseMovedDate = [[NSDate dateWithTimeIntervalSinceNow:0.0] retain];
64    
65 masaki 2 id d = [self document];
66     // NSLog(@"Add Observed! %@", d);
67     [d addObserver:self
68 masaki 38 forKeyPath:kQTMovieKeyPath
69 masaki 2 options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
70     context:NULL];
71 masaki 14 [d addObserver:self
72 masaki 40 forKeyPath:kIsPlayedKeyPath
73 masaki 14 options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
74     context:NULL];
75 masaki 2
76 masaki 66 [self setValue:[NSNumber numberWithInt:0]
77     forKeyPath:@"document.trackList.selectionIndex"];
78 masaki 17 [self sizeTofitWidnow];
79 masaki 2 [self play];
80     }
81 masaki 10
82 masaki 62 - (NSString *)windowTitleForDocumentDisplayName:(NSString *)displayName
83     {
84     id title = [self valueForKeyPath:@"document.trackList.currentTrack.title"];
85     if(title) {
86     return [NSString stringWithFormat:@"%@ - %@",
87     displayName, title];
88     }
89     return displayName;
90     }
91    
92 masaki 10 #pragma mark ### KVO & KVC ###
93 masaki 2 - (void)observeValueForKeyPath:(NSString *)keyPath
94     ofObject:(id)object
95     change:(NSDictionary *)change
96     context:(void *)context
97     {
98     // NSLog(@"Observed!");
99 masaki 49 if([keyPath isEqualToString:kQTMovieKeyPath]) {
100 masaki 2 id new = [change objectForKey:NSKeyValueChangeNewKey];
101 masaki 49 [self setQtMovie:new];
102 masaki 2 return;
103     }
104 masaki 49 if([keyPath isEqualToString:kIsPlayedKeyPath]) {
105 masaki 14 id new = [change objectForKey:NSKeyValueChangeNewKey];
106 masaki 66 // NSLog(@"Observed!");
107 masaki 14 if([new boolValue]) {
108     [playButton setTitle:@"||"];
109     } else {
110     [playButton setTitle:@">"];
111     }
112     return;
113     }
114 masaki 2
115 masaki 14
116 masaki 2 [super observeValueForKeyPath:keyPath
117     ofObject:object
118     change:change
119     context:context];
120     }
121    
122     - (void)setQtMovie:(QTMovie *)qt
123     {
124     if(qtMovie == qt) return;
125     if([qtMovie isEqual:qt]) return;
126 masaki 62 if(qt == (id)[NSNull null]) qt = nil;
127 masaki 2
128     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
129    
130     if(qtMovie) {
131     [nc removeObserver:self name:nil object:qtMovie];
132     }
133     if(qt) {
134     [nc addObserver:self selector:@selector(didEndMovie:) name:QTMovieDidEndNotification object:qt];
135     }
136 masaki 3
137     if(qtMovie) {
138     [qt setVolume:[qtMovie volume]];
139     [qt setMuted:[qtMovie muted]];
140     }
141 masaki 2 [qtMovie autorelease];
142     qtMovie = [qt retain];
143 masaki 49
144     if(!qtMovie) return;
145    
146 masaki 2 [self synchronizeWindowTitleWithDocumentName];
147 masaki 17 [self sizeTofitWidnow];
148 masaki 2 [self play];
149     }
150     - (QTMovie *)qtMovie
151     {
152     return qtMovie;
153     }
154    
155 masaki 10 #pragma mark ### Other functions ###
156 masaki 45 - (NSSize)windowSizeWithoutQTView
157     {
158     if(windowSizeWithoutQTView.width == 0
159     && windowSizeWithoutQTView.height == 0) {
160     QTMovie *curMovie = [self qtMovie];
161     if(!curMovie) return windowSizeWithoutQTView;
162    
163     NSSize qtViewSize = [qtView frame].size;
164     NSSize currentWindowSize = [[self window] frame].size;
165    
166     windowSizeWithoutQTView = NSMakeSize(currentWindowSize.width - qtViewSize.width,
167     currentWindowSize.height - qtViewSize.height);
168     }
169    
170     return windowSizeWithoutQTView;
171     }
172 masaki 17 - (void)sizeTofitWidnow
173     {
174     id window = [self window];
175     NSRect frame = [window frame];
176     NSSize newSize = [self fitSizeToSize:frame.size];
177 masaki 19 frame.origin.y += frame.size.height - newSize.height;
178 masaki 17 frame.size = newSize;
179    
180 masaki 19 [window setFrame:frame display:YES animate:YES];
181 masaki 17 }
182 masaki 2 - (NSSize)fitSizeToSize:(NSSize)toSize
183     {
184     QTMovie *curMovie = [self qtMovie];
185     if(!curMovie) return toSize;
186    
187 masaki 10 // Area size without QTMovieView.
188 masaki 45 NSSize delta = [self windowSizeWithoutQTView];
189 masaki 2
190     NSSize movieSize = [[curMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
191    
192     float targetViewWidth = toSize.width - delta.width;
193     float targetViewHeight = targetViewWidth * (movieSize.height / movieSize.width);
194    
195     targetViewWidth += delta.width;
196     targetViewHeight += delta.height;
197    
198     NSSize newSize = NSMakeSize(targetViewWidth, targetViewHeight);
199    
200     return newSize;
201     }
202    
203     - (void)play
204     {
205     [qtView performSelectorOnMainThread:@selector(play:) withObject:self waitUntilDone:NO];
206     }
207 masaki 14 - (void)pause
208     {
209     [qtView performSelectorOnMainThread:@selector(pause:) withObject:self waitUntilDone:NO];
210     }
211 masaki 56 - (void)stop
212     {
213     [qtView performSelectorOnMainThread:@selector(pause:) withObject:self waitUntilDone:YES];
214     }
215 masaki 3 - (void)enterFullScreen
216 masaki 2 {
217 masaki 17 NSWindow *w = [self fullscreenWindow];
218 masaki 3
219 masaki 17 nomalModeSavedFrame = [qtView frame];
220    
221     [[self window] orderOut:self];
222     [w setContentView:qtView];
223    
224     // [NSMenu setMenuBarVisible:NO];
225     SetSystemUIMode (kUIModeAllHidden, kUIOptionAutoShowMenuBar);
226    
227     [w makeKeyAndOrderFront:self];
228     [w makeFirstResponder:qtView];
229 masaki 2 }
230 masaki 3 - (void)exitFullScreen
231 masaki 2 {
232 masaki 17 NSWindow *w = [self fullscreenWindow];
233    
234     [qtView retain];
235     {
236     [qtView removeFromSuperview];
237     [qtView setFrame:nomalModeSavedFrame];
238     [[[self window] contentView] addSubview:qtView];
239     }
240     [qtView release];
241    
242     [NSMenu setMenuBarVisible:YES];
243     [w orderOut:self];
244     [[self window] makeKeyAndOrderFront:self];
245     [[self window] makeFirstResponder:qtView];
246 masaki 3 }
247 masaki 10
248     - (NSWindow *)fullscreenWindow
249     {
250     if(fullscreenWindow) return fullscreenWindow;
251    
252     NSRect mainScreenRect = [[NSScreen mainScreen] frame];
253     fullscreenWindow = [[XspfFullScreenWindow alloc] initWithContentRect:mainScreenRect
254     styleMask:NSBorderlessWindowMask
255     backing:NSBackingStoreBuffered
256     defer:YES];
257     [fullscreenWindow setReleasedWhenClosed:NO];
258     [fullscreenWindow setBackgroundColor:[NSColor blackColor]];
259     [fullscreenWindow setDelegate:self];
260 masaki 49 [fullscreenWindow setWindowController:self];
261 masaki 10
262     return fullscreenWindow;
263     }
264    
265     #pragma mark ### Actions ###
266 masaki 14 - (IBAction)togglePlayAndPause:(id)sender
267     {
268     if([[self valueForKeyPath:@"document.trackList.isPlayed"] boolValue]) {
269     [self pause];
270     } else {
271     [self play];
272     }
273     }
274    
275 masaki 3 - (IBAction)turnUpVolume:(id)sender
276     {
277     NSNumber *cv = [self valueForKeyPath:@"qtMovie.volume"];
278     cv = [NSNumber numberWithFloat:[cv floatValue] + sVolumeDelta];
279     [self setValue:cv forKeyPath:@"qtMovie.volume"];
280     }
281     - (IBAction)turnDownVolume:(id)sender
282     {
283     NSNumber *cv = [self valueForKeyPath:@"qtMovie.volume"];
284     cv = [NSNumber numberWithFloat:[cv floatValue] - sVolumeDelta];
285     [self setValue:cv forKeyPath:@"qtMovie.volume"];
286     }
287     - (IBAction)toggleFullScreenMode:(id)sender
288     {
289 masaki 10 if(fullScreenMode) {
290 masaki 3 [self exitFullScreen];
291 masaki 10 fullScreenMode = NO;
292 masaki 2 } else {
293 masaki 3 [self enterFullScreen];
294 masaki 10 fullScreenMode = YES;
295 masaki 2 }
296     }
297    
298 masaki 4 - (IBAction)forwardTagValueSecends:(id)sender
299     {
300     if(![sender respondsToSelector:@selector(tag)]) return;
301    
302     int tag = [sender tag];
303     if(tag == 0) return;
304    
305     QTTime current = [[self qtMovie] currentTime];
306     NSTimeInterval cur;
307     if(!QTGetTimeInterval(current, &cur)) return;
308    
309     QTTime new = QTMakeTimeWithTimeInterval(cur + tag);
310 masaki 9 [[self qtMovie] setCurrentTime:new];
311 masaki 4 }
312     - (IBAction)backwardTagValueSecends:(id)sender
313     {
314     if(![sender respondsToSelector:@selector(tag)]) return;
315    
316     int tag = [sender tag];
317     if(tag == 0) return;
318    
319     QTTime current = [[self qtMovie] currentTime];
320     NSTimeInterval cur;
321     if(!QTGetTimeInterval(current, &cur)) return;
322    
323     QTTime new = QTMakeTimeWithTimeInterval(cur - tag);
324 masaki 9 [[self qtMovie] setCurrentTime:new];
325 masaki 4 }
326 masaki 24 - (IBAction)nextTrack:(id)sender
327     {
328 masaki 49 [qtView pause:sender];
329 masaki 24 [[[self document] trackList] next];
330     }
331     - (IBAction)previousTrack:(id)sender
332     {
333 masaki 49 [qtView pause:sender];
334 masaki 24 [[[self document] trackList] previous];
335     }
336 masaki 4
337 masaki 10 #pragma mark ### Notification & Timer ###
338 masaki 2 - (void)didEndMovie:(id)notification
339     {
340     [[[self document] trackList] next];
341     }
342     - (void)updateTimeIfNeeded:(id)timer
343     {
344     QTMovie *qt = [self qtMovie];
345     if(qt) {
346 masaki 10 // force update time indicator.
347 masaki 2 [qt willChangeValueForKey:@"currentTime"];
348     [qt didChangeValueForKey:@"currentTime"];
349     }
350 masaki 3
351     // Hide cursor and controller, if mouse didn't move for 3 seconds.
352     NSPoint mouse = [NSEvent mouseLocation];
353     if(!NSEqualPoints(prevMouse, mouse)) {
354     prevMouse = mouse;
355     [prevMouseMovedDate autorelease];
356     prevMouseMovedDate = [[NSDate dateWithTimeIntervalSinceNow:0.0] retain];
357 masaki 10 } else if(fullScreenMode && [prevMouseMovedDate timeIntervalSinceNow] < -3.0 ) {
358 masaki 3 [NSCursor setHiddenUntilMouseMoves:YES];
359     //
360     // hide controller.
361     }
362 masaki 2 }
363    
364 masaki 10 #pragma mark ### NSResponder ###
365 masaki 2 - (void)cancelOperation:(id)sender
366     {
367 masaki 10 if(fullScreenMode) {
368 masaki 2 [self toggleFullScreenMode:self];
369     }
370     }
371    
372 masaki 10 #pragma mark ### NSMenu valivation ###
373     - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
374     {
375     if([menuItem action] == @selector(toggleFullScreenMode:)) {
376     if(fullScreenMode) {
377     [menuItem setTitle:NSLocalizedString(@"Exit Full Screen", @"Exit Full Screen")];
378     } else {
379     [menuItem setTitle:NSLocalizedString(@"Full Screen", @"Full Screen")];
380     }
381     return YES;
382     }
383 masaki 50 // if([menuItem tag] == 10000) {
384     // NSString *title = [self valueForKeyPath:@"document.trackList.currentTrack.title"];
385     // if(title) {
386     // [menuItem setTitle:title];
387     // }
388     // return NO;
389     // }
390 masaki 10
391     return YES;
392     }
393    
394     #pragma mark ### NSApplication Delegate ###
395 masaki 2 - (void)applicationWillTerminate:(NSNotification *)notification
396     {
397 masaki 10 if(fullScreenMode) {
398 masaki 2 [self toggleFullScreenMode:self];
399     }
400 masaki 38 [[self document] removeObserver:self forKeyPath:kQTMovieKeyPath];
401 masaki 40 [[self document] removeObserver:self forKeyPath:kIsPlayedKeyPath];
402 masaki 2 }
403    
404 masaki 10 #pragma mark ### NSWindow Delegate ###
405 masaki 2 - (BOOL)windowShouldClose:(id)sender
406     {
407     [qtView pause:self];
408     [self setQtMovie:nil];
409    
410 masaki 38 [[self document] removeObserver:self forKeyPath:kQTMovieKeyPath];
411 masaki 40 [[self document] removeObserver:self forKeyPath:kIsPlayedKeyPath];
412 masaki 2
413 masaki 66 [updateTime invalidate];
414 masaki 2 updateTime = nil;
415    
416     return YES;
417     }
418     - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
419     {
420     return [self fitSizeToSize:frameSize];
421     }
422 masaki 16 - (void)windowDidMove:(NSNotification *)notification
423     {
424     if(fullscreenWindow && [notification object] == fullscreenWindow) {
425     NSRect r = [fullscreenWindow frame];
426 masaki 45 if(!NSEqualPoints(r.origin, NSZeroPoint)) {
427 masaki 16 [fullscreenWindow setFrameOrigin:NSZeroPoint];
428     }
429     }
430     }
431 masaki 2 @end

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26