Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTMovieWindowController.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 143 - (hide annotations) (download)
Tue Feb 24 14:49:55 2009 UTC (15 years, 1 month ago) by masaki
File size: 15001 byte(s)
フルスクリーンに変更時、アニメーションでフルスクリーンモードに変わるようにした。
1 masaki 2 //
2 masaki 72 // XspfQTMovieWindowController.m
3 masaki 2 // XspfQT
4     //
5     // Created by Hori,Masaki on 08/08/31.
6     // Copyright 2008 masakih. All rights reserved.
7     //
8    
9 masaki 72 #import "XspfQTMovieWindowController.h"
10     #import "XspfQTDocument.h"
11     #import "XspfQTComponent.h"
12     #import "XspfQTFullScreenWindow.h"
13 masaki 2
14    
15 masaki 72 @interface XspfQTMovieWindowController (Private)
16 masaki 45 - (NSSize)windowSizeWithoutQTView;
17 masaki 17 - (void)sizeTofitWidnow;
18 masaki 2 - (NSSize)fitSizeToSize:(NSSize)toSize;
19     - (NSWindow *)fullscreenWindow;
20 masaki 135 - (void)startedMovie;
21     - (void)stopedMovie;
22 masaki 2 @end
23    
24 masaki 72 @implementation XspfQTMovieWindowController
25 masaki 2
26 masaki 10 #pragma mark ### Static variables ###
27 masaki 132 static const float sVolumeDelta = 0.1;
28 masaki 135 static const NSTimeInterval sUpdateTimeInterval = 0.01;
29 masaki 38 static NSString *const kQTMovieKeyPath = @"trackList.qtMovie";
30 masaki 40 static NSString *const kIsPlayedKeyPath = @"trackList.isPlayed";
31 masaki 135 static NSString *const kVolumeKeyPath = @"qtMovie.volume";
32 masaki 2
33 masaki 10 - (id)init
34 masaki 2 {
35 masaki 73 if(self = [super initWithWindowNibName:@"XspfQTDocument"]) {
36 masaki 135 // updateTime = [NSTimer scheduledTimerWithTimeInterval:sUpdateTimeInterval
37     // target:self
38     // selector:@selector(updateTimeIfNeeded:)
39     // userInfo:NULL
40     // repeats:YES];
41 masaki 2 }
42    
43     return self;
44     }
45    
46     - (void)dealloc
47     {
48     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
49     [nc removeObserver:self];
50 masaki 49
51     [self setQtMovie:nil];
52 masaki 2
53     [fullscreenWindow release];
54 masaki 135 [self stopedMovie];
55 masaki 10 [prevMouseMovedDate release];
56 masaki 76
57 masaki 2 [super dealloc];
58     }
59     - (void)awakeFromNib
60     {
61 masaki 3 prevMouseMovedDate = [[NSDate dateWithTimeIntervalSinceNow:0.0] retain];
62    
63 masaki 100 id doc = [self document];
64     // NSLog(@"Add Observed! %@", doc);
65     [doc addObserver:self
66     forKeyPath:kQTMovieKeyPath
67     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
68     context:NULL];
69     [doc addObserver:self
70     forKeyPath:kIsPlayedKeyPath
71     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
72     context:NULL];
73 masaki 2
74 masaki 100 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
75     [nc addObserver:self
76     selector:@selector(documentWillClose:)
77     name:XspfQTDocumentWillCloseNotification
78     object:doc];
79    
80 masaki 66 [self setValue:[NSNumber numberWithInt:0]
81     forKeyPath:@"document.trackList.selectionIndex"];
82 masaki 17 [self sizeTofitWidnow];
83 masaki 2 [self play];
84     }
85 masaki 10
86 masaki 62 - (NSString *)windowTitleForDocumentDisplayName:(NSString *)displayName
87     {
88 masaki 70 id title1 = [self valueForKeyPath:@"document.trackList.title"];
89     id title2 = [self valueForKeyPath:@"document.trackList.currentTrack.title"];
90     if(title1 && title2) {
91 masaki 62 return [NSString stringWithFormat:@"%@ - %@",
92 masaki 70 title1, title2];
93 masaki 62 }
94 masaki 116 if(title2) {
95     return [NSString stringWithFormat:@"%@ - %@",
96     displayName, title2];
97     }
98 masaki 62 return displayName;
99     }
100    
101 masaki 10 #pragma mark ### KVO & KVC ###
102 masaki 2 - (void)observeValueForKeyPath:(NSString *)keyPath
103     ofObject:(id)object
104     change:(NSDictionary *)change
105     context:(void *)context
106     {
107     // NSLog(@"Observed!");
108 masaki 49 if([keyPath isEqualToString:kQTMovieKeyPath]) {
109 masaki 2 id new = [change objectForKey:NSKeyValueChangeNewKey];
110 masaki 49 [self setQtMovie:new];
111 masaki 2 return;
112     }
113 masaki 49 if([keyPath isEqualToString:kIsPlayedKeyPath]) {
114 masaki 14 id new = [change objectForKey:NSKeyValueChangeNewKey];
115 masaki 66 // NSLog(@"Observed!");
116 masaki 14 if([new boolValue]) {
117 masaki 135 [self startedMovie];
118 masaki 14 } else {
119 masaki 135 [self stopedMovie];
120 masaki 14 }
121     return;
122     }
123 masaki 2
124 masaki 14
125 masaki 2 [super observeValueForKeyPath:keyPath
126     ofObject:object
127     change:change
128     context:context];
129     }
130    
131     - (void)setQtMovie:(QTMovie *)qt
132     {
133     if(qtMovie == qt) return;
134     if([qtMovie isEqual:qt]) return;
135 masaki 62 if(qt == (id)[NSNull null]) qt = nil;
136 masaki 2
137     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
138    
139     if(qtMovie) {
140     [nc removeObserver:self name:nil object:qtMovie];
141     }
142     if(qt) {
143     [nc addObserver:self selector:@selector(didEndMovie:) name:QTMovieDidEndNotification object:qt];
144     }
145 masaki 3
146     if(qtMovie) {
147     [qt setVolume:[qtMovie volume]];
148     [qt setMuted:[qtMovie muted]];
149     }
150 masaki 2 [qtMovie autorelease];
151     qtMovie = [qt retain];
152 masaki 49
153     if(!qtMovie) return;
154    
155 masaki 2 [self synchronizeWindowTitleWithDocumentName];
156 masaki 17 [self sizeTofitWidnow];
157 masaki 2 [self play];
158     }
159     - (QTMovie *)qtMovie
160     {
161     return qtMovie;
162     }
163    
164 masaki 10 #pragma mark ### Other functions ###
165 masaki 45 - (NSSize)windowSizeWithoutQTView
166     {
167     if(windowSizeWithoutQTView.width == 0
168     && windowSizeWithoutQTView.height == 0) {
169     QTMovie *curMovie = [self qtMovie];
170     if(!curMovie) return windowSizeWithoutQTView;
171    
172     NSSize qtViewSize = [qtView frame].size;
173     NSSize currentWindowSize = [[self window] frame].size;
174    
175     windowSizeWithoutQTView = NSMakeSize(currentWindowSize.width - qtViewSize.width,
176     currentWindowSize.height - qtViewSize.height);
177     }
178    
179     return windowSizeWithoutQTView;
180     }
181 masaki 17 - (void)sizeTofitWidnow
182     {
183     id window = [self window];
184     NSRect frame = [window frame];
185     NSSize newSize = [self fitSizeToSize:frame.size];
186 masaki 19 frame.origin.y += frame.size.height - newSize.height;
187 masaki 17 frame.size = newSize;
188    
189 masaki 19 [window setFrame:frame display:YES animate:YES];
190 masaki 17 }
191 masaki 2 - (NSSize)fitSizeToSize:(NSSize)toSize
192     {
193     QTMovie *curMovie = [self qtMovie];
194     if(!curMovie) return toSize;
195    
196 masaki 10 // Area size without QTMovieView.
197 masaki 45 NSSize delta = [self windowSizeWithoutQTView];
198 masaki 2
199     NSSize movieSize = [[curMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
200 masaki 107 if(movieSize.width == 0) return toSize;
201 masaki 2
202     float targetViewWidth = toSize.width - delta.width;
203     float targetViewHeight = targetViewWidth * (movieSize.height / movieSize.width);
204    
205     targetViewWidth += delta.width;
206     targetViewHeight += delta.height;
207    
208 masaki 107 return NSMakeSize(targetViewWidth, targetViewHeight);
209 masaki 2 }
210    
211 masaki 134 - (NSSize)windowSizeFromMovieSize:(NSSize)movieSize
212     {
213    
214     //
215 masaki 135
216     return NSZeroSize;
217 masaki 134 }
218    
219     - (void)setMovieSize:(NSSize)movieSize
220     {
221 masaki 139 NSRect newFrame = [[self window] frame];
222     NSSize newSize;
223    
224     newSize = [self windowSizeWithoutQTView];
225     newSize.width += movieSize.width;
226     newSize.height += movieSize.height;
227    
228     newFrame.origin.y -= newSize.height - newFrame.size.height;
229     newFrame.size = newSize;
230    
231     NSWindow *w = [self window];
232     [w setFrame:newFrame display:YES animate:YES];
233 masaki 134 }
234 masaki 135 - (void)startedMovie
235     {
236     [playButton setTitle:@"||"];
237    
238     @synchronized(self) {
239     if(updateTime) return;
240    
241     updateTime = [[NSTimer timerWithTimeInterval:sUpdateTimeInterval
242     target:self
243     selector:@selector(updateTimeIfNeeded:)
244     userInfo:NULL
245     repeats:YES] retain];
246    
247     NSRunLoop *currentLoop = [NSRunLoop currentRunLoop];
248     [currentLoop addTimer:updateTime forMode:NSDefaultRunLoopMode];
249     }
250     }
251    
252     - (void)stopedMovie
253     {
254     [playButton setTitle:@">"];
255    
256     @synchronized(self) {
257     [updateTime invalidate];
258     [updateTime release];
259     updateTime = nil;
260     }
261     }
262 masaki 2 - (void)play
263     {
264     [qtView performSelectorOnMainThread:@selector(play:) withObject:self waitUntilDone:NO];
265     }
266 masaki 14 - (void)pause
267     {
268     [qtView performSelectorOnMainThread:@selector(pause:) withObject:self waitUntilDone:NO];
269     }
270 masaki 56 - (void)stop
271     {
272     [qtView performSelectorOnMainThread:@selector(pause:) withObject:self waitUntilDone:YES];
273     }
274 masaki 3 - (void)enterFullScreen
275 masaki 2 {
276 masaki 17 NSWindow *w = [self fullscreenWindow];
277 masaki 3
278 masaki 17 nomalModeSavedFrame = [qtView frame];
279    
280 masaki 143 NSWindow *player = [self window];
281     NSRect originalWFrame = [player frame];
282 masaki 17
283 masaki 143 // [NSMenu setMenuBarVisible:NO];
284 masaki 107 SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
285 masaki 17
286 masaki 143 NSRect newWFrame = [[NSScreen mainScreen] frame];
287     // NSLog(@"screen ->\t%@",NSStringFromRect(newWFrame));
288    
289     NSSize delta = [self windowSizeWithoutQTView];
290     newWFrame.size.width += delta.width;
291     newWFrame.size.height += delta.height;
292     newWFrame.origin.y -= delta.height;
293     // newWFrame.size = [self fitSizeToSize:[[NSScreen mainScreen] frame].size];
294     // NSLog(@"window ->\t%@",NSStringFromRect(newWFrame));
295    
296     isExchangingFullScreen = YES;
297     [player setIsExchangingFullScreen:YES];
298     [player setFrame:newWFrame display:YES animate:YES];
299     [player setIsExchangingFullScreen:NO];
300     isExchangingFullScreen = NO;
301     // NSLog(@"new window ->\t%@",NSStringFromRect([player frame]));
302    
303    
304 masaki 17 [w makeKeyAndOrderFront:self];
305 masaki 143 [w setContentView:qtView];
306    
307     [w makeFirstResponder:qtView];
308    
309     [player orderOut:self];
310     [player setFrame:originalWFrame display:NO];
311 masaki 2 }
312 masaki 3 - (void)exitFullScreen
313 masaki 2 {
314 masaki 17 [qtView retain];
315     {
316     [qtView removeFromSuperview];
317     [qtView setFrame:nomalModeSavedFrame];
318     [[[self window] contentView] addSubview:qtView];
319     }
320     [qtView release];
321    
322 masaki 132 [self sizeTofitWidnow];
323     NSSize movieSize = [[[self qtMovie] attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
324     if(movieSize.width != 0) {
325     NSRect windowRect = [[self window] frame];
326    
327     CGFloat contentViewHeight = [[[self window] contentView] frame].size.height;
328     NSRect newViewRect = nomalModeSavedFrame;
329     newViewRect.size.height = newViewRect.size.width * (movieSize.height / movieSize.width);
330     newViewRect.origin.y = contentViewHeight - newViewRect.size.height;
331    
332     NSSize delta = [self windowSizeWithoutQTView];
333     windowRect.size.height = newViewRect.size.height + delta.height;
334     [[self window] setFrame:windowRect display:NO];
335    
336     [qtView setFrame:newViewRect];
337     }
338    
339 masaki 17 [NSMenu setMenuBarVisible:YES];
340 masaki 132 [[self fullscreenWindow] orderOut:self];
341 masaki 107
342 masaki 17 [[self window] makeKeyAndOrderFront:self];
343     [[self window] makeFirstResponder:qtView];
344 masaki 3 }
345 masaki 10
346     - (NSWindow *)fullscreenWindow
347     {
348     if(fullscreenWindow) return fullscreenWindow;
349    
350     NSRect mainScreenRect = [[NSScreen mainScreen] frame];
351 masaki 72 fullscreenWindow = [[XspfQTFullScreenWindow alloc] initWithContentRect:mainScreenRect
352 masaki 132 styleMask:NSBorderlessWindowMask
353     backing:NSBackingStoreBuffered
354     defer:YES];
355 masaki 10 [fullscreenWindow setReleasedWhenClosed:NO];
356     [fullscreenWindow setBackgroundColor:[NSColor blackColor]];
357     [fullscreenWindow setDelegate:self];
358 masaki 49 [fullscreenWindow setWindowController:self];
359 masaki 10
360     return fullscreenWindow;
361     }
362    
363     #pragma mark ### Actions ###
364 masaki 14 - (IBAction)togglePlayAndPause:(id)sender
365     {
366     if([[self valueForKeyPath:@"document.trackList.isPlayed"] boolValue]) {
367     [self pause];
368     } else {
369     [self play];
370     }
371     }
372    
373 masaki 3 - (IBAction)turnUpVolume:(id)sender
374     {
375 masaki 135 NSNumber *cv = [self valueForKeyPath:kVolumeKeyPath];
376 masaki 3 cv = [NSNumber numberWithFloat:[cv floatValue] + sVolumeDelta];
377 masaki 135 [self setValue:cv forKeyPath:kVolumeKeyPath];
378 masaki 3 }
379     - (IBAction)turnDownVolume:(id)sender
380     {
381 masaki 135 NSNumber *cv = [self valueForKeyPath:kVolumeKeyPath];
382 masaki 3 cv = [NSNumber numberWithFloat:[cv floatValue] - sVolumeDelta];
383 masaki 135 [self setValue:cv forKeyPath:kVolumeKeyPath];
384 masaki 3 }
385     - (IBAction)toggleFullScreenMode:(id)sender
386     {
387 masaki 10 if(fullScreenMode) {
388 masaki 3 [self exitFullScreen];
389 masaki 10 fullScreenMode = NO;
390 masaki 2 } else {
391 masaki 3 [self enterFullScreen];
392 masaki 10 fullScreenMode = YES;
393 masaki 2 }
394     }
395    
396 masaki 4 - (IBAction)forwardTagValueSecends:(id)sender
397     {
398     if(![sender respondsToSelector:@selector(tag)]) return;
399    
400     int tag = [sender tag];
401     if(tag == 0) return;
402    
403     QTTime current = [[self qtMovie] currentTime];
404     NSTimeInterval cur;
405     if(!QTGetTimeInterval(current, &cur)) return;
406    
407     QTTime new = QTMakeTimeWithTimeInterval(cur + tag);
408 masaki 9 [[self qtMovie] setCurrentTime:new];
409 masaki 4 }
410     - (IBAction)backwardTagValueSecends:(id)sender
411     {
412     if(![sender respondsToSelector:@selector(tag)]) return;
413    
414     int tag = [sender tag];
415     if(tag == 0) return;
416    
417     QTTime current = [[self qtMovie] currentTime];
418     NSTimeInterval cur;
419     if(!QTGetTimeInterval(current, &cur)) return;
420    
421     QTTime new = QTMakeTimeWithTimeInterval(cur - tag);
422 masaki 9 [[self qtMovie] setCurrentTime:new];
423 masaki 4 }
424 masaki 24 - (IBAction)nextTrack:(id)sender
425     {
426 masaki 49 [qtView pause:sender];
427 masaki 24 [[[self document] trackList] next];
428     }
429     - (IBAction)previousTrack:(id)sender
430     {
431 masaki 49 [qtView pause:sender];
432 masaki 24 [[[self document] trackList] previous];
433     }
434 masaki 4
435 masaki 134 - (IBAction)normalSize:(id)sender
436     {
437     if(fullScreenMode) return;
438    
439     QTMovie *curMovie = [self qtMovie];
440     if(!curMovie) return;
441    
442     NSSize movieSize = [[curMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
443     if(movieSize.width == 0) return;
444    
445     [self setMovieSize:movieSize];
446     }
447     - (IBAction)halfSize:(id)sender
448     {
449     if(fullScreenMode) return;
450    
451     QTMovie *curMovie = [self qtMovie];
452     if(!curMovie) return;
453    
454     NSSize movieSize = [[curMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
455     if(movieSize.width == 0) return;
456    
457     movieSize.width *= 0.5;
458     movieSize.height *= 0.5;
459    
460     [self setMovieSize:movieSize];
461     }
462     - (IBAction)doubleSize:(id)sender
463     {
464     if(fullScreenMode) return;
465    
466     QTMovie *curMovie = [self qtMovie];
467     if(!curMovie) return;
468    
469     NSSize movieSize = [[curMovie attributeForKey:QTMovieNaturalSizeAttribute] sizeValue];
470     if(movieSize.width == 0) return;
471    
472     movieSize.width *= 2;
473     movieSize.height *= 2;
474    
475     [self setMovieSize:movieSize];
476     }
477 masaki 135 - (IBAction)screenSize:(id)sender
478     {
479     //
480     //
481     }
482 masaki 134
483 masaki 10 #pragma mark ### Notification & Timer ###
484 masaki 2 - (void)didEndMovie:(id)notification
485     {
486     [[[self document] trackList] next];
487     }
488     - (void)updateTimeIfNeeded:(id)timer
489     {
490     QTMovie *qt = [self qtMovie];
491     if(qt) {
492 masaki 10 // force update time indicator.
493 masaki 2 [qt willChangeValueForKey:@"currentTime"];
494     [qt didChangeValueForKey:@"currentTime"];
495     }
496 masaki 3
497     // Hide cursor and controller, if mouse didn't move for 3 seconds.
498     NSPoint mouse = [NSEvent mouseLocation];
499     if(!NSEqualPoints(prevMouse, mouse)) {
500     prevMouse = mouse;
501     [prevMouseMovedDate autorelease];
502     prevMouseMovedDate = [[NSDate dateWithTimeIntervalSinceNow:0.0] retain];
503 masaki 10 } else if(fullScreenMode && [prevMouseMovedDate timeIntervalSinceNow] < -3.0 ) {
504 masaki 3 [NSCursor setHiddenUntilMouseMoves:YES];
505     //
506     // hide controller.
507     }
508 masaki 2 }
509    
510 masaki 10 #pragma mark ### NSResponder ###
511 masaki 2 - (void)cancelOperation:(id)sender
512     {
513 masaki 10 if(fullScreenMode) {
514 masaki 2 [self toggleFullScreenMode:self];
515     }
516     }
517    
518 masaki 10 #pragma mark ### NSMenu valivation ###
519     - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
520     {
521     if([menuItem action] == @selector(toggleFullScreenMode:)) {
522     if(fullScreenMode) {
523     [menuItem setTitle:NSLocalizedString(@"Exit Full Screen", @"Exit Full Screen")];
524     } else {
525     [menuItem setTitle:NSLocalizedString(@"Full Screen", @"Full Screen")];
526     }
527     return YES;
528     }
529    
530 masaki 139 if([menuItem action] == @selector(screenSize:)) {
531     return NO;
532     }
533    
534     if([menuItem action] == @selector(normalSize:)
535     || [menuItem action] == @selector(halfSize:)
536     || [menuItem action] == @selector(doubleSize:)) {
537     if(fullScreenMode) {
538     return NO;
539     } else {
540     return YES;
541     }
542     }
543    
544 masaki 10 return YES;
545     }
546    
547 masaki 100 #pragma mark ### XspfQTDocument Notification ###
548     - (void)documentWillClose:(NSNotification *)notification
549 masaki 2 {
550 masaki 100 id doc = [notification object];
551     // NSLog(@"Remove Observed! %@", doc);
552 masaki 10 if(fullScreenMode) {
553 masaki 2 [self toggleFullScreenMode:self];
554     }
555 masaki 100
556     [doc removeObserver:self forKeyPath:kQTMovieKeyPath];
557     [doc removeObserver:self forKeyPath:kIsPlayedKeyPath];
558    
559     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
560     [nc removeObserver:self name:XspfQTDocumentWillCloseNotification object:doc];
561 masaki 2 }
562    
563 masaki 10 #pragma mark ### NSWindow Delegate ###
564 masaki 2 - (BOOL)windowShouldClose:(id)sender
565     {
566     [qtView pause:self];
567     [self setQtMovie:nil];
568    
569 masaki 66 [updateTime invalidate];
570 masaki 2 updateTime = nil;
571    
572     return YES;
573     }
574     - (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
575     {
576 masaki 143 if(isExchangingFullScreen) return frameSize;
577    
578 masaki 2 return [self fitSizeToSize:frameSize];
579     }
580 masaki 16 - (void)windowDidMove:(NSNotification *)notification
581     {
582     if(fullscreenWindow && [notification object] == fullscreenWindow) {
583     NSRect r = [fullscreenWindow frame];
584 masaki 45 if(!NSEqualPoints(r.origin, NSZeroPoint)) {
585 masaki 16 [fullscreenWindow setFrameOrigin:NSZeroPoint];
586     }
587     }
588     }
589 masaki 2 @end

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