# HG changeset patch # User Frank Benoit # Date 1207031091 -7200 # Node ID f459f9147650eda5bbfccc4825228e33ad3c1633 # Parent e0f0aaf75edd11942b0737e99d08b958d767a67a ImageAndMessgeDialog diff -r e0f0aaf75edd -r f459f9147650 dwtx/jface/dialogs/ImageAndMessageArea.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/dialogs/ImageAndMessageArea.d Tue Apr 01 08:24:51 2008 +0200 @@ -0,0 +1,219 @@ +/******************************************************************************* + * 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.ImageAndMessageArea; + +import dwtx.jface.dialogs.IDialogConstants; + +import dwt.DWT; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.layout.GridData; +import dwt.layout.GridLayout; +import dwt.widgets.Composite; +import dwt.widgets.Layout; +import dwt.widgets.Text; +import dwtx.jface.fieldassist.DecoratedField; +import dwtx.jface.fieldassist.FieldDecorationRegistry; +import dwtx.jface.fieldassist.TextControlCreator; +import dwtx.jface.resource.JFaceResources; + +import dwt.dwthelper.utils; + +/** + * Instances of this class provide a message area to display a message and an + * associated image. + *

+ * This class is not intended to be extended by clients. + *

+ * + * @since 3.2 + * @deprecated As of 3.3, this class is no longer necessary. + * + */ +public class ImageAndMessageArea : Composite { + + private int BORDER_MARGIN = IDialogConstants.HORIZONTAL_SPACING / 2; + + private DecoratedField messageField; + + private Composite container; + + /** + * Constructs a new ImageAndMessageArea with an empty decorated field. Calls + * to setText(String text) and + * setImage(Image image) are required in order to fill the + * message area. Also, the instance will be invisible when initially + * created. + *

+ * The style bit DWT.WRAP should be used if a larger message + * area is desired. + *

+ * + * @param parent + * the parent composite + * @param style + * the DWT style bits. Using DWT.WRAP will create a larger + * message area. + */ + public this(Composite parent, int style) { + super(parent, style); + container = new Composite(this, style); + GridLayout glayout = new GridLayout(); + glayout.numColumns = 2; + glayout.marginWidth = 0; + glayout.marginHeight = 0; + glayout.marginTop = BORDER_MARGIN; + glayout.marginBottom = BORDER_MARGIN; + container.setLayout(glayout); + + messageField = new DecoratedField(container, DWT.READ_ONLY | style, + new TextControlCreator()); + setFont(JFaceResources.getDialogFont()); + + GridData gd = new GridData(DWT.FILL, DWT.FILL, true, true); + int lineHeight = (cast(Text) messageField.getControl()).getLineHeight(); + if ((style & DWT.WRAP) > 0) + gd.heightHint = 2 * lineHeight; + else + gd.heightHint = lineHeight; + + messageField.getLayoutControl().setLayoutData(gd); + + addPaintListener(new class PaintListener { + /* + * (non-Javadoc) + * + * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent) + */ + public void paintControl(PaintEvent e) { + onPaint(e); + } + }); + + // sets the layout and size to account for the BORDER_MARGIN between + // the border drawn around the container and the decorated field. + setLayout(new class Layout { + /* + * (non-Javadoc) + * + * @see dwt.widgets.Layout#layout(dwt.widgets.Composite, + * bool) + */ + public void layout(Composite parent, bool changed) { + Rectangle carea = getClientArea(); + container.setBounds(carea.x + BORDER_MARGIN, carea.y + + BORDER_MARGIN, carea.width - (2 * BORDER_MARGIN), + carea.height - (2 * BORDER_MARGIN)); + } + + /* + * (non-Javadoc) + * + * @see dwt.widgets.Layout#computeSize(dwt.widgets.Composite, + * int, int, bool) + */ + public Point computeSize(Composite parent, int wHint, int hHint, + bool changed) { + Point size; + size = container.computeSize(wHint, hHint, changed); + + // size set to account for the BORDER_MARGIN on + // all sides of the decorated field + size.x += 4; + size.y += 4; + return size; + } + }); + setVisible(false); + } + + /* + * (non-Javadoc) + * + * @see dwt.widgets.Control#setBackground(dwt.graphics.Color) + */ + public void setBackground(Color bg) { + super.setBackground(bg); + messageField.getLayoutControl().setBackground(bg); + messageField.getControl().setBackground(bg); + container.setBackground(bg); + } + + /** + * Sets the text in the decorated field which will be displayed in the + * message area. + * + * @param text + * the text to be displayed in the message area + * + * @see dwt.widgets.Text#setText(String string) + */ + public void setText(String text) { + (cast(Text) messageField.getControl()).setText(text); + } + + /** + * Adds an image to decorated field to be shown in the message area. + * + * @param image + * desired image to be shown in the ImageAndMessageArea + */ + public void setImage(Image image) { + FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault(); + registry.registerFieldDecoration("messageImage", null, image); //$NON-NLS-1$ + messageField.addFieldDecoration(registry + .getFieldDecoration("messageImage"), //$NON-NLS-1$ + DWT.LEFT | DWT.TOP, false); + } + + /** + * Draws the message area composite with rounded corners. + */ + private void onPaint(PaintEvent e) { + Rectangle carea = getClientArea(); + e.gc.setForeground(getForeground()); + + // draws the polyline to be rounded in a 2 pixel squared area + e.gc.drawPolyline([ carea.x, carea.y + carea.height - 1, + carea.x, carea.y + 2, carea.x + 2, carea.y, + carea.x + carea.width - 3, carea.y, carea.x + carea.width - 1, + carea.y + 2, carea.x + carea.width - 1, + carea.y + carea.height - 1 ]); + } + + /* + * (non-Javadoc) + * + * @see dwt.widgets.Control#setFont(dwt.graphics.Font) + */ + public void setFont(Font font) { + super.setFont(font); + (cast(Text) messageField.getControl()).setFont(font); + } + + /* + * (non-Javadoc) + * + * @see dwt.widgets.Control#setToolTipText(java.lang.String) + */ + public void setToolTipText(String text) { + super.setToolTipText(text); + (cast(Text) messageField.getControl()).setToolTipText(text); + } +} diff -r e0f0aaf75edd -r f459f9147650 dwtx/jface/dialogs/ProgressIndicator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/dialogs/ProgressIndicator.d Tue Apr 01 08:24:51 2008 +0200 @@ -0,0 +1,129 @@ +/******************************************************************************* + * 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.dialogs.ProgressIndicator; + +import dwtx.jface.dialogs.IDialogConstants; + +import dwt.DWT; +import dwt.custom.StackLayout; +import dwt.widgets.Composite; +import dwt.widgets.ProgressBar; + +import dwt.dwthelper.utils; + +/** + * A control for showing progress feedback for a long running operation. This + * control supports both determinate and indeterminate DWT progress bars. For + * indeterminate progress, we don't have to know the total amount of work in + * advance and no worked method needs to be called. + */ +public class ProgressIndicator : Composite { + private const static int PROGRESS_MAX = 1000; // value to use for max in + + // progress bar + private bool animated = true; + + private StackLayout layout_; + + private ProgressBar determinateProgressBar; + + private ProgressBar indeterminateProgressBar; + + private double totalWork; + + private double sumWorked; + + /** + * Create a ProgressIndicator as a child under the given parent. + * + * @param parent + * The widgets parent + */ + public this(Composite parent) { + super(parent, DWT.NULL); + determinateProgressBar = new ProgressBar(this, DWT.HORIZONTAL); + indeterminateProgressBar = new ProgressBar(this, DWT.HORIZONTAL + | DWT.INDETERMINATE); + layout_ = new StackLayout(); + setLayout(layout_); + } + + /** + * Initialize the progress bar to be animated. + */ + public void beginAnimatedTask() { + done(); + layout_.topControl = indeterminateProgressBar; + layout(); + animated = true; + } + + /** + * Initialize the progress bar. + * + * @param max + * The maximum value. + */ + public void beginTask(int max) { + done(); + this.totalWork = max; + this.sumWorked = 0; + determinateProgressBar.setMinimum(0); + determinateProgressBar.setMaximum(PROGRESS_MAX); + determinateProgressBar.setSelection(0); + layout_.topControl = determinateProgressBar; + layout(); + animated = false; + } + + /** + * Progress is done. + */ + public void done() { + if (!animated) { + determinateProgressBar.setMinimum(0); + determinateProgressBar.setMaximum(0); + determinateProgressBar.setSelection(0); + } + layout_.topControl = null; + layout(); + } + + /** + * Moves the progress indicator to the end. + */ + public void sendRemainingWork() { + worked(totalWork - sumWorked); + } + + /** + * Moves the progress indicator by the given amount of work units + * @param work the amount of work to increment by. + */ + public void worked(double work) { + if (work is 0 || animated) { + return; + } + sumWorked += work; + if (sumWorked > totalWork) { + sumWorked = totalWork; + } + if (sumWorked < 0) { + sumWorked = 0; + } + int value = cast(int) (sumWorked / totalWork * PROGRESS_MAX); + if (determinateProgressBar.getSelection() < value) { + determinateProgressBar.setSelection(value); + } + } +} diff -r e0f0aaf75edd -r f459f9147650 dwtx/jface/fieldassist/DecoratedField.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/fieldassist/DecoratedField.d Tue Apr 01 08:24:51 2008 +0200 @@ -0,0 +1,886 @@ +/******************************************************************************* + * Copyright (c) 2005, 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.fieldassist.DecoratedField; + +import dwtx.jface.fieldassist.FieldDecoration; +import dwtx.jface.fieldassist.FieldDecorationRegistry; +import dwtx.jface.fieldassist.IControlCreator; + +import dwt.DWT; +import dwt.events.DisposeEvent; +import dwt.events.DisposeListener; +import dwt.events.FocusEvent; +import dwt.events.FocusListener; +import dwt.events.MouseAdapter; +import dwt.events.MouseEvent; +import dwt.events.MouseTrackListener; +import dwt.events.PaintEvent; +import dwt.events.PaintListener; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Region; +import dwt.layout.FormAttachment; +import dwt.layout.FormData; +import dwt.layout.FormLayout; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Label; +import dwt.widgets.Shell; +import dwtx.core.runtime.Assert; + +import dwt.dwthelper.utils; + +/** + * DecoratedField manages image decorations around a control. It allows clients + * to specify an image decoration and a position for the decoration relative to + * the field. Decorations may be assigned descriptions, which are shown when the + * user hovers over the decoration. Clients can decorate any kind of control by + * supplying a {@link IControlCreator} to create the control that is decorated. + *

+ * Decorations always appear on either horizontal side of the field, never above + * or below it. Decorations can be positioned at the top or bottom of either + * side. Future implementations may provide additional positioning options for + * decorations. + *

+ * By default, DecoratedField will consult the {@link FieldDecorationRegistry} + * to determine how much space should be reserved for each decoration. This + * allows fields with decorations from different sources to align properly on + * the same dialog, since the registry tracks the size of all decorations + * registered. Therefore, it is recommended, but not required, that clients of + * DecoratedField register the decorations used. In cases where alignment + * between different fields is not a concern, clients can use + * setUseMaximumDecorationWidth(false) and need not register + * their decorations. + *

+ * This class is not intended to be subclassed. + * + * @since 3.2 + * @deprecated As of 3.3, clients should use {@link ControlDecoration} instead. + */ +public class DecoratedField { + + /** + * Cached platform flags for dealing with platform-specific issues. + */ + private static bool CARBON = "carbon".equals(DWT.getPlatform()); //$NON-NLS-1$ + + /** + * Constants describing the array indices used to hold the decorations in + * array slots. + */ + + private static const int LEFT_TOP = 0; + + private static const int LEFT_BOTTOM = 1; + + private static const int RIGHT_TOP = 2; + + private static const int RIGHT_BOTTOM = 3; + + private static const int DECORATION_SLOTS = 4; + + /** + * Simple data structure class for specifying the internals for a field + * decoration. This class contains data specific to the implementation of + * field decorations as labels attached to the field. Clients should use + * FieldDecoration for specifying a decoration. + */ + private class FieldDecorationData { + + /* Package */FieldDecoration decoration; + + /* Package */Label label; + + /* Package */FormData data; + + /* Package */bool showOnFocus; + + /* Package */bool visible = true; + + /** + * Create a decoration data representing the specified decoration, using + * the specified label and form data for its representation. + * + * @param decoration + * the decoration whose data is kept. + * @param label + * the label used to represent the decoration. + * @param formData + * the form data used to attach the decoration to its field. + * @param showOnFocus + * a bool specifying whether the decoration should only be + * shown when the field has focus. + */ + this(FieldDecoration decoration, Label label, + FormData formData, bool showOnFocus) { + this.decoration = decoration; + this.label = label; + this.data = formData; + this.showOnFocus = showOnFocus; + } + } + + /** + * Decorations keyed by position. + */ + private FieldDecorationData[] decDatas; + + /** + * The associated control + */ + private Control control; + + /** + * The composite with form layout used to manage decorations. + */ + private Composite form; + + /** + * The bool that indicates whether the maximum decoration width is used + * when allocating space for decorations. + */ + private bool useMaxDecorationWidth = true; + + /** + * The hover used for showing description text + */ + private Hover hover; + + /** + * The hover used to show a decoration image's description. + */ + class Hover { + private static const String EMPTY = ""; //$NON-NLS-1$ + + /** + * Offset of info hover arrow from the left or right side. + */ + private int hao = 10; + + /** + * Width of info hover arrow. + */ + private int haw = 8; + + /** + * Height of info hover arrow. + */ + private int hah = 10; + + /** + * Margin around info hover text. + */ + private int hm = 2; + + /** + * This info hover's shell. + */ + Shell hoverShell; + + /** + * The info hover text. + */ + String text = EMPTY; + + /** + * The region used to manage the shell shape + */ + Region region; + + /** + * bool indicating whether the last computed polygon location had an + * arrow on left. (true if left, false if right). + */ + bool arrowOnLeft = true; + + /* + * Create a hover parented by the specified shell. + */ + this(Shell parent) { + final Display display = parent.getDisplay(); + hoverShell = new Shell(parent, DWT.NO_TRIM | DWT.ON_TOP + | DWT.NO_FOCUS); + hoverShell.setBackground(display + .getSystemColor(DWT.COLOR_INFO_BACKGROUND)); + hoverShell.setForeground(display + .getSystemColor(DWT.COLOR_INFO_FOREGROUND)); + hoverShell.addPaintListener(new class PaintListener { + public void paintControl(PaintEvent pe) { + pe.gc.drawString(text, hm, hm); + if (!CARBON) { + pe.gc.drawPolygon(getPolygon(true)); + } + } + }); + hoverShell.addMouseListener(new class MouseAdapter { + public void mouseDown(MouseEvent e) { + hideHover(); + } + }); + } + + /* + * Compute a polygon that represents a hover with an arrow pointer. If + * border is true, compute the polygon inset by 1-pixel border. Consult + * the arrowOnLeft flag to determine which side the arrow is on. + */ + int[] getPolygon(bool border) { + Point e = getExtent(); + int b = border ? 1 : 0; + if (arrowOnLeft) { + return [ 0, 0, e.x - b, 0, e.x - b, e.y - b, + hao + haw, e.y - b, hao + haw / 2, e.y + hah - b, hao, + e.y - b, 0, e.y - b, 0, 0 ]; + } + return [ 0, 0, e.x - b, 0, e.x - b, e.y - b, + e.x - hao - b, e.y - b, e.x - hao - haw / 2, e.y + hah - b, + e.x - hao - haw, e.y - b, 0, e.y - b, 0, 0 ]; + } + + /* + * Dispose the hover, it is no longer needed. Dispose any resources + * allocated by the hover. + */ + void dispose() { + if (!hoverShell.isDisposed()) { + hoverShell.dispose(); + } + if (region !is null) { + region.dispose(); + } + } + + /* + * Set the visibility of the hover. + */ + void setVisible(bool visible) { + if (visible) { + if (!hoverShell.isVisible()) { + hoverShell.setVisible(true); + } + } else { + if (hoverShell.isVisible()) { + hoverShell.setVisible(false); + } + } + } + + /* + * Set the text of the hover to the specified text. Recompute the size + * and location of the hover to hover near the specified control, + * pointing the arrow toward the target control. + */ + void setText(String t, Control hoverNear, Control targetControl) { + if (t is null) { + t = EMPTY; + } + if (!t.equals(text)) { + Point oldSize = getExtent(); + text = t; + hoverShell.redraw(); + Point newSize = getExtent(); + if (!oldSize.opEquals(newSize)) { + // set a flag that indicates the direction of arrow + arrowOnLeft = hoverNear.getLocation().x <= targetControl + .getLocation().x; + setNewShape(); + } + } + + if (hoverNear !is null) { + Point extent = getExtent(); + int y = -extent.y - hah + 1; + int x = arrowOnLeft ? -hao + haw / 2 : -extent.x + hao + haw + / 2; + + hoverShell.setLocation(hoverNear.toDisplay(x, y)); + } + + } + + /* + * Return whether or not the hover (shell) is visible. + */ + bool isVisible() { + return hoverShell.isVisible(); + } + + /* + * Compute the extent of the hover for the current text. + */ + Point getExtent() { + GC gc = new GC(hoverShell); + Point e = gc.textExtent(text); + gc.dispose(); + e.x += hm * 2; + e.y += hm * 2; + return e; + } + + /* + * Compute a new shape for the hover shell. + */ + void setNewShape() { + Region oldRegion = region; + region = new Region(); + region.add(getPolygon(false)); + hoverShell.setRegion(region); + if (oldRegion !is null) { + oldRegion.dispose(); + } + + } + } + + /** + * Construct a decorated field which is parented by the specified composite + * and has the given style bits. Use the controlCreator to create the + * specific kind of control that is decorated inside the field. + * + * @param parent + * the parent of the decorated field. + * @param style + * the desired style bits for the field. + * @param controlCreator + * the IControlCreator used to specify the specific kind of + * control that is to be decorated. + * + * @see IControlCreator + */ + public this(Composite parent, int style, + IControlCreator controlCreator) { + decDatas = new FieldDecorationData[DECORATION_SLOTS]; + this.form = createForm(parent); + this.control = controlCreator.createControl(form, style); + + addControlListeners(); + form.setTabList([ control ]); + + // Set up the initial layout data. + FormData data = new FormData(); + data.left = new FormAttachment(0, 0); + data.top = new FormAttachment(0, 0); + data.right = new FormAttachment(100, 0); + data.bottom = new FormAttachment(100, 0); + control.setLayoutData(data); + + } + + /** + * Adds an image decoration to the field. + * + * @param decoration + * A FieldDecoration describing the image and description for the + * decoration + * + * @param position + * The DWT constant indicating the position of the decoration + * relative to the field's control. The position should include + * style bits describing both the vertical and horizontal + * orientation. DWT.LEFT and + * DWT.RIGHT describe the horizontal placement of + * the decoration relative to the field, and the constants + * DWT.TOP and DWT.BOTTOM describe + * the vertical alignment of the decoration relative to the + * field. Decorations always appear on either horizontal side of + * the field, never above or below it. For example, a decoration + * appearing on the left side of the field, at the top, is + * specified as DWT.LEFT | DWT.TOP. If an image decoration + * already exists in the specified position, it will be replaced + * by the one specified. + * @param showOnFocus + * true if the decoration should only be shown + * when the associated control has focus, false if + * it should always be shown. + * + */ + public void addFieldDecoration(FieldDecoration decoration, int position, + bool showOnFocus) { + Label label; + FormData formData; + int i = indexForPosition(position); + if (decDatas[i] is null) { + formData = createFormDataForIndex(i, decoration.getImage()); + label = new Label(form, DWT.HORIZONTAL | DWT.VERTICAL | DWT.CENTER); + label.addMouseTrackListener(new class MouseTrackListener { + Label label_; + this(){ + label_=label; + } + public void mouseHover(MouseEvent event) { + FieldDecorationData decData = cast(FieldDecorationData) event.widget + .getData(); + String desc = decData.decoration.getDescription(); + if (desc !is null) { + showHoverText(desc, label_); + } + } + + public void mouseEnter(MouseEvent event) { + } + + public void mouseExit(MouseEvent event) { + hideHover(); + } + }); + decDatas[i] = new FieldDecorationData(decoration, label, formData, + showOnFocus); + } else { + label = decDatas[i].label; + formData = decDatas[i].data; + decDatas[i].decoration = decoration; + decDatas[i].showOnFocus = showOnFocus; + } + label.setImage(decDatas[i].decoration.getImage()); + label.setData(decDatas[i]); + label.setLayoutData(formData); + label.setVisible(!showOnFocus); + + // Since sizes may have changed or there could be a new position + // defined, we need to update layout data on the control. + updateControlAttachments(i, decDatas[i]); + } + + /* + * A decoration at the specified index has been added. Update the control's + * attachments if it has not previously been attached on that side or if it + * was attached to a decoration with a lesser width. + */ + private void updateControlAttachments(int index, FieldDecorationData decData) { + FormData formData = cast(FormData) control.getLayoutData(); + int newWidth = widthOf(decData.decoration.getImage()); + // opposing represents the location of the decoration above or below + // the one in question. + int opposing; + + switch (index) { + case LEFT_TOP: + case LEFT_BOTTOM: + if (index is LEFT_TOP) { + opposing = LEFT_BOTTOM; + } else { + opposing = LEFT_TOP; + } + if (decDatas[opposing] is null) { + // No decorator on the opposing side. + // Attach the control to this decorator + formData.left = new FormAttachment(decData.label); + } else if (decDatas[opposing].data.width < newWidth) { + // Decorator on opposing side is the smaller one. Attach + // control to the new one. + formData.left = new FormAttachment(decData.label); + // Center align the smaller one relative to the larger one. + decDatas[opposing].data.left.alignment = DWT.CENTER; + decDatas[opposing].data.left.control = decData.label; + } else { + // The new decorator is the smaller one. Keep the + // control attached to the opposing one. + formData = null; + // Horizontally center the smaller one relative to the larger + // one. + decData.data.left.alignment = DWT.CENTER; + decData.data.left.control = decDatas[opposing].label; + } + break; + /* + * The only real difference in right side cases is that we are attaching + * the right side of the control to the wider decoration rather than the + * left side of the control. Other concerns (horizontally aligning the + * smaller decoration relative to the larger one) are the same. + */ + case RIGHT_TOP: + case RIGHT_BOTTOM: + if (index is RIGHT_TOP) { + opposing = RIGHT_BOTTOM; + } else { + opposing = RIGHT_TOP; + } + if (decDatas[opposing] is null) { + // No decorator on the opposing side. + // Attach the control to this decorator. + formData.right = new FormAttachment(decData.label); + } else if (decDatas[opposing].data.width < newWidth) { + // Decorator on opposing side is the smaller one. Attach + // control to the new one. + formData.right = new FormAttachment(decData.label); + // Center align the smaller one to the larger one. + // Note that this could be done using the left or right + // attachment, we use the right since it is already + // created for all right-side decorations. + decDatas[opposing].data.right.alignment = DWT.CENTER; + decDatas[opposing].data.right.control = decData.label; + } else { + // The new decorator is the smaller one. Keep the + // control attached to the opposing one. + formData = null; + // Horizontally center align the smaller one to the + // larger one. + decData.data.right.alignment = DWT.CENTER; + decData.data.right.control = decDatas[opposing].label; + } + break; + default: + return; + } + if (formData !is null) { + // Form data was updated. + control.setLayoutData(formData); + form.layout(); + } + } + + /** + * Get the control that is decorated by the receiver. + * + * @return the Control decorated by the receiver, or null if + * none has been created yet. + */ + public Control getControl() { + return control; + } + + /** + * Get the control that represents the decorated field. This composite + * should be used to lay out the field within its parent. + * + * @return the Control that should be layed out in the field's parent's + * layout. This is typically not the control itself, since + * additional controls are used to represent the decorations. + */ + public Control getLayoutControl() { + return form; + } + + /** + * Create the parent composite and a form layout that will be used to manage + * decorations. + */ + private Composite createForm(Composite parent) { + Composite composite = new Composite(parent, DWT.NO_FOCUS); + // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=126553 + composite.setBackgroundMode(DWT.INHERIT_DEFAULT); + composite.setLayout(new FormLayout()); + return composite; + } + + /** + * Add any listeners needed on the target control. + */ + private void addControlListeners() { + control.addDisposeListener(new class DisposeListener { + public void widgetDisposed(DisposeEvent event) { + if (hover !is null) { + hover.dispose(); + } + } + }); + control.addFocusListener(new class FocusListener { + public void focusGained(FocusEvent event) { + controlFocusGained(); + } + + public void focusLost(FocusEvent event) { + controlFocusLost(); + } + + }); + } + + /* + * Return the index in the array of decoration datas that represents the + * specified DWT position. + * + * @param position The DWT constant indicating the position of the + * decoration relative to the field's control. The position should include + * style bits describing both the vertical and horizontal orientation. + * DWT.LEFT and DWT.RIGHT describe the + * horizontal placement of the decoration relative to the field, and the + * constants DWT.TOP and DWT.BOTTOM describe + * the vertical alignment of the decoration relative to the field. + * Decorations always appear on either horizontal side of the field, never + * above or below it. For example, a decoration appearing on the left side + * of the field, at the top, is specified as DWT.LEFT | DWT.TOP. + * + * @return index the index in the array of decorations that represents the + * specified DWT position. If the position is not an expected position, the + * index representing the top left position will be returned. + * + */ + private int indexForPosition(int position) { + switch (position) { + case DWT.LEFT | DWT.BOTTOM: + return LEFT_BOTTOM; + case DWT.RIGHT | DWT.TOP: + return RIGHT_TOP; + case DWT.RIGHT | DWT.BOTTOM: + return RIGHT_BOTTOM; + default: + return LEFT_TOP; + } + } + + /* + * Create a form data that will place the decoration at the specified + * position. + * + * @param index the index in the decDatas describing the position of the + * decoration. + * + * @param image the image shown in the decoration. + * + */ + private FormData createFormDataForIndex(int index, Image image) { + Assert.isTrue(index >= 0 && index < DECORATION_SLOTS, + "Index out of range"); //$NON-NLS-1$ + + FormData data = new FormData(); + switch (index) { + case LEFT_TOP: + data.left = new FormAttachment(0, 0); + data.top = new FormAttachment(0, 0); + break; + case LEFT_BOTTOM: + data.left = new FormAttachment(0, 0); + data.bottom = new FormAttachment(100, 0); + break; + case RIGHT_TOP: + data.right = new FormAttachment(100, 0); + data.top = new FormAttachment(0, 0); + break; + case RIGHT_BOTTOM: + data.right = new FormAttachment(100, 0); + data.bottom = new FormAttachment(100, 0); + break; + } + data.width = widthOf(image); + data.height = DWT.DEFAULT; + + return data; + } + + /** + * Show the specified text using the same hover dialog as is used to show + * decorator descriptions. Normally, a decoration's description text will be + * shown in an info hover over the field's control whenever the mouse hovers + * over the decoration. This method can be used to show a decoration's + * description text at other times (such as when the control receives + * focus), or to show other text associated with the field. + * + *

+ * If there is currently a hover visible, the hover's text will be replaced + * with the specified text. + * + * @param text + * the text to be shown in the info hover, or null + * if no text should be shown. + */ + public void showHoverText(String text) { + showHoverText(text, control); + } + + /** + * Hide any hover popups that are currently showing on the control. + * Normally, a decoration's description text will be shown in an info hover + * over the field's control as long as the mouse hovers over the decoration, + * and will be hidden when the mouse exits the control. This method can be + * used to hide a hover that was shown using showHoverText, + * or to programatically hide the current decoration hover. + * + *

+ * This message has no effect if there is no current hover. + * + */ + public void hideHover() { + if (hover !is null) { + hover.setVisible(false); + } + } + + /* + * The target control gained focus. Any decorations that should show only + * when they have the focus should be shown here. + */ + private void controlFocusGained() { + for (int i = 0; i < DECORATION_SLOTS; i++) { + if (decDatas[i] !is null && decDatas[i].showOnFocus) { + setVisible(decDatas[i], true); + } + } + } + + /* + * The target control lost focus. Any decorations that should show only when + * they have the focus should be hidden here. + */ + private void controlFocusLost() { + for (int i = 0; i < DECORATION_SLOTS; i++) { + if (decDatas[i] !is null && decDatas[i].showOnFocus) { + setVisible(decDatas[i], false); + } + } + } + + /** + * Show the specified decoration. This message has no effect if the + * decoration is already showing, or was not already added to the field + * using addFieldDecoration. + * + * @param decoration + * the decoration to be shown. + */ + public void showDecoration(FieldDecoration decoration) { + FieldDecorationData data = getDecorationData(decoration); + if (data is null) { + return; + } + // record the fact that client would like it to be visible + data.visible = true; + // even if it is supposed to be shown, if the field does not have focus, + // do not show it (yet) + if (!data.showOnFocus || control.isFocusControl()) { + setVisible(data, true); + } + } + + /** + * Hide the specified decoration. This message has no effect if the + * decoration is already hidden, or was not already added to the field using + * addFieldDecoration. + * + * @param decoration + * the decoration to be hidden. + */ + public void hideDecoration(FieldDecoration decoration) { + FieldDecorationData data = getDecorationData(decoration); + if (data is null) { + return; + } + // Store the desired visibility in the decData. We remember the + // client's instructions so that changes in visibility caused by + // field focus changes won't violate the client's visibility setting. + data.visible = false; + setVisible(data, false); + } + + /** + * Update the specified decoration. This message should be used if the image + * or description in the decoration have changed. This message has no + * immediate effect if the decoration is not visible, and no effect at all + * if the decoration was not previously added to the field. + * + * @param decoration + * the decoration to be hidden. + */ + public void updateDecoration(FieldDecoration decoration) { + FieldDecorationData data = getDecorationData(decoration); + if (data is null) { + return; + } + if (data.label !is null) { + data.label.setImage(decoration.getImage()); + // If the decoration is being shown, and a hover is active, + // update the hover text to display the new description. + if (data.label.getVisible() is true && hover !is null) { + showHoverText(decoration.getDescription(), data.label); + } + } + } + + /* + * Set the visibility of the specified decoration data. This method does not + * change the visibility value stored in the decData, but instead consults + * it to determine how the visibility should be changed. This method is + * called any time visibility of a decoration might change, whether by + * client API or focus changes. + */ + private void setVisible(FieldDecorationData decData, bool visible) { + // Check the decData visibility flag, since it contains the client's + // instructions for visibility. + if (visible && decData.visible) { + decData.label.setVisible(true); + } else { + decData.label.setVisible(false); + } + } + + /* + * Get the FieldDecorationData that corresponds to the given decoration. + */ + private FieldDecorationData getDecorationData(FieldDecoration dec) { + for (int i = 0; i < DECORATION_SLOTS; i++) { + if (decDatas[i] !is null && dec is decDatas[i].decoration + && decDatas[i].label !is null + && !decDatas[i].label.isDisposed()) { + return decDatas[i]; + } + } + return null; + } + + /* + * Show the specified text in the hover, positioning the hover near the + * specified control. + */ + private void showHoverText(String text, Control hoverNear) { + if (text is null) { + hideHover(); + return; + } + + if (hover is null) { + hover = new Hover(hoverNear.getShell()); + } + hover.setText(text, hoverNear, control); + hover.setVisible(true); + } + + /** + * Set a bool that indicates whether the receiver should use the + * decoration registry's maximum decoration width when allocating space for + * decorations. The default value is true. Using the maximum + * decoration width is useful so that decorated fields on the same dialog + * that have different decoration widths will all align. This also allows + * client dialogs to align non-decorated fields with decorated fields by + * consulting the maximum decoration width. + *

+ *

+ * Clients may wish to set this value to false in cases where + * space usage is more important than alignment of fields. This value must + * be set before the decorations are added in order to ensure proper + * alignment. + *

+ * + * @param useMaximumWidth + * true if the maximum decoration width should be + * used as the size for all decorations, false if + * only the decoration size should be used. + * + * @see FieldDecorationRegistry#getMaximumDecorationWidth() + */ + public void setUseMaximumDecorationWidth(bool useMaximumWidth) { + useMaxDecorationWidth = useMaximumWidth; + } + + /* + * Return the width appropriate for the specified decoration image. + */ + private int widthOf(Image image) { + if (image is null) { + return 0; + } + return useMaxDecorationWidth ? FieldDecorationRegistry.getDefault() + .getMaximumDecorationWidth() : image.getBounds().width; + } +} diff -r e0f0aaf75edd -r f459f9147650 dwtx/jface/fieldassist/FieldDecoration.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/fieldassist/FieldDecoration.d Tue Apr 01 08:24:51 2008 +0200 @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2005, 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.fieldassist.FieldDecoration; + +import dwt.graphics.Image; + +import dwt.dwthelper.utils; + +/** + * FieldDecoration is a simple data structure class for specifying a decoration + * for a field. A decoration may be rendered in different ways depending on the + * type of field it is used with. + * + * @see FieldDecorationRegistry + * + * @since 3.2 + */ +public class FieldDecoration { + + /* + * The image to be shown in the decoration. + */ + private Image image; + + /* + * The description to show in the decoration's hover. + */ + private String description; + + /** + * Create a decoration for a field with the specified image and description + * text. + * + * @param image + * the image shown in the decoration. A null image + * will result in a blank decoration, which may be used to + * reserve space near the field. + * @param description + * the description shown when the user hovers over the + * decoration. A null description indicates that + * there will be no hover for the decoration. + */ + public this(Image image, String description) { + this.image = image; + this.description = description; + } + + /** + * Return the image shown in the decoration, or null if no + * image is specified. + * + * @return the image shown in the decoration. A return value of + * null signifies a blank decoration. + */ + public Image getImage() { + return image; + } + + /** + * Set the image shown in the decoration, or null if no image + * is specified. It is up to the caller to update any decorated fields that + * are showing the description in order to display the new image. + * + * @param image + * the image shown in the decoration. A value of + * null signifies a blank decoration. + */ + public void setImage(Image image) { + this.image = image; + } + + /** + * Return the description for the decoration shown when the user hovers over + * the decoration. + * + * @return the String description of the decoration. A return value of + * null indicates that no description will be shown. + */ + public String getDescription() { + return description; + } + + /** + * Set the description for the decoration shown when the user hovers over + * the decoration. It is up to the caller to update any decorated fields + * showing the description. + * + * @param description + * the String description of the decoration. A value of + * null indicates that no description will be + * shown. + */ + public void setDescription(String description) { + this.description = description; + } +} diff -r e0f0aaf75edd -r f459f9147650 dwtx/jface/fieldassist/FieldDecorationRegistry.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/fieldassist/FieldDecorationRegistry.d Tue Apr 01 08:24:51 2008 +0200 @@ -0,0 +1,413 @@ +/******************************************************************************* + * Copyright (c) 2006, 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.fieldassist.FieldDecorationRegistry; + +import dwtx.jface.fieldassist.FieldDecoration; + +import tango.util.collection.HashMap; + +import dwt.graphics.Image; +import dwtx.jface.resource.ImageDescriptor; +import dwtx.jface.resource.ImageRegistry; +import dwtx.jface.resource.JFaceResources; + +import dwt.dwthelper.utils; + +/** + * FieldDecorationRegistry is a common registry used to define shared field + * decorations within an application. Unlike resource registries, the + * FieldDecorationRegistry does not perform any lifecycle management of the + * decorations. + *

+ *

+ * Clients may specify images for the decorations in several different ways. + * Images may be described by their image id in a specified + * {@link ImageRegistry}. In this case, the life cycle of the image is managed + * by the image registry, and the decoration registry will not attempt to obtain + * an image from the image registry until the decoration is actually requested. + * In cases where the client has access to an already-created image, the image + * itself can be specified when registering the decoration. In this case, the + * life cycle should be managed by the specifying client. + *

+ * + * @see FieldDecoration + * @see ImageRegistry + * + * @since 3.2 + */ +public class FieldDecorationRegistry { + + /** + * Decoration id for the decoration that should be used to cue the user that + * content proposals are available. + */ + public static const String DEC_CONTENT_PROPOSAL = "DEC_CONTENT_PROPOSAL"; //$NON-NLS-1$ + + /** + * Decoration id for the decoration that should be used to cue the user that + * a field is required. + */ + public static const String DEC_REQUIRED = "DEC_REQUIRED"; //$NON-NLS-1$ + + /** + * Decoration id for the decoration that should be used to cue the user that + * a field has an error. + */ + public static const String DEC_ERROR = "DEC_ERROR"; //$NON-NLS-1$ + + /** + * Decoration id for the decoration that should be used to cue the user that + * a field has a warning. + */ + public static const String DEC_WARNING = "DEC_WARNING"; //$NON-NLS-1$ + + /** + * Decoration id for the decoration that should be used to cue the user that + * a field has additional information. + * + * @since 3.3 + */ + public static const String DEC_INFORMATION = "DEC_INFORMATION"; //$NON-NLS-1$ + + /** + * Decoration id for the decoration that should be used to cue the user that + * a field has an error with quick fix available. + * + * @since 3.3 + */ + public static const String DEC_ERROR_QUICKFIX = "DEC_ERRORQUICKFIX"; //$NON-NLS-1$ + + /* + * Image id's + */ + private static const String IMG_DEC_FIELD_CONTENT_PROPOSAL = "dwtx.jface.fieldassist.IMG_DEC_FIELD_CONTENT_PROPOSAL"; //$NON-NLS-1$ + + private static const String IMG_DEC_FIELD_REQUIRED = "dwtx.jface.fieldassist.IMG_DEC_FIELD_REQUIRED"; //$NON-NLS-1$ + + private static const String IMG_DEC_FIELD_ERROR = "dwtx.jface.fieldassist.IMG_DEC_FIELD_ERROR"; //$NON-NLS-1$ + + private static const String IMG_DEC_FIELD_ERROR_QUICKFIX = "dwtx.jface.fieldassist.IMG_DEC_FIELD_ERROR_QUICKFIX"; //$NON-NLS-1$ + + private static const String IMG_DEC_FIELD_WARNING = "dwtx.jface.fieldassist.IMG_DEC_FIELD_WARNING"; //$NON-NLS-1$ + + private static const String IMG_DEC_FIELD_INFO = "dwtx.jface.fieldassist.IMG_DEC_FIELD_INFO"; //$NON-NLS-1$ + + /* + * Declare images and decorations immediately. + */ + static this() { + ImageRegistry imageRegistry = JFaceResources.getImageRegistry(); + + // Define the images used in the standard decorations. + imageRegistry.put(IMG_DEC_FIELD_CONTENT_PROPOSAL, ImageDescriptor + .createFromFile(FieldDecorationRegistry.classinfo, + "images/contassist_ovr.gif"));//$NON-NLS-1$ + imageRegistry.put(IMG_DEC_FIELD_ERROR, ImageDescriptor.createFromFile( + FieldDecorationRegistry.classinfo, "images/error_ovr.gif"));//$NON-NLS-1$ + + imageRegistry.put(IMG_DEC_FIELD_WARNING, ImageDescriptor + .createFromFile(FieldDecorationRegistry.classinfo, + "images/warn_ovr.gif"));//$NON-NLS-1$ + + imageRegistry.put(IMG_DEC_FIELD_REQUIRED, ImageDescriptor + .createFromFile(FieldDecorationRegistry.classinfo, + "images/required_field_cue.gif"));//$NON-NLS-1$ + + imageRegistry.put(IMG_DEC_FIELD_ERROR_QUICKFIX, ImageDescriptor + .createFromFile(FieldDecorationRegistry.classinfo, + "images/errorqf_ovr.gif"));//$NON-NLS-1$ + + imageRegistry.put(IMG_DEC_FIELD_INFO, ImageDescriptor + .createFromFile(FieldDecorationRegistry.classinfo, + "images/info_ovr.gif"));//$NON-NLS-1$ + + // Define the standard decorations. Some do not have standard + // descriptions. Use null in these cases. + getDefault() + .registerFieldDecoration( + DEC_CONTENT_PROPOSAL, + JFaceResources + .getString("FieldDecorationRegistry.contentAssistMessage"), //$NON-NLS-1$ + IMG_DEC_FIELD_CONTENT_PROPOSAL, imageRegistry); + + getDefault().registerFieldDecoration( + DEC_ERROR, + JFaceResources + .getString("FieldDecorationRegistry.errorMessage"), //$NON-NLS-1$ + IMG_DEC_FIELD_ERROR, imageRegistry); + + getDefault().registerFieldDecoration( + DEC_ERROR_QUICKFIX, + JFaceResources + .getString("FieldDecorationRegistry.errorQuickFixMessage"), //$NON-NLS-1$ + IMG_DEC_FIELD_ERROR_QUICKFIX, imageRegistry); + + getDefault().registerFieldDecoration(DEC_WARNING, null, + IMG_DEC_FIELD_WARNING, imageRegistry); + + getDefault().registerFieldDecoration(DEC_INFORMATION, null, + IMG_DEC_FIELD_INFO, imageRegistry); + + getDefault() + .registerFieldDecoration( + DEC_REQUIRED, + JFaceResources + .getString("FieldDecorationRegistry.requiredFieldMessage"), //$NON-NLS-1$ + IMG_DEC_FIELD_REQUIRED, imageRegistry); + + } + + /* + * Data structure that holds onto the decoration image info and description, + * and can produce a decorator on request. + */ + class Entry { + private String description; + + private String imageId; + + private ImageRegistry imageRegistry; + + private Image image; + + private FieldDecoration decoration; + + this(String description, String imageId, ImageRegistry registry) { + this.description = description; + this.imageId = imageId; + this.imageRegistry = registry; + } + + this(String description, Image image) { + this.description = description; + this.image = image; + } + + FieldDecoration getDecoration() { + if (decoration is null) { + if (image is null) { + if (imageRegistry is null) { + imageRegistry = JFaceResources.getImageRegistry(); + } + image = imageRegistry.get(imageId); + } + decoration = new FieldDecoration(image, description); + } + // Null out all other fields now that the decoration has an image + description = null; + imageId = null; + imageRegistry = null; + image = null; + + return decoration; + } + } + + /** + * Default instance of the registry. Applications may install their own + * registry. + */ + private static FieldDecorationRegistry defaultInstance; + + /** + * Maximum width and height used by decorations in this registry. Clients + * may use these values to reserve space in dialogs for decorations or to + * adjust layouts so that decorated and non-decorated fields line up. + */ + private int maxDecorationWidth = 0; + private int maxDecorationHeight = 0; + + private HashMap!(String,Object) /* */decorations; + + /** + * Get the default FieldDecorationRegistry. + * + * @return the singleton FieldDecorationRegistry that is used to manage + * shared field decorations. + */ + public static FieldDecorationRegistry getDefault() { + if (defaultInstance is null) { + defaultInstance = new FieldDecorationRegistry(); + } + return defaultInstance; + } + + /** + * Set the default FieldDecorationRegistry. + * + * @param defaultRegistry + * the singleton FieldDecorationRegistry that is used to manage + * shared field decorations. + */ + public static void setDefault(FieldDecorationRegistry defaultRegistry) { + defaultInstance = defaultRegistry; + } + + /** + * Construct a FieldDecorationRegistry. + */ + public this() { + decorations = new HashMap!(String,Object); + maxDecorationWidth = 0; + maxDecorationHeight = 0; + } + + /** + * Get the maximum width (in pixels) of any decoration retrieved so far in + * the registry. This value changes as decorations are added and retrieved. + * This value can be used by clients to reserve space or otherwise compute + * margins when aligning non-decorated fields with decorated fields. + * + * @return the maximum width in pixels of any accessed decoration + */ + public int getMaximumDecorationWidth() { + return maxDecorationWidth; + } + + /** + * Get the maximum height (in pixels) of any decoration retrieved so far in + * the registry. This value changes as decorations are added and retrieved. + * This value can be used by clients to reserve space or otherwise compute + * margins when aligning non-decorated fields with decorated fields. + * + * + * @return the maximum height in pixels of any accessed decoration + */ + public int getMaximumDecorationHeight() { + return maxDecorationHeight; + } + + /** + * Registers a field decoration using the specified id. The lifecyle of the + * supplied image should be managed by the client. That is, it will never be + * disposed by this registry and the decoration should be removed from the + * registry if the image is ever disposed elsewhere. + * + * @param id + * the String id used to identify and access the decoration. + * @param description + * the String description to be used in the decoration, or + * null if the decoration has no description. + * @param image + * the image to be used in the decoration + */ + public void registerFieldDecoration(String id, String description, + Image image) { + decorations.add(id, new Entry(description, image)); + // Recompute the maximums since this might be a replacement + recomputeMaximums(); + } + + /** + * Registers a field decoration using the specified id. An image id of an + * image located in the default JFaceResources image registry is supplied. + * The image will not be created until the decoration is requested. + * + * @param id + * the String id used to identify and access the decoration. + * @param description + * the String description to be used in the decoration, or + * null if the decoration has no description. * + * @param imageId + * the id of the image in the JFaceResources image registry that + * is used for this decorator + */ + public void registerFieldDecoration(String id, String description, + String imageId) { + decorations.add(id, new Entry(description, imageId, JFaceResources + .getImageRegistry())); + // Recompute the maximums as this could be a replacement of a previous + // image. + recomputeMaximums(); + } + + /** + * Registers a field decoration using the specified id. An image id and an + * image registry are supplied. The image will not be created until the + * decoration is requested. + * + * @param id + * the String id used to identify and access the decoration. + * @param description + * the String description to be used in the decoration, or + * null if the decoration has no description. * + * @param imageId + * the id of the image in the supplied image registry that is + * used for this decorator + * @param imageRegistry + * the registry used to obtain the image + */ + public void registerFieldDecoration(String id, String description, + String imageId, ImageRegistry imageRegistry) { + decorations.add(id, new Entry(description, imageId, imageRegistry)); + // Recompute the maximums since this could be a replacement + recomputeMaximums(); + } + + /** + * Unregisters the field decoration with the specified id. No lifecycle + * management is performed on the decoration's image. This message has no + * effect if no field decoration with the specified id was previously + * registered. + *

+ *

+ * This method need not be called if the registered decoration's image is + * managed in an image registry. In that case, leaving the decoration in the + * registry will do no harm since the image will remain valid and will be + * properly disposed when the application is shut down. This method should + * be used in cases where the caller intends to dispose of the image + * referred to by the decoration, or otherwise determines that the + * decoration should no longer be used. + * + * @param id + * the String id of the decoration to be unregistered. + */ + public void unregisterFieldDecoration(String id) { + decorations.removeKey(id); + recomputeMaximums(); + } + + /** + * Returns the field decoration registered by the specified id . + * + * @param id + * the String id used to access the decoration. + * @return the FieldDecoration with the specified id, or null + * if there is no decoration with the specified id. + */ + public FieldDecoration getFieldDecoration(String id) { + Object entry = decorations.get(id); + if (entry is null) { + return null; + } + return (cast(Entry) entry).getDecoration(); + + } + + /* + * The maximum decoration width and height must be recomputed. Typically + * called in response to adding, removing, or replacing a decoration. + */ + private void recomputeMaximums() { + maxDecorationHeight = 0; + maxDecorationWidth = 0; + foreach( k,v; decorations ){ + Image image = (cast(Entry)v).getDecoration().getImage(); + if (image !is null) { + maxDecorationHeight = Math.max(maxDecorationHeight, image.getBounds().height); + maxDecorationWidth = Math.max(maxDecorationWidth, image.getBounds().width); + } + } + + } +} diff -r e0f0aaf75edd -r f459f9147650 dwtx/jface/fieldassist/IControlCreator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/fieldassist/IControlCreator.d Tue Apr 01 08:24:51 2008 +0200 @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2005, 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.fieldassist.IControlCreator; + +import dwt.widgets.Composite; +import dwt.widgets.Control; + +import dwt.dwthelper.utils; + +/** + * This interface is used to create a control with a specific parent and style + * bits. It is used by {@link DecoratedField} to create the control to be + * decorated. Clients are expected to implement this interface in order to + * create a particular kind of control for decoration. + * + * @since 3.2 + * @deprecated As of 3.3, clients should use {@link ControlDecoration} instead + * of {@link DecoratedField}. + * + */ +public interface IControlCreator { + /** + * Create a control with the specified parent and style bits. + * + * @param parent + * the parent of the control + * @param style + * the style of the control + * + * @return the Control that was created. + */ + public Control createControl(Composite parent, int style); +} diff -r e0f0aaf75edd -r f459f9147650 dwtx/jface/fieldassist/TextControlCreator.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwtx/jface/fieldassist/TextControlCreator.d Tue Apr 01 08:24:51 2008 +0200 @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2005, 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.fieldassist.TextControlCreator; + +import dwtx.jface.fieldassist.IControlCreator; + +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Text; + +import dwt.dwthelper.utils; + +/** + * An {@link IControlCreator} for DWT Text controls. This is a convenience class + * for creating text controls to be supplied to a decorated field. + * + * @since 3.2 + * @deprecated As of 3.3, clients should use {@link ControlDecoration} instead + * of {@link DecoratedField}. + * + */ +public class TextControlCreator : IControlCreator { + + public Control createControl(Composite parent, int style) { + return new Text(parent, style); + } +}