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

Last change on this file since 583 was 583, checked in by Nicholas Riley, 15 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.