DCDie-Accessibility.m
/* |
File: DCDie-Accessibility.m |
Abstract: Accessibility implementation for each die |
Version: <1.0> |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple |
Computer, Inc. ("Apple") in consideration of your agreement to the |
following terms, and your use, installation, modification or |
redistribution of this Apple software constitutes acceptance of these |
terms. If you do not agree with these terms, please do not use, |
install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and |
subject to these terms, Apple grants you a personal, non-exclusive |
license, under Apple's copyrights in this original Apple software (the |
"Apple Software"), to use, reproduce, modify and redistribute the Apple |
Software, with or without modifications, in source and/or binary forms; |
provided that if you redistribute the Apple Software in its entirety and |
without modifications, you must retain this notice and the following |
text and disclaimers in all such redistributions of the Apple Software. |
Neither the name, trademarks, service marks or logos of Apple Computer, |
Inc. may be used to endorse or promote products derived from the Apple |
Software without specific prior written permission from Apple. Except |
as expressly stated in this notice, no other rights or licenses, express |
or implied, are granted by Apple herein, including but not limited to |
any patent rights that may be infringed by your derivative works or by |
other works in which the Apple Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE |
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION |
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS |
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND |
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL |
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, |
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED |
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), |
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGE. |
Copyright © 2006-2009 Apple Inc., All Rights Reserved |
*/ |
#import "DCDie.h" |
#import "DCDiceView-Private.h" |
@implementation DCDie (Accessibility) |
-(BOOL)accessibilityIsIgnored { |
return NO; |
} |
/* The list of attributes is taken from what an AXCheckbox UI Element supports */ |
- (NSArray *)accessibilityAttributeNames { |
static NSArray *attributes; |
if (!attributes) { |
attributes = [[NSArray alloc] initWithObjects: NSAccessibilityRoleAttribute, NSAccessibilityRoleDescriptionAttribute, NSAccessibilityParentAttribute, NSAccessibilityPositionAttribute, NSAccessibilitySizeAttribute, NSAccessibilityWindowAttribute, NSAccessibilityTopLevelUIElementAttribute, NSAccessibilityValueAttribute, NSAccessibilityHelpAttribute, NSAccessibilityEnabledAttribute, NSAccessibilityFocusedAttribute, NSAccessibilityDescriptionAttribute, nil]; |
} |
return attributes; |
} |
- (NSString *)dieDescriptionForAccessiblity { |
NSString *heldString = nil; |
if (hasHold) heldString = NSLocalizedString(@"held", @"Accessibility description for held die"); |
else heldString = NSLocalizedString(@"unheld", @"Accessibility description for unheld die"); |
if (spotCount > 1) // @"%@ die with %d spots" |
return [NSString stringWithFormat:NSLocalizedString(@"held die with X spots", @"Accessibility description for die with more than one spots"), heldString, [self spotCount]]; |
else // @"%@ die with %d spot" |
return [NSString stringWithFormat:NSLocalizedString(@"held die with X spot", @"Accessibility description for die with one spot"), heldString, [self spotCount]]; |
} |
/* This should return a localized string */ |
- (id)accessibilityAttributeValue:(NSString *)attribute { |
id attributeValue = nil; |
/* We are a button that maintains state (held/unheld) our closest UI Element is a checkbox */ |
if ([attribute isEqualToString: NSAccessibilityRoleAttribute]) { |
attributeValue = NSAccessibilityCheckBoxRole; |
} |
/* Can use the convenience function NSAccessibilityRoleDescription to get localized role descriptions of standard roles */ |
else if ([attribute isEqualToString: NSAccessibilityRoleDescriptionAttribute]) { |
attributeValue = NSAccessibilityRoleDescription(NSAccessibilityCheckBoxRole,nil); |
} |
/* We need to have some way to return a reference to our parent. */ |
else if ([attribute isEqualToString: NSAccessibilityParentAttribute]) { |
attributeValue = parent; |
} |
/* Screen geometery properties: |
Accessibility coordinates are always screen coordinates. |
We return NSValues of points and rects. |
*/ |
/* We take our origin, if we're flipped, our origin is in the top-left corner. We need to use our bottom-left corner |
Then: |
1. Convert the point to the window coordinates (base coordinates) |
2. Convert that point from base to screen |
3. Wrap the result as an NSValue using -valueWithPoint: |
*/ |
else if ([attribute isEqualToString: NSAccessibilityPositionAttribute]) { |
NSPoint localPoint = [self bounds].origin; |
if ([parent isFlipped]) { |
localPoint.y += [self bounds].size.height; |
} |
NSPoint windowPoint = [parent convertPoint:localPoint toView: nil]; |
attributeValue = [NSValue valueWithPoint:[[parent window] convertBaseToScreen:windowPoint]];; |
} |
/* Base (window) coordinate and screen coordinate sizes are the same so we can just: |
1. Convert from local coordinate system size to window coordinates |
2. Return as an NSValue using -valueWithSize: |
*/ |
else if ([attribute isEqualToString: NSAccessibilitySizeAttribute]) { |
NSRect localBounds = [self bounds]; |
attributeValue = [NSValue valueWithSize:[parent convertSize:localBounds.size toView:nil]]; |
} |
/* For our Window and Top Level UI Element, we can just return whatever our parent says */ |
else if ([attribute isEqualToString: NSAccessibilityWindowAttribute]) { |
attributeValue = [parent accessibilityAttributeValue:NSAccessibilityWindowAttribute]; |
} |
else if ([attribute isEqualToString: NSAccessibilityTopLevelUIElementAttribute]) { |
attributeValue = [parent accessibilityAttributeValue:NSAccessibilityTopLevelUIElementAttribute]; |
} |
/* Our value is an integer, so create one basedon the value of hasHold */ |
else if ([attribute isEqualToString: NSAccessibilityValueAttribute]) { |
attributeValue = [NSNumber numberWithInt:hasHold ? 1 : 0]; |
} |
/* We are always enabled if we are showing, so return YES */ |
else if ([attribute isEqualToString: NSAccessibilityEnabledAttribute]) { |
attributeValue = [NSNumber numberWithBool:YES]; |
} |
/* We know if we have focus, so return that value as a bool */ |
else if ([attribute isEqualToString: NSAccessibilityFocusedAttribute]) { |
attributeValue = [NSNumber numberWithBool:hasFocus]; |
} |
/* We return no help */ |
else if ([attribute isEqualToString: NSAccessibilityHelpAttribute]) { |
attributeValue = @""; |
} |
else if ([attribute isEqualToString: NSAccessibilityDescriptionAttribute]) { |
attributeValue = [self dieDescriptionForAccessiblity]; |
} |
return attributeValue; |
} |
/* Only focused and value attributes are settable*/ |
- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute { |
if ([attribute isEqualToString: NSAccessibilityFocusedAttribute]) return YES; |
else if ([attribute isEqualToString: NSAccessibilityValueAttribute]) return YES; |
else return NO; |
} |
/* If someone tries to set the focused attribute we do the following: |
Tell parent to set us as the focused die. |
*/ |
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute { |
if ([attribute isEqualToString: NSAccessibilityFocusedAttribute]) { |
if ([value boolValue]) { |
[[self parent] setFocusedDie: self]; |
} |
} |
else if ([attribute isEqualToString: NSAccessibilityValueAttribute]) { |
if ([value boolValue] != hasHold) { |
[self toggleHold]; |
[parent setNeedsDisplay: YES]; |
} |
} |
} |
/* We only respond to one action AXPress */ |
-(NSArray *)accessibilityActionNames { |
static NSArray *actions; |
if (!actions) actions = [[NSArray alloc] initWithObjects: NSAccessibilityPressAction, nil]; |
return actions; |
} |
/* Use convenience function to return standard localized description for action */ |
- (NSString *)accessibilityActionDescription:(NSString *)action { |
return NSAccessibilityActionDescription(action); |
} |
/* If we are asked to perform action we need to toggle ourselves and tell parent to redisplay */ |
- (void)accessibilityPerformAction:(NSString *)action { |
if ([action isEqualToString:NSAccessibilityPressAction]) { |
[self toggleHold]; |
[parent setNeedsDisplay: YES]; |
} |
} |
/* For both hit testing and focus testing, we return ourselves */ |
- (id)accessibilityHitTest:(NSPoint)point { |
return NSAccessibilityUnignoredAncestor(self); |
} |
- (id)accessibilityFocusedUIElement { |
return NSAccessibilityUnignoredAncestor(self); |
} |
@end |
Copyright © 2009 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2009-06-29