1/*
2  File:		MBCBoardViewAccessibility.mm
3  Contains:	Accessibility navigation for chess board
4  Copyright:	© 2004-2008 by Apple Inc., all rights reserved.
5	IMPORTANT: This Apple software is supplied to you by Apple Computer,
6	Inc.  ("Apple") in consideration of your agreement to the following
7	terms, and your use, installation, modification or redistribution of
8	this Apple software constitutes acceptance of these terms.  If you do
9	not agree with these terms, please do not use, install, modify or
10	redistribute this Apple software.
11
12	In consideration of your agreement to abide by the following terms,
13	and subject to these terms, Apple grants you a personal, non-exclusive
14	license, under Apple's copyrights in this original Apple software (the
15	"Apple Software"), to use, reproduce, modify and redistribute the
16	Apple Software, with or without modifications, in source and/or binary
17	forms; provided that if you redistribute the Apple Software in its
18	entirety and without modifications, you must retain this notice and
19	the following text and disclaimers in all such redistributions of the
20	Apple Software.  Neither the name, trademarks, service marks or logos
21	of Apple Inc. may be used to endorse or promote products
22	derived from the Apple Software without specific prior written
23	permission from Apple.  Except as expressly stated in this notice, no
24	other rights or licenses, express or implied, are granted by Apple
25	herein, including but not limited to any patent rights that may be
26	infringed by your derivative works or by other works in which the
27	Apple Software may be incorporated.
28
29	The Apple Software is provided by Apple on an "AS IS" basis.  APPLE
30	MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
31	THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND
32	FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
33	USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
34
35	IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
36	INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
37	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
38	PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
39	REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE,
40	HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
41	NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
42	ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43*/
44
45#import "MBCMoveTableViewAccessibility.h"
46#import "MBCMoveTableView.h"
47
48@implementation MBCMoveAccessibilityProxy
49
50+ (id) proxyWithInfo:(MBCGameInfo *)info move:(int)move
51{
52	return [[[MBCMoveAccessibilityProxy alloc]
53				initWithInfo:info move:move]
54			   autorelease];
55}
56
57- (id) initWithInfo:(MBCGameInfo *)info move:(int)move
58{
59	fInfo	= info;
60	fMove   = move;
61
62	return self;
63}
64
65- (BOOL) isEqual:(MBCMoveAccessibilityProxy *)other
66{
67	return [other isKindOfClass:[MBCMoveAccessibilityProxy class]]
68		&& fInfo == other->fInfo && fMove == other->fMove;
69}
70
71- (NSUInteger)hash {
72    // Equal objects must hash the same.
73    return [fInfo hash] + fMove;
74}
75
76- (NSString *) description
77{
78	return [NSString stringWithFormat:@"Move %d", fMove];
79}
80
81- (NSArray *)accessibilityAttributeNames
82{
83	return [NSArray arrayWithObjects:
84					NSAccessibilityRoleAttribute,
85					NSAccessibilityRoleDescriptionAttribute,
86					NSAccessibilityParentAttribute,
87					NSAccessibilityWindowAttribute,
88					NSAccessibilityPositionAttribute,
89					NSAccessibilitySizeAttribute,
90					NSAccessibilityTitleAttribute,
91                   NSAccessibilityDescriptionAttribute,
92					NSAccessibilityFocusedAttribute,
93					NSAccessibilityEnabledAttribute,
94					NSAccessibilityTopLevelUIElementAttribute,
95					nil];
96}
97
98- (NSArray *)accessibilityActionNames
99{
100    return [NSArray array];
101}
102
103- (id)accessibilityFocusedUIElement
104{
105	return self;
106}
107
108- (BOOL)accessibilityIsIgnored
109{
110	return NO;
111}
112
113- (NSRect)accessibilityFocusRingBounds
114{
115    NSRect  rect = [[fInfo moveList] rectOfRow:fMove-1];
116    rect         = [[fInfo moveList] convertRect:rect toView:nil];
117
118    return [[[fInfo moveList] window] convertRectToScreen:rect];
119}
120
121- (id)accessibilityAttributeValue:(NSString *)attribute
122{
123 	if ([attribute isEqual:NSAccessibilityParentAttribute])
124		return [fInfo moveList];
125	else if ([attribute isEqual:NSAccessibilityChildrenAttribute])
126		return [NSArray array];
127	else if ([attribute isEqual:NSAccessibilityWindowAttribute])
128		return [[fInfo moveList] window];
129	else if ([attribute isEqual:NSAccessibilityRoleAttribute])
130		return NSAccessibilityStaticTextRole;
131	else if ([attribute isEqual:NSAccessibilityRoleDescriptionAttribute])
132		return NSAccessibilityRoleDescription(NSAccessibilityStaticTextRole, nil);
133	else if ([attribute isEqual:NSAccessibilityPositionAttribute])
134		return [NSValue valueWithPoint:
135							[self accessibilityFocusRingBounds].origin];
136	else if ([attribute isEqual:NSAccessibilitySizeAttribute])
137		return [NSValue valueWithSize:
138							[self accessibilityFocusRingBounds].size];
139	else if ([attribute isEqual:NSAccessibilityTitleAttribute])
140		return [fInfo describeMove:fMove];
141	else if ([attribute isEqual:NSAccessibilityValueAttribute])
142		return nil;
143	else if ([attribute isEqual:NSAccessibilityDescriptionAttribute])
144		return @"";
145	else if ([attribute isEqual:NSAccessibilityFocusedAttribute])
146		return [NSNumber numberWithBool:
147							 [[NSApp accessibilityFocusedUIElement]
148								 isEqual:self]];
149	else if ([attribute isEqual:NSAccessibilityEnabledAttribute])
150		return [NSNumber numberWithBool:YES];
151	else if ([attribute isEqual:NSAccessibilityTopLevelUIElementAttribute])
152		return [[fInfo moveList] window];
153#if 0
154	else
155		NSLog(@"unknown attr: %@\n", attribute);
156#endif
157
158	return nil;
159}
160
161- (BOOL)accessibilityIsAttributeSettable:(NSString *)attribute
162{
163	if ([attribute isEqual:NSAccessibilityFocusedAttribute])
164		return YES;
165
166	return NO;
167}
168
169- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
170{
171}
172
173@end
174
175@implementation MBCMoveTableView ( Accessibility )
176
177
178- (NSArray *)accessibilityAttributeNames
179{
180	return [NSArray arrayWithObjects:
181            NSAccessibilityRoleAttribute,
182            NSAccessibilityRoleDescriptionAttribute,
183            NSAccessibilityParentAttribute,
184            NSAccessibilityChildrenAttribute,
185            NSAccessibilityContentsAttribute,
186            NSAccessibilityWindowAttribute,
187            NSAccessibilityPositionAttribute,
188            NSAccessibilitySizeAttribute,
189            NSAccessibilityTopLevelUIElementAttribute,
190            NSAccessibilitySelectedChildrenAttribute,
191            NSAccessibilityDescriptionAttribute,
192            nil];
193}
194
195- (NSArray *)accessibilityActionNames
196{
197    return [NSArray array];
198}
199
200- (NSString *)accessibilityRoleAttribute
201{
202    return NSAccessibilityGroupRole;
203}
204
205- (NSArray *)accessibilityChildrenAttribute
206{
207	NSInteger           numMoves    = [self numberOfRows];
208    NSMutableArray *    kids        = [NSMutableArray arrayWithCapacity:numMoves];
209	for (NSInteger move = 0; move++ < numMoves; )
210		[kids addObject: [MBCMoveAccessibilityProxy proxyWithInfo:[self dataSource]
211													 move:move]];
212
213	return kids;
214}
215
216- (NSArray *)accessibilitySelectedChildrenAttribute
217{
218    return [NSArray arrayWithObject:
219            [MBCMoveAccessibilityProxy
220             proxyWithInfo:[self dataSource] move:[self selectedRow]+1]];
221}
222
223- (id)accessibilityAttributeValue:(NSString *)attribute
224{
225	if ([attribute isEqual:NSAccessibilityChildrenAttribute] || [attribute isEqual:NSAccessibilityContentsAttribute]) {
226		return [self accessibilityChildrenAttribute];
227    } else if ([attribute isEqual:NSAccessibilitySelectedChildrenAttribute]) {
228        return [self accessibilitySelectedChildrenAttribute];
229    } else if ([attribute isEqual:NSAccessibilityDescriptionAttribute]) {
230        return NSLocalizedStringFromTable(@"move_table_desc", @"Spoken", @"Moves");
231    } else {
232        return [super accessibilityAttributeValue:attribute];
233    }
234}
235
236- (NSUInteger)accessibilityIndexOfChild:(id)child
237{
238    if ([child isKindOfClass:[MBCMoveAccessibilityProxy class]]) {
239        MBCMoveAccessibilityProxy * moveProxy = (MBCMoveAccessibilityProxy *)child;
240
241        if (moveProxy->fInfo == [self dataSource])
242            return moveProxy->fMove-1;
243        else
244            return NSNotFound;
245    }
246    return [super accessibilityIndexOfChild:child];
247}
248
249- (NSUInteger)accessibilityArrayAttributeCount:(NSString *)attribute
250{
251    if ([attribute isEqual:NSAccessibilityChildrenAttribute])
252        return [self numberOfRows];
253    else
254        return [super accessibilityArrayAttributeCount:attribute];
255}
256
257- (NSArray *)accessibilityArrayAttributeValues:(NSString *)attribute index:(NSUInteger)index maxCount:(NSUInteger)maxCount
258{
259    if ([attribute isEqual:NSAccessibilityChildrenAttribute]) {
260        NSUInteger numKids = [self numberOfRows];
261        NSMutableArray *    kids        = [NSMutableArray arrayWithCapacity:numKids];
262        while (index++ < numKids && maxCount--)
263            [kids addObject: [MBCMoveAccessibilityProxy proxyWithInfo:[self dataSource]
264                                                                 move:index]];
265        return kids;
266    } else {
267        return [super accessibilityArrayAttributeValues:attribute index:index maxCount:maxCount];
268    }
269}
270
271- (BOOL)accessibilityIsIgnored
272{
273	return NO;
274}
275
276- (id)accessibilityHitTest:(NSPoint)point
277{
278    NSInteger   move = [self rowAtPoint:point];
279    id          hit;
280	if (move < 0)
281		hit = self;
282	else
283		hit = [MBCMoveAccessibilityProxy proxyWithInfo:[self dataSource] move:move+1];
284
285	return hit;
286}
287
288- (void)accessibilityPostNotification:(NSString *)notification
289{
290    //
291    // We are a group, groups have children, not rows
292    //
293    if ([notification isEqual:NSAccessibilitySelectedRowsChangedNotification])
294        notification = NSAccessibilitySelectedChildrenChangedNotification;
295    [super accessibilityPostNotification:notification];
296}
297
298@end
299
300// Local Variables:
301// mode:ObjC
302// End:
303