# HG changeset patch
# User Frank Benoit
+ * This class is not intended to be extended by clients.
+ *
+ * The style bit
+ * 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
+ *
+ * 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
+ *
+ * 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
+ * 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
+ * Clients may wish to set this value 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.
+ * DWT.WRAP
should be used if a larger message
+ * area is desired.
+ * 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 setUseMaximumDecorationWidth(false)
and need not register
+ * their decorations.
+ * 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.
+ *
+ * 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.
+ *
+ * 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.
+ * 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.
+ * 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 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
+ * 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) /*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