Re: Custom accessible Cocoa controls
Re: Custom accessible Cocoa controls
- Subject: Re: Custom accessible Cocoa controls
- From: Mike Engber <email@hidden>
- Date: Mon, 14 Apr 2003 09:03:20 -0700
I can't use NSMatrix for this control because of the way it's drawn,
NSMatrix doesn't have the appropriate geometry.
I've seen this control successfully implemented as an NSMatrix. That
approach should be workable if you want to go that route.
I tried implementing the various areas of the control as children,
but ran into the same problems (e.g. what objects do I put in the
children array that's returned from accessibilityAttributeValue?)
You need to return an object that implement the accessibility protocol
(see NSAccessibility.h)
They don't have to be NSViews or NSCells. NSViews and NSCells already
implement the Accessibility Protocol - so that makes returning them
easier, but it's not a requirement and there are many occasions, like
your case, when there is no existing object you can return.
Below is an idea you might find useful. I have successfully used this
approach so I can help with further specifics if needed.
-ME
---
Create a generic accessible object class (this can be re-used in other
controls). The object would have a field to store its role and parent.
It should implement the Accessibility Protocol - parent & role
attributes, empty array of actions, ...
Depending on the situation, subclasses may want to add other fields.
E.g. you might want it to store its bounds. Alternatively, it might be
simpler if it sent a message to its parent to find out its bounds. The
parent has to keep track of this info anyway so it can properly
implement hit testing (i.e. return one of these objects).
I would suggest keeping these objects as lightweight as possible just
create them on the fly as needed (as opposed to trying to cache them).
The approach of asking the parent for bounds and other info can help in
this regard. (I further suggest inventing a protocol for parents to
implement in order to answer these q's - position, size, isFocused,
setFocus, ...)
Note: you will need to override isEqual as appropriate. If you're
running into mysterious problems - go back and make sure isEqual is
doing the right thing with these objects. The base class probably would
want to use something like:
- (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[FakeObjectClass self]]) {
FakeObjectClass *other = object;
return [_role isEqualToString:other->_role] && [_parent
isEqual:other->_parent];
} else {
return NO;
}
}
But, subclasses _will_ have to override isEqual too. E.g. if you return
three button from your control, they will all have the same role and be
considered equal - this is bad. Here's an example where the subclass
objects contain foo's that can be compared with pointer equality.
- (BOOL)isEqual:(id)object {
if ([object isKindOfClass:[FakeObjectClassSubclass self]]) {
FakeObjectClassSubclass *other = object;
return [self foo] == [other foo] && [super isEqual:object];
} else {
return NO;
}
}
This all may sound pretty elaborate, but it's not really too bad and if
you do it a general/re-usable way it will pay off if in the long run
when you have other controls to accessorize.
_______________________________________________
accessibility-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/accessibility-dev
Do not post admin requests to the list. They will be ignored.