Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTMovieWindowController.m

Parent Directory Parent Directory | Revision Log Revision Log


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

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