source: trunk/Cocoa/Pester/Source/PSMovieAlertController.m @ 543

Last change on this file since 543 was 543, checked in by Nicholas Riley, 10 years ago

Minimally convert media playback to QTKit. Some direct QuickTime? access still needs migrating.

File size: 4.8 KB
Line 
1//
2//  PSMovieAlertController.m
3//  Pester
4//
5//  Created by Nicholas Riley on Sat Oct 26 2002.
6//  Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "PSAlarmAlertController.h"
10#import "PSMovieAlertController.h"
11#import "PSMovieAlert.h"
12#import "QTMovie-NJRExtensions.h"
13#import "NJRSoundManager.h"
14#import <QuickTime/Movies.h>
15
16@implementation PSMovieAlertController
17
18+ (PSMovieAlertController *)controllerWithAlarm:(PSAlarm *)anAlarm movieAlert:(PSMovieAlert *)anAlert;
19{
20    return [[self alloc] initWithAlarm: anAlarm movieAlert: anAlert];
21}
22
23- (void)close;
24{
25    [super close];
26    [NJRSoundManager restoreSavedDefaultOutputVolumeIfCurrently: [alert outputVolume]];
27}
28
29- (void)play;
30{
31    NSTimeInterval delay;
32    if (repetitions == 0) return;
33    if (IsMovieDone((Movie)theMovie) || repetitionsRemaining == repetitions) {
34        if (repetitionsRemaining == 0) {
35            [self close];
36            return;
37        }
38        repetitionsRemaining--;
39        [movieView gotoBeginning: self];
40        [movieView play: self];
41    }
42    delay = (GetMovieDuration((Movie)theMovie) - GetMovieTime((Movie)theMovie, NULL)) / (double)GetMovieTimeScale((Movie)theMovie);
43    // XXX should use a timebase callback for this instead (see NJRQTMediaPopUpButton); also, use QuickTimeÕs built-in loop functionality instead of rolling our own?
44    [self performSelector: @selector(play) withObject: nil afterDelay: delay inModes: [NSArray arrayWithObject: NSDefaultRunLoopMode]];
45}
46
47- (id)initWithAlarm:(PSAlarm *)anAlarm movieAlert:(PSMovieAlert *)anAlert;
48{
49    if ([self initWithWindowNibName: @"Movie alert"]) {
50        QTMovie *movie = [anAlert movie];
51        NSWindow *window = [self window]; // connect outlets
52        alarm = anAlarm;
53        alert = anAlert;
54        theMovie = [movie quickTimeMovie];
55        [movieView setMovie: movie];
56        if ([alert hasVideo]) {
57            NSRect screenRect = [[window screen] visibleFrame];
58            NSSize movieSize = [[movie attributeForKey: QTMovieNaturalSizeAttribute] sizeValue];
59            NSSize minSize = [window minSize];
60            float windowFrameHeight = [window frame].size.height - [[window contentView] frame].size.height;
61            NSRect frame;
62            screenRect.size.height -= windowFrameHeight;
63            minSize.height -= windowFrameHeight;
64            while (movieSize.width > screenRect.size.width || movieSize.height > screenRect.size.height) {
65                movieSize.width /= 2;
66                movieSize.height /= 2;
67            }
68            if (movieSize.width < minSize.width) movieSize.width = minSize.width;
69            if (movieSize.height < minSize.height) movieSize.width = minSize.height;
70            [window setContentSize: movieSize];
71            [window center];
72            frame = [window frame];
73            frame.origin.y -= 400; // appear below notifier window - XXX this is very inaccurate, fix
74            if (frame.origin.y < screenRect.origin.y) frame.origin.y = screenRect.origin.y;
75            [window setFrame: frame display: NO];
76            [window setTitle: [alarm message]];
77            {   // XXX workaround for (IMO) ugly appearance of Cocoa utility windows
78                NSView *miniButton = [window standardWindowButton: NSWindowMiniaturizeButton],
79                *zoomButton = [window standardWindowButton: NSWindowZoomButton];
80                // NOTE: this will not work if the window is resizable: when the frame is reset, the standard buttons reappear
81                [miniButton setFrameOrigin: NSMakePoint(-100, -100)];
82                [zoomButton setFrameOrigin: NSMakePoint(-100, -100)];
83                [[miniButton superview] setNeedsDisplay: YES];
84                [[zoomButton superview] setNeedsDisplay: YES];
85            }
86            [[self window] orderFrontRegardless];
87        }
88        [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(close) name: PSAlarmAlertStopNotification object: nil];
89        repetitions = [alert repetitions];
90        repetitionsRemaining = repetitions;
91        if ([movie NJR_hasAudio] && [NJRSoundManager volumeIsNotMutedOrInvalid: [alert outputVolume]] && [NJRSoundManager saveDefaultOutputVolume]) {
92            [NJRSoundManager setDefaultOutputVolume: [alert outputVolume]];
93        }
94        if (![movie NJR_isStatic]) [self play]; // if it's an image, don't close the window automatically
95    }
96    return self;
97}
98
99- (void)dealloc;
100{
101    [[NSNotificationCenter defaultCenter] removeObserver: self];
102    [super dealloc];
103}
104
105@end
106
107@implementation PSMovieAlertController (NSWindowNotifications)
108
109- (void)windowWillClose:(NSNotification *)notification;
110{
111    repetitions = 0;
112    [movieView pause: self];
113    [alert completedForAlarm: alarm];
114    [self autorelease];
115    // note: there may still be a retained copy of this object until the runloop timer has let go of us at the end of the current movie playback cycle; donÕt worry about it.
116}
117
118@end
Note: See TracBrowser for help on using the repository browser.