Mercurial > projects > dwt-linux
comparison dwt/accessibility/Accessible.d @ 42:787b5413b0ce
accessibility package
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 11 Jan 2008 05:07:22 +0100 |
parents | |
children | 8cec8f536af3 |
comparison
equal
deleted
inserted
replaced
41:c83c51423d03 | 42:787b5413b0ce |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2000, 2005 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.Accessible; | |
12 | |
13 import dwt.accessibility.AccessibleListener; | |
14 import dwt.accessibility.AccessibleTextListener; | |
15 import dwt.accessibility.AccessibleControlListener; | |
16 import dwt.accessibility.AccessibleControlListener; | |
17 import dwt.accessibility.AccessibleFactory; | |
18 import dwt.accessibility.AccessibleObject; | |
19 import tango.core.Thread; | |
20 import dwt.SWT; | |
21 //import dwt.events.*; | |
22 import dwt.internal.gtk.OS; | |
23 import dwt.widgets.Control; | |
24 import tango.core.Array; | |
25 import dwt.events.DisposeListener; | |
26 import dwt.events.DisposeEvent; | |
27 | |
28 /** | |
29 * Instances of this class provide a bridge between application | |
30 * code and assistive technology clients. Many platforms provide | |
31 * default accessible behavior for most widgets, and this class | |
32 * allows that default behavior to be overridden. Applications | |
33 * can get the default Accessible object for a control by sending | |
34 * it <code>getAccessible</code>, and then add an accessible listener | |
35 * to override simple items like the name and help string, or they | |
36 * can add an accessible control listener to override complex items. | |
37 * As a rule of thumb, an application would only want to use the | |
38 * accessible control listener to implement accessibility for a | |
39 * custom control. | |
40 * | |
41 * @see Control#getAccessible | |
42 * @see AccessibleListener | |
43 * @see AccessibleEvent | |
44 * @see AccessibleControlListener | |
45 * @see AccessibleControlEvent | |
46 * | |
47 * @since 2.0 | |
48 */ | |
49 public class Accessible { | |
50 AccessibleListener[] accessibleListeners; | |
51 AccessibleControlListener[] controlListeners; | |
52 AccessibleTextListener[] textListeners; | |
53 AccessibleObject accessibleObject; | |
54 Control control; | |
55 | |
56 this (Control control) { | |
57 this.control = control; | |
58 AccessibleFactory.registerAccessible (this); | |
59 control.addDisposeListener (new class () DisposeListener { | |
60 public void widgetDisposed (DisposeEvent e) { | |
61 release (); | |
62 } | |
63 }); | |
64 } | |
65 | |
66 /** | |
67 * Adds the listener to the collection of listeners who will | |
68 * be notified when an accessible client asks for certain strings, | |
69 * such as name, description, help, or keyboard shortcut. The | |
70 * listener is notified by sending it one of the messages defined | |
71 * in the <code>AccessibleListener</code> interface. | |
72 * | |
73 * @param listener the listener that should be notified when the receiver | |
74 * is asked for a name, description, help, or keyboard shortcut string | |
75 * | |
76 * @exception IllegalArgumentException <ul> | |
77 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
78 * </ul> | |
79 * @exception SWTException <ul> | |
80 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
81 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
82 * </ul> | |
83 * | |
84 * @see AccessibleListener | |
85 * @see #removeAccessibleListener | |
86 */ | |
87 public void addAccessibleListener (AccessibleListener listener) { | |
88 checkWidget (); | |
89 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
90 accessibleListeners ~= listener; | |
91 } | |
92 | |
93 /** | |
94 * Adds the listener to the collection of listeners who will | |
95 * be notified when an accessible client asks for custom control | |
96 * specific information. The listener is notified by sending it | |
97 * one of the messages defined in the <code>AccessibleControlListener</code> | |
98 * interface. | |
99 * | |
100 * @param listener the listener that should be notified when the receiver | |
101 * is asked for custom control specific information | |
102 * | |
103 * @exception IllegalArgumentException <ul> | |
104 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
105 * </ul> | |
106 * @exception SWTException <ul> | |
107 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
108 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
109 * </ul> | |
110 * | |
111 * @see AccessibleControlListener | |
112 * @see #removeAccessibleControlListener | |
113 */ | |
114 public void addAccessibleControlListener (AccessibleControlListener listener) { | |
115 checkWidget (); | |
116 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
117 controlListeners ~= listener; | |
118 } | |
119 | |
120 /** | |
121 * Adds the listener to the collection of listeners who will | |
122 * be notified when an accessible client asks for custom text control | |
123 * specific information. The listener is notified by sending it | |
124 * one of the messages defined in the <code>AccessibleTextListener</code> | |
125 * interface. | |
126 * | |
127 * @param listener the listener that should be notified when the receiver | |
128 * is asked for custom text control specific information | |
129 * | |
130 * @exception IllegalArgumentException <ul> | |
131 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
132 * </ul> | |
133 * @exception SWTException <ul> | |
134 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
135 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
136 * </ul> | |
137 * | |
138 * @see AccessibleTextListener | |
139 * @see #removeAccessibleTextListener | |
140 * | |
141 * @since 3.0 | |
142 */ | |
143 public void addAccessibleTextListener (AccessibleTextListener listener) { | |
144 checkWidget (); | |
145 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
146 textListeners ~= listener; | |
147 } | |
148 | |
149 /** | |
150 * Returns the control for this Accessible object. | |
151 * | |
152 * @return the receiver's control | |
153 * @since 3.0 | |
154 */ | |
155 public Control getControl() { | |
156 return control; | |
157 } | |
158 | |
159 /* checkWidget was copied from Widget, and rewritten to work in this package */ | |
160 void checkWidget () { | |
161 if (!isValidThread ()) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS); | |
162 if (control.isDisposed ()) SWT.error (SWT.ERROR_WIDGET_DISPOSED); | |
163 } | |
164 | |
165 AccessibleListener[] getAccessibleListeners () { | |
166 if (accessibleListeners.length is 0 ) return null; | |
167 return accessibleListeners.dup; | |
168 } | |
169 | |
170 GtkWidget* getControlHandle () { | |
171 return control.handle; | |
172 } | |
173 | |
174 AccessibleControlListener[] getControlListeners () { | |
175 if (controlListeners.length is 0) return null; | |
176 return controlListeners.dup; | |
177 } | |
178 | |
179 AccessibleTextListener[] getTextListeners () { | |
180 if (textListeners.length is 0) return null; | |
181 return textListeners.dup; | |
182 } | |
183 | |
184 /** | |
185 * Invokes platform specific functionality to allocate a new accessible object. | |
186 * <p> | |
187 * <b>IMPORTANT:</b> This method is <em>not</em> part of the public | |
188 * API for <code>Accessible</code>. It is marked public only so that it | |
189 * can be shared within the packages provided by SWT. It is not | |
190 * available on all platforms, and should never be called from | |
191 * application code. | |
192 * </p> | |
193 * | |
194 * @param control the control to get the accessible object for | |
195 * @return the platform specific accessible object | |
196 */ | |
197 public static Accessible internal_new_Accessible (Control control) { | |
198 return new Accessible (control); | |
199 } | |
200 | |
201 /* isValidThread was copied from Widget, and rewritten to work in this package */ | |
202 bool isValidThread () { | |
203 return control.getDisplay ().getThread () is Thread.getThis (); | |
204 } | |
205 | |
206 void release () { | |
207 AccessibleFactory.unregisterAccessible (/*Accessible.*/this); | |
208 if (accessibleObject !is null) { | |
209 accessibleObject.release (); | |
210 accessibleObject = null; | |
211 } | |
212 accessibleListeners = null; | |
213 controlListeners = null; | |
214 textListeners = null; | |
215 } | |
216 /** | |
217 * Removes the listener from the collection of listeners who will | |
218 * be notified when an accessible client asks for custom control | |
219 * specific information. | |
220 * | |
221 * @param listener the listener that should no longer be notified when the receiver | |
222 * is asked for custom control specific information | |
223 * | |
224 * @exception IllegalArgumentException <ul> | |
225 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
226 * </ul> | |
227 * @exception SWTException <ul> | |
228 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
229 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
230 * </ul> | |
231 * | |
232 * @see AccessibleControlListener | |
233 * @see #addAccessibleControlListener | |
234 */ | |
235 public void removeAccessibleControlListener (AccessibleControlListener listener) { | |
236 checkWidget (); | |
237 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
238 remove( controlListeners, listener, delegate bool(AccessibleControlListener a1, AccessibleControlListener a2 ){ return a1 is a2; }); | |
239 } | |
240 | |
241 /** | |
242 * Removes the listener from the collection of listeners who will | |
243 * be notified when an accessible client asks for certain strings, | |
244 * such as name, description, help, or keyboard shortcut. | |
245 * | |
246 * @param listener the listener that should no longer be notified when the receiver | |
247 * is asked for a name, description, help, or keyboard shortcut string | |
248 * | |
249 * @exception IllegalArgumentException <ul> | |
250 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
251 * </ul> | |
252 * @exception SWTException <ul> | |
253 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
254 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
255 * </ul> | |
256 * | |
257 * @see AccessibleListener | |
258 * @see #addAccessibleListener | |
259 */ | |
260 public void removeAccessibleListener (AccessibleListener listener) { | |
261 checkWidget (); | |
262 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
263 remove( accessibleListeners, listener, delegate bool( AccessibleListener a1, AccessibleListener a2 ){ return a1 is a2; }); | |
264 } | |
265 | |
266 /** | |
267 * Removes the listener from the collection of listeners who will | |
268 * be notified when an accessible client asks for custom text control | |
269 * specific information. | |
270 * | |
271 * @param listener the listener that should no longer be notified when the receiver | |
272 * is asked for custom text control specific information | |
273 * | |
274 * @exception IllegalArgumentException <ul> | |
275 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
276 * </ul> | |
277 * @exception SWTException <ul> | |
278 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
279 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
280 * </ul> | |
281 * | |
282 * @see AccessibleTextListener | |
283 * @see #addAccessibleTextListener | |
284 * | |
285 * @since 3.0 | |
286 */ | |
287 public void removeAccessibleTextListener (AccessibleTextListener listener) { | |
288 checkWidget (); | |
289 if (listener is null) SWT.error (SWT.ERROR_NULL_ARGUMENT); | |
290 remove( textListeners, listener, delegate bool(AccessibleTextListener a1, AccessibleTextListener a2 ){ return a1 is a2; }); | |
291 } | |
292 | |
293 /** | |
294 * Sends a message to accessible clients that the child selection | |
295 * within a custom container control has changed. | |
296 * | |
297 * @exception SWTException <ul> | |
298 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
299 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
300 * </ul> | |
301 * | |
302 * @since 3.0 | |
303 */ | |
304 public void selectionChanged () { | |
305 checkWidget (); | |
306 if (accessibleObject !is null) { | |
307 accessibleObject.selectionChanged (); | |
308 } | |
309 } | |
310 | |
311 /** | |
312 * Sends a message to accessible clients indicating that the focus | |
313 * has changed within a custom control. | |
314 * | |
315 * @param childID an identifier specifying a child of the control | |
316 * | |
317 * @exception SWTException <ul> | |
318 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
319 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
320 * </ul> | |
321 */ | |
322 public void setFocus (int childID) { | |
323 checkWidget (); | |
324 if (accessibleObject !is null) { | |
325 accessibleObject.setFocus (childID); | |
326 } | |
327 } | |
328 | |
329 /** | |
330 * Sends a message to accessible clients that the text | |
331 * caret has moved within a custom control. | |
332 * | |
333 * @param index the new caret index within the control | |
334 * | |
335 * @exception SWTException <ul> | |
336 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
337 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
338 * </ul> | |
339 * | |
340 * @since 3.0 | |
341 */ | |
342 public void textCaretMoved (int index) { | |
343 checkWidget (); | |
344 if (accessibleObject !is null) { | |
345 accessibleObject.textCaretMoved (index); | |
346 } | |
347 } | |
348 | |
349 /** | |
350 * Sends a message to accessible clients that the text | |
351 * within a custom control has changed. | |
352 * | |
353 * @param type the type of change, one of <code>ACC.NOTIFY_TEXT_INSERT</code> | |
354 * or <code>ACC.NOTIFY_TEXT_DELETE</code> | |
355 * @param startIndex the text index within the control where the insertion or deletion begins | |
356 * @param length the non-negative length in characters of the insertion or deletion | |
357 * | |
358 * @exception SWTException <ul> | |
359 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
360 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
361 * </ul> | |
362 * | |
363 * @see ACC#TEXT_INSERT | |
364 * @see ACC#TEXT_DELETE | |
365 * | |
366 * @since 3.0 | |
367 */ | |
368 public void textChanged (int type, int startIndex, int length) { | |
369 checkWidget (); | |
370 if (accessibleObject !is null) { | |
371 accessibleObject.textChanged (type, startIndex, length); | |
372 } | |
373 } | |
374 | |
375 /** | |
376 * Sends a message to accessible clients that the text | |
377 * selection has changed within a custom control. | |
378 * | |
379 * @exception SWTException <ul> | |
380 * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> | |
381 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> | |
382 * </ul> | |
383 * | |
384 * @since 3.0 | |
385 */ | |
386 public void textSelectionChanged () { | |
387 checkWidget (); | |
388 if (accessibleObject !is null) { | |
389 accessibleObject.textSelectionChanged (); | |
390 } | |
391 } | |
392 } |