Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /XspfQT/XspfQTMovieWindowController.m

Parent Directory Parent Directory | Revision Log Revision Log


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

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