Skip to content

Commit a8b9734

Browse files
committed
• Xcode has suddenly decided that SSYAlertSounder.h/.m were not under version control???
• Added comment in SSYProgressView.m explaining a bug (vertical line to the left of the progress bar) which I cannot explain nor fix.
1 parent 4f9f249 commit a8b9734

4 files changed

+237
-4
lines changed

SSYAlertSounder (original).h

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#import <Cocoa/Cocoa.h>
2+
3+
/*
4+
Use this if you need to keep a process running long enough for your
5+
sound to complete playing. This is an integer so that it can be
6+
used as a parameters to functions that require integers, like sleep().
7+
*/
8+
#define SECONDS_NEEDED_FOR_ONE_ALERT_SOUND 1
9+
10+
11+
/*!
12+
@brief This is a quick hacky wrapper on Audio Services
13+
to play an alert sound cheaply and reliably (in contrast to NSSound)
14+
15+
@details Requires System/Library/Frameworks/AudioToolbox.framework,
16+
which is Mac OS 10.5 or later.
17+
18+
In the earlier System Sound API, for these sounds to play, it was required
19+
that, in System Preferences > Sound > Play User Interface Sound Effects
20+
be enabled. But this appears to work without it.
21+
*/
22+
__attribute__((visibility("default"))) @interface SSYAlertSounder : NSObject {
23+
NSMutableDictionary* m_soundIds ;
24+
}
25+
26+
/*!
27+
@brief Plays a desired sound
28+
29+
@details
30+
@param name The name of a sound file, not including the .aiff extension,
31+
or nil to no-op
32+
*/
33+
- (void)playAlertSoundNamed:(NSString*)name ;
34+
35+
/*!
36+
@brief Returns an array, localizedly sorted, containing all of the names
37+
of the sounds which are available for use by -playAlertSoundNamed, provided
38+
that none of the underlying files disappear in the meantime
39+
*/
40+
- (NSArray*)availableSoundsSorted ;
41+
42+
+ (SSYAlertSounder*)sharedSounder ;
43+
44+
@end
45+

SSYAlertSounder (original).m

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#import "SSYAlertSounder.h"
2+
#import <AudioToolbox/AudioServices.h>
3+
#import "NSBundle+MainApp.h"
4+
#import "SSY_ARC_OR_NO_ARC.h"
5+
6+
7+
static SSYAlertSounder* static_sharedSounder = nil ;
8+
9+
@interface SSYAlertSounder ()
10+
11+
@end
12+
13+
@implementation SSYAlertSounder
14+
15+
- (id)init {
16+
self = [super init] ;
17+
if (self) {
18+
m_soundIds = [[NSMutableDictionary alloc] init] ;
19+
}
20+
21+
return self ;
22+
}
23+
24+
- (void)dealloc {
25+
for (NSNumber* soundId in [m_soundIds allValues]) {
26+
AudioServicesDisposeSystemSoundID((unsigned int)[soundId longValue]) ;
27+
}
28+
29+
#if NO_ARC
30+
[m_soundIds release] ;
31+
32+
[super dealloc] ;
33+
#endif
34+
}
35+
36+
- (NSMutableDictionary*)soundIds {
37+
return m_soundIds ;
38+
}
39+
40+
41+
+ (SSYAlertSounder*)sharedSounder {
42+
@synchronized(self) {
43+
if (!static_sharedSounder) {
44+
static_sharedSounder = [[self alloc] init] ;
45+
}
46+
}
47+
48+
// No autorelease. This sticks around forever.
49+
return static_sharedSounder ;
50+
}
51+
52+
- (SystemSoundID)soundIdForPath:(NSString*)path
53+
rememberAs:(NSString*)name {
54+
SystemSoundID soundId = 0 ;
55+
56+
if (path) {
57+
CFURLRef url = (__bridge CFURLRef)[NSURL fileURLWithPath:path] ;
58+
if (url) {
59+
OSStatus err ;
60+
err = AudioServicesCreateSystemSoundID(url, &soundId) ;
61+
62+
if (err) {
63+
// This will happen if file was not found.
64+
soundId = 0 ;
65+
}
66+
else {
67+
[[self soundIds] setObject:[NSNumber numberWithLong:soundId]
68+
forKey:name] ;
69+
}
70+
}
71+
}
72+
73+
return soundId ;
74+
}
75+
76+
- (NSArray*)availableSoundsSorted {
77+
NSString* const type = @"aiff" ;
78+
NSMutableArray* paths = [[NSMutableArray alloc] init] ;
79+
NSString* path ;
80+
NSArray* morePaths ;
81+
82+
morePaths = [[NSBundle mainAppBundle] pathsForResourcesOfType:type
83+
inDirectory:nil] ;
84+
[paths addObjectsFromArray:morePaths] ;
85+
86+
path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Sounds"] ;
87+
morePaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path
88+
error:NULL] ;
89+
[paths addObjectsFromArray:morePaths] ;
90+
91+
path = @"/System/Library/Sounds" ;
92+
morePaths = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path
93+
error:NULL] ;
94+
[paths addObjectsFromArray:morePaths] ;
95+
96+
NSMutableArray* names = [[NSMutableArray alloc] init] ;
97+
for (NSString* path in paths) {
98+
NSString* name = [[path lastPathComponent] stringByDeletingPathExtension] ;
99+
if ([[path pathExtension] isEqualToString:type]) {
100+
[names addObject:name] ;
101+
}
102+
}
103+
104+
[names sortUsingComparator:^NSComparisonResult(NSString* s1, NSString* s2) {
105+
return [s1 localizedCaseInsensitiveCompare:s2] ;
106+
}] ;
107+
108+
NSArray* answer = [names copy] ;
109+
110+
#if NO_ARC
111+
[paths release] ;
112+
[names release] ;
113+
[answer autorelease] ;
114+
#endif
115+
116+
return answer ;
117+
}
118+
119+
120+
- (void)playAlertSoundNamed:(NSString*)name {
121+
if (!name) {
122+
return ;
123+
}
124+
125+
// First, see if we've got this sound cached
126+
SystemSoundID soundId = (SystemSoundID)[[[self soundIds] objectForKey:name] longValue] ;
127+
// Used -longValue because SystemSoundID is a UInt32
128+
129+
NSString* path ;
130+
131+
// If not found, look in the current application's bundle
132+
if (!soundId) {
133+
path = [[NSBundle mainAppBundle] pathForResource:name
134+
ofType:@"aiff"] ;
135+
136+
soundId = [self soundIdForPath:path
137+
rememberAs:name] ;
138+
// If not found, look in current user's library
139+
if (!soundId) {
140+
path = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Sounds"] ;
141+
path = [path stringByAppendingPathComponent:[name stringByAppendingPathExtension:@"aiff"]] ;
142+
143+
soundId = [self soundIdForPath:path
144+
rememberAs:name] ;
145+
146+
// If not found, look in system's library
147+
if (!soundId) {
148+
path = @"/System/Library/Sounds" ;
149+
path = [path stringByAppendingPathComponent:[name stringByAppendingPathExtension:@"aiff"]] ;
150+
151+
soundId = [self soundIdForPath:path
152+
rememberAs:name] ;
153+
}
154+
}
155+
}
156+
157+
if (soundId) {
158+
AudioServicesPlayAlertSound(soundId) ;
159+
}
160+
else {
161+
NSBeep() ;
162+
}
163+
}
164+
165+
@end

