source: trunk/Cocoa/Pester/Source/PSVolumeController.m @ 583

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

PSVolumeController.m: Restore volume slider functionality for 10.6; beeps on cancellation now, though.

File size: 3.5 KB
Line 
1//
2//  PSVolumeController.m
3//  Pester
4//
5//  Created by Nicholas Riley on Tue Apr 08 2003.
6//  Copyright (c) 2003 Nicholas Riley. All rights reserved.
7//
8
9#import "PSVolumeController.h"
10#import "NJRSoundManager.h"
11#import "NJRNonCenteringWindow.h"
12
13@implementation PSVolumeController
14
15+ (PSVolumeController *)controllerWithVolume:(float)volume delegate:(id)aDelegate;
16{
17    return [[self alloc] initWithVolume: volume delegate: aDelegate];
18}
19
20- (id)initWithVolume:(float)volume delegate:(id)aDelegate;
21{
22    if ( (self = [self initWithWindowNibName: @"Volume"]) != nil) {
23        [self window]; // connect outlets
24        NSWindow *window = [[NJRNonCenteringWindow alloc] initWithContentRect: [contentView bounds] styleMask: NSBorderlessWindowMask backing: NSBackingStoreBuffered defer: NO];
25
26        if ([NJRSoundManager volumeIsNotMutedOrInvalid: volume])
27            [volumeSlider setFloatValue: volume];
28
29        delegate = [aDelegate retain];
30
31        [window setContentView: contentView];
32        [window setInitialFirstResponder: volumeSlider];
33        [window makeFirstResponder: volumeSlider];
34        [window setOpaque: NO];
35        [window setBackgroundColor: [NSColor colorWithCalibratedWhite: 0.81f alpha: 0.9f]];
36        [window setHasShadow: YES];
37        [window setOneShot: YES];
38        [window setDelegate: self];
39        NSView *view = [aDelegate volumeControllerLaunchingView: self];
40        if (view != nil) {
41            NSRect rect = [view convertRect: [view bounds] toView: nil];
42            NSWindow *parentWindow = [view window];
43            rect.origin = [parentWindow convertBaseToScreen: rect.origin];
44            rect.origin.x -= [window frame].size.width - rect.size.width + 1;
45            [window setFrameTopLeftPoint: rect.origin];
46            NSRect visibleFrame = [[parentWindow screen] visibleFrame];
47            if (!NSContainsRect(visibleFrame, [window frame])) {
48                NSPoint viewTopLeft = { rect.origin.x, rect.origin.y + rect.size.height };
49                [window setFrameOrigin: viewTopLeft];
50            }
51        }
52
53        // -[NSApplication beginModalSessionForWindow:] shows and centers the window; we use NJRNonCenteringWindow to prevent the repositioning from succeeding
54        NSModalSession session = [NSApp beginModalSessionForWindow: window];
55        // In 10.6, we can no longer force the modal session to work by "seeding" the slider with a mouse-down event.
56        // Instead, we stop the modal session on a volume change.
57        while ([NSApp runModalSession: session] == NSRunContinuesResponse) {
58            // Any mouse click events that do not change the slider value should abort.
59            NSEvent *event = [NSApp currentEvent];
60            unsigned int eventTypeMask = NSEventMaskFromType([event type]);
61            if (eventTypeMask & (NSLeftMouseDownMask | NSRightMouseDownMask | NSOtherMouseDownMask)) {
62                [NSApp preventWindowOrdering];
63                [NSApp discardEventsMatchingMask: NSAnyEventMask beforeEvent: event];
64                break;
65            }
66            if (eventTypeMask & (NSKeyDownMask | NSKeyUpMask)) {
67                unsigned short keyCode = [event keyCode];
68                if (keyCode == 53 || keyCode == 36 || keyCode == 76) { // escape, return, enter
69                    [NSApp discardEventsMatchingMask: NSAnyEventMask beforeEvent: event];
70                    break;
71                }
72            }
73        }
74        [NSApp endModalSession: session];
75        [window close];
76        [self autorelease];
77        // XXX make sure window and self are released
78    }
79    return self;
80}
81
82- (void)dealloc;
83{
84    [delegate release];
85    [super dealloc];
86}
87
88- (IBAction)volumeSet:(NSSlider *)sender;
89{
90    [delegate volumeController: self didSetVolume: [sender floatValue]];
91    [NSApp stopModal];
92}
93
94@end
Note: See TracBrowser for help on using the repository browser.