# HG changeset patch # User Frank Benoit # Date 1206720513 -3600 # Node ID c876179528478f8eb30ad8e89f8860c5e2cab94d # Parent 6518c18a01f7c834a5cd1a9ccfc3040cea2b0d3c some JFace modules diff -r 6518c18a01f7 -r c87617952847 dwtx/core/commands/IHandlerAttributes.d --- a/dwtx/core/commands/IHandlerAttributes.d Wed Mar 26 00:57:19 2008 +0100 +++ b/dwtx/core/commands/IHandlerAttributes.d Fri Mar 28 17:08:33 2008 +0100 @@ -34,6 +34,6 @@ * The command should act and behave as if it has no handler. *

*/ - public static final String ATTRIBUTE_HANDLED = "handled"; //$NON-NLS-1$ + public static const String ATTRIBUTE_HANDLED = "handled"; //$NON-NLS-1$ } diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/action/IAction.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/action/IAction.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,522 @@ +/******************************************************************************* + * 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 + *******************************************************************************/ +module dwtx.jface.action.IAction; + +import dwtx.jface.action.IMenuCreator; + +import dwt.events.HelpListener; +import dwt.widgets.Event; +import dwtx.core.commands.IHandlerAttributes; +import dwtx.jface.resource.ImageDescriptor; +import dwtx.jface.util.IPropertyChangeListener; + +import dwt.dwthelper.utils; + +/** + * An action represents the non-UI side of a command which can be triggered + * by the end user. Actions are typically associated with buttons, menu items, + * and items in tool bars. The controls for a command are built by some container, + * which furnished the context where these controls appear and configures + * them with data from properties declared by the action. When the end user + * triggers the command via its control, the action's run + * method is invoked to do the real work. + *

+ * Actions support a predefined set of properties (and possibly others as well). + * Clients of an action may register property change listeners so that they get + * notified whenever the value of a property changes. + *

+ *

+ * Clients should subclass the abstract base class Action to define + * concrete actions rather than implementing IAction from scratch. + *

+ *

+ * This interface exists only to define the API for actions. + * It is not intended to be implemented by clients. + *

