comparison dwt/accessibility/SWTAccessibleDelegate.d @ 45:d8635bb48c7c

Merge with SWT 3.5
author Jacob Carlborg <doob@me.com>
date Mon, 01 Dec 2008 17:07:00 +0100
parents
children cfa563df4fdd
comparison
equal deleted inserted replaced
44:ca5e494f2bbf 45:d8635bb48c7c
1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 module dwt.accessibility.SWTAccessibleDelegate;
12
13 import dwt.dwthelper.utils;
14
15
16 import dwt.DWT;
17 import dwt.internal.C;
18 import dwt.internal.Callback;
19 import dwt.internal.cocoa.NSArray;
20 import dwt.internal.cocoa.NSObject;
21 import dwt.internal.cocoa.NSPoint;
22 import dwt.internal.cocoa.NSString;
23 import dwt.internal.cocoa.OS;
24 import dwt.internal.cocoa.id;
25
26 class SWTAccessibleDelegate extends NSObject {
27
28 /**
29 * Accessible Key: The string constant for looking up the accessible
30 * for a control using <code>getData(String)</code>. When an accessible
31 * is created for a control, it is stored as a property in the control
32 * using <code>setData(String, Object)</code>.
33 */
34 static final String ACCESSIBLE_KEY = "Accessible"; //$NON-NLS-1$
35 static final String DWT_OBJECT = "DWT_OBJECT";
36
37 static Callback accessible2Args, accessible3Args, accessible4Args;
38 static int /*long*/ proc2Args, proc3Args, proc4Args;
39
40 Accessible accessibleParent;
41 int /*long*/ delegateJniRef;
42 int childID;
43
44 NSArray attributeNames = null;
45 NSArray parameterizedAttributeNames = null;
46 NSArray actionNames = null;
47
48 static {
49 Class clazz = SWTAccessibleDelegate.class;
50
51 accessible2Args = new Callback(clazz, "accessibleProc", 2);
52 proc2Args = accessible2Args.getAddress();
53 if (proc2Args is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
54
55 accessible3Args = new Callback(clazz, "accessibleProc", 3);
56 proc3Args = accessible3Args.getAddress();
57 if (proc3Args is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
58
59 accessible4Args = new Callback(clazz, "accessibleProc", 4);
60 proc4Args = accessible3Args.getAddress();
61 if (proc4Args is 0) DWT.error (DWT.ERROR_NO_MORE_CALLBACKS);
62
63 // Accessible custom controls need to implement the NSAccessibility protocol. To do that,
64 // we dynamically add the methods to the control's class that are required
65 // by NSAccessibility. Then, when external assistive technology services are used,
66 // those methods get called to provide the needed information.
67
68 String className = "SWTAccessibleDelegate";
69
70 // TODO: These should either move out of Display or be accessible to this class.
71 String types = "*";
72 int size = C.PTR_SIZEOF, align = C.PTR_SIZEOF is 4 ? 2 : 3;
73
74 int /*long*/ cls = OS.objc_allocateClassPair(OS.class_NSObject, className, 0);
75 OS.class_addIvar(cls, DWT_OBJECT, size, (byte)align, types);
76
77 // Add the NSAccessibility overrides
78 OS.class_addMethod(cls, OS.sel_accessibilityActionNames, proc2Args, "@:");
79 OS.class_addMethod(cls, OS.sel_accessibilityAttributeNames, proc2Args, "@:");
80 OS.class_addMethod(cls, OS.sel_accessibilityParameterizedAttributeNames, proc2Args, "@:");
81 OS.class_addMethod(cls, OS.sel_accessibilityIsIgnored, proc2Args, "@:");
82 OS.class_addMethod(cls, OS.sel_accessibilityFocusedUIElement, proc2Args, "@:");
83
84 OS.class_addMethod(cls, OS.sel_accessibilityAttributeValue_, proc3Args, "@:@");
85 OS.class_addMethod(cls, OS.sel_accessibilityHitTest_, proc3Args, "@:{NSPoint}");
86 OS.class_addMethod(cls, OS.sel_accessibilityIsAttributeSettable_, proc3Args, "@:@");
87 OS.class_addMethod(cls, OS.sel_accessibilityActionDescription_, proc3Args, "@:@");
88 OS.class_addMethod(cls, OS.sel_accessibilityPerformAction_, proc3Args, "@:@");
89
90 OS.class_addMethod(cls, OS.sel_accessibilityAttributeValue_forParameter_, proc4Args, "@:@@");
91 OS.class_addMethod(cls, OS.sel_accessibilitySetValue_forAttribute_, proc4Args, "@:@@");
92
93 OS.objc_registerClassPair(cls);
94 }
95
96
97 public SWTAccessibleDelegate(Accessible accessible, int childID) {
98 super(0);
99 this.accessibleParent = accessible;
100 this.childID = childID;
101 alloc().init();
102 delegateJniRef = OS.NewGlobalRef(this);
103 if (delegateJniRef is 0) DWT.error(DWT.ERROR_NO_HANDLES);
104 OS.object_setInstanceVariable(this.id, DWT_OBJECT, delegateJniRef);
105 }
106
107 NSArray accessibilityActionNames() {
108
109 if (actionNames !is null)
110 return retainedAutoreleased(actionNames);
111
112 actionNames = accessibleParent.internal_accessibilityActionNames(childID);
113 actionNames.retain();
114 return retainedAutoreleased(actionNames);
115 }
116
117 NSArray accessibilityAttributeNames() {
118
119 if (attributeNames !is null)
120 return retainedAutoreleased(attributeNames);
121
122 attributeNames = accessibleParent.internal_accessibilityAttributeNames(childID);
123 attributeNames.retain();
124 return retainedAutoreleased(attributeNames);
125 }
126
127 id accessibilityAttributeValue(NSString attribute) {
128 return accessibleParent.internal_accessibilityAttributeValue(attribute, childID);
129 }
130
131 // parameterized attribute methods
132 NSArray accessibilityParameterizedAttributeNames() {
133
134 if (parameterizedAttributeNames !is null)
135 return retainedAutoreleased(parameterizedAttributeNames);
136
137 parameterizedAttributeNames = accessibleParent.internal_accessibilityParameterizedAttributeNames(childID);
138 parameterizedAttributeNames.retain();
139 return retainedAutoreleased(parameterizedAttributeNames);
140 }
141
142 id accessibilityAttributeValue_forParameter(NSString attribute, id parameter) {
143 return accessibleParent.internal_accessibilityAttributeValue_forParameter(attribute, parameter, childID);
144 }
145
146 // Return YES if the UIElement doesn't show up to the outside world - i.e. its parent should return the UIElement's children as its own - cutting the UIElement out. E.g. NSControls are ignored when they are single-celled.
147 bool accessibilityIsIgnored() {
148 return accessibleParent.internal_accessibilityIsIgnored(childID);
149 }
150
151 bool accessibilityIsAttributeSettable(NSString attribute) {
152 return accessibleParent.internal_accessibilityIsAttributeSettable(attribute, childID);
153 }
154
155 // Returns the deepest descendant of the UIElement hierarchy that contains the point. You can assume the point has already been determined to lie within the receiver. Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix would test its cells. The point is bottom-left relative screen coordinates.
156 id accessibilityHitTest(NSPoint point) {
157 return accessibleParent.internal_accessibilityHitTest(point, childID);
158 }
159
160 // Returns the UI Element that has the focus. You can assume that the search for the focus has already been narrowed down to the reciever. Override this method to do a deeper search with a UIElement - e.g. a NSMatrix would determine if one of its cells has the focus.
161 id accessibilityFocusedUIElement() {
162 return accessibleParent.internal_accessibilityFocusedUIElement(childID);
163 }
164
165 void accessibilityPerformAction(NSString action) {
166 accessibleParent.internal_accessibilityPerformAction(action, childID);
167 }
168
169 id accessibilityActionDescription(NSString action) {
170 return accessibleParent.internal_accessibilityActionDescription(action, childID);
171 }
172
173
174 void accessibilitySetValue_forAttribute(id value, NSString attribute) {
175 // This shouldn't be called!
176 System.out.println("Ignoring attribute: " + attribute.getString());
177 }
178
179 static NSArray retainedAutoreleased(NSArray inObject) {
180 id temp = inObject.retain();
181 id temp2 = new NSObject(temp.id).autorelease();
182 return new NSArray(temp2.id);
183 }
184
185 static int /*long*/ accessibleProc(int /*long*/ id, int /*long*/ sel) {
186 SWTAccessibleDelegate swtAcc = getAccessibleDelegate(id);
187 if (swtAcc is null) return 0;
188
189 if (sel is OS.sel_accessibilityAttributeNames) {
190 NSArray retObject = swtAcc.accessibilityAttributeNames();
191 return (retObject is null ? 0 : retObject.id);
192 } else if (sel is OS.sel_accessibilityActionNames) {
193 NSArray retObject = swtAcc.accessibilityActionNames();
194 return (retObject is null ? 0 : retObject.id);
195 } else if (sel is OS.sel_accessibilityParameterizedAttributeNames) {
196 NSArray retObject = swtAcc.accessibilityParameterizedAttributeNames();
197 return (retObject is null ? 0 : retObject.id);
198 } else if (sel is OS.sel_accessibilityIsIgnored) {
199 bool retVal = swtAcc.accessibilityIsIgnored();
200 return (retVal ? 1 : 0);
201 } else if (sel is OS.sel_accessibilityFocusedUIElement) {
202 id retObject = swtAcc.accessibilityFocusedUIElement();
203 return (retObject is null ? 0 : retObject.id);
204 }
205
206 return 0;
207 }
208
209 static int /*long*/ accessibleProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0) {
210 SWTAccessibleDelegate swtAcc = getAccessibleDelegate(id);
211 if (swtAcc is null) return 0;
212
213 if (sel is OS.sel_accessibilityAttributeValue_) {
214 NSString attribute = new NSString(arg0);
215 id retObject = swtAcc.accessibilityAttributeValue(attribute);
216 return (retObject is null ? 0 : retObject.id);
217 } else if (sel is OS.sel_accessibilityHitTest_) {
218 NSPoint point= new NSPoint();
219 OS.memmove(point, arg0, NSPoint.sizeof);
220 id retObject = swtAcc.accessibilityHitTest(point);
221 return (retObject is null ? 0 : retObject.id);
222 } else if (sel is OS.sel_accessibilityIsAttributeSettable_) {
223 NSString attribute = new NSString(arg0);
224 return (swtAcc.accessibilityIsAttributeSettable(attribute) ? 1 : 0);
225 } else if (sel is OS.sel_accessibilityActionDescription_) {
226 NSString action = new NSString(arg0);
227 id retObject = swtAcc.accessibilityActionDescription(action);
228 return (retObject is null ? 0 : retObject.id);
229 } else if (sel is OS.sel_accessibilityPerformAction_) {
230 NSString action = new NSString(arg0);
231 swtAcc.accessibilityPerformAction(action);
232 }
233
234 return 0;
235 }
236
237 static int /*long*/ accessibleProc(int /*long*/ id, int /*long*/ sel, int /*long*/ arg0, int /*long*/ arg1) {
238 SWTAccessibleDelegate swtAcc = getAccessibleDelegate(id);
239 if (swtAcc is null) return 0;
240
241 if (sel is OS.sel_accessibilityAttributeValue_forParameter_) {
242 NSString attribute = new NSString(arg0);
243 id parameter = new id(arg1);
244 id retObject = swtAcc.accessibilityAttributeValue_forParameter(attribute, parameter);
245 return (retObject is null ? 0 : retObject.id);
246 } else if (sel is OS.sel_accessibilitySetValue_forAttribute_) {
247 id value = new id(arg0);
248 NSString attribute = new NSString(arg1);
249 swtAcc.accessibilitySetValue_forAttribute(value, attribute);
250 }
251
252 return 0;
253 }
254
255 static SWTAccessibleDelegate getAccessibleDelegate(int /*long*/ id) {
256 if (id is 0) return null;
257 int /*long*/ [] jniRef = new int /*long*/ [1];
258 OS.object_getInstanceVariable(id, DWT_OBJECT, jniRef);
259 if (jniRef[0] is 0) return null;
260 return (SWTAccessibleDelegate)OS.JNIGetObject(jniRef[0]);
261 }
262
263 public void internal_dispose_SWTAccessibleDelegate() {
264 if (actionNames !is null) actionNames.release();
265 actionNames = null;
266 if (attributeNames !is null) attributeNames.release();
267 attributeNames = null;
268 if (parameterizedAttributeNames !is null) parameterizedAttributeNames.release();
269 parameterizedAttributeNames = null;
270 }
271
272 }