Mercurial > projects > dwt2
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org.eclipse.draw2d/src/org/eclipse/draw2d/ButtonModel.d Sat Mar 14 18:23:29 2009 +0100 @@ -0,0 +1,571 @@ +/******************************************************************************* + * Copyright (c) 2000, 2005 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + * Port to the D programming language: + * Frank Benoit <benoit@tionex.de> + *******************************************************************************/ +module org.eclipse.draw2d.ButtonModel; + +import java.lang.all; +import org.eclipse.swt.dwthelper.Runnable; +import org.eclipse.dwtxhelper.Timer; +import org.eclipse.dwtxhelper.TimerTask; +static import org.eclipse.swt.widgets.Display; + +import org.eclipse.draw2d.ButtonGroup; +import org.eclipse.draw2d.ActionListener; +import org.eclipse.draw2d.ChangeListener; +import org.eclipse.draw2d.ButtonStateTransitionListener; +import org.eclipse.draw2d.EventListenerList; +import org.eclipse.draw2d.ActionEvent; +import org.eclipse.draw2d.ChangeEvent; + + +//import org.eclipse.draw2d.internal.Timer; + +/** + * A model for buttons containing several properties, including enabled, pressed, + * selected, rollover enabled and mouseover. + */ +public class ButtonModel { + +/** Enabled property */ +public static const String ENABLED_PROPERTY = "enabled"; //$NON-NLS-1$ +/** Pressed property */ +public static const String PRESSED_PROPERTY = "pressed"; //$NON-NLS-1$ +/** Selected property */ +public static const String SELECTED_PROPERTY = "selected"; //$NON-NLS-1$ +/** Rollover Enabled property */ +public static const String ROLLOVER_ENABLED_PROPERTY = "rollover enabled"; //$NON-NLS-1$ +/** Mouseover property */ +public static const String MOUSEOVER_PROPERTY = "mouseover"; //$NON-NLS-1$ + +/** Armed property */ +public static const String ARMED_PROPERTY = "armed"; //$NON-NLS-1$ + + +/** Flag for armed button state */ +protected static const int ARMED_FLAG = 1; +/** Flag for pressed button state */ +protected static const int PRESSED_FLAG = 2; +/** Flag for mouseOver state */ +protected static const int MOUSEOVER_FLAG = 4; +/** Flag for selected button state */ +protected static const int SELECTED_FLAG = 8; +/** Flag for enablement button state */ +protected static const int ENABLED_FLAG = 16; +/** Flag for rollover enablement button state */ +protected static const int ROLLOVER_ENABLED_FLAG = 32; +/** Flag that can be used by subclasses to define more states */ +protected static const int MAX_FLAG = ROLLOVER_ENABLED_FLAG; + +private int state = ENABLED_FLAG; +private Object data; + +/** + * Action performed events are not fired until the mouse button is released. + */ +public static const int DEFAULT_FIRING_BEHAVIOR = 0; + +/** + * Action performed events fire repeatedly until the mouse button is released. + */ +public static const int REPEAT_FIRING_BEHAVIOR = 1; + +/** + * The name of the action associated with this button. + */ +protected String actionName; + +/** + * The ButtonGroup this button belongs to (if any). + */ +protected ButtonGroup group = null; + +private EventListenerList listeners; + +/** + * Listens to button state transitions and fires action performed events based on the + * desired behavior ({@link #DEFAULT_FIRING_BEHAVIOR} or {@link #REPEAT_FIRING_BEHAVIOR}). + */ +protected ButtonStateTransitionListener firingBehavior; + +this(){ + listeners = new EventListenerList(); + installFiringBehavior(); +} + +/** + * Registers the given listener as an ActionListener. + * + * @param listener The ActionListener to add + * @since 2.0 + */ +public void addActionListener(ActionListener listener) { + if (listener is null) + throw new IllegalArgumentException(""); + listeners.addListener(ActionListener.classinfo, cast(Object)listener); +} + +/** + * Registers the given listener as a ChangeListener. + * + * @param listener The ChangeListener to add + * @since 2.0 + */ +public void addChangeListener(ChangeListener listener) { + if (listener is null) + throw new IllegalArgumentException(""); + listeners.addListener(ChangeListener.classinfo, cast(Object)listener); +} + +/** + * Registers the given listener as a ButtonStateTransitionListener. + * + * @param listener The ButtonStateTransitionListener to add + * @since 2.0 + */ +public void addStateTransitionListener(ButtonStateTransitionListener listener) { + if (listener is null) + throw new IllegalArgumentException(""); + listeners.addListener(ButtonStateTransitionListener.classinfo, cast(Object)listener); +} + +/** + * Notifies any ActionListeners on this ButtonModel that an action has been performed. + * + * @since 2.0 + */ +protected void fireActionPerformed() { + Iterator iter = listeners.getListeners(ActionListener.classinfo); + ActionEvent action = new ActionEvent(this); + while (iter.hasNext()) + (cast(ActionListener)iter.next()). + actionPerformed(action); +} + +/** + * Notifies any listening ButtonStateTransitionListener that the pressed state of this + * button has been cancelled. + * + * @since 2.0 + */ +protected void fireCanceled() { + Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); + while (iter.hasNext()) + (cast(ButtonStateTransitionListener)iter.next()). + canceled(); +} + +/** + * Notifies any listening ButtonStateTransitionListener that this button has been pressed. + * + * @since 2.0 + */ +protected void firePressed() { + Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); + while (iter.hasNext()) + (cast(ButtonStateTransitionListener)iter.next()). + pressed(); +} + +/** + * Notifies any listening ButtonStateTransitionListener that this button has been + * released. + * + * @since 2.0 + */ +protected void fireReleased() { + Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); + while (iter.hasNext()) + (cast(ButtonStateTransitionListener)iter.next()). + released(); +} + +/** + * Notifies any listening ButtonStateTransitionListeners that this button has resumed + * activity. + * + * @since 2.0 + */ +protected void fireResume() { + Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); + while (iter.hasNext()) + (cast(ButtonStateTransitionListener)iter.next()). + resume(); +} + +/** + * Notifies any listening ChangeListeners that this button's state has changed. + * + * @param property The name of the property that changed + * @since 2.0 + */ +protected void fireStateChanged(String property) { + Iterator iter = listeners.getListeners(ChangeListener.classinfo); + ChangeEvent change = new ChangeEvent(this, property); + while (iter.hasNext()) + (cast(ChangeListener)iter.next()). + handleStateChanged(change); +} + +/** + * Notifies any listening ButtonStateTransitionListeners that this button has suspended + * activity. + * + * @since 2.0 + */ +protected void fireSuspend() { + Iterator iter = listeners.getListeners(ButtonStateTransitionListener.classinfo); + while (iter.hasNext()) + (cast(ButtonStateTransitionListener)iter.next()). + suspend(); +} + +bool getFlag(int which) { + return (state & which) !is 0; +} + +/** + * Returns the group to which this model belongs. + * + * @return The ButtonGroup to which this model belongs + * @since 2.0 + */ +public ButtonGroup getGroup() { + return group; +} + +/** + * Returns an object representing user data. + * + * @return User data + * @since 2.0 + */ +public Object getUserData() { + return data; +} + +/** + * Sets the firing behavior for this button. + * + * @since 2.0 + */ +protected void installFiringBehavior() { + setFiringBehavior(DEFAULT_FIRING_BEHAVIOR); +} + +/** + * Returns <code>true</code> if this button is armed. If a button is armed, it will fire + * an ActionPerformed when released. + * + * @return <code>true</code> if this button is armed + * @since 2.0 + */ +public bool isArmed() { + return (state & ARMED_FLAG) !is 0; +} + +/** + * Returns <code>true</code> if this button is enabled. + * + * @return <code>true</code> if this button is enabled + * @since 2.0 + */ +public bool isEnabled() { + return (state & ENABLED_FLAG) !is 0; +} + +/** + * Returns <code>true</code> if the mouse is over this button. + * + * @return <code>true</code> if the mouse is over this button + * @since 2.0 + */ +public bool isMouseOver() { + return (state & MOUSEOVER_FLAG) !is 0; +} + +/** + * Returns <code>true</code> if this button is pressed. + * + * @return <code>true</code> if this button is pressed + * @since 2.0 + */ +public bool isPressed() { + return (state & PRESSED_FLAG) !is 0; +} + +/** + * Returns the selection state of this model. If this model belongs to any group, the + * group is queried for selection state, else the flags are used. + * + * @return <code>true</code> if this button is selected + * @since 2.0 + */ +public bool isSelected() { + if (group is null) { + return (state & SELECTED_FLAG) !is 0; + } else { + return group.isSelected(this); + } +} + +/** + * Removes the given ActionListener. + * + * @param listener The ActionListener to remove + * @since 2.0 + */ +public void removeActionListener(ActionListener listener) { + listeners.removeListener(ActionListener.classinfo, cast(Object)listener); +} + +/** + * Removes the given ChangeListener. + * + * @param listener The ChangeListener to remove + * @since 2.0 + */ +public void removeChangeListener(ChangeListener listener) { + listeners.removeListener(ChangeListener.classinfo, cast(Object)listener); +} + +/** + * Removes the given ButtonStateTransitionListener. + * + * @param listener The ButtonStateTransitionListener to remove + * @since 2.0 + */ +public void removeStateTransitionListener(ButtonStateTransitionListener listener) { + listeners.removeListener(ButtonStateTransitionListener.classinfo, cast(Object)listener); +} + +/** + * Sets this button to be armed. If a button is armed, it will fire an ActionPerformed + * when released. + * + *@param value The armed state + * @since 2.0 + */ +public void setArmed(bool value) { + if (isArmed() is value) + return; + if (!isEnabled()) + return; + setFlag(ARMED_FLAG, value); + fireStateChanged(ARMED_PROPERTY); +} + +/** + * Sets this button to be enabled. + * + * @param value The enabled state + * @since 2.0 + */ +public void setEnabled(bool value) { + if (isEnabled() is value) + return; + if (!value) { + setMouseOver(false); + setArmed(false); + setPressed(false); + } + setFlag(ENABLED_FLAG, value); + fireStateChanged(ENABLED_PROPERTY); +} + +/** + * Sets the firing behavior for this button. {@link #DEFAULT_FIRING_BEHAVIOR} is the + * default behavior, where action performed events are not fired until the mouse button is + * released. {@link #REPEAT_FIRING_BEHAVIOR} causes action performed events to fire + * repeatedly until the mouse button is released. + * + * @param type The firing behavior type + * @since 2.0 + * + */ +public void setFiringBehavior(int type) { + if (firingBehavior !is null) + removeStateTransitionListener(firingBehavior); + switch (type) { + case REPEAT_FIRING_BEHAVIOR: + firingBehavior = new RepeatFiringBehavior(); + break; + default: + firingBehavior = new DefaultFiringBehavior(); + } + addStateTransitionListener(firingBehavior); +} + +void setFlag(int flag, bool value) { + if (value) + state |= flag; + else + state &= ~flag; +} + +/** + * Sets the ButtonGroup to which this model belongs to. Adds this model as a listener to + * the group. + * + * @param bg The group to which this model belongs. + * @since 2.0 + */ +public void setGroup(ButtonGroup bg) { + if (group is bg) + return; + if (group !is null) + group.remove(this); + group = bg; + if (group !is null) + group.add(this); +} + +/** + * Sets the mouseover property of this button. + * + * @param value The value the mouseover property will be set to + * @since 2.0 + */ +public void setMouseOver(bool value) { + if (isMouseOver() is value) + return; + if (isPressed()) + if (value) + fireResume(); + else + fireSuspend(); + setFlag(MOUSEOVER_FLAG, value); + fireStateChanged(MOUSEOVER_PROPERTY); +} + +/** + * Sets the pressed property of this button. + * + * @param value The value the pressed property will be set to + * @since 2.0 + */ +public void setPressed(bool value) { + if (isPressed() is value) + return; + setFlag(PRESSED_FLAG, value); + if (value) + firePressed(); + else { + if (isArmed()) + fireReleased(); + else + fireCanceled(); + } + fireStateChanged(PRESSED_PROPERTY); +} + +/** + * Sets this button to be selected. + * + * @param value The value the selected property will be set to + * @since 2.0 + */ +public void setSelected(bool value) { + if (group is null) { + if (isSelected() is value) + return; + } else { + group.setSelected(this, value); + if (getFlag(SELECTED_FLAG) is isSelected()) + return; + } + setFlag(SELECTED_FLAG, value); + fireStateChanged(SELECTED_PROPERTY); +} + +/** + * Sets user data. + * + * @param data The user data + * @since 2.0 + */ +public void setUserData(Object data) { + this.data = data; +} + +class DefaultFiringBehavior + : ButtonStateTransitionListener +{ + public void released() { + fireActionPerformed(); + } +} + +class RepeatFiringBehavior + : ButtonStateTransitionListener +{ + protected static const int + INITIAL_DELAY = 250, + STEP_DELAY = 40; + + protected int + stepDelay = INITIAL_DELAY, + initialDelay = STEP_DELAY; + + protected Timer timer; + + public void pressed() { + fireActionPerformed(); + if (!isEnabled()) + return; + + timer = new Timer(); + TimerTask runAction = new Task(timer); + + timer.scheduleAtFixedRate(runAction, INITIAL_DELAY, STEP_DELAY); + } + + public void canceled() { + suspend(); + } + public void released() { + suspend(); + } + + public void resume() { + timer = new Timer(); + + TimerTask runAction = new Task(timer); + + timer.scheduleAtFixedRate(runAction, STEP_DELAY, STEP_DELAY); + } + + public void suspend() { + if (timer is null) return; + timer.cancel(); + timer = null; + } +} + +class Task + : TimerTask { + + private Timer timer; + + public this(Timer timer) { + this.timer = timer; + } + + public void run() { + org.eclipse.swt.widgets.Display.Display.getDefault().syncExec(dgRunnable( { + if (!isEnabled()) + timer.cancel(); + fireActionPerformed(); + })); + } +} + +}