SSYInterappClient.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ + (BOOL)sendHeaderByte:(char)txHeaderByte
4141
usleep(100000) ;
4242
}
4343
} while (!remotePort) ;
44-
44+
4545
if (!remotePort) {
4646
ok = NO ;
4747
result = SSYInterappClientErrorCantFindReceiver ;

SSYProgressView.m

+26-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,32 @@
1616
NSString* const constKeyTarget = @"target" ;
1717
NSString* const constKeyActionValue = @"actionValue" ;
1818

19-
@interface SSYRolloverButton : NSButton {
19+
#if 0
20+
/* I can't figure out why the left edge of the progress indicator's rect is
21+
sometimes, in Yosemite, a thin black line. I know it is part of the
22+
NSProgressIndicator, because it I set the 'hidden' attribute of _progBar to
23+
YES, the thin black line disappears (along with the progress indicator).
24+
The following code, which attempts to thin black line with a thicker red line,
25+
makes a thick red line only when the thin black line is not there. To use
26+
this code, in -rejuvenateProgressBar, instantiate one of these instead
27+
of an NSProgressIndicator: */
28+
@interface SSYPatchedProgressIndicator : NSProgressIndicator
29+
@end
30+
@implementation SSYPatchedProgressIndicator
31+
- (void)drawRect:(NSRect)dirtyRect {
32+
[super drawRect:dirtyRect] ;
33+
[[NSGraphicsContext currentContext] saveGraphicsState] ;
34+
[[NSColor redColor] set] ;
35+
NSRect patchRect = [self frame] ;
36+
patchRect.size.width = 3.0 ;
37+
[NSBezierPath fillRect: patchRect] ;
38+
[[NSGraphicsContext currentContext] restoreGraphicsState] ;
2039
}
2140
@end
41+
#endif
42+
43+
@interface SSYRolloverButton : NSButton
44+
@end
2245

2346
@implementation SSYRolloverButton
2447

@@ -172,7 +195,7 @@ - (NSTextField*)textField {
172195
}
173196

174197
- (void)rejuvenateProgressBar {
175-
NSRect frame ;
198+
NSRect frame ;
176199
if (_progBar != nil) {
177200
frame = [_progBar frame] ;
178201
[_progBar removeFromSuperviewWithoutNeedingDisplay] ;
@@ -181,7 +204,7 @@ - (void)rejuvenateProgressBar {
181204
frame = NSMakeRect(0,1.0,100,[self frame].size.height - 3.0) ;
182205
// The y=1.0, h-=3.0 makes it line up with the text nicer.
183206
}
184-
_progBar = [[NSProgressIndicator alloc] initWithFrame:frame] ;
207+
_progBar = [[NSProgressIndicator alloc] initWithFrame:frame] ;
185208
[self addSubview:_progBar] ;
186209
[_progBar release] ;
187210
[_progBar setStyle:NSProgressIndicatorBarStyle] ;

0 commit comments

Comments
 (0)