+ * + * @see Action + */ +public interface IAction { + + /** + * Action style constant (value 0) indicating action style + * is not specified yet. By default, the action will assume a push button + * style. If setChecked is called, then the style will change + * to a check box, or if setMenuCreator is called, then the + * style will change to a drop down menu. + * + * @since 2.1 + */ + public static int AS_UNSPECIFIED = 0x00; + + /** + * Action style constant (value 1) indicating action is + * a simple push button. + */ + public static int AS_PUSH_BUTTON = 0x01; + + /** + * Action style constant (value 2) indicating action is + * a check box (or a toggle button). + */ + public static int AS_CHECK_BOX = 0x02; + + /** + * Action style constant (value 4) indicating action is + * a drop down menu. + */ + public static int AS_DROP_DOWN_MENU = 0x04; + + /** + * Action style constant (value 8) indicating action is + * a radio button. + * + * @since 2.1 + */ + public static int AS_RADIO_BUTTON = 0x08; + + /** + * Property name of an action's text (value "text"). + */ + public static const String TEXT = "text"; //$NON-NLS-1$ + + /** + * Property name of an action's enabled state + * (value "enabled"). + */ + public static const String ENABLED = "enabled"; //$NON-NLS-1$ + + /** + * Property name of an action's image (value "image"). + */ + public static const String IMAGE = "image"; //$NON-NLS-1$ + + /** + * Property name of an action's tooltip text (value "toolTipText"). + */ + public static const String TOOL_TIP_TEXT = "toolTipText"; //$NON-NLS-1$ + + /** + * Property name of an action's description (value "description"). + * Typically the description is shown as a (longer) help text in the status line. + */ + public static const String DESCRIPTION = "description"; //$NON-NLS-1$ + + /** + * Property name of an action's checked status (value + * "checked"). Applicable when the style is + * AS_CHECK_BOX or AS_RADIO_BUTTON. + */ + public static const String CHECKED = "checked"; //$NON-NLS-1$ + + /** + * Property name of an action's success/fail result + * (value "result"). The values are + * bool.TRUE if running the action succeeded and + * bool.FALSE if running the action failed or did not + * complete. + *

+ * Not all actions report whether they succeed or fail. This property + * is provided for use by actions that may be invoked by clients that can + * take advantage of this information when present (for example, actions + * used in cheat sheets). Clients should always assume that running the + * action succeeded in the absence of notification to the contrary. + *

+ * + * @since 3.0 + */ + public static const String RESULT = "result"; //$NON-NLS-1$ + + /** + * Property name of an action's handler. Some actions delegate some or all + * of their behaviour or state to another object. In this case, if the + * object to which behaviour has been delegated changes, then a property + * change event should be sent with this name. + * + * This is used to support backward compatibility of actions within the + * commands framework. + * + * @since 3.1 + */ + public static const String HANDLED = IHandlerAttributes.ATTRIBUTE_HANDLED; + + /** + * Adds a property change listener to this action. + * Has no effect if an identical listener is already registered. + * + * @param listener a property change listener + */ + public void addPropertyChangeListener(IPropertyChangeListener listener); + + /** + * Returns the accelerator keycode for this action. + * The result is the bit-wise OR of zero or more modifier masks + * and a key, as explained in MenuItem.getAccelerator. + * + * @return the accelerator keycode + * @see dwt.widgets.MenuItem#getAccelerator() + */ + public int getAccelerator(); + + /** + * Returns the action definition id of this action. + * + * @return the action definition id of this action, or + * null if none + * @since 2.0 + */ + public String getActionDefinitionId(); + + /** + * Returns the action's description if it has one. + * Otherwise it returns getToolTipText(). + * + * @return a description for the action; may be null + */ + public String getDescription(); + + /** + * Returns the disabled image for this action as an image descriptor. + *

+ * This method is associated with the IMAGE property; + * property change events are reported when its value changes. + *

+ * + * @return the image, or null if this action has no image + * @see #IMAGE + */ + public ImageDescriptor getDisabledImageDescriptor(); + + /** + * Returns a help listener for this action. + * + * @return a help listener for this action + */ + public HelpListener getHelpListener(); + + /** + * Returns the hover image for this action as an image descriptor. + *

+ * Hover images will be used on platforms that support changing the image + * when the user hovers over the item. This method is associated with + * the IMAGE property; + * property change events are reported when its value changes. + *

+ * + * @return the image, or null if this action has no image + * @see #IMAGE + */ + public ImageDescriptor getHoverImageDescriptor(); + + /** + * Returns a unique identifier for this action, or null if it has + * none. + * + * @return the action id, or null if none + */ + public String getId(); + + /** + * Returns the image for this action as an image descriptor. + *

+ * This method is associated with the IMAGE property; + * property change events are reported when its value changes. + *

+ * + * @return the image, or null if this action has no image + * @see #IMAGE + */ + public ImageDescriptor getImageDescriptor(); + + /** + * Returns the menu creator for this action. + * + * @return the menu creator, or null if none + */ + public IMenuCreator getMenuCreator(); + + /** + * Return this action's style. + * + * @return one of AS_PUSH_BUTTON, AS_CHECK_BOX, + * AS_RADIO_BUTTON and AS_DROP_DOWN_MENU. + */ + public int getStyle(); + + /** + * Returns the text for this action. + *

+ * This method is associated with the TEXT property; + * property change events are reported when its value changes. + *

+ * + * @return the text, or null if none + * @see #TEXT + */ + public String getText(); + + /** + * Returns the tool tip text for this action. + *

+ * This method is associated with the TOOL_TIP_TEXT property; + * property change events are reported when its value changes. + *

+ * + * @return the tool tip text, or null if none + * @see #TOOL_TIP_TEXT + */ + public String getToolTipText(); + + /** + * Returns the checked status of this action. Applicable only if the style is + * AS_CHECK_BOX or AS_RADIO_BUTTON. + *

+ * This method is associated with the CHECKED property; + * property change events are reported when its value changes. + *

+ * + * @return the checked status + * @see #CHECKED + */ + public bool isChecked(); + + /** + * Returns whether this action is enabled. + *

+ * This method is associated with the ENABLED property; + * property change events are reported when its value changes. + *

+ * + * @return true if enabled, and + * false if disabled + * @see #ENABLED + */ + public bool isEnabled(); + + /** + * Returns whether this action is handled. In the default case, this is + * always true. However, if the action delegates some of its + * behaviour to some other object, then this method should answer whether + * such an object is currently available. + * + * @return true if all of the action's behaviour is + * available; false otherwise. + * @since 3.1 + */ + public bool isHandled(); + + /** + * Removes the given listener from this action. + * Has no effect if an identical listener is not registered. + * + * @param listener a property change listener + */ + public void removePropertyChangeListener(IPropertyChangeListener listener); + + /** + * Runs this action. + * Each action implementation must define the steps needed to carry out this action. + * The default implementation of this method in Action + * does nothing. + */ + public void run(); + + /** + * Runs this action, passing the triggering DWT event. + * As of 2.0, ActionContributionItem calls this method + * instead of run(). + * The default implementation of this method in Action + * simply calls run() for backwards compatibility. + * + * @param event the DWT event which triggered this action being run + * @since 2.0 + */ + public void runWithEvent(Event event); + + /** + * Sets the action definition id of this action. + * + * @param id the action definition id + * @since 2.0 + */ + public void setActionDefinitionId(String id); + + /** + * Sets the checked status of this action. Applicable for the styles + * AS_CHECK_BOX or AS_RADIO_BUTTON. + *

+ * Fires a property change event for the CHECKED property + * if the checked status actually changes as a consequence. + *

+ * + * @param checked the new checked status + * @see #CHECKED + */ + public void setChecked(bool checked); + + /** + * Sets this action's description. + * Typically the description is shown as a (longer) help text in the status line. + *

+ * Fires a property change event for the DESCRIPTION property + * if the description actually changes as a consequence. + *

+ * + * @param text the description, or null to clear the description + * @see #DESCRIPTION + */ + public void setDescription(String text); + + /** + * Sets the disabled image for this action, as an image descriptor. + *

+ * Disabled images will be used on platforms that support changing the image + * when the item is disabled.Fires a property change event for + * the IMAGE property + * if the image actually changes as a consequence. + *

+ * + * @param newImage the image, or null if this + * action should not have an image + * @see #IMAGE + */ + public void setDisabledImageDescriptor(ImageDescriptor newImage); + + /** + * Sets the enabled state of this action. + *

+ * When an action is in the enabled state, the control associated with + * it is active; triggering it will end up inkoking this action's + * run method. + *

+ *

+ * Fires a property change event for the ENABLED property + * if the enabled state actually changes as a consequence. + *

+ * + * @param enabled true to enable, and + * false to disable + * @see #ENABLED + */ + public void setEnabled(bool enabled); + + /** + * Sets a help listener for this action. + * + * @param listener a help listener for this action + */ + public void setHelpListener(HelpListener listener); + + /** + * Sets the hover image for this action, as an image descriptor. + *

+ * Hover images will be used on platforms that support changing the image + * when the user hovers over the item.Fires a property change event for + * the IMAGE property + * if the image actually changes as a consequence. + *

+ * + * @param newImage the image, or null if this + * action should not have an image + * @see #IMAGE + */ + public void setHoverImageDescriptor(ImageDescriptor newImage); + + /** + * Sets the unique identifier for this action. This is used to identify actions + * when added to a contribution manager. + * It should be set when the action is created. It should not be modified once + * the action is part of an action contribution item. + * + * @param id the action id + * + * @see ActionContributionItem + * @see IContributionItem#getId + */ + public void setId(String id); + + /** + * Sets the image for this action, as an image descriptor. + *

+ * Fires a property change event for the IMAGE property + * if the image actually changes as a consequence. + *

+ * + * @param newImage the image, or null if this + * action should not have an image + * @see #IMAGE + */ + public void setImageDescriptor(ImageDescriptor newImage); + + /** + * Sets the menu creator for this action. Applicable for style + * AS_DROP_DOWN_MENU. + * + * @param creator the menu creator, or null if none + */ + public void setMenuCreator(IMenuCreator creator); + + /** + * Sets the text for this action. + *

+ * An accelerator specification may follow the actual text, separated from it by + * an '@' or a '\t' character. An accelerator specification consists of zero or more + * modifier tokens followed by a key code token. The tokens are separated by a '+' character. + *

+ *

+ * Fires a property change event for the TEXT property + * if the text actually changes as a consequence. + *

+ * + * @param text the text, or null if none + * @see #TEXT + * @see Action#findModifier + * @see Action#findKeyCode + */ + public void setText(String text); + + /** + * Sets the tool tip text for this action. + *

+ * Fires a property change event for the TOOL_TIP_TEXT property + * if the tool tip text actually changes as a consequence. + *

+ * + * @param text the tool tip text, or null if none + * @see #TOOL_TIP_TEXT + */ + public void setToolTipText(String text); + + /** + *

+ * Sets the accelerator keycode that this action maps to. This is a bitwise OR + * of zero or more DWT key modifier masks (i.e. DWT.CTRL or DWT.ALT) and a + * character code. For example, for Ctrl+Z, use DWT.CTRL | 'Z'. + * Use 0 for no accelerator. + *

+ *

+ * This method should no longer be used for actions in the Eclipse workbench. + * IWorkbenchCommandSupport and + * IWorkbenchContextSupport provide all the functionality + * required for key bindings. If you set an accelerator using this method, then + * it will not work in the workbench if it conflicts any existing key binding, + * or if there is a different key binding defined for this action's definition + * id. The definition id should be used instead -- referring to the command in + * the workbench from which the key binding should be retrieved. + *

+ * + * @param keycode + * the keycode to be accepted. + */ + public void setAccelerator(int keycode); +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/action/IMenuCreator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/action/IMenuCreator.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.action.IMenuCreator; + +import dwt.widgets.Control; +import dwt.widgets.Menu; + +/** + * Interface for something that creates and disposes of DWT menus. Note that + * it is the responsibility of the implementor to dispose of DWT menus it + * creates. + */ +public interface IMenuCreator { + /** + * Disposes the menu returned by getMenu. Does nothing + * if there is no menu. This method will be executed only when the + * parent of the menu is disposed. + */ + public void dispose(); + + /** + * Returns the DWT menu, created as a pop up menu parented by the + * given control. In most cases, this menu can be created once, cached and reused + * when the pop-up/drop-down action occurs. If the menu must be dynamically + * created (i.e., each time it is popped up or dropped down), the old menu + * should be disposed of before replacing it with the new menu. + * + * @param parent the parent control + * @return the menu, or null if the menu could not + * be created + */ + public Menu getMenu(Control parent); + + /** + * Returns an DWT menu created as a drop down menu parented by the + * given menu. In most cases, this menu can be created once, cached and reused + * when the pop-up/drop-down action occurs. If the menu must be dynamically + * created (i.e., each time it is popped up or dropped down), the old menu + * should be disposed of before replacing it with the new menu. + * + * @param parent the parent menu + * @return the menu, or null if the menu could not + * be created + */ + public Menu getMenu(Menu parent); +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/dialogs/AnimatorFactory.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/dialogs/AnimatorFactory.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2006 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 + ******************************************************************************/ + +module dwtx.jface.dialogs.AnimatorFactory; + +import dwtx.jface.dialogs.ControlAnimator; + +import dwt.widgets.Control; + + +/** + * Factory for control animators used by JFace to animate the display of an DWT + * Control. Through the use of the method + * {@link dwtx.jface.util.Policy#setAnimatorFactory(AnimatorFactory)} + * a new type of animator factory can be plugged into JFace. + * + * @since 3.2 + * @deprecated as of 3.3, this class is no longer used. + */ +public class AnimatorFactory { + /** + * Creates a new ControlAnimator for use by JFace in animating + * the display of an DWT Control.

+ * Subclasses should override this method. + * + * @param control the DWT Control to de displayed + * @return the ControlAnimator. + * @since 3.2 + */ + public ControlAnimator createAnimator(Control control) { + return new ControlAnimator(control); + } +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/dialogs/ControlAnimator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/dialogs/ControlAnimator.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2006 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 + ******************************************************************************/ + +module dwtx.jface.dialogs.ControlAnimator; + +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; + +/** + * ControlAnimator provides a simple implementation to display or hide a control + * at the bottom of the parent composite. Other animations will be written as + * subclasses of this class.

+ * Instances of this class can be created using an AnimatorFactory. + * + * @since 3.2 + */ + + +public class ControlAnimator { + /** the control that will be displayed or hidden */ + protected Control control; + + /** + * Constructs a new ControlAnimator instance and passes along the + * control that will be displayed or hidden. + * + * @param control the control that will be displayed or hidden. + */ + public this(Control control) { + this.control = control; + } + + /** + * Displays or hides a control at the bottom of the parent composite + * and makes use of the control's DWT visible flag.

+ * Subclasses should override this method.

+ * + * @param visible true if the control should be shown, + * and false otherwise. + */ + public void setVisible(bool visible){ + // Using the DWT visible flag to determine if the control has + // already been displayed or hidden. Return if already displayed + // and visible is true, or if already hidden and visible is false. + if (!(control.isVisible() ^ visible)) + return; + control.setVisible(visible); + Rectangle parentBounds = control.getParent().getBounds(); + int bottom = parentBounds.height; + int endY = visible ? bottom - control.getBounds().height + : bottom; + Point loc = control.getLocation(); + control.setLocation(loc.x,endY); + } + +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/dialogs/ErrorSupportProvider.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/dialogs/ErrorSupportProvider.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2007 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 + ******************************************************************************/ + +module dwtx.jface.dialogs.ErrorSupportProvider; + + +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwtx.core.runtime.IStatus; + +/** + * A ErrorSupportProvider defines the area to be shown in an error dialog for extra support information. + * @since 3.3 + * + */ +public abstract class ErrorSupportProvider { + + + /** + * Create an area for adding support components as a child of parent. + * @param parent The parent {@link Composite} + * @param status The {@link IStatus} that is being displayed. + * @return Control + */ + public abstract Control createSupportArea(Composite parent, IStatus status); +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/resource/DerivedImageDescriptor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/DerivedImageDescriptor.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 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 + *******************************************************************************/ +module dwtx.jface.resource.DerivedImageDescriptor; + +import dwtx.jface.resource.ImageDescriptor; +import dwtx.jface.resource.DeviceResourceException; + +import dwt.DWT; +import dwt.DWTException; +import dwt.graphics.Device; +import dwt.graphics.Image; +import dwt.graphics.ImageData; +import dwt.widgets.Display; + +import dwt.dwthelper.utils; + +/** + * An image descriptor which creates images based on another ImageDescriptor, but with + * additional DWT flags. Note that this is only intended for compatibility. + * + * @since 3.1 + */ +final class DerivedImageDescriptor : ImageDescriptor { + + private ImageDescriptor original; + private int flags; + + /** + * Create a new image descriptor + * @param original the original one + * @param swtFlags flags to be used when image is created {@link Image#Image(Device, Image, int)} + * @see DWT#IMAGE_COPY + * @see DWT#IMAGE_DISABLE + * @see DWT#IMAGE_GRAY + */ + public this(ImageDescriptor original, int swtFlags) { + this.original = original; + flags = swtFlags; + } + + public Object createResource(Device device) { + try { + return internalCreateImage(device); + } catch (DWTException e) { + throw new DeviceResourceException(this, e); + } + } + + public Image createImage(Device device) { + return internalCreateImage(device); + } + + public override hash_t toHash() { + return original.toHash() + flags; + } + + public override int opEquals(Object arg0) { + if ( auto desc = cast(DerivedImageDescriptor)arg0 ) { + return desc.original is original && flags is desc.flags; + } + + return false; + } + + /** + * Creates a new Image on the given device. Note that we defined a new + * method rather than overloading createImage since this needs to be + * called by getImageData(), and we want to be absolutely certain not + * to cause infinite recursion if the base class gets refactored. + * + * @param device device to create the image on + * @return a newly allocated Image. Must be disposed by calling image.dispose(). + */ + private final Image internalCreateImage(Device device) { + Image originalImage = original.createImage(device); + Image result = new Image(device, originalImage, flags); + original.destroyResource(originalImage); + return result; + } + + public ImageData getImageData() { + Image image = internalCreateImage(Display.getCurrent()); + ImageData result = image.getImageData(); + image.dispose(); + return result; + } + +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/resource/DeviceResourceDescriptor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/DeviceResourceDescriptor.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 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 + *******************************************************************************/ +module dwtx.jface.resource.DeviceResourceDescriptor; + +import dwt.graphics.Device; + +/** + * Instances of this class can allocate and dispose DWT resources. Each + * instance describes a particular resource (such as a Color, Font, or Image) + * and can create and destroy that resource on demand. DeviceResourceDescriptors + * are managed by a ResourceRegistry. + * + * @see dwtx.jface.resource.ResourceManager + * + * @since 3.1 + */ +public abstract class DeviceResourceDescriptor { + /** + * Creates the resource described by this descriptor + * + * @since 3.1 + * + * @param device the Device on which to allocate the resource + * @return the newly allocated resource (not null) + * @throws DeviceResourceException if unable to allocate the resource + */ + public abstract Object createResource(Device device); + + /** + * Undoes everything that was done by a previous call to create(...), given + * the object that was returned by create(...). + * + * @since 3.1 + * + * @param previouslyCreatedObject an object that was returned by an equal + * descriptor in a previous call to createResource(...). + */ + public abstract void destroyResource(Object previouslyCreatedObject); +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/resource/DeviceResourceException.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/DeviceResourceException.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 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 + *******************************************************************************/ +module dwtx.jface.resource.DeviceResourceException; + +import dwtx.jface.resource.DeviceResourceDescriptor; + +import dwt.dwthelper.utils; + +/** + * Thrown when allocation of an DWT device resource fails + * + * @since 3.1 + */ +public class DeviceResourceException : RuntimeException { + + private Exception cause; + + /** + * All serializable objects should have a stable serialVersionUID + */ + private static const long serialVersionUID = 11454598756198L; + + /** + * Creates a DeviceResourceException indicating an error attempting to + * create a resource and an embedded low-level exception describing the cause + * + * @param missingResource + * @param cause cause of the exception (or null if none) + */ + public this(DeviceResourceDescriptor missingResource, Exception cause) { + super("Unable to create resource " ~ missingResource.toString()); //$NON-NLS-1$ + // don't pass the cause to super, to allow compilation against JCL Foundation (bug 80059) + this.cause = cause; + } + + /** + * Creates a DeviceResourceException indicating an error attempting to + * create a resource + * + * @param missingResource + */ + public this(DeviceResourceDescriptor missingResource) { + this(missingResource, null); + } + + /** + * Returns the cause of this throwable or null if the + * cause is nonexistent or unknown. + * + * @return the cause or null + * @since 3.1 + */ + public Exception getCause() { + return cause; + } + +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/resource/FileImageDescriptor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/FileImageDescriptor.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,158 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.resource.FileImageDescriptor; + +import dwtx.jface.resource.ImageDescriptor; + +// import java.io.BufferedInputStream; +// import java.io.FileInputStream; +// import java.io.FileNotFoundException; +// import java.io.IOException; +// import java.io.InputStream; + +import dwt.DWT; +import dwt.DWTException; +import dwt.graphics.ImageData; + +import dwt.dwthelper.utils; +import dwt.dwthelper.InputStream; +import dwt.dwthelper.FileInputStream; +import dwt.dwthelper.BufferedInputStream; + +/** + * An image descriptor that loads its image information + * from a file. + */ +class FileImageDescriptor : ImageDescriptor { + + /** + * The class whose resource directory contain the file, + * or null if none. + */ + private ClassInfo location; + + /** + * The name of the file. + */ + private String name; + + /** + * Creates a new file image descriptor. + * The file has the given file name and is located + * in the given class's resource directory. If the given + * class is null, the file name must be absolute. + *

+ * Note that the file is not accessed until its + * getImageDate method is called. + *

+ * + * @param clazz class for resource directory, or + * null + * @param filename the name of the file + */ + this(ClassInfo clazz, String filename) { + this.location = clazz; + this.name = filename; + } + + /* (non-Javadoc) + * Method declared on Object. + */ + public bool equals(Object o) { + if (!( cast(FileImageDescriptor)o )) { + return false; + } + FileImageDescriptor other = cast(FileImageDescriptor) o; + if (location !is null) { + if ( location.name != other.location.name ) { + return false; + } + } else { + if (other.location !is null) { + return false; + } + } + return name == other.name; + } + + /* (non-Javadoc) + * Method declared on ImageDesciptor. + * Returns null if the image data cannot be read. + */ + public ImageData getImageData() { + InputStream in_ = getStream(); + ImageData result = null; + if (in_ !is null) { + try { + result = new ImageData(in_); + } catch (DWTException e) { + if (e.code !is DWT.ERROR_INVALID_IMAGE) { + throw e; + // fall through otherwise + } + } finally { + in_.close(); + } + } + return result; + } + + /** + * Returns a stream on the image contents. Returns + * null if a stream could not be opened. + * + * @return the buffered stream on the file or null + * if the file cannot be found + */ + private InputStream getStream() { + InputStream is_ = null; + + if (location !is null) { + is_ = ClassInfoGetResourceAsStream( location, name); + + } else { + try { + is_ = new FileInputStream(name); + } catch (/+FileNotFoundException+/ IOException e) { + return null; + } + } + if (is_ is null) { + return null; + } else { + return new BufferedInputStream(is_); + } + } + + /* (non-Javadoc) + * Method declared on Object. + */ + public override hash_t toHash() { + int code = dwt.dwthelper.utils.toHash(name); + if (location !is null) { + code += location.toHash(); + } + return code; + } + + /* (non-Javadoc) + * Method declared on Object. + */ + /** + * The FileImageDescriptor implementation of this Object method + * returns a string representation of this object which is suitable only for debugging. + */ + public override String toString() { + return "FileImageDescriptor(location=" ~ location.toString() ~ ", name=" ~ name ~ ")";//$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$ + } +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/resource/ImageDataImageDescriptor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/ImageDataImageDescriptor.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 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 + *******************************************************************************/ +module dwtx.jface.resource.ImageDataImageDescriptor; + +import dwt.graphics.Device; +import dwt.graphics.Image; +import dwt.graphics.ImageData; + +import dwtx.jface.resource.ImageDescriptor; + +import dwt.dwthelper.utils; + +/** + * @since 3.1 + */ +class ImageDataImageDescriptor : ImageDescriptor { + + private ImageData data; + + /** + * Original image being described, or null if this image is described + * completely using its ImageData + */ + private Image originalImage = null; + + /** + * Creates an image descriptor, given an image and the device it was created on. + * + * @param originalImage + */ + this(Image originalImage) { + this(originalImage.getImageData()); + this.originalImage = originalImage; + } + + /** + * Creates an image descriptor, given some image data. + * + * @param data describing the image + */ + + this(ImageData data) { + this.data = data; + } + + /* (non-Javadoc) + * @see dwtx.jface.resource.DeviceResourceDescriptor#create(dwt.graphics.Device) + */ + public Object createResource(Device device) { + + // If this descriptor is an existing font, then we can return the original font + // if this is the same device. + if (originalImage !is null) { + // If we're allocating on the same device as the original font, return the original. + if (originalImage.getDevice() is device) { + return originalImage; + } + } + + return super.createResource(device); + } + + /* (non-Javadoc) + * @see dwtx.jface.resource.DeviceResourceDescriptor#destroy(java.lang.Object) + */ + public void destroyResource(Object previouslyCreatedObject) { + if (previouslyCreatedObject is originalImage) { + return; + } + + super.destroyResource(previouslyCreatedObject); + } + + /* (non-Javadoc) + * @see dwtx.jface.resource.ImageDescriptor#getImageData() + */ + public ImageData getImageData() { + return data; + } + + /* (non-Javadoc) + * @see Object#hashCode + */ + public override hash_t toHash() { + if (originalImage !is null) { + return System.identityHashCode(originalImage); + } + return data.toHash(); + } + + /* (non-Javadoc) + * @see Object#equals + */ + public override int opEquals(Object obj) { + if (!(cast(ImageDataImageDescriptor)obj )) { + return false; + } + + ImageDataImageDescriptor imgWrap = cast(ImageDataImageDescriptor) obj; + + //Intentionally using is instead of equals() as Image.hashCode() changes + //when the image is disposed and so leaks may occur with equals() + + if (originalImage !is null) { + return imgWrap.originalImage is originalImage; + } + + return (imgWrap.originalImage is null && data.opEquals(imgWrap.data)); + } + +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/resource/ImageDescriptor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/ImageDescriptor.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,344 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.resource.ImageDescriptor; + +import dwtx.jface.resource.DeviceResourceDescriptor; +import dwtx.jface.resource.FileImageDescriptor; +import dwtx.jface.resource.URLImageDescriptor; +import dwtx.jface.resource.ImageDataImageDescriptor; +import dwtx.jface.resource.DerivedImageDescriptor; +import dwtx.jface.resource.DeviceResourceException; +import dwtx.jface.resource.MissingImageDescriptor; + +import tango.net.Uri; + +import dwt.DWTException; +import dwt.graphics.Device; +import dwt.graphics.Image; +import dwt.graphics.ImageData; +import dwt.graphics.PaletteData; +import dwt.graphics.RGB; +import dwt.widgets.Display; + +import dwt.dwthelper.utils; + +/** + * An image descriptor is an object that knows how to create + * an DWT image. It does not hold onto images or cache them, + * but rather just creates them on demand. An image descriptor + * is intended to be a lightweight representation of an image + * that can be manipulated even when no DWT display exists. + *

+ * This package defines a concrete image descriptor implementation + * which reads an image from a file (FileImageDescriptor). + * It also provides abstract framework classes (this one and + * CompositeImageDescriptor) which may be subclassed to define + * news kinds of image descriptors. + *

+ *

+ * Using this abstract class involves defining a concrete subclass + * and providing an implementation for the getImageData + * method. + *

+ *

+ * There are two ways to get an Image from an ImageDescriptor. The method + * createImage will always return a new Image which must be disposed by + * the caller. Alternatively, createResource() returns a shared + * Image. When the caller is done with an image obtained from createResource, + * they must call destroyResource() rather than disposing the Image directly. + * The result of createResource() can be safely cast to an Image. + *

+ * + * @see dwt.graphics.Image + */ +public abstract class ImageDescriptor : DeviceResourceDescriptor { + + /** + * A small red square used to warn that an image cannot be created. + *

+ */ + protected static const ImageData DEFAULT_IMAGE_DATA; + + static this(){ + DEFAULT_IMAGE_DATA = new ImageData(6, 6, 1, new PaletteData( [ new RGB(255, 0, 0) ] )); + } + + /** + * Constructs an image descriptor. + */ + protected this() { + // do nothing + } + + /** + * Creates and returns a new image descriptor from a file. + * Convenience method for + * new FileImageDescriptor(location,filename). + * + * @param location the class whose resource directory contain the file + * @param filename the file name + * @return a new image descriptor + */ + public static ImageDescriptor createFromFile(ClassInfo location, String filename) { + return new FileImageDescriptor(location, filename); + } + + /** + * Creates and returns a new image descriptor given ImageData + * describing the image. + * + * @since 3.1 + * + * @param data contents of the image + * @return newly created image descriptor + */ + public static ImageDescriptor createFromImageData(ImageData data) { + return new ImageDataImageDescriptor(data); + } + + /** + * Creates and returns a new image descriptor for the given image. Note + * that disposing the original Image will cause the descriptor to become invalid. + * + * @since 3.1 + * + * @param img image to create + * @return a newly created image descriptor + */ + public static ImageDescriptor createFromImage(Image img) { + return new ImageDataImageDescriptor(img); + } + + /** + * Creates an ImageDescriptor based on the given original descriptor, but with additional + * DWT flags. + * + *

+ * Note that this sort of ImageDescriptor is slower and consumes more resources than + * a regular image descriptor. It will also never generate results that look as nice as + * a hand-drawn image. Clients are encouraged to supply their own disabled/grayed/etc. images + * rather than using a default image and transforming it. + *

+ * + * @param originalImage image to transform + * @param swtFlags any flag that can be passed to the flags argument of Image#Image(Device, Image, int) + * @return an ImageDescriptor that creates new images by transforming the given image descriptor + * + * @see Image#Image(Device, Image, int) + * @since 3.1 + * + */ + public static ImageDescriptor createWithFlags(ImageDescriptor originalImage, int swtFlags) { + return new DerivedImageDescriptor(originalImage, swtFlags); + } + + /** + * Creates and returns a new image descriptor for the given image. This + * method takes the Device that created the Image as an argument, allowing + * the original Image to be reused if the descriptor is asked for another + * Image on the same device. Note that disposing the original Image will + * cause the descriptor to become invalid. + * + * @deprecated use {@link ImageDescriptor#createFromImage(Image)} + * @since 3.1 + * + * @param img image to create + * @param theDevice the device that was used to create the Image + * @return a newly created image descriptor + */ + public static ImageDescriptor createFromImage(Image img, Device theDevice) { + return new ImageDataImageDescriptor(img); + } + + /** + * Creates and returns a new image descriptor from a URL. + * + * @param url The URL of the image file. + * @return a new image descriptor + */ + public static ImageDescriptor createFromURL(Uri url) { + if (url is null) { + return getMissingImageDescriptor(); + } + return new URLImageDescriptor(url); + } + + /* (non-Javadoc) + * @see dwtx.jface.resource.DeviceResourceDescriptor#createResource(dwt.graphics.Device) + */ + public Object createResource(Device device) { + Image result = createImage(false, device); + if (result is null) { + throw new DeviceResourceException(this); + } + return result; + } + + /* (non-Javadoc) + * @see dwtx.jface.resource.DeviceResourceDescriptor#destroyResource(Object) + */ + public void destroyResource(Object previouslyCreatedObject) { + (cast(Image)previouslyCreatedObject).dispose(); + } + + /** + * Creates and returns a new DWT image for this image descriptor. Note that + * each call returns a new DWT image object. The returned image must be + * explicitly disposed using the image's dispose call. The image will not be + * automatically garbage collected. A default image is returned in the event + * of an error. + * + *

+ * Note: this method differs from createResource(Device) in that the returned image + * must be disposed directly, whereas an image obtained from createResource(...) + * must be disposed by calling destroyResource(...). It is not possible to + * mix-and-match. If you obtained the Image from this method, you must not dispose + * it by calling destroyResource. Clients are encouraged to use + * create/destroyResource and downcast the result to Image rather than using + * createImage. + *

+ * + *

+ * Note: it is still possible for this method to return null + * in extreme cases, for example if DWT runs out of image handles. + *

+ * + * @return a new image or null if the image could not be + * created + */ + public Image createImage() { + return createImage(true); + } + + /** + * Creates and returns a new DWT image for this image descriptor. The + * returned image must be explicitly disposed using the image's dispose + * call. The image will not be automatically garbage collected. In the event + * of an error, a default image is returned if + * returnMissingImageOnError is true, otherwise + * null is returned. + *

+ * Note: Even if returnMissingImageOnError is true, it is + * still possible for this method to return null in extreme + * cases, for example if DWT runs out of image handles. + *

+ * + * @param returnMissingImageOnError + * flag that determines if a default image is returned on error + * @return a new image or null if the image could not be + * created + */ + public Image createImage(bool returnMissingImageOnError) { + return createImage(returnMissingImageOnError, Display.getCurrent()); + } + + /** + * Creates and returns a new DWT image for this image descriptor. The + * returned image must be explicitly disposed using the image's dispose + * call. The image will not be automatically garbage collected. A default + * image is returned in the event of an error. + *

+ * Note: it is still possible for this method to return null + * in extreme cases, for example if DWT runs out of image handles. + *

+ * + * @param device + * the device on which to create the image + * @return a new image or null if the image could not be + * created + * @since 2.0 + */ + public Image createImage(Device device) { + return createImage(true, device); + } + + /** + * Creates and returns a new DWT image for this image descriptor. The + * returned image must be explicitly disposed using the image's dispose + * call. The image will not be automatically garbage collected. In the even + * of an error, a default image is returned if + * returnMissingImageOnError is true, otherwise + * null is returned. + *

+ * Note: Even if returnMissingImageOnError is true, it is + * still possible for this method to return null in extreme + * cases, for example if DWT runs out of image handles. + *

+ * + * @param returnMissingImageOnError + * flag that determines if a default image is returned on error + * @param device + * the device on which to create the image + * @return a new image or null if the image could not be + * created + * @since 2.0 + */ + public Image createImage(bool returnMissingImageOnError, Device device) { + + ImageData data = getImageData(); + if (data is null) { + if (!returnMissingImageOnError) { + return null; + } + data = DEFAULT_IMAGE_DATA; + } + + /* + * Try to create the supplied image. If there is an DWT Exception try and create + * the default image if that was requested. Return null if this fails. + */ + + try { + if (data.transparentPixel >= 0) { + ImageData maskData = data.getTransparencyMask(); + return new Image(device, data, maskData); + } + return new Image(device, data); + } catch (DWTException exception) { + if (returnMissingImageOnError) { + try { + return new Image(device, DEFAULT_IMAGE_DATA); + } catch (DWTException nextException) { + return null; + } + } + return null; + } + } + + /** + * Creates and returns a new DWT ImageData object + * for this image descriptor. + * Note that each call returns a new DWT image data object. + *

+ * This framework method is declared public so that it is + * possible to request an image descriptor's image data without + * creating an DWT image object. + *

+ *

+ * Returns null if the image data could not be created. + *

+ * + * @return a new image data or null + */ + public abstract ImageData getImageData(); + + /** + * Returns the shared image descriptor for a missing image. + * + * @return the missing image descriptor + */ + public static ImageDescriptor getMissingImageDescriptor() { + return MissingImageDescriptor.getInstance(); + } +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/resource/MissingImageDescriptor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/MissingImageDescriptor.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.resource.MissingImageDescriptor; + +import dwtx.jface.resource.ImageDescriptor; + +import dwt.graphics.ImageData; + +/** + * The image descriptor for a missing image. + *

+ * Use MissingImageDescriptor.getInstance to + * access the singleton instance maintained in an + * internal state variable. + *

+ */ +class MissingImageDescriptor : ImageDescriptor { + private static MissingImageDescriptor instance; + + /** + * Constructs a new missing image descriptor. + */ + private this() { + super(); + } + + /* (non-Javadoc) + * Method declared on ImageDesciptor. + */ + public ImageData getImageData() { + return DEFAULT_IMAGE_DATA; + } + + /** + * Returns the shared missing image descriptor instance. + * + * @return the image descriptor for a missing image + */ + static MissingImageDescriptor getInstance() { + if (instance is null) { + instance = new MissingImageDescriptor(); + } + return instance; + } +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/resource/URLImageDescriptor.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/resource/URLImageDescriptor.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.resource.URLImageDescriptor; + +import dwtx.jface.resource.ImageDescriptor; + +// import java.io.BufferedInputStream; +// import java.io.IOException; +// import java.io.InputStream; +import tango.net.Uri; + +import dwt.DWT; +import dwt.DWTException; +import dwt.graphics.ImageData; + +import dwt.dwthelper.utils; +import dwt.dwthelper.BufferedInputStream; +import dwt.dwthelper.InputStream; + +/** + * An ImageDescriptor that gets its information from a URL. + * This class is not public API. Use ImageDescriptor#createFromURL + * to create a descriptor that uses a URL. + */ +class URLImageDescriptor : ImageDescriptor { + private Uri url; + + /** + * Creates a new URLImageDescriptor. + * @param url The URL to load the image from. Must be non-null. + */ + this(Uri url) { + this.url = url; + } + + /* (non-Javadoc) + * Method declared on Object. + */ + public bool equals(Object o) { + if (!(cast(URLImageDescriptor)o )) { + return false; + } + return (cast(URLImageDescriptor) o).url.opEquals(this.url) !is 0; + } + + /* (non-Javadoc) + * Method declared on ImageDesciptor. + * Returns null if the image data cannot be read. + */ + public ImageData getImageData() { + ImageData result = null; + InputStream in_ = getStream(); + if (in_ !is null) { + scope(exit) + in_.close(); + try { + result = new ImageData(in_); + } catch (DWTException e) { + if (e.code !is DWT.ERROR_INVALID_IMAGE) { + throw e; + // fall through otherwise + } + } + } + return result; + } + + /** + * Returns a stream on the image contents. Returns + * null if a stream could not be opened. + * @return the stream for loading the data + */ + protected InputStream getStream() { + implMissing( __FILE__, __LINE__ ); + return null; + //FIXME + /+ + try { + return new BufferedInputStream(url.openStream()); + } catch (IOException e) { + return null; + } + +/ + } + + /* (non-Javadoc) + * Method declared on Object. + */ + public override hash_t toHash() { + return url.toHash(); + } + + /* (non-Javadoc) + * Method declared on Object. + */ + /** + * The URLImageDescriptor implementation of this Object method + * returns a string representation of this object which is suitable only for debugging. + */ + public override String toString() { + return "URLImageDescriptor(" ~ url.toString ~ ")"; //$NON-NLS-1$ //$NON-NLS-2$ + } +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/Assert.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/Assert.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.util.Assert; + +import dwt.dwthelper.utils; + +/** + * Assert is useful for for embedding runtime sanity checks + * in code. The static predicate methods all test a condition and throw some + * type of unchecked exception if the condition does not hold. + *

+ * Assertion failure exceptions, like most runtime exceptions, are + * thrown when something is misbehaving. Assertion failures are invariably + * unspecified behavior; consequently, clients should never rely on + * these being thrown (or not thrown). If you find yourself in the + * position where you need to catch an assertion failure, you have most + * certainly written your program incorrectly. + *

+ *

+ * Note that an assert statement is slated to be added to the + * Java language in JDK 1.4, rending this class obsolete. + * + * @deprecated As of 3.3, replaced by {@link dwtx.core.runtime.Assert} + *

+ */ +public final class Assert { + + /** + * AssertionFailedException is a runtime exception thrown + * by some of the methods in Assert. + *

+ * This class is not declared public to prevent some misuses; programs that catch + * or otherwise depend on assertion failures are susceptible to unexpected + * breakage when assertions in the code are added or removed. + *

+ */ + private static class AssertionFailedException : RuntimeException { + + /** + * Generated serial version UID for this class. + * @since 3.1 + */ + private static final long serialVersionUID = 3257852073508024376L; + + /** + * Constructs a new exception. + */ + public this() { + } + + /** + * Constructs a new exception with the given message. + * @param detail the detail message + */ + public this(String detail) { + super(detail); + } + } + + /* This class is not intended to be instantiated. */ + private this() { + } + + /** + * Asserts that an argument is legal. If the given bool is + * not true, an IllegalArgumentException + * is thrown. + * + * @param expression the outcome of the check + * @return true if the check passes (does not return + * if the check fails) + * @exception IllegalArgumentException if the legality test failed + */ + public static bool isLegal(bool expression) { + // succeed as quickly as possible + if (expression) { + return true; + } + return isLegal(expression, "");//$NON-NLS-1$ + } + + /** + * Asserts that an argument is legal. If the given bool is + * not true, an IllegalArgumentException + * is thrown. + * The given message is included in that exception, to aid debugging. + * + * @param expression the outcome of the check + * @param message the message to include in the exception + * @return true if the check passes (does not return + * if the check fails) + * @exception IllegalArgumentException if the legality test failed + */ + public static bool isLegal(bool expression, String message) { + if (!expression) { + throw new IllegalArgumentException("assertion failed; " ~ message); //$NON-NLS-1$ + } + return expression; + } + + /** + * Asserts that the given object is not null. If this + * is not the case, some kind of unchecked exception is thrown. + *

+ * As a general rule, parameters passed to API methods must not be + * null unless explicitly allowed in the method's + * specification. Similarly, results returned from API methods are never + * null unless explicitly allowed in the method's + * specification. Implementations are encouraged to make regular use of + * Assert.isNotNull to ensure that null + * parameters are detected as early as possible. + *

+ * + * @param object the value to test + * @exception AssertionFailedException an unspecified unchecked exception if the object + * is null + */ + public static void isNotNull(Object object) { + // succeed as quickly as possible + if (object !is null) { + return; + } + isNotNull(object, "");//$NON-NLS-1$ + } + + /** + * Asserts that the given object is not null. If this + * is not the case, some kind of unchecked exception is thrown. + * The given message is included in that exception, to aid debugging. + *

+ * As a general rule, parameters passed to API methods must not be + * null unless explicitly allowed in the method's + * specification. Similarly, results returned from API methods are never + * null unless explicitly allowed in the method's + * specification. Implementations are encouraged to make regular use of + * Assert.isNotNull to ensure that null + * parameters are detected as early as possible. + *

+ * + * @param object the value to test + * @param message the message to include in the exception + * @exception AssertionFailedException an unspecified unchecked exception if the object + * is null + */ + public static void isNotNull(Object object, String message) { + if (object is null) { + throw new AssertionFailedException("null argument;" ~ message);//$NON-NLS-1$ + } + } + + /** + * Asserts that the given bool is true. If this + * is not the case, some kind of unchecked exception is thrown. + * + * @param expression the outcome of the check + * @return true if the check passes (does not return + * if the check fails) + */ + public static bool isTrue(bool expression) { + // succeed as quickly as possible + if (expression) { + return true; + } + return isTrue(expression, "");//$NON-NLS-1$ + } + + /** + * Asserts that the given bool is true. If this + * is not the case, some kind of unchecked exception is thrown. + * The given message is included in that exception, to aid debugging. + * + * @param expression the outcome of the check + * @param message the message to include in the exception + * @return true if the check passes (does not return + * if the check fails) + */ + public static bool isTrue(bool expression, String message) { + if (!expression) { + throw new AssertionFailedException("Assertion failed: " ~ message);//$NON-NLS-1$ + } + return expression; + } +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/Geometry.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/Geometry.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,812 @@ +/******************************************************************************* + * Copyright (c) 2004, 2006 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 + *******************************************************************************/ +module dwtx.jface.util.Geometry; + +import dwt.DWT; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Control; + +import dwt.dwthelper.utils; +import dwt.dwthelper.Integer; + +/** + * Contains static methods for performing simple geometric operations + * on the DWT geometry classes. + * + * @since 3.0 + */ +public class Geometry { + + /** + * Prevent this class from being instantiated. + * + * @since 3.0 + */ + private this() { + //This is not instantiated + } + + /** + * Returns the square of the distance between two points. + *

This is preferred over the real distance when searching + * for the closest point, since it avoids square roots.

+ * + * @param p1 first endpoint + * @param p2 second endpoint + * @return the square of the distance between the two points + * + * @since 3.0 + */ + public static int distanceSquared(Point p1, Point p2) { + int term1 = p1.x - p2.x; + int term2 = p1.y - p2.y; + return term1 * term1 + term2 * term2; + } + + /** + * Returns the magnitude of the given 2d vector (represented as a Point) + * + * @param p point representing the 2d vector whose magnitude is being computed + * @return the magnitude of the given 2d vector + * @since 3.0 + */ + public static double magnitude(Point p) { + return Math.sqrt( cast(real) magnitudeSquared(p)); + } + + /** + * Returns the square of the magnitude of the given 2-space vector (represented + * using a point) + * + * @param p the point whose magnitude is being computed + * @return the square of the magnitude of the given vector + * @since 3.0 + */ + public static int magnitudeSquared(Point p) { + return p.x * p.x + p.y * p.y; + } + + /** + * Returns the dot product of the given vectors (expressed as Points) + * + * @param p1 the first vector + * @param p2 the second vector + * @return the dot product of the two vectors + * @since 3.0 + */ + public static int dotProduct(Point p1, Point p2) { + return p1.x * p2.x + p1.y * p2.y; + } + + /** + * Returns a new point whose coordinates are the minimum of the coordinates of the + * given points + * + * @param p1 a Point + * @param p2 a Point + * @return a new point whose coordinates are the minimum of the coordinates of the + * given points + * @since 3.0 + */ + public static Point min(Point p1, Point p2) { + return new Point(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y)); + } + + /** + * Returns a new point whose coordinates are the maximum of the coordinates + * of the given points + * @param p1 a Point + * @param p2 a Point + * @return point a new point whose coordinates are the maximum of the coordinates + * @since 3.0 + */ + public static Point max(Point p1, Point p2) { + return new Point(Math.max(p1.x, p2.x), Math.max(p1.y, p2.y)); + } + + /** + * Returns a vector in the given direction with the given + * magnitude. Directions are given using DWT direction constants, and + * the resulting vector is in the screen's coordinate system. That is, + * the vector (0, 1) is down and the vector (1, 0) is right. + * + * @param distance magnitude of the vector + * @param direction one of DWT.TOP, DWT.BOTTOM, DWT.LEFT, or DWT.RIGHT + * @return a point representing a vector in the given direction with the given magnitude + * @since 3.0 + */ + public static Point getDirectionVector(int distance, int direction) { + switch (direction) { + case DWT.TOP: + return new Point(0, -distance); + case DWT.BOTTOM: + return new Point(0, distance); + case DWT.LEFT: + return new Point(-distance, 0); + case DWT.RIGHT: + return new Point(distance, 0); + } + + return new Point(0, 0); + } + + /** + * Returns the point in the center of the given rectangle. + * + * @param rect rectangle being computed + * @return a Point at the center of the given rectangle. + * @since 3.0 + */ + public static Point centerPoint(Rectangle rect) { + return new Point(rect.x + rect.width / 2, rect.y + rect.height / 2); + } + + /** + * Returns a copy of the given point + * + * @param toCopy point to copy + * @return a copy of the given point + */ + public static Point copy(Point toCopy) { + return new Point(toCopy.x, toCopy.y); + } + + /** + * Sets result equal to toCopy + * + * @param result object that will be modified + * @param toCopy object that will be copied + * @since 3.1 + */ + public static void set(Point result, Point toCopy) { + result.x = toCopy.x; + result.y = toCopy.y; + } + + /** + * Sets result equal to toCopy + * + * @param result object that will be modified + * @param toCopy object that will be copied + * @since 3.1 + */ + public static void set(Rectangle result, Rectangle toCopy) { + result.x = toCopy.x; + result.y = toCopy.y; + result.width = toCopy.width; + result.height = toCopy.height; + } + + /** + *

Returns a new difference Rectangle whose x, y, width, and height are equal to the difference of the corresponding + * attributes from the given rectangles

+ * + *

+ * Example: Compute the margins for a given Composite, and apply those same margins to a new GridLayout + * + *
+     *      // Compute the client area, in the coordinate system of the input composite's parent
+     *      Rectangle clientArea = Display.getCurrent().map(inputComposite,
+     *          inputComposite.getParent(), inputComposite.getClientArea());
+     *
+     *      // Compute the margins for a given Composite by subtracting the client area from the composite's bounds
+     *      Rectangle margins = Geometry.subtract(inputComposite.getBounds(), clientArea);
+     *
+     *      // Now apply these margins to a new GridLayout
+     *      GridLayout layout = GridLayoutFactory.fillDefaults().margins(margins).create();
+     * 
+ * + * @param rect1 first rectangle + * @param rect2 rectangle to subtract + * @return the difference between the two rectangles (computed as rect1 - rect2) + * @since 3.3 + */ + public static Rectangle subtract(Rectangle rect1, Rectangle rect2) { + return new Rectangle(rect1.x - rect2.x, rect1.y - rect2.y, rect1.width - rect2.width, rect1.height - rect2.height); + } + + /** + *

Returns a new Rectangle whose x, y, width, and height is the sum of the x, y, width, and height values of + * both rectangles respectively.

+ * + * @param rect1 first rectangle to add + * @param rect2 second rectangle to add + * @return a new rectangle whose x, y, height, and width attributes are the sum of the corresponding attributes from + * the arguments. + * @since 3.3 + */ + public static Rectangle add(Rectangle rect1, Rectangle rect2) { + return new Rectangle(rect1.x + rect2.x, rect1.y + rect2.y, + rect1.width + rect2.width, rect1.height + rect2.height); + } + + /** + * Adds two points as 2d vectors. Returns a new point whose coordinates are + * the sum of the original two points. + * + * @param point1 the first point (not null) + * @param point2 the second point (not null) + * @return a new point whose coordinates are the sum of the given points + * @since 3.0 + */ + public static Point add(Point point1, Point point2) { + return new Point(point1.x + point2.x, point1.y + point2.y); + } + + /** + * Divides both coordinates of the given point by the given scalar. + * + * @since 3.1 + * + * @param toDivide point to divide + * @param scalar denominator + * @return a new Point whose coordinates are equal to the original point divided by the scalar + */ + public static Point divide(Point toDivide, int scalar) { + return new Point(toDivide.x / scalar, toDivide.y / scalar); + } + + + /** + * Performs vector subtraction on two points. Returns a new point equal to + * (point1 - point2). + * + * @param point1 initial point + * @param point2 vector to subtract + * @return the difference (point1 - point2) + * @since 3.0 + */ + public static Point subtract(Point point1, Point point2) { + return new Point(point1.x - point2.x, point1.y - point2.y); + } + + /** + * Swaps the X and Y coordinates of the given point. + * + * @param toFlip modifies this point + * @since 3.1 + */ + public static void flipXY(Point toFlip) { + int temp = toFlip.x; + toFlip.x = toFlip.y; + toFlip.y = temp; + } + + /** + * Swaps the X and Y coordinates of the given rectangle, along with the height and width. + * + * @param toFlip modifies this rectangle + * @since 3.1 + */ + public static void flipXY(Rectangle toFlip) { + int temp = toFlip.x; + toFlip.x = toFlip.y; + toFlip.y = temp; + + temp = toFlip.width; + toFlip.width = toFlip.height; + toFlip.height = temp; + } + + /** + * Returns the height or width of the given rectangle. + * + * @param toMeasure rectangle to measure + * @param width returns the width if true, and the height if false + * @return the width or height of the given rectangle + * @since 3.0 + */ + public static int getDimension(Rectangle toMeasure, bool width) { + if (width) { + return toMeasure.width; + } + return toMeasure.height; + } + + /** + * Returns the x or y coordinates of the given point. + * + * @param toMeasure point being measured + * @param width if true, returns x. Otherwise, returns y. + * @return the x or y coordinate + * @since 3.1 + */ + public static int getCoordinate(Point toMeasure, bool width) { + return width ? toMeasure.x : toMeasure.y; + } + + /** + * Returns the x or y coordinates of the given rectangle. + * + * @param toMeasure rectangle being measured + * @param width if true, returns x. Otherwise, returns y. + * @return the x or y coordinate + * @since 3.1 + */ + public static int getCoordinate(Rectangle toMeasure, bool width) { + return width ? toMeasure.x : toMeasure.y; + } + + /** + * Sets one dimension of the given rectangle. Modifies the given rectangle. + * + * @param toSet rectangle to modify + * @param width if true, the width is modified. If false, the height is modified. + * @param newCoordinate new value of the width or height + * @since 3.1 + */ + public static void setDimension(Rectangle toSet, bool width, int newCoordinate) { + if (width) { + toSet.width = newCoordinate; + } else { + toSet.height = newCoordinate; + } + } + + /** + * Sets one coordinate of the given rectangle. Modifies the given rectangle. + * + * @param toSet rectangle to modify + * @param width if true, the x coordinate is modified. If false, the y coordinate is modified. + * @param newCoordinate new value of the x or y coordinates + * @since 3.1 + */ + public static void setCoordinate(Rectangle toSet, bool width, int newCoordinate) { + if (width) { + toSet.x = newCoordinate; + } else { + toSet.y = newCoordinate; + } + } + + /** + * Sets one coordinate of the given point. Modifies the given point. + * + * @param toSet point to modify + * @param width if true, the x coordinate is modified. If false, the y coordinate is modified. + * @param newCoordinate new value of the x or y coordinates + * @since 3.1 + */ + public static void setCoordinate(Point toSet, bool width, int newCoordinate) { + if (width) { + toSet.x = newCoordinate; + } else { + toSet.y = newCoordinate; + } + } + + /** + * Returns the distance of the given point from a particular side of the given rectangle. + * Returns negative values for points outside the rectangle. + * + * @param rectangle a bounding rectangle + * @param testPoint a point to test + * @param edgeOfInterest side of the rectangle to test against + * @return the distance of the given point from the given edge of the rectangle + * @since 3.0 + */ + public static int getDistanceFromEdge(Rectangle rectangle, Point testPoint, + int edgeOfInterest) { + switch (edgeOfInterest) { + case DWT.TOP: + return testPoint.y - rectangle.y; + case DWT.BOTTOM: + return rectangle.y + rectangle.height - testPoint.y; + case DWT.LEFT: + return testPoint.x - rectangle.x; + case DWT.RIGHT: + return rectangle.x + rectangle.width - testPoint.x; + } + + return 0; + } + + /** + * Extrudes the given edge inward by the given distance. That is, if one side of the rectangle + * was sliced off with a given thickness, this returns the rectangle that forms the slice. Note + * that the returned rectangle will be inside the given rectangle if size > 0. + * + * @param toExtrude the rectangle to extrude. The resulting rectangle will share three sides + * with this rectangle. + * @param size distance to extrude. A negative size will extrude outwards (that is, the resulting + * rectangle will overlap the original iff this is positive). + * @param orientation the side to extrude. One of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM. The + * resulting rectangle will always share this side with the original rectangle. + * @return a rectangle formed by extruding the given side of the rectangle by the given distance. + * @since 3.0 + */ + public static Rectangle getExtrudedEdge(Rectangle toExtrude, int size, + int orientation) { + Rectangle bounds = new Rectangle(toExtrude.x, toExtrude.y, + toExtrude.width, toExtrude.height); + + if (!isHorizontal(orientation)) { + bounds.width = size; + } else { + bounds.height = size; + } + + switch (orientation) { + case DWT.RIGHT: + bounds.x = toExtrude.x + toExtrude.width - bounds.width; + break; + case DWT.BOTTOM: + bounds.y = toExtrude.y + toExtrude.height - bounds.height; + break; + } + + normalize(bounds); + + return bounds; + } + + /** + * Returns the opposite of the given direction. That is, returns DWT.LEFT if + * given DWT.RIGHT and visa-versa. + * + * @param swtDirectionConstant one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM + * @return one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM + * @since 3.0 + */ + public static int getOppositeSide(int swtDirectionConstant) { + switch (swtDirectionConstant) { + case DWT.TOP: + return DWT.BOTTOM; + case DWT.BOTTOM: + return DWT.TOP; + case DWT.LEFT: + return DWT.RIGHT; + case DWT.RIGHT: + return DWT.LEFT; + } + + return swtDirectionConstant; + } + + /** + * Converts the given bool into an DWT orientation constant. + * + * @param horizontal if true, returns DWT.HORIZONTAL. If false, returns DWT.VERTICAL + * @return DWT.HORIZONTAL or DWT.VERTICAL. + * @since 3.0 + */ + public static int getSwtHorizontalOrVerticalConstant(bool horizontal) { + if (horizontal) { + return DWT.HORIZONTAL; + } + return DWT.VERTICAL; + } + + /** + * Returns true iff the given DWT side constant corresponds to a horizontal side + * of a rectangle. That is, returns true for the top and bottom but false for the + * left and right. + * + * @param swtSideConstant one of DWT.TOP, DWT.BOTTOM, DWT.LEFT, or DWT.RIGHT + * @return true iff the given side is horizontal. + * @since 3.0 + */ + public static bool isHorizontal(int swtSideConstant) { + return !(swtSideConstant is DWT.LEFT || swtSideConstant is DWT.RIGHT); + } + + /** + * Moves the given rectangle by the given delta. + * + * @param rect rectangle to move (will be modified) + * @param delta direction vector to move the rectangle by + * @since 3.0 + */ + public static void moveRectangle(Rectangle rect, Point delta) { + rect.x += delta.x; + rect.y += delta.y; + } + + /** + * Moves each edge of the given rectangle outward by the given amount. Negative values + * cause the rectangle to contract. Does not allow the rectangle's width or height to be + * reduced below zero. + * + * @param rect normalized rectangle to modify + * @param differenceRect difference rectangle to be added to rect + * @since 3.3 + */ + public static void expand(Rectangle rect, Rectangle differenceRect) { + rect.x += differenceRect.x; + rect.y += differenceRect.y; + rect.height = Math.max(0, rect.height + differenceRect.height); + rect.width = Math.max(0, rect.width + differenceRect.width); + } + + /** + *

Returns a rectangle which, when added to another rectangle, will expand each side + * by the given number of units.

+ * + *

This is commonly used to store margin sizes. For example:

+ * + *
+     *     // Expands the left, right, top, and bottom
+     *     // of the given control by 10, 5, 1, and 15 units respectively
+     *
+     *     Rectangle margins = Geometry.createDifferenceRect(10,5,1,15);
+     *     Rectangle bounds = someControl.getBounds();
+     *     someControl.setBounds(Geometry.add(bounds, margins));
+     * 
+ * + * @param left distance to expand the left side (negative values move the edge inward) + * @param right distance to expand the right side (negative values move the edge inward) + * @param top distance to expand the top (negative values move the edge inward) + * @param bottom distance to expand the bottom (negative values move the edge inward) + * + * @return a difference rectangle that, when added to another rectangle, will cause each + * side to expand by the given number of units + * @since 3.3 + */ + public static Rectangle createDiffRectangle(int left, int right, int top, int bottom) { + return new Rectangle(-left, -top, left + right, top + bottom); + } + + /** + * Moves each edge of the given rectangle outward by the given amount. Negative values + * cause the rectangle to contract. Does not allow the rectangle's width or height to be + * reduced below zero. + * + * @param rect normalized rectangle to modify + * @param left distance to move the left edge outward (negative values move the edge inward) + * @param right distance to move the right edge outward (negative values move the edge inward) + * @param top distance to move the top edge outward (negative values move the edge inward) + * @param bottom distance to move the bottom edge outward (negative values move the edge inward) + * @since 3.1 + */ + public static void expand(Rectangle rect, int left, int right, int top, int bottom) { + rect.x -= left; + rect.width = Math.max(0, rect.width + left + right); + rect.y -= top; + rect.height = Math.max(0, rect.height + top + bottom); + } + + /** + * Normalizes the given rectangle. That is, any rectangle with + * negative width or height becomes a rectangle with positive + * width or height that extends to the upper-left of the original + * rectangle. + * + * @param rect rectangle to modify + * @since 3.0 + */ + public static void normalize(Rectangle rect) { + if (rect.width < 0) { + rect.width = -rect.width; + rect.x -= rect.width; + } + + if (rect.height < 0) { + rect.height = -rect.height; + rect.y -= rect.height; + } + } + + /** + * Converts the given rectangle from display coordinates to the local coordinate system + * of the given object into display coordinates. + * + * @param coordinateSystem local coordinate system being converted to + * @param toConvert rectangle to convert + * @return a rectangle in control coordinates + * @since 3.0 + */ + public static Rectangle toControl(Control coordinateSystem, + Rectangle toConvert) { + return(coordinateSystem.getDisplay().map + (null,coordinateSystem,toConvert)); + } + + /** + * Converts the given rectangle from the local coordinate system of the given object + * into display coordinates. + * + * @param coordinateSystem local coordinate system being converted from + * @param toConvert rectangle to convert + * @return a rectangle in display coordinates + * @since 3.0 + */ + public static Rectangle toDisplay(Control coordinateSystem, + Rectangle toConvert) { + return(coordinateSystem.getDisplay().map + (coordinateSystem,null,toConvert)); + + } + + /** + * Determines where the given point lies with respect to the given rectangle. + * Returns a combination of DWT.LEFT, DWT.RIGHT, DWT.TOP, and DWT.BOTTOM, combined + * with bitwise or (for example, returns DWT.TOP | DWT.LEFT if the point is to the + * upper-left of the rectangle). Returns 0 if the point lies within the rectangle. + * Positions are in screen coordinates (ie: a point is to the upper-left of the + * rectangle if its x and y coordinates are smaller than any point in the rectangle) + * + * @param boundary normalized boundary rectangle + * @param toTest point whose relative position to the rectangle is being computed + * @return one of DWT.LEFT | DWT.TOP, DWT.TOP, DWT.RIGHT | DWT.TOP, DWT.LEFT, 0, + * DWT.RIGHT, DWT.LEFT | DWT.BOTTOM, DWT.BOTTOM, DWT.RIGHT | DWT.BOTTOM + * @since 3.0 + */ + public static int getRelativePosition(Rectangle boundary, Point toTest) { + int result = 0; + + if (toTest.x < boundary.x) { + result |= DWT.LEFT; + } else if (toTest.x >= boundary.x + boundary.width) { + result |= DWT.RIGHT; + } + + if (toTest.y < boundary.y) { + result |= DWT.TOP; + } else if (toTest.y >= boundary.y + boundary.height) { + result |= DWT.BOTTOM; + } + + return result; + } + + /** + * Returns the distance from the point to the nearest edge of the given + * rectangle. Returns negative values if the point lies outside the rectangle. + * + * @param boundary rectangle to test + * @param toTest point to test + * @return the distance between the given point and the nearest edge of the rectangle. + * Returns positive values for points inside the rectangle and negative values for points + * outside the rectangle. + * @since 3.1 + */ + public static int getDistanceFrom(Rectangle boundary, Point toTest) { + int side = getClosestSide(boundary, toTest); + return getDistanceFromEdge(boundary, toTest, side); + } + + /** + * Returns the edge of the given rectangle is closest to the given + * point. + * + * @param boundary rectangle to test + * @param toTest point to compare + * @return one of DWT.LEFT, DWT.RIGHT, DWT.TOP, or DWT.BOTTOM + * + * @since 3.0 + */ + public static int getClosestSide(Rectangle boundary, Point toTest) { + int[] sides = [ DWT.LEFT, DWT.RIGHT, DWT.TOP, DWT.BOTTOM ]; + + int closestSide = DWT.LEFT; + int closestDistance = Integer.MAX_VALUE; + + for (int idx = 0; idx < sides.length; idx++) { + int side = sides[idx]; + + int distance = getDistanceFromEdge(boundary, toTest, side); + + if (distance < closestDistance) { + closestDistance = distance; + closestSide = side; + } + } + + return closestSide; + } + + /** + * Returns a copy of the given rectangle + * + * @param toCopy rectangle to copy + * @return a copy of the given rectangle + * @since 3.0 + */ + public static Rectangle copy(Rectangle toCopy) { + return new Rectangle(toCopy.x, toCopy.y, toCopy.width, toCopy.height); + } + + /** + * Returns the size of the rectangle, as a Point + * + * @param rectangle rectangle whose size is being computed + * @return the size of the given rectangle + * @since 3.0 + */ + public static Point getSize(Rectangle rectangle) { + return new Point(rectangle.width, rectangle.height); + } + + /** + * Sets the size of the given rectangle to the given size + * + * @param rectangle rectangle to modify + * @param newSize new size of the rectangle + * @since 3.0 + */ + public static void setSize(Rectangle rectangle, Point newSize) { + rectangle.width = newSize.x; + rectangle.height = newSize.y; + } + + /** + * Sets the x,y position of the given rectangle. For a normalized + * rectangle (a rectangle with positive width and height), this will + * be the upper-left corner of the rectangle. + * + * @param rectangle rectangle to modify + * @param newSize new size of the rectangle + * + * @since 3.0 + */ + public static void setLocation(Rectangle rectangle, Point newSize) { + rectangle.width = newSize.x; + rectangle.height = newSize.y; + } + + /** + * Returns the x,y position of the given rectangle. For normalized rectangles + * (rectangles with positive width and height), this is the upper-left + * corner of the rectangle. + * + * @param toQuery rectangle to query + * @return a Point containing the x,y position of the rectangle + * + * @since 3.0 + */ + public static Point getLocation(Rectangle toQuery) { + return new Point(toQuery.x, toQuery.y); + } + + /** + * Returns a new rectangle with the given position and dimensions, expressed + * as points. + * + * @param position the (x,y) position of the rectangle + * @param size the size of the new rectangle, where (x,y) -> (width, height) + * @return a new Rectangle with the given position and size + * + * @since 3.0 + */ + public static Rectangle createRectangle(Point position, Point size) { + return new Rectangle(position.x, position.y, size.x, size.y); + } + + /** + * Repositions the 'inner' rectangle to lie completely within the bounds of the 'outer' + * rectangle if possible. One use for this is to ensure that, when setting a control's bounds, + * that they will always lie within its parent's client area (to avoid clipping). + * + * @param inner The 'inner' rectangle to be repositioned (should be smaller than the 'outer' rectangle) + * @param outer The 'outer' rectangle + */ + public static void moveInside(Rectangle inner, Rectangle outer) { + // adjust X + if (inner.x < outer.x) { + inner.x = outer.x; + } + if ((inner.x + inner.width) > (outer.x + outer.width)) { + inner.x -= (inner.x + inner.width) - (outer.x + outer.width); + } + + // Adjust Y + if (inner.y < outer.y) { + inner.y = outer.y; + } + if ((inner.y + inner.height) > (outer.y + outer.height)) { + inner.y -= (inner.y + inner.height) - (outer.y + outer.height); + } + } + +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/ILogger.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/ILogger.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 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: + * Chris Gross (schtoo@schtoo.com) - initial API and implementation + * (bug 49497 [RCP] JFace dependency on dwtx.core.runtime enlarges standalone JFace applications) + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ + +module dwtx.jface.util.ILogger; + +import dwtx.core.runtime.IStatus; + +/** + * A mechanism to log errors throughout JFace. + *

+ * Clients may provide their own implementation to change + * how errors are logged from within JFace. + *

+ * + * @see dwtx.jface.util.Policy#getLog() + * @see dwtx.jface.util.Policy#setLog(ILogger) + * @since 3.1 + */ +public interface ILogger { + + /** + * Logs the given status. + * + * @param status the status to log + */ + public void log(IStatus status); + +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/IOpenEventListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/IOpenEventListener.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.util.IOpenEventListener; + +import dwt.events.SelectionEvent; + +/** + * Listener for open events which are generated on selection + * of default selection depending on the user preferences. + * + *

+ * Usage: + *

+ *  OpenStrategy handler = new OpenStrategy(control);
+ *  handler.addOpenListener(new IOpenEventListener() {
+ *      public void handleOpen(SelectionEvent e) {
+ *          ... // code to handle the open event.
+ *      }
+ *  });
+ * 
+ *

+ * + * @see OpenStrategy + */ +public interface IOpenEventListener { + /** + * Called when a selection or default selection occurs + * depending on the user preference. + * @param e the selection event + */ + public void handleOpen(SelectionEvent e); +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/IPropertyChangeListener.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/IPropertyChangeListener.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.util.IPropertyChangeListener; + +import dwtx.jface.util.PropertyChangeEvent; + +import dwt.dwthelper.utils; + +/** + * Listener for property changes. + *

+ * Usage: + *

+ * IPropertyChangeListener listener =
+ *   new IPropertyChangeListener() {
+ *      public void propertyChange(PropertyChangeEvent event) {
+ *         ... // code to deal with occurrence of property change
+ *      }
+ *   };
+ * emitter.addPropertyChangeListener(listener);
+ * ...
+ * emitter.removePropertyChangeListener(listener);
+ * 
+ *

+ */ +public interface IPropertyChangeListener : EventListener { + /** + * Notification that a property has changed. + *

+ * This method gets called when the observed object fires a property + * change event. + *

+ * + * @param event the property change event object describing which property + * changed and how + */ + public void propertyChange(PropertyChangeEvent event); +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/ISafeRunnableRunner.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/ISafeRunnableRunner.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2005, 2006 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: + * Chris Gross (schtoo@schtoo.com) - initial API and implementation + * (bug 49497 [RCP] JFace dependency on dwtx.core.runtime enlarges standalone JFace applications) + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ + +module dwtx.jface.util.ISafeRunnableRunner; + +import dwtx.core.runtime.ISafeRunnable; + +/** + * Runs a safe runnables. + *

+ * Clients may provide their own implementation to change + * how safe runnables are run from within JFace. + *

+ * + * @see SafeRunnable#getRunner() + * @see SafeRunnable#setRunner(ISafeRunnableRunner) + * @see SafeRunnable#run(ISafeRunnable) + * @since 3.1 + */ +public interface ISafeRunnableRunner { + + /** + * Runs the runnable. All ISafeRunnableRunners must catch any exception + * thrown by the ISafeRunnable and pass the exception to + * ISafeRunnable.handleException(). + * @param code the code executed as a save runnable + * + * @see SafeRunnable#run(ISafeRunnable) + */ + public abstract void run(ISafeRunnable code); + +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/ListenerList.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/ListenerList.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.util.ListenerList; + +static import dwtx.core.runtime.ListenerList; + +import dwt.dwthelper.utils; + +/** + * This class is used to maintain a list of listeners, and is used in the + * implementations of several classes within JFace which allow you to register + * listeners of various kinds. It is a fairly lightweight object, occupying + * minimal space when no listeners are registered. + *

+ * Note that the add method checks for and eliminates duplicates + * based on identity (not equality). Likewise, the remove method + * compares based on identity. + *

+ *

+ * Use the getListeners method when notifying listeners. Note + * that no garbage is created if no listeners are registered. The recommended + * code sequence for notifying all registered listeners of say, + * FooListener.eventHappened, is: + * + *

+ * Object[] listeners = myListenerList.getListeners();
+ * for (int i = 0; i < listeners.length; ++i) {
+ *  ((FooListener) listeners[i]).eventHappened(event);
+ * }
+ * 
+ * + *

+ * + * @deprecated Please use {@link dwtx.core.runtime.ListenerList} instead. + * Please note that the {@link #ListenerList(int)} and + * {@link dwtx.core.runtime.ListenerList#ListenerList(int)} + * constructors have different semantics. Please read the javadoc + * carefully. Also note that the equivalent of + * {@link #ListenerList()} is actually + * {@link dwtx.core.runtime.ListenerList#ListenerList(int)} + * with {@link dwtx.core.runtime.ListenerList#IDENTITY} as + * the argument. + */ +public class ListenerList : dwtx.core.runtime.ListenerList.ListenerList { + + /** + * Creates a listener list with an initial capacity of 1. + */ + public this() { + super(IDENTITY); + } + + /** + * Creates a listener list with the given initial capacity. + * + * @param capacity + * the number of listeners which this list can initially accept + * without growing its internal representation; must be at least + * 1 + */ + public this(int capacity) { + // the runtime ListenerList does not support capacity + this(); + } +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/OpenStrategy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/OpenStrategy.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,495 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.util.OpenStrategy; + +import dwtx.jface.util.IOpenEventListener; + +import dwt.DWT; +import dwt.custom.TableTree; +import dwt.custom.TableTreeItem; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.graphics.Point; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Table; +import dwt.widgets.TableItem; +import dwt.widgets.Tree; +import dwt.widgets.TreeItem; +import dwt.widgets.Widget; +import dwtx.core.runtime.ListenerList; + +import dwt.dwthelper.utils; +import dwt.dwthelper.Runnable; + +/** + * Implementation of single-click and double-click strategies. + *

+ * Usage: + *

+ *  OpenStrategy handler = new OpenStrategy(control);
+ *  handler.addOpenListener(new IOpenEventListener() {
+ *      public void handleOpen(SelectionEvent e) {
+ *          ... // code to handle the open event.
+ *      }
+ *  });
+ * 
+ *

+ */ +public class OpenStrategy { + /** + * Default behavior. Double click to open the item. + */ + public static const int DOUBLE_CLICK = 0; + + /** + * Single click will open the item. + */ + public static const int SINGLE_CLICK = 1; + + /** + * Hover will select the item. + */ + public static const int SELECT_ON_HOVER = 1 << 1; + + /** + * Open item when using arrow keys + */ + public static const int ARROW_KEYS_OPEN = 1 << 2; + + /** A single click will generate + * an open event but key arrows will not do anything. + * + * @deprecated + */ + public static const int NO_TIMER = SINGLE_CLICK; + + /** A single click will generate an open + * event and key arrows will generate an open event after a + * small time. + * + * @deprecated + */ + public static const int FILE_EXPLORER = SINGLE_CLICK | ARROW_KEYS_OPEN; + + /** Pointing to an item will change the selection + * and a single click will gererate an open event + * + * @deprecated + */ + public static const int ACTIVE_DESKTOP = SINGLE_CLICK | SELECT_ON_HOVER; + + // Time used in FILE_EXPLORER and ACTIVE_DESKTOP + private static const int TIME = 500; + + /* SINGLE_CLICK or DOUBLE_CLICK; + * In case of SINGLE_CLICK, the bits SELECT_ON_HOVER and ARROW_KEYS_OPEN + * my be set as well. */ + private static int CURRENT_METHOD = DOUBLE_CLICK; + + private Listener eventHandler; + + private ListenerList openEventListeners; + + private ListenerList selectionEventListeners; + + private ListenerList postSelectionEventListeners; + + /** + * @param control the control the strategy is applied to + */ + public this(Control control) { + openEventListeners = new ListenerList(); + selectionEventListeners = new ListenerList(); + postSelectionEventListeners = new ListenerList(); + initializeHandler(control.getDisplay()); + addListener(control); + } + + /** + * Adds an IOpenEventListener to the collection of openEventListeners + * @param listener the listener to add + */ + public void addOpenListener(IOpenEventListener listener) { + openEventListeners.add(cast(Object)listener); + } + + /** + * Removes an IOpenEventListener to the collection of openEventListeners + * @param listener the listener to remove + */ + public void removeOpenListener(IOpenEventListener listener) { + openEventListeners.remove(cast(Object)listener); + } + + /** + * Adds an SelectionListener to the collection of selectionEventListeners + * @param listener the listener to add + */ + public void addSelectionListener(SelectionListener listener) { + selectionEventListeners.add(cast(Object)listener); + } + + /** + * Removes an SelectionListener to the collection of selectionEventListeners + * @param listener the listener to remove + */ + public void removeSelectionListener(SelectionListener listener) { + selectionEventListeners.remove(cast(Object)listener); + } + + /** + * Adds an SelectionListener to the collection of selectionEventListeners + * @param listener the listener to add + */ + public void addPostSelectionListener(SelectionListener listener) { + postSelectionEventListeners.add(cast(Object)listener); + } + + /** + * Removes an SelectionListener to the collection of selectionEventListeners + * @param listener the listener to remove + */ + public void removePostSelectionListener(SelectionListener listener) { + postSelectionEventListeners.remove(cast(Object)listener); + } + + /** + * This method is internal to the framework; it should not be implemented outside + * the framework. + * @return the current used single/double-click method + * + */ + public static int getOpenMethod() { + return CURRENT_METHOD; + } + + /** + * Set the current used single/double-click method. + * + * This method is internal to the framework; it should not be implemented outside + * the framework. + * @param method the method to be used + * @see OpenStrategy#DOUBLE_CLICK + * @see OpenStrategy#SINGLE_CLICK + * @see OpenStrategy#SELECT_ON_HOVER + * @see OpenStrategy#ARROW_KEYS_OPEN + */ + public static void setOpenMethod(int method) { + if (method is DOUBLE_CLICK) { + CURRENT_METHOD = method; + return; + } + if ((method & SINGLE_CLICK) is 0) { + throw new IllegalArgumentException("Invalid open mode"); //$NON-NLS-1$ + } + if ((method & (SINGLE_CLICK | SELECT_ON_HOVER | ARROW_KEYS_OPEN)) is 0) { + throw new IllegalArgumentException("Invalid open mode"); //$NON-NLS-1$ + } + CURRENT_METHOD = method; + } + + /** + * @return true if editors should be activated when opened. + */ + public static bool activateOnOpen() { + return getOpenMethod() is DOUBLE_CLICK; + } + + /* + * Adds all needed listener to the control in order to implement + * single-click/double-click strategies. + */ + private void addListener(Control c) { + c.addListener(DWT.MouseEnter, eventHandler); + c.addListener(DWT.MouseExit, eventHandler); + c.addListener(DWT.MouseMove, eventHandler); + c.addListener(DWT.MouseDown, eventHandler); + c.addListener(DWT.MouseUp, eventHandler); + c.addListener(DWT.KeyDown, eventHandler); + c.addListener(DWT.Selection, eventHandler); + c.addListener(DWT.DefaultSelection, eventHandler); + c.addListener(DWT.Collapse, eventHandler); + c.addListener(DWT.Expand, eventHandler); + } + + /* + * Fire the selection event to all selectionEventListeners + */ + private void fireSelectionEvent(SelectionEvent e) { + if (e.item !is null && e.item.isDisposed()) { + return; + } + Object l[] = selectionEventListeners.getListeners(); + for (int i = 0; i < l.length; i++) { + (cast(SelectionListener) l[i]).widgetSelected(e); + } + } + + /* + * Fire the default selection event to all selectionEventListeners + */ + private void fireDefaultSelectionEvent(SelectionEvent e) { + Object l[] = selectionEventListeners.getListeners(); + for (int i = 0; i < l.length; i++) { + (cast(SelectionListener) l[i]).widgetDefaultSelected(e); + } + } + + /* + * Fire the post selection event to all postSelectionEventListeners + */ + private void firePostSelectionEvent(SelectionEvent e) { + if (e.item !is null && e.item.isDisposed()) { + return; + } + Object l[] = postSelectionEventListeners.getListeners(); + for (int i = 0; i < l.length; i++) { + (cast(SelectionListener) l[i]).widgetSelected(e); + } + } + + /* + * Fire the open event to all openEventListeners + */ + private void fireOpenEvent(SelectionEvent e) { + if (e.item !is null && e.item.isDisposed()) { + return; + } + Object l[] = openEventListeners.getListeners(); + for (int i = 0; i < l.length; i++) { + (cast(IOpenEventListener) l[i]).handleOpen(e); + } + } + + //Initialize event handler. + private void initializeHandler( Display display_) { + eventHandler = new class() Listener { + Display display; + bool timerStarted = false; + + Event mouseUpEvent = null; + + Event mouseMoveEvent = null; + + SelectionEvent selectionPendent = null; + + bool enterKeyDown = false; + + SelectionEvent defaultSelectionPendent = null; + + bool arrowKeyDown = false; + + int[] count; + + long startTime; + + bool collapseOccurred = false; + + bool expandOccurred = false; + + this(){ + display = display_; + startTime = System.currentTimeMillis(); + count = new int[1]; + } + + public void handleEvent( Event e) { + if (e.type is DWT.DefaultSelection) { + SelectionEvent event = new SelectionEvent(e); + fireDefaultSelectionEvent(event); + if (CURRENT_METHOD is DOUBLE_CLICK) { + fireOpenEvent(event); + } else { + if (enterKeyDown) { + fireOpenEvent(event); + enterKeyDown = false; + defaultSelectionPendent = null; + } else { + defaultSelectionPendent = event; + } + } + return; + } + + switch (e.type) { + case DWT.MouseEnter: + case DWT.MouseExit: + mouseUpEvent = null; + mouseMoveEvent = null; + selectionPendent = null; + break; + case DWT.MouseMove: + if ((CURRENT_METHOD & SELECT_ON_HOVER) is 0) { + return; + } + if (e.stateMask !is 0) { + return; + } + if (e.widget.getDisplay().getFocusControl() !is e.widget) { + return; + } + mouseMoveEvent = e; + Runnable runnable = new class() Runnable { + public void run() { + long time = System.currentTimeMillis(); + int diff = cast(int) (time - startTime); + if (diff <= TIME) { + display.timerExec(diff * 2 / 3, this ); + } else { + timerStarted = false; + setSelection(mouseMoveEvent); + } + } + }; + startTime = System.currentTimeMillis(); + if (!timerStarted) { + timerStarted = true; + display.timerExec(TIME * 2 / 3, runnable ); + } + break; + case DWT.MouseDown: + mouseUpEvent = null; + arrowKeyDown = false; + break; + case DWT.Expand: + expandOccurred = true; + break; + case DWT.Collapse: + collapseOccurred = true; + break; + case DWT.MouseUp: + mouseMoveEvent = null; + if ((e.button !is 1) || ((e.stateMask & ~DWT.BUTTON1) !is 0)) { + return; + } + if (selectionPendent !is null + && !(collapseOccurred || expandOccurred)) { + mouseSelectItem(selectionPendent); + } else { + mouseUpEvent = e; + collapseOccurred = false; + expandOccurred = false; + } + break; + case DWT.KeyDown: + mouseMoveEvent = null; + mouseUpEvent = null; + arrowKeyDown = ((e.keyCode is DWT.ARROW_UP) || (e.keyCode is DWT.ARROW_DOWN)) + && e.stateMask is 0; + if (e.character is DWT.CR) { + if (defaultSelectionPendent !is null) { + fireOpenEvent(new SelectionEvent(e)); + enterKeyDown = false; + defaultSelectionPendent = null; + } else { + enterKeyDown = true; + } + } + break; + case DWT.Selection: + SelectionEvent event = new SelectionEvent(e); + fireSelectionEvent(event); + mouseMoveEvent = null; + if (mouseUpEvent !is null) { + mouseSelectItem(event); + } else { + selectionPendent = event; + } + count[0]++; + // In the case of arrowUp/arrowDown when in the arrowKeysOpen mode, we + // want to delay any selection until the last arrowDown/Up occurs. This + // handles the case where the user presses arrowDown/Up successively. + // We only want to open an editor for the last selected item. + display.asyncExec(new class() Runnable { + int id; + Event e2; + this(){ id = count[0]; e2 = e; } + public void run() { + if (arrowKeyDown) { + display.timerExec(TIME, new class() Runnable { + int id2; + Event e3; + this(){ id2 = id; e3 = e2; } + public void run() { + if (id2 is count[0]) { + firePostSelectionEvent(new SelectionEvent(e3)); + if ((CURRENT_METHOD & ARROW_KEYS_OPEN) !is 0) { + fireOpenEvent(new SelectionEvent(e3)); + } + } + } + }); + } else { + firePostSelectionEvent(new SelectionEvent(e2)); + } + } + }); + break; + } + } + + void mouseSelectItem(SelectionEvent e) { + if ((CURRENT_METHOD & SINGLE_CLICK) !is 0) { + fireOpenEvent(e); + } + mouseUpEvent = null; + selectionPendent = null; + } + + void setSelection(Event e) { + if (e is null) { + return; + } + Widget w = e.widget; + if (w.isDisposed()) { + return; + } + + SelectionEvent selEvent = new SelectionEvent(e); + + /*ISSUE: May have to create a interface with method: + setSelection(Point p) so that user's custom widgets + can use this class. If we keep this option. */ + if ( auto tree = cast(Tree)w) { + TreeItem item = tree.getItem(new Point(e.x, e.y)); + if (item !is null) { + tree.setSelection([ item ]); + } + selEvent.item = item; + } else if ( auto table = cast(Table)w) { + TableItem item = table.getItem(new Point(e.x, e.y)); + if (item !is null) { + table.setSelection([ item ]); + } + selEvent.item = item; + } else if ( auto table = cast(TableTree)w) { + TableTreeItem item = table.getItem(new Point(e.x, e.y)); + if (item !is null) { + table.setSelection([ item ]); + } + selEvent.item = item; + } else { + return; + } + if (selEvent.item is null) { + return; + } + fireSelectionEvent(selEvent); + firePostSelectionEvent(selEvent); + } + }; + } +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/Policy.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/Policy.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,217 @@ +/******************************************************************************* + * Copyright (c) 2004, 2007 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 + * Chris Gross (schtoo@schtoo.com) - support for ILogger added + * (bug 49497 [RCP] JFace dependency on dwtx.core.runtime enlarges standalone JFace applications) + * Port to the D programming language: + * Frank Benoit + *******************************************************************************/ +module dwtx.jface.util.Policy; + +static import dwtx.core.runtime.Assert; +import dwtx.core.runtime.IStatus; +import dwtx.jface.dialogs.AnimatorFactory; +import dwtx.jface.dialogs.ErrorSupportProvider; + +import dwtx.jface.util.ILogger; + +import dwt.dwthelper.utils; +import tango.io.Stdout; + +/** + * The Policy class handles settings for behaviour, debug flags and logging + * within JFace. + * + * @since 3.0 + */ +public class Policy { + + /** + * Constant for the the default setting for debug options. + */ + public static const bool DEFAULT = false; + + /** + * The unique identifier of the JFace plug-in. + */ + public static const String JFACE = "dwtx.jface";//$NON-NLS-1$ + + private static ILogger log; + + private static Comparator viewerComparator; + + private static AnimatorFactory animatorFactory; + + /** + * A flag to indicate whether unparented dialogs should be checked. + */ + public static bool DEBUG_DIALOG_NO_PARENT = DEFAULT; + + /** + * A flag to indicate whether actions are being traced. + */ + public static bool TRACE_ACTIONS = DEFAULT; + + /** + * A flag to indicate whether toolbars are being traced. + */ + + public static bool TRACE_TOOLBAR = DEFAULT; + + private static ErrorSupportProvider errorSupportProvider; + + /** + * Returns the dummy log to use if none has been set + */ + private static ILogger getDummyLog() { + return new class ILogger { + public void log(IStatus status) { + Stderr.formatln(status.getMessage()); + if (status.getException() !is null) { + auto e = status.getException(); + Stderr( "Exception in {}({}): {}", e.file, e.line, e.msg ); + foreach( msg; e.info ){ + Stderr( " trc: {}", msg ); + } +// status.getException().printStackTrace(); + } + } + }; + } + + /** + * Sets the logger used by JFace to log errors. + * + * @param logger + * the logger to use, or null to use the default + * logger + * @since 3.1 + */ + public static void setLog(ILogger logger) { + log = logger; + } + + /** + * Returns the logger used by JFace to log errors. + *

+ * The default logger prints the status to System.err. + *

+ * + * @return the logger + * @since 3.1 + */ + public static ILogger getLog() { + if (log is null) { + log = getDummyLog(); + } + return log; + } + + /** + * Return the default comparator used by JFace to sort strings. + * + * @return a default comparator used by JFace to sort strings + */ + private static Comparator getDefaultComparator() { + return new class() Comparator { + /** + * Compares string s1 to string s2. + * + * @param s1 + * string 1 + * @param s2 + * string 2 + * @return Returns an integer value. Value is less than zero if + * source is less than target, value is zero if source and + * target are equal, value is greater than zero if source is + * greater than target. + * @exception ClassCastException + * the arguments cannot be cast to Strings. + */ + public int compare(Object s1, Object s2) { + auto a = (cast(ArrayWrapperString) s1).array; + auto b = (cast(ArrayWrapperString) s2).array; + return a < b; + } + }; + } + + /** + * Return the comparator used by JFace to sort strings. + * + * @return the comparator used by JFace to sort strings + * @since 3.2 + */ + public static Comparator getComparator() { + if (viewerComparator is null) { + viewerComparator = getDefaultComparator(); + } + return viewerComparator; + } + + /** + * Sets the comparator used by JFace to sort strings. + * + * @param comparator + * comparator used by JFace to sort strings + * @since 3.2 + */ + public static void setComparator(Comparator comparator) { + dwtx.core.runtime.Assert.Assert.isTrue(viewerComparator is null); + viewerComparator = comparator; + } + + /** + * Sets the animator factory used by JFace to create control animator + * instances. + * + * @param factory + * the AnimatorFactory to use. + * @since 3.2 + * @deprecated this is no longer in use as of 3.3 + */ + public static void setAnimatorFactory(AnimatorFactory factory) { + animatorFactory = factory; + } + + /** + * Returns the animator factory used by JFace to create control animator + * instances. + * + * @return the animator factory used to create control animator instances. + * @since 3.2 + * @deprecated this is no longer in use as of 3.3 + */ + public static AnimatorFactory getAnimatorFactory() { + if (animatorFactory is null) + animatorFactory = new AnimatorFactory(); + return animatorFactory; + } + + /** + * Set the error support provider for error dialogs. + * + * @param provider + * @since 3.3 + */ + public static void setErrorSupportProvider(ErrorSupportProvider provider) { + errorSupportProvider = provider; + } + + /** + * Return the ErrorSupportProvider for the receiver. + * + * @return ErrorSupportProvider or null if this has not been set + * @since 3.3 + */ + public static ErrorSupportProvider getErrorSupportProvider() { + return errorSupportProvider; + } + +} diff -r 6518c18a01f7 -r c87617952847 dwtx/jface/util/PropertyChangeEvent.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/util/PropertyChangeEvent.d Fri Mar 28 17:08:33 2008 +0100 @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2000, 2006 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 + *******************************************************************************/ +module dwtx.jface.util.PropertyChangeEvent; + +import dwtx.core.runtime.Assert; + +import dwt.dwthelper.utils; + +/** + * An event object describing a change to a named property. + *

+ * This concrete class was designed to be instantiated, but may + * also be subclassed if required. + *

+ *

+ * The JFace frameworks contain classes that report property + * change events for internal state changes that may be of interest + * to external parties. A special listener interface + * (IPropertyChangeListener) is defined for this purpose, + * and a typical class allow listeners to be registered via + * an addPropertyChangeListener method. + *

+ * + * @see IPropertyChangeListener + */ +public class PropertyChangeEvent : EventObject { + + /** + * Generated serial version UID for this class. + * @since 3.1 + */ + private static final long serialVersionUID = 3256726173533811256L; + + /** + * The name of the changed property. + */ + private String propertyName; + + /** + * The old value of the changed property, or null if + * not known or not relevant. + */ + private Object oldValue; + + /** + * The new value of the changed property, or null if + * not known or not relevant. + */ + private Object newValue; + + /** + * Creates a new property change event. + * + * @param source the object whose property has changed + * @param property the property that has changed (must not be null) + * @param oldValue the old value of the property, or null if none + * @param newValue the new value of the property, or null if none + */ + public this(Object source, String property, Object oldValue, + Object newValue) { + super(source); + Assert.isTrue( property.length > 0 ); + this.propertyName = property; + this.oldValue = oldValue; + this.newValue = newValue; + } + + /** + * Returns the new value of the property. + * + * @return the new value, or null if not known + * or not relevant (for instance if the property was removed). + */ + public Object getNewValue() { + return newValue; + } + + /** + * Returns the old value of the property. + * + * @return the old value, or null if not known + * or not relevant (for instance if the property was just + * added and there was no old value). + */ + public Object getOldValue() { + return oldValue; + } + + /** + * Returns the name of the property that changed. + *

+ * Warning: there is no guarantee that the property name returned + * is a constant string. Callers must compare property names using + * equals, not is. + *

+ * + * @return the name of the property that changed + */ + public String getProperty() { + return propertyName; + } +}