Mercurial > projects > dwt2
comparison org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonModel.d @ 12:bc29606a740c
Added dwt-addons in original directory structure of eclipse.org
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 14 Mar 2009 18:23:29 +0100 |
parents | |
children | dbfb303e8fb0 |
comparison
equal
deleted
inserted
replaced
11:43904fec5dca | 12:bc29606a740c |
---|---|
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 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.draw2d.ButtonModel; | |
14 | |
15 import java.lang.all; | |
16 import org.eclipse.swt.dwthelper.Runnable; | |
17 import org.eclipse.dwtxhelper.Timer; | |
18 import org.eclipse.dwtxhelper.TimerTask; | |
19 static import org.eclipse.swt.widgets.Display; | |
20 | |
21 import org.eclipse.draw2d.ButtonGroup; | |
22 import org.eclipse.draw2d.ActionListener; | |
23 import org.eclipse.draw2d.ChangeListener; | |
24 import org.eclipse.draw2d.ButtonStateTransitionListener; | |
25 import org.eclipse.draw2d.EventListenerList; | |
26 import org.eclipse.draw2d.ActionEvent; | |
27 import org.eclipse.draw2d.ChangeEvent; | |
28 | |
29 | |
30 //import org.eclipse.draw2d.internal.Timer; | |
31 | |
32 /** | |
33 * A model for buttons containing several properties, including enabled, pressed, | |
34 * selected, rollover enabled and mouseover. | |
35 */ | |
36 public class ButtonModel { | |
37 | |
38 /** Enabled property */ | |
39 public static const String ENABLED_PROPERTY = "enabled"; //$NON-NLS-1$ | |
40 /** Pressed property */ | |
41 public static const String PRESSED_PROPERTY = "pressed"; //$NON-NLS-1$ | |
42 /** Selected property */ | |
43 public static const String SELECTED_PROPERTY = "selected"; //$NON-NLS-1$ | |
44 /** Rollover Enabled property */ | |
45 public static const String ROLLOVER_ENABLED_PROPERTY = "rollover enabled"; //$NON-NLS-1$ | |
46 /** Mouseover property */ | |
47 public static const String MOUSEOVER_PROPERTY = "mouseover"; //$NON-NLS-1$ | |
48 | |
49 /** Armed property */ | |
50 public static const String ARMED_PROPERTY = "armed"; //$NON-NLS-1$ | |
51 | |
52 | |
53 /** Flag for armed button state */ | |
54 protected static const int ARMED_FLAG = 1; | |
55 /** Flag for pressed button state */ | |
56 protected static const int PRESSED_FLAG = 2; | |
57 /** Flag for mouseOver state */ | |
58 protected static const int MOUSEOVER_FLAG = 4; | |
59 /** Flag for selected button state */ | |
60 protected static const int SELECTED_FLAG = 8; | |
61 /** Flag for enablement button state */ | |
62 protected static const int ENABLED_FLAG = 16; | |
63 /** Flag for rollover enablement button state */ | |
64 protected static const int ROLLOVER_ENABLED_FLAG = 32; | |
65 /** Flag that can be used by subclasses to define more states */ | |
66 protected static const int MAX_FLAG = ROLLOVER_ENABLED_FLAG; | |
67 | |
68 private int state = ENABLED_FLAG; | |
69 private Object data; | |
70 | |
71 /** | |
72 * Action performed events are not fired until the mouse button is released. | |
73 */ | |
74 public static const int DEFAULT_FIRING_BEHAVIOR = 0; | |
75 | |
76 /** | |
77 * Action performed events fire repeatedly until the mouse button is released. | |
78 */ | |
79 public static const int REPEAT_FIRING_BEHAVIOR = 1; | |
80 | |
81 /** | |
82 * The name of the action associated with this button. | |
83 */ | |
84 protected String actionName; | |
85 | |
86 /** | |
87 * The ButtonGroup this button belongs to (if any). | |
88 */ | |
89 protected ButtonGroup group = null; | |
90 | |
91 private EventListenerList listeners; | |
92 | |
93 /** | |
94 * Listens to button state transitions and fires action performed events based on the | |
95 * desired behavior ({@link #DEFAULT_FIRING_BEHAVIOR} or {@link #REPEAT_FIRING_BEHAVIOR}). | |
96 */ | |
97 protected ButtonStateTransitionListener firingBehavior; | |
98 | |
99 this(){ | |
100 listeners = new EventListenerList(); | |
101 installFiringBehavior(); | |
102 } | |
103 | |
104 /** | |
105 * Registers the given listener as an ActionListener. | |
106 * | |
107 * @param listener The ActionListener to add | |
108 * @since 2.0 | |
109 */ | |
110 public void addActionListener(ActionListener listener) { | |
111 if (listener is null) | |
112 throw new IllegalArgumentException(""); | |
113 listeners.addListener(ActionListener.classinfo, cast(Object)listener); | |
114 } | |
115 | |
116 /** | |
117 * Registers the given listener as a ChangeListener. | |
118 * | |
119 * @param listener The ChangeListener to add | |
120 * @since 2.0 | |
121 */ | |
122 public void addChangeListener(ChangeListener listener) { | |
123 if (listener is null) | |
124 throw new IllegalArgumentException(""); | |
125 listeners.addListener(ChangeListener.classinfo, cast(Object)listener); | |
126 } | |
127 | |
128 /** | |
129 * Registers the given listener as a ButtonStateTransitionListener. | |
130 * | |
131 * @param listener The ButtonStateTransitionListener to add | |
132 * @since 2.0 | |
133 */ | |
134 public void addStateTransitionListener(ButtonStateTransitionListener listener) { | |
135 if (listener is null) | |
136 throw new IllegalArgumentException(""); | |
137 listeners.addListener(ButtonStateTransitionListener.classinfo, cast(Object)listener); | |
138 } | |
139 | |
140 /** | |
141 * Notifies any ActionListeners on this ButtonModel that an action has been performed. | |
142 * | |
143 * @since 2.0 | |
144 */ | |
145 protected void fireActionPerformed() { | |
146 Iterator iter = listeners.getListeners(ActionListener.classinfo); | |
147 ActionEvent action = new ActionEvent(this); | |
148 while (iter.hasNext()) | |
149 (cast(ActionListener)iter.next()). | |
150 actionPerformed(action); | |
151 } | |
152 | |
153 /** | |
154 * Notifies any listening ButtonStateTransitionListener that the pressed state of this | |
155 * button has been cancelled. | |
156 * | |
157 * @since 2.0 | |
158 */ | |
159 protected void fireCanceled() { | |
160 Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); | |
161 while (iter.hasNext()) | |
162 (cast(ButtonStateTransitionListener)iter.next()). | |
163 canceled(); | |
164 } | |
165 | |
166 /** | |
167 * Notifies any listening ButtonStateTransitionListener that this button has been pressed. | |
168 * | |
169 * @since 2.0 | |
170 */ | |
171 protected void firePressed() { | |
172 Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); | |
173 while (iter.hasNext()) | |
174 (cast(ButtonStateTransitionListener)iter.next()). | |
175 pressed(); | |
176 } | |
177 | |
178 /** | |
179 * Notifies any listening ButtonStateTransitionListener that this button has been | |
180 * released. | |
181 * | |
182 * @since 2.0 | |
183 */ | |
184 protected void fireReleased() { | |
185 Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); | |
186 while (iter.hasNext()) | |
187 (cast(ButtonStateTransitionListener)iter.next()). | |
188 released(); | |
189 } | |
190 | |
191 /** | |
192 * Notifies any listening ButtonStateTransitionListeners that this button has resumed | |
193 * activity. | |
194 * | |
195 * @since 2.0 | |
196 */ | |
197 protected void fireResume() { | |
198 Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); | |
199 while (iter.hasNext()) | |
200 (cast(ButtonStateTransitionListener)iter.next()). | |
201 resume(); | |
202 } | |
203 | |
204 /** | |
205 * Notifies any listening ChangeListeners that this button's state has changed. | |
206 * | |
207 * @param property The name of the property that changed | |
208 * @since 2.0 | |
209 */ | |
210 protected void fireStateChanged(String property) { | |
211 Iterator iter = listeners.getListeners(ChangeListener.classinfo); | |
212 ChangeEvent change = new ChangeEvent(this, property); | |
213 while (iter.hasNext()) | |
214 (cast(ChangeListener)iter.next()). | |
215 handleStateChanged(change); | |
216 } | |
217 | |
218 /** | |
219 * Notifies any listening ButtonStateTransitionListeners that this button has suspended | |
220 * activity. | |
221 * | |
222 * @since 2.0 | |
223 */ | |
224 protected void fireSuspend() { | |
225 Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); | |
226 while (iter.hasNext()) | |
227 (cast(ButtonStateTransitionListener)iter.next()). | |
228 suspend(); | |
229 } | |
230 | |
231 bool getFlag(int which) { | |
232 return (state & which) !is 0; | |
233 } | |
234 | |
235 /** | |
236 * Returns the group to which this model belongs. | |
237 * | |
238 * @return The ButtonGroup to which this model belongs | |
239 * @since 2.0 | |
240 */ | |
241 public ButtonGroup getGroup() { | |
242 return group; | |
243 } | |
244 | |
245 /** | |
246 * Returns an object representing user data. | |
247 * | |
248 * @return User data | |
249 * @since 2.0 | |
250 */ | |
251 public Object getUserData() { | |
252 return data; | |
253 } | |
254 | |
255 /** | |
256 * Sets the firing behavior for this button. | |
257 * | |
258 * @since 2.0 | |
259 */ | |
260 protected void installFiringBehavior() { | |
261 setFiringBehavior(DEFAULT_FIRING_BEHAVIOR); | |
262 } | |
263 | |
264 /** | |
265 * Returns <code>true</code> if this button is armed. If a button is armed, it will fire | |
266 * an ActionPerformed when released. | |
267 * | |
268 * @return <code>true</code> if this button is armed | |
269 * @since 2.0 | |
270 */ | |
271 public bool isArmed() { | |
272 return (state & ARMED_FLAG) !is 0; | |
273 } | |
274 | |
275 /** | |
276 * Returns <code>true</code> if this button is enabled. | |
277 * | |
278 * @return <code>true</code> if this button is enabled | |
279 * @since 2.0 | |
280 */ | |
281 public bool isEnabled() { | |
282 return (state & ENABLED_FLAG) !is 0; | |
283 } | |
284 | |
285 /** | |
286 * Returns <code>true</code> if the mouse is over this button. | |
287 * | |
288 * @return <code>true</code> if the mouse is over this button | |
289 * @since 2.0 | |
290 */ | |
291 public bool isMouseOver() { | |
292 return (state & MOUSEOVER_FLAG) !is 0; | |
293 } | |
294 | |
295 /** | |
296 * Returns <code>true</code> if this button is pressed. | |
297 * | |
298 * @return <code>true</code> if this button is pressed | |
299 * @since 2.0 | |
300 */ | |
301 public bool isPressed() { | |
302 return (state & PRESSED_FLAG) !is 0; | |
303 } | |
304 | |
305 /** | |
306 * Returns the selection state of this model. If this model belongs to any group, the | |
307 * group is queried for selection state, else the flags are used. | |
308 * | |
309 * @return <code>true</code> if this button is selected | |
310 * @since 2.0 | |
311 */ | |
312 public bool isSelected() { | |
313 if (group is null) { | |
314 return (state & SELECTED_FLAG) !is 0; | |
315 } else { | |
316 return group.isSelected(this); | |
317 } | |
318 } | |
319 | |
320 /** | |
321 * Removes the given ActionListener. | |
322 * | |
323 * @param listener The ActionListener to remove | |
324 * @since 2.0 | |
325 */ | |
326 public void removeActionListener(ActionListener listener) { | |
327 listeners.removeListener(ActionListener.classinfo, cast(Object)listener); | |
328 } | |
329 | |
330 /** | |
331 * Removes the given ChangeListener. | |
332 * | |
333 * @param listener The ChangeListener to remove | |
334 * @since 2.0 | |
335 */ | |
336 public void removeChangeListener(ChangeListener listener) { | |
337 listeners.removeListener(ChangeListener.classinfo, cast(Object)listener); | |
338 } | |
339 | |
340 /** | |
341 * Removes the given ButtonStateTransitionListener. | |
342 * | |
343 * @param listener The ButtonStateTransitionListener to remove | |
344 * @since 2.0 | |
345 */ | |
346 public void removeStateTransitionListener(ButtonStateTransitionListener listener) { | |
347 listeners.removeListener(ButtonStateTransitionListener.classinfo, cast(Object)listener); | |
348 } | |
349 | |
350 /** | |
351 * Sets this button to be armed. If a button is armed, it will fire an ActionPerformed | |
352 * when released. | |
353 * | |
354 *@param value The armed state | |
355 * @since 2.0 | |
356 */ | |
357 public void setArmed(bool value) { | |
358 if (isArmed() is value) | |
359 return; | |
360 if (!isEnabled()) | |
361 return; | |
362 setFlag(ARMED_FLAG, value); | |
363 fireStateChanged(ARMED_PROPERTY); | |
364 } | |
365 | |
366 /** | |
367 * Sets this button to be enabled. | |
368 * | |
369 * @param value The enabled state | |
370 * @since 2.0 | |
371 */ | |
372 public void setEnabled(bool value) { | |
373 if (isEnabled() is value) | |
374 return; | |
375 if (!value) { | |
376 setMouseOver(false); | |
377 setArmed(false); | |
378 setPressed(false); | |
379 } | |
380 setFlag(ENABLED_FLAG, value); | |
381 fireStateChanged(ENABLED_PROPERTY); | |
382 } | |
383 | |
384 /** | |
385 * Sets the firing behavior for this button. {@link #DEFAULT_FIRING_BEHAVIOR} is the | |
386 * default behavior, where action performed events are not fired until the mouse button is | |
387 * released. {@link #REPEAT_FIRING_BEHAVIOR} causes action performed events to fire | |
388 * repeatedly until the mouse button is released. | |
389 * | |
390 * @param type The firing behavior type | |
391 * @since 2.0 | |
392 * | |
393 */ | |
394 public void setFiringBehavior(int type) { | |
395 if (firingBehavior !is null) | |
396 removeStateTransitionListener(firingBehavior); | |
397 switch (type) { | |
398 case REPEAT_FIRING_BEHAVIOR: | |
399 firingBehavior = new RepeatFiringBehavior(); | |
400 break; | |
401 default: | |
402 firingBehavior = new DefaultFiringBehavior(); | |
403 } | |
404 addStateTransitionListener(firingBehavior); | |
405 } | |
406 | |
407 void setFlag(int flag, bool value) { | |
408 if (value) | |
409 state |= flag; | |
410 else | |
411 state &= ~flag; | |
412 } | |
413 | |
414 /** | |
415 * Sets the ButtonGroup to which this model belongs to. Adds this model as a listener to | |
416 * the group. | |
417 * | |
418 * @param bg The group to which this model belongs. | |
419 * @since 2.0 | |
420 */ | |
421 public void setGroup(ButtonGroup bg) { | |
422 if (group is bg) | |
423 return; | |
424 if (group !is null) | |
425 group.remove(this); | |
426 group = bg; | |
427 if (group !is null) | |
428 group.add(this); | |
429 } | |
430 | |
431 /** | |
432 * Sets the mouseover property of this button. | |
433 * | |
434 * @param value The value the mouseover property will be set to | |
435 * @since 2.0 | |
436 */ | |
437 public void setMouseOver(bool value) { | |
438 if (isMouseOver() is value) | |
439 return; | |
440 if (isPressed()) | |
441 if (value) | |
442 fireResume(); | |
443 else | |
444 fireSuspend(); | |
445 setFlag(MOUSEOVER_FLAG, value); | |
446 fireStateChanged(MOUSEOVER_PROPERTY); | |
447 } | |
448 | |
449 /** | |
450 * Sets the pressed property of this button. | |
451 * | |
452 * @param value The value the pressed property will be set to | |
453 * @since 2.0 | |
454 */ | |
455 public void setPressed(bool value) { | |
456 if (isPressed() is value) | |
457 return; | |
458 setFlag(PRESSED_FLAG, value); | |
459 if (value) | |
460 firePressed(); | |
461 else { | |
462 if (isArmed()) | |
463 fireReleased(); | |
464 else | |
465 fireCanceled(); | |
466 } | |
467 fireStateChanged(PRESSED_PROPERTY); | |
468 } | |
469 | |
470 /** | |
471 * Sets this button to be selected. | |
472 * | |
473 * @param value The value the selected property will be set to | |
474 * @since 2.0 | |
475 */ | |
476 public void setSelected(bool value) { | |
477 if (group is null) { | |
478 if (isSelected() is value) | |
479 return; | |
480 } else { | |
481 group.setSelected(this, value); | |
482 if (getFlag(SELECTED_FLAG) is isSelected()) | |
483 return; | |
484 } | |
485 setFlag(SELECTED_FLAG, value); | |
486 fireStateChanged(SELECTED_PROPERTY); | |
487 } | |
488 | |
489 /** | |
490 * Sets user data. | |
491 * | |
492 * @param data The user data | |
493 * @since 2.0 | |
494 */ | |
495 public void setUserData(Object data) { | |
496 this.data = data; | |
497 } | |
498 | |
499 class DefaultFiringBehavior | |
500 : ButtonStateTransitionListener | |
501 { | |
502 public void released() { | |
503 fireActionPerformed(); | |
504 } | |
505 } | |
506 | |
507 class RepeatFiringBehavior | |
508 : ButtonStateTransitionListener | |
509 { | |
510 protected static const int | |
511 INITIAL_DELAY = 250, | |
512 STEP_DELAY = 40; | |
513 | |
514 protected int | |
515 stepDelay = INITIAL_DELAY, | |
516 initialDelay = STEP_DELAY; | |
517 | |
518 protected Timer timer; | |
519 | |
520 public void pressed() { | |
521 fireActionPerformed(); | |
522 if (!isEnabled()) | |
523 return; | |
524 | |
525 timer = new Timer(); | |
526 TimerTask runAction = new Task(timer); | |
527 | |
528 timer.scheduleAtFixedRate(runAction, INITIAL_DELAY, STEP_DELAY); | |
529 } | |
530 | |
531 public void canceled() { | |
532 suspend(); | |
533 } | |
534 public void released() { | |
535 suspend(); | |
536 } | |
537 | |
538 public void resume() { | |
539 timer = new Timer(); | |
540 | |
541 TimerTask runAction = new Task(timer); | |
542 | |
543 timer.scheduleAtFixedRate(runAction, STEP_DELAY, STEP_DELAY); | |
544 } | |
545 | |
546 public void suspend() { | |
547 if (timer is null) return; | |
548 timer.cancel(); | |
549 timer = null; | |
550 } | |
551 } | |
552 | |
553 class Task | |
554 : TimerTask { | |
555 | |
556 private Timer timer; | |
557 | |
558 public this(Timer timer) { | |
559 this.timer = timer; | |
560 } | |
561 | |
562 public void run() { | |
563 org.eclipse.swt.widgets.Display.Display.getDefault().syncExec(dgRunnable( { | |
564 if (!isEnabled()) | |
565 timer.cancel(); | |
566 fireActionPerformed(); | |
567 })); | |
568 } | |
569 } | |
570 | |
571 } |