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 }