Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTMovieWindowController.m

Parent Directory Parent Directory | Revision Log Revision Log


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

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