78
|
1 /*******************************************************************************
|
|
2 * Copyright (c) 2005, 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 * Matt Carter - bug 170668
|
|
11 * Brad Reynolds - bug 170848
|
|
12 * Matthew Hall - bug 180746, bug 207844
|
|
13 * Michael Krauter, bug 180223
|
|
14 *******************************************************************************/
|
|
15 module org.eclipse.jface.databinding.swt.SWTObservables;
|
85
|
16 import org.eclipse.jface.databinding.swt.ISWTObservableValue;
|
78
|
17
|
|
18 import java.lang.all;
|
|
19
|
|
20 import java.util.ArrayList;
|
|
21 import java.util.Iterator;
|
85
|
22 static import java.util.List;
|
78
|
23
|
|
24 import org.eclipse.core.databinding.observable.Realm;
|
|
25 import org.eclipse.core.databinding.observable.list.IObservableList;
|
|
26 import org.eclipse.jface.internal.databinding.internal.swt.LinkObservableValue;
|
|
27 import org.eclipse.jface.internal.databinding.swt.ButtonObservableValue;
|
|
28 import org.eclipse.jface.internal.databinding.swt.CComboObservableList;
|
|
29 import org.eclipse.jface.internal.databinding.swt.CComboObservableValue;
|
|
30 import org.eclipse.jface.internal.databinding.swt.CComboSingleSelectionObservableValue;
|
|
31 import org.eclipse.jface.internal.databinding.swt.CLabelObservableValue;
|
|
32 import org.eclipse.jface.internal.databinding.swt.ComboObservableList;
|
|
33 import org.eclipse.jface.internal.databinding.swt.ComboObservableValue;
|
|
34 import org.eclipse.jface.internal.databinding.swt.ComboSingleSelectionObservableValue;
|
|
35 import org.eclipse.jface.internal.databinding.swt.ControlObservableValue;
|
|
36 import org.eclipse.jface.internal.databinding.swt.DelayedObservableValue;
|
|
37 import org.eclipse.jface.internal.databinding.swt.LabelObservableValue;
|
|
38 import org.eclipse.jface.internal.databinding.swt.ListObservableList;
|
|
39 import org.eclipse.jface.internal.databinding.swt.ListObservableValue;
|
|
40 import org.eclipse.jface.internal.databinding.swt.ListSingleSelectionObservableValue;
|
|
41 import org.eclipse.jface.internal.databinding.swt.SWTProperties;
|
|
42 import org.eclipse.jface.internal.databinding.swt.ScaleObservableValue;
|
|
43 import org.eclipse.jface.internal.databinding.swt.ShellObservableValue;
|
|
44 import org.eclipse.jface.internal.databinding.swt.SpinnerObservableValue;
|
|
45 import org.eclipse.jface.internal.databinding.swt.TableSingleSelectionObservableValue;
|
|
46 import org.eclipse.jface.internal.databinding.swt.TextEditableObservableValue;
|
|
47 import org.eclipse.jface.internal.databinding.swt.TextObservableValue;
|
|
48 import org.eclipse.swt.custom.CCombo;
|
|
49 import org.eclipse.swt.custom.CLabel;
|
|
50 import org.eclipse.swt.widgets.Button;
|
|
51 import org.eclipse.swt.widgets.Combo;
|
|
52 import org.eclipse.swt.widgets.Control;
|
|
53 import org.eclipse.swt.widgets.Display;
|
|
54 import org.eclipse.swt.widgets.Label;
|
|
55 import org.eclipse.swt.widgets.Link;
|
|
56 import org.eclipse.swt.widgets.List;
|
|
57 import org.eclipse.swt.widgets.Scale;
|
|
58 import org.eclipse.swt.widgets.Shell;
|
|
59 import org.eclipse.swt.widgets.Spinner;
|
|
60 import org.eclipse.swt.widgets.Table;
|
|
61 import org.eclipse.swt.widgets.Text;
|
|
62
|
|
63 /**
|
|
64 * A factory for creating observables for SWT widgets
|
|
65 *
|
|
66 * @since 1.1
|
|
67 *
|
|
68 */
|
|
69 public class SWTObservables {
|
|
70
|
85
|
71 private static java.util.List.List realms;
|
|
72 static this(){
|
|
73 realms = new ArrayList();
|
|
74 }
|
78
|
75
|
|
76 /**
|
|
77 * Returns the realm representing the UI thread for the given display.
|
|
78 *
|
|
79 * @param display
|
|
80 * @return the realm representing the UI thread for the given display
|
|
81 */
|
|
82 public static Realm getRealm(Display display) {
|
|
83 synchronized (realms) {
|
|
84 for (Iterator it = realms.iterator(); it.hasNext();) {
|
|
85 DisplayRealm displayRealm = cast(DisplayRealm) it.next();
|
|
86 if (displayRealm.display is display) {
|
|
87 return displayRealm;
|
|
88 }
|
|
89 }
|
|
90 DisplayRealm result = new DisplayRealm(display);
|
|
91 realms.add(result);
|
|
92 return result;
|
|
93 }
|
|
94 }
|
|
95
|
|
96 /**
|
|
97 * Returns an observable which delays notification of value change events
|
|
98 * from <code>observable</code> until <code>delay</code> milliseconds
|
|
99 * have passed since the last change event, or until a FocusOut event is
|
|
100 * received from the underlying widget (whichever happens earlier). This
|
|
101 * class helps to delay validation until the user stops typing. To notify
|
|
102 * about pending changes, the returned observable value will fire a stale
|
|
103 * event when the wrapped observable value fires a change event, but this
|
|
104 * change is being delayed.
|
|
105 *
|
|
106 * @param delay
|
|
107 * @param observable
|
|
108 * @return an observable which delays notification of value change events
|
|
109 * from <code>observable</code> until <code>delay</code>
|
|
110 * milliseconds have passed since the last change event.
|
|
111 *
|
|
112 * @since 1.2
|
|
113 */
|
|
114 public static ISWTObservableValue observeDelayedValue(int delay, ISWTObservableValue observable) {
|
|
115 return new DelayedObservableValue(delay, observable);
|
|
116 }
|
|
117
|
|
118 /**
|
|
119 * @param control
|
|
120 * @return an observable value tracking the enabled state of the given
|
|
121 * control
|
|
122 */
|
|
123 public static ISWTObservableValue observeEnabled(Control control) {
|
|
124 return new ControlObservableValue(control, SWTProperties.ENABLED);
|
|
125 }
|
|
126
|
|
127 /**
|
|
128 * @param control
|
|
129 * @return an observable value tracking the visible state of the given
|
|
130 * control
|
|
131 */
|
|
132 public static ISWTObservableValue observeVisible(Control control) {
|
|
133 return new ControlObservableValue(control, SWTProperties.VISIBLE);
|
|
134 }
|
|
135
|
|
136 /**
|
|
137 * @param control
|
|
138 * @return an observable value tracking the tooltip text of the given
|
|
139 * control
|
|
140 */
|
|
141 public static ISWTObservableValue observeTooltipText(Control control) {
|
|
142 return new ControlObservableValue(control, SWTProperties.TOOLTIP_TEXT);
|
|
143 }
|
|
144
|
|
145 /**
|
|
146 * Returns an observable observing the selection attribute of the provided
|
|
147 * <code>control</code>. The supported types are:
|
|
148 * <ul>
|
|
149 * <li>org.eclipse.swt.widgets.Spinner</li>
|
|
150 * <li>org.eclipse.swt.widgets.Button</li>
|
|
151 * <li>org.eclipse.swt.widgets.Combo</li>
|
|
152 * <li>org.eclipse.swt.custom.CCombo</li>
|
|
153 * <li>org.eclipse.swt.widgets.List</li>
|
|
154 * <li>org.eclipse.swt.widgets.Scale</li>
|
|
155 * </ul>
|
|
156 *
|
|
157 * @param control
|
|
158 * @return observable value
|
|
159 * @throws IllegalArgumentException
|
|
160 * if <code>control</code> type is unsupported
|
|
161 */
|
|
162 public static ISWTObservableValue observeSelection(Control control) {
|
|
163 if (null !is cast(Spinner)control) {
|
|
164 return new SpinnerObservableValue(cast(Spinner) control,
|
|
165 SWTProperties.SELECTION);
|
|
166 } else if (null !is cast(Button)control) {
|
|
167 return new ButtonObservableValue(cast(Button) control);
|
|
168 } else if (null !is cast(Combo)control) {
|
|
169 return new ComboObservableValue(cast(Combo) control,
|
|
170 SWTProperties.SELECTION);
|
|
171 } else if (null !is cast(CCombo)control) {
|
|
172 return new CComboObservableValue(cast(CCombo) control,
|
|
173 SWTProperties.SELECTION);
|
|
174 } else if (null !is cast(List)control) {
|
|
175 return new ListObservableValue(cast(List) control);
|
|
176 } else if (null !is cast(Scale)control) {
|
|
177 return new ScaleObservableValue(cast(Scale) control,
|
|
178 SWTProperties.SELECTION);
|
|
179 }
|
|
180
|
|
181 throw new IllegalArgumentException(
|
85
|
182 "Widget [" ~ Class.fromObject(control).getName() ~ "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
|
78
|
183 }
|
|
184
|
|
185 /**
|
|
186 * Returns an observable observing the minimum attribute of the provided
|
|
187 * <code>control</code>. The supported types are:
|
|
188 * <ul>
|
|
189 * <li>org.eclipse.swt.widgets.Spinner</li>
|
|
190 * <li>org.eclipse.swt.widgets.Scale</li>
|
|
191 * </ul>
|
|
192 *
|
|
193 * @param control
|
|
194 * @return observable value
|
|
195 * @throws IllegalArgumentException
|
|
196 * if <code>control</code> type is unsupported
|
|
197 */
|
|
198 public static ISWTObservableValue observeMin(Control control) {
|
|
199 if (null !is cast(Spinner)control) {
|
|
200 return new SpinnerObservableValue(cast(Spinner) control,
|
|
201 SWTProperties.MIN);
|
|
202 } else if (null !is cast(Scale)control) {
|
|
203 return new ScaleObservableValue(cast(Scale) control, SWTProperties.MIN);
|
|
204 }
|
|
205
|
|
206 throw new IllegalArgumentException(
|
85
|
207 "Widget [" ~ Class.fromObject(control).getName() ~ "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
|
78
|
208 }
|
|
209
|
|
210 /**
|
|
211 * Returns an observable observing the maximum attribute of the provided
|
|
212 * <code>control</code>. The supported types are:
|
|
213 * <ul>
|
|
214 * <li>org.eclipse.swt.widgets.Spinner</li>
|
|
215 * <li>org.eclipse.swt.widgets.Scale</li>
|
|
216 * </ul>
|
|
217 *
|
|
218 * @param control
|
|
219 * @return observable value
|
|
220 * @throws IllegalArgumentException
|
|
221 * if <code>control</code> type is unsupported
|
|
222 */
|
|
223 public static ISWTObservableValue observeMax(Control control) {
|
|
224 if (null !is cast(Spinner)control) {
|
|
225 return new SpinnerObservableValue(cast(Spinner) control,
|
|
226 SWTProperties.MAX);
|
|
227 } else if (null !is cast(Scale)control) {
|
|
228 return new ScaleObservableValue(cast(Scale) control, SWTProperties.MAX);
|
|
229 }
|
|
230
|
|
231 throw new IllegalArgumentException(
|
85
|
232 "Widget [" ~ Class.fromObject(control).getName() ~ "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
|
78
|
233 }
|
|
234
|
|
235 /**
|
|
236 * Returns an observable observing the text attribute of the provided
|
|
237 * <code>control</code>. The supported types are:
|
|
238 * <ul>
|
|
239 * <li>org.eclipse.swt.widgets.Text</li>
|
|
240 * </ul>
|
|
241 *
|
|
242 * <li>org.eclipse.swt.widgets.Label</li>
|
|
243 * @param control
|
|
244 * @param event event type to register for change events
|
|
245 * @return observable value
|
|
246 * @throws IllegalArgumentException
|
|
247 * if <code>control</code> type is unsupported
|
|
248 */
|
|
249 public static ISWTObservableValue observeText(Control control, int event) {
|
|
250 if (null !is cast(Text)control) {
|
|
251 return new TextObservableValue(cast(Text) control, event);
|
|
252 }
|
|
253
|
|
254 throw new IllegalArgumentException(
|
85
|
255 "Widget [" ~ Class.fromObject(control).getName() ~ "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
|
78
|
256 }
|
|
257
|
|
258 /**
|
|
259 * Returns an observable observing the text attribute of the provided
|
|
260 * <code>control</code>. The supported types are:
|
|
261 * <ul>
|
|
262 * <li>org.eclipse.swt.widgets.Label</li>
|
|
263 * <li>org.eclipse.swt.widgets.Link (as of 1.2)</li>
|
|
264 * <li>org.eclipse.swt.custom.Label</li>
|
|
265 * <li>org.eclipse.swt.widgets.Combo</li>
|
|
266 * <li>org.eclipse.swt.custom.CCombo</li>
|
|
267 * <li>org.eclipse.swt.widgets.Shell</li>
|
|
268 * </ul>
|
|
269 *
|
|
270 * @param control
|
|
271 * @return observable value
|
|
272 * @throws IllegalArgumentException
|
|
273 * if <code>control</code> type is unsupported
|
|
274 */
|
|
275 public static ISWTObservableValue observeText(Control control) {
|
|
276 if (null !is cast(Label)control) {
|
|
277 return new LabelObservableValue(cast(Label) control);
|
|
278 } else if (null !is cast(Link)control) {
|
|
279 return new LinkObservableValue(cast(Link) control);
|
|
280 } else if (null !is cast(CLabel)control) {
|
|
281 return new CLabelObservableValue(cast(CLabel) control);
|
|
282 } else if (null !is cast(Combo)control) {
|
|
283 return new ComboObservableValue(cast(Combo) control, SWTProperties.TEXT);
|
|
284 } else if (null !is cast(CCombo)control) {
|
|
285 return new CComboObservableValue(cast(CCombo) control,
|
|
286 SWTProperties.TEXT);
|
|
287 } else if (null !is cast(Shell)control) {
|
|
288 return new ShellObservableValue(cast(Shell) control);
|
|
289 }
|
|
290
|
|
291 throw new IllegalArgumentException(
|
85
|
292 "Widget [" ~ Class.fromObject(control).getName() ~ "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
|
78
|
293 }
|
|
294
|
|
295 /**
|
|
296 * Returns an observable observing the items attribute of the provided
|
|
297 * <code>control</code>. The supported types are:
|
|
298 * <ul>
|
|
299 * <li>org.eclipse.swt.widgets.Combo</li>
|
|
300 * <li>org.eclipse.swt.custom.CCombo</li>
|
|
301 * <li>org.eclipse.swt.widgets.List</li>
|
|
302 * </ul>
|
|
303 *
|
|
304 * @param control
|
|
305 * @return observable list
|
|
306 * @throws IllegalArgumentException
|
|
307 * if <code>control</code> type is unsupported
|
|
308 */
|
|
309 public static IObservableList observeItems(Control control) {
|
|
310 if (null !is cast(Combo)control) {
|
|
311 return new ComboObservableList(cast(Combo) control);
|
|
312 } else if (null !is cast(CCombo)control) {
|
|
313 return new CComboObservableList(cast(CCombo) control);
|
|
314 } else if (null !is cast(List)control) {
|
|
315 return new ListObservableList(cast(List) control);
|
|
316 }
|
|
317
|
|
318 throw new IllegalArgumentException(
|
85
|
319 "Widget [" ~ Class.fromObject(control).getName() ~ "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
|
78
|
320 }
|
|
321
|
|
322 /**
|
|
323 * Returns an observable observing the single selection index attribute of
|
|
324 * the provided <code>control</code>. The supported types are:
|
|
325 * <ul>
|
|
326 * <li>org.eclipse.swt.widgets.Table</li>
|
|
327 * <li>org.eclipse.swt.widgets.Combo</li>
|
|
328 * <li>org.eclipse.swt.custom.CCombo</li>
|
|
329 * <li>org.eclipse.swt.widgets.List</li>
|
|
330 * </ul>
|
|
331 *
|
|
332 * @param control
|
|
333 * @return observable value
|
|
334 * @throws IllegalArgumentException
|
|
335 * if <code>control</code> type is unsupported
|
|
336 */
|
|
337 public static ISWTObservableValue observeSingleSelectionIndex(
|
|
338 Control control) {
|
|
339 if (null !is cast(Table)control) {
|
|
340 return new TableSingleSelectionObservableValue(cast(Table) control);
|
|
341 } else if (null !is cast(Combo)control) {
|
|
342 return new ComboSingleSelectionObservableValue(cast(Combo) control);
|
|
343 } else if (null !is cast(CCombo)control) {
|
|
344 return new CComboSingleSelectionObservableValue(cast(CCombo) control);
|
|
345 } else if (null !is cast(List)control) {
|
|
346 return new ListSingleSelectionObservableValue(cast(List) control);
|
|
347 }
|
|
348
|
|
349 throw new IllegalArgumentException(
|
85
|
350 "Widget [" ~ Class.fromObject(control).getName() ~ "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
|
78
|
351 }
|
|
352
|
|
353 /**
|
|
354 * @param control
|
|
355 * @return an observable value tracking the foreground color of the given
|
|
356 * control
|
|
357 */
|
|
358 public static ISWTObservableValue observeForeground(Control control) {
|
|
359 return new ControlObservableValue(control, SWTProperties.FOREGROUND);
|
|
360 }
|
|
361
|
|
362 /**
|
|
363 * @param control
|
|
364 * @return an observable value tracking the background color of the given
|
|
365 * control
|
|
366 */
|
|
367 public static ISWTObservableValue observeBackground(Control control) {
|
|
368 return new ControlObservableValue(control, SWTProperties.BACKGROUND);
|
|
369 }
|
|
370
|
|
371 /**
|
|
372 * @param control
|
|
373 * @return an observable value tracking the font of the given control
|
|
374 */
|
|
375 public static ISWTObservableValue observeFont(Control control) {
|
|
376 return new ControlObservableValue(control, SWTProperties.FONT);
|
|
377 }
|
|
378
|
|
379 /**
|
|
380 * Returns an observable observing the editable attribute of
|
|
381 * the provided <code>control</code>. The supported types are:
|
|
382 * <ul>
|
|
383 * <li>org.eclipse.swt.widgets.Text</li>
|
|
384 * </ul>
|
|
385 *
|
|
386 * @param control
|
|
387 * @return observable value
|
|
388 * @throws IllegalArgumentException
|
|
389 * if <code>control</code> type is unsupported
|
|
390 */
|
|
391 public static ISWTObservableValue observeEditable(Control control) {
|
|
392 if (null !is cast(Text)control) {
|
|
393 return new TextEditableObservableValue(cast(Text) control);
|
|
394 }
|
|
395
|
|
396 throw new IllegalArgumentException(
|
85
|
397 "Widget [" ~ Class.fromObject(control).getName() ~ "] is not supported."); //$NON-NLS-1$//$NON-NLS-2$
|
78
|
398 }
|
|
399
|
|
400 private static class DisplayRealm : Realm {
|
|
401 private Display display;
|
|
402
|
|
403 /**
|
|
404 * @param display
|
|
405 */
|
|
406 private this(Display display) {
|
|
407 this.display = display;
|
|
408 }
|
|
409
|
|
410 public bool isCurrent() {
|
|
411 return Display.getCurrent() is display;
|
|
412 }
|
|
413
|
|
414 public void asyncExec(Runnable runnable) {
|
|
415 Runnable safeRunnable = dgRunnable((Runnable runnable_) {
|
|
416 safeRun(runnable_);
|
|
417 }, runnable);
|
|
418 if (!display.isDisposed()) {
|
|
419 display.asyncExec(safeRunnable);
|
|
420 }
|
|
421 }
|
|
422
|
|
423 /*
|
|
424 * (non-Javadoc)
|
|
425 *
|
|
426 * @see java.lang.Object#hashCode()
|
|
427 */
|
85
|
428 public override hash_t toHash() {
|
|
429 return (display is null) ? 0 : display.toHash();
|
78
|
430 }
|
|
431
|
|
432 /*
|
|
433 * (non-Javadoc)
|
|
434 *
|
|
435 * @see java.lang.Object#equals(java.lang.Object)
|
|
436 */
|
85
|
437 public override equals_t opEquals(Object obj) {
|
78
|
438 if (this is obj)
|
|
439 return true;
|
|
440 if (obj is null)
|
|
441 return false;
|
85
|
442 if (Class.fromObject(this) !is Class.fromObject(obj))
|
78
|
443 return false;
|
|
444 final DisplayRealm other = cast(DisplayRealm) obj;
|
|
445 if (display is null) {
|
|
446 if (other.display !is null)
|
|
447 return false;
|
85
|
448 } else if (!display.opEquals(other.display))
|
78
|
449 return false;
|
|
450 return true;
|
|
451 }
|
|
452 }
|
|
453 }
|