Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTMovieWindowController.m

Parent Directory Parent Directory | Revision Log Revision Log


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

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