diff dwt/custom/CLabel.d @ 41:6337764516f1

Sync dwt/custom with dwt-linux (took copy of complete folder)
author Frank Benoit <benoit@tionex.de>
date Tue, 07 Oct 2008 16:29:55 +0200
parents f565d3a95c0a
children
line wrap: on
line diff
--- a/dwt/custom/CLabel.d	Tue Oct 07 14:41:31 2008 +0200
+++ b/dwt/custom/CLabel.d	Tue Oct 07 16:29:55 2008 +0200
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -7,12 +7,12 @@
  *
  * Contributors:
  *     IBM Corporation - initial API and implementation
- *     
  * Port to the D programming language:
- *     Jacob Carlborg <jacob.carlborg@gmail.com>
+ *     Frank Benoit <benoit@tionex.de>
  *******************************************************************************/
 module dwt.custom.CLabel;
 
+
 import dwt.DWT;
 import dwt.DWTException;
 import dwt.accessibility.ACC;
@@ -38,13 +38,15 @@
 import dwt.widgets.Composite;
 import dwt.widgets.Control;
 import dwt.widgets.Display;
+import dwt.dwthelper.utils;
 
-import dwt.dwthelper.utils;
+static import tango.text.Unicode;
+static import tango.text.convert.Utf;
 
 /**
  * A Label which supports aligned text and/or an image and different border styles.
  * <p>
- * If there is not enough space a CLabel uses the following strategy to fit the 
+ * If there is not enough space a CLabel uses the following strategy to fit the
  * information into the available space:
  * <pre>
  *      ignores the indent in left align mode
@@ -59,22 +61,26 @@
  * <dt><b>Events:</b>
  * <dd></dd>
  * </dl>
- * 
+ *
  * </p><p>
  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
  * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: CustomControlExample</a>
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
  */
-public class CLabel : Canvas
-{
+public class CLabel : Canvas {
+
+    alias Canvas.computeSize computeSize;
 
     /** Gap between icon and text */
     private static const int GAP = 5;
     /** Left and right margins */
     private static const int INDENT = 3;
-    /** a String inserted in the middle of text that has been shortened */
+    /** a string inserted in the middle of text that has been shortened */
     private static const String ELLIPSIS = "..."; //$NON-NLS-1$ // could use the ellipsis glyph on some platforms "\u2026"
-    /** the alignnment. Either CENTER, RIGHT, LEFT. Default is LEFT*/
-    private int alignn = DWT.LEFT;
+    /** the alignment. Either CENTER, RIGHT, LEFT. Default is LEFT*/
+    private int align_ = DWT.LEFT;
     private int hIndent = INDENT;
     private int vIndent = INDENT;
     /** the current text */
@@ -84,7 +90,7 @@
     // The tooltip is used for two purposes - the application can set
     // a tooltip or the tooltip can be used to display the full text when the
     // the text has been truncated due to the label being too short.
-    // The appToolTip stores the tooltip set by the application.  Control.tooltiptext 
+    // The appToolTip stores the tooltip set by the application.  Control.tooltiptext
     // contains whatever tooltip is currently being displayed.
     private String appToolTipText;
 
@@ -94,947 +100,750 @@
     private bool gradientVertical;
     private Color background;
 
-    private static int
-            DRAW_FLAGS = DWT.DRAW_MNEMONIC | DWT.DRAW_TAB | DWT.DRAW_TRANSPARENT | DWT.DRAW_DELIMITER;
+    private static int DRAW_FLAGS = DWT.DRAW_MNEMONIC | DWT.DRAW_TAB | DWT.DRAW_TRANSPARENT | DWT.DRAW_DELIMITER;
 
-    /**
-     * Constructs a new instance of this class given its parent
-     * and a style value describing its behavior and appearance.
-     * <p>
-     * The style value is either one of the style constants defined in
-     * class <code>DWT</code> which is applicable to instances of this
-     * class, or must be built by <em>bitwise OR</em>'ing together 
-     * (that is, using the <code>int</code> "|" operator) two or more
-     * of those <code>DWT</code> style constants. The class description
-     * lists the style constants that are applicable to the class.
-     * Style bits are also inherited from superclasses.
-     * </p>
-     *
-     * @param parent a widget which will be the parent of the new instance (cannot be null)
-     * @param style the style of widget to construct
-     *
-     * @exception IllegalArgumentException <ul>
-     *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
-     * </ul>
-     * @exception DWTException <ul>
-     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
-     * </ul>
-     *
-     * @see DWT#LEFT
-     * @see DWT#RIGHT
-     * @see DWT#CENTER
-     * @see DWT#SHADOW_IN
-     * @see DWT#SHADOW_OUT
-     * @see DWT#SHADOW_NONE
-     * @see #getStyle()
-     */
-    public this (Composite parent, int style)
-    {
-        super(parent, checkStyle(style));
-        if ((style & (DWT.CENTER | DWT.RIGHT)) is 0)
-            style |= DWT.LEFT;
-        if ((style & DWT.CENTER) !is 0)
-            alignn = DWT.CENTER;
-        if ((style & DWT.RIGHT) !is 0)
-            alignn = DWT.RIGHT;
-        if ((style & DWT.LEFT) !is 0)
-            alignn = DWT.LEFT;
+/**
+ * Constructs a new instance of this class given its parent
+ * and a style value describing its behavior and appearance.
+ * <p>
+ * The style value is either one of the style constants defined in
+ * class <code>DWT</code> which is applicable to instances of this
+ * class, or must be built by <em>bitwise OR</em>'ing together
+ * (that is, using the <code>int</code> "|" operator) two or more
+ * of those <code>DWT</code> style constants. The class description
+ * lists the style constants that are applicable to the class.
+ * Style bits are also inherited from superclasses.
+ * </p>
+ *
+ * @param parent a widget which will be the parent of the new instance (cannot be null)
+ * @param style the style of widget to construct
+ *
+ * @exception IllegalArgumentException <ul>
+ *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
+ * </ul>
+ * @exception DWTException <ul>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
+ * </ul>
+ *
+ * @see DWT#LEFT
+ * @see DWT#RIGHT
+ * @see DWT#CENTER
+ * @see DWT#SHADOW_IN
+ * @see DWT#SHADOW_OUT
+ * @see DWT#SHADOW_NONE
+ * @see #getStyle()
+ */
+public this(Composite parent, int style) {
+    super(parent, checkStyle(style));
+    if ((style & (DWT.CENTER | DWT.RIGHT)) is 0) style |= DWT.LEFT;
+    if ((style & DWT.CENTER) !is 0) align_ = DWT.CENTER;
+    if ((style & DWT.RIGHT) !is 0)  align_ = DWT.RIGHT;
+    if ((style & DWT.LEFT) !is 0)   align_ = DWT.LEFT;
 
-        addPaintListener(new class PaintListener
-        {
-            public void paintControl (PaintEvent event)
-            {
-                onPaint(event);
-            }
-        });
+    addPaintListener(new class() PaintListener{
+        public void paintControl(PaintEvent event) {
+            onPaint(event);
+        }
+    });
 
-        addDisposeListener(new class DisposeListener
-        {
-            public void widgetDisposed (DisposeEvent event)
-            {
-                onDispose(event);
+    addDisposeListener(new class() DisposeListener{
+        public void widgetDisposed(DisposeEvent event) {
+            onDispose(event);
+        }
+    });
+
+    addTraverseListener(new class() TraverseListener {
+        public void keyTraversed(TraverseEvent event) {
+            if (event.detail is DWT.TRAVERSE_MNEMONIC) {
+                onMnemonic(event);
             }
-        });
+        }
+    });
+
+    initAccessible();
 
-        addTraverseListener(new class TraverseListener
-        {
-            public void keyTraversed (TraverseEvent event)
-            {
-                if (event.detail is DWT.TRAVERSE_MNEMONIC)
-                {
-                    onMnemonic(event);
-                }
-            }
-        });
-
-        initAccessible();
-
-    }
+}
+/**
+ * Check the style bits to ensure that no invalid styles are applied.
+ */
+private static int checkStyle (int style) {
+    if ((style & DWT.BORDER) !is 0) style |= DWT.SHADOW_IN;
+    int mask = DWT.SHADOW_IN | DWT.SHADOW_OUT | DWT.SHADOW_NONE | DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT;
+    style = style & mask;
+    return style |= DWT.NO_FOCUS | DWT.DOUBLE_BUFFERED;
+}
 
-    /**
-     * Check the style bits to ensure that no invalid styles are applied.
-     */
-    private static int checkStyle (int style)
-    {
-        if ((style & DWT.BORDER) !is 0)
-            style |= DWT.SHADOW_IN;
-        int
-                mask = DWT.SHADOW_IN | DWT.SHADOW_OUT | DWT.SHADOW_NONE | DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT;
-        style = style & mask;
-        return style |= DWT.NO_FOCUS | DWT.DOUBLE_BUFFERED;
-    }
-
-    //protected void checkSubclass () {
-    //  String name = getClass().getName ();
-    //  String validName = CLabel.class.getName();
-    //  if (!validName.opEquals(name)) {
-    //      DWT.error (DWT.ERROR_INVALID_SUBCLASS);
-    //  }
-    //}
+//protected void checkSubclass () {
+//  String name = getClass().getName ();
+//  String validName = CLabel.class.getName();
+//  if (!validName.equals(name)) {
+//      DWT.error (DWT.ERROR_INVALID_SUBCLASS);
+//  }
+//}
 
-    public Point computeSize (int wHint, int hHint, bool changed)
-    {
-        checkWidget();
-        Point e = getTotalSize(image, text);
-        if (wHint is DWT.DEFAULT)
-        {
-            e.x += 2 * hIndent;
-        }
-        else
-        {
-            e.x = wHint;
-        }
-        if (hHint is DWT.DEFAULT)
-        {
-            e.y += 2 * vIndent;
-        }
-        else
-        {
-            e.y = hHint;
-        }
-        return e;
+public override Point computeSize(int wHint, int hHint, bool changed) {
+    checkWidget();
+    Point e = getTotalSize(image, text);
+    if (wHint is DWT.DEFAULT){
+        e.x += 2*hIndent;
+    } else {
+        e.x = wHint;
     }
+    if (hHint is DWT.DEFAULT) {
+        e.y += 2*vIndent;
+    } else {
+        e.y = hHint;
+    }
+    return e;
+}
+/**
+ * Draw a rectangle in the given colors.
+ */
+private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topleft, Color bottomright) {
+    gc.setForeground(bottomright);
+    gc.drawLine(x+w, y,   x+w, y+h);
+    gc.drawLine(x,   y+h, x+w, y+h);
 
-    /**
-     * Draw a rectangle in the given colors.
-     */
-    private void drawBevelRect (GC gc, int x, int y, int w, int h,
-            Color topleft, Color bottomright)
-    {
-        gc.setForeground(bottomright);
-        gc.drawLine(x + w, y, x + w, y + h);
-        gc.drawLine(x, y + h, x + w, y + h);
-
-        gc.setForeground(topleft);
-        gc.drawLine(x, y, x + w - 1, y);
-        gc.drawLine(x, y, x, y + h - 1);
-    }
+    gc.setForeground(topleft);
+    gc.drawLine(x, y, x+w-1, y);
+    gc.drawLine(x, y, x,     y+h-1);
+}
+/*
+ * Return the lowercase of the first non-'&' character following
+ * an '&' character in the given string. If there are no '&'
+ * characters in the given string, return '\0'.
+ */
+dchar _findMnemonic (String string) {
+    if (string is null) return '\0';
+    int index = 0;
+    int length = string.length;
+    do {
+        while (index < length && string[index] !is '&') index++;
+        if (++index >= length) return '\0';
+        if (string[index] !is '&') {
+            dchar[1] tmp; uint ate;
+            dchar[] tmp2 = tango.text.convert.Utf.toString32( string[index .. Math.min( index + 4, string.length ) ], tmp, &ate );
+            assert( tmp2.length == 1 );
+            return tango.text.Unicode.toLower( tmp2 )[0];
+        }
+        index++;
+    } while (index < length);
+    return '\0';
+}
+/**
+ * Returns the alignment.
+ * The alignment style (LEFT, CENTER or RIGHT) is returned.
+ *
+ * @return DWT.LEFT, DWT.RIGHT or DWT.CENTER
+ */
+public int getAlignment() {
+    //checkWidget();
+    return align_;
+}
+/**
+ * Return the CLabel's image or <code>null</code>.
+ *
+ * @return the image of the label or null
+ */
+public Image getImage() {
+    //checkWidget();
+    return image;
+}
+/**
+ * Compute the minimum size.
+ */
+private Point getTotalSize(Image image, String text) {
+    Point size = new Point(0, 0);
 
-    /*
-     * Return the lowercase of the first non-'&' character following
-     * an '&' character in the given String. If there are no '&'
-     * characters in the given String, return '\0'.
-     */
-    char _findMnemonic (String str)
-    {
-        if (str is null)
-            return '\0';
-        int index = 0;
-        int length = str.length();
-        do
-        {
-            while (index < length && str.charAt(index) !is '&')
-                index++;
-            if (++index >= length)
-                return '\0';
-            if (str.charAt(index) !is '&')
-                return CharacterToLower(str.charAt(index));
-            index++;
-        } while (index < length);
-        return '\0';
-    }
-
-    /**
-     * Returns the alignnment.
-     * The alignnment style (LEFT, CENTER or RIGHT) is returned.
-     * 
-     * @return DWT.LEFT, DWT.RIGHT or DWT.CENTER
-     */
-    public int getAlignment ()
-    {
-        //checkWidget();
-        return alignn;
+    if (image !is null) {
+        Rectangle r = image.getBounds();
+        size.x += r.width;
+        size.y += r.height;
     }
 
-    /**
-     * Return the CLabel's image or <code>null</code>.
-     * 
-     * @return the image of the label or null
-     */
-    public Image getImage ()
-    {
-        //checkWidget();
-        return image;
+    GC gc = new GC(this);
+    if (text !is null && text.length > 0) {
+        Point e = gc.textExtent(text, DRAW_FLAGS);
+        size.x += e.x;
+        size.y = Math.max(size.y, e.y);
+        if (image !is null) size.x += GAP;
+    } else {
+        size.y = Math.max(size.y, gc.getFontMetrics().getHeight());
     }
+    gc.dispose();
+
+    return size;
+}
+public override int getStyle () {
+    int style = super.getStyle();
+    switch (align_) {
+        case DWT.RIGHT: style |= DWT.RIGHT; break;
+        case DWT.CENTER: style |= DWT.CENTER; break;
+        case DWT.LEFT: style |= DWT.LEFT; break;
+        default:
+    }
+    return style;
+}
 
-    /**
-     * Compute the minimum size.
-     */
-    private Point getTotalSize (Image image, String text)
-    {
-        Point size = new Point(0, 0);
+/**
+ * Return the Label's text.
+ *
+ * @return the text of the label or null
+ */
+public String getText() {
+    //checkWidget();
+    return text;
+}
+public override String getToolTipText () {
+    checkWidget();
+    return appToolTipText;
+}
+private void initAccessible() {
+    Accessible accessible = getAccessible();
+    accessible.addAccessibleListener(new class() AccessibleAdapter {
+        public void getName(AccessibleEvent e) {
+            e.result = getText();
+        }
 
-        if (image !is null)
-        {
-            Rectangle r = image.getBounds();
-            size.x += r.width;
-            size.y += r.height;
+        public void getHelp(AccessibleEvent e) {
+            e.result = getToolTipText();
+        }
+
+        public void getKeyboardShortcut(AccessibleEvent e) {
+            dchar mnemonic = _findMnemonic(this.outer.text);
+            if (mnemonic !is '\0') {
+                dchar[1] d;
+                d[0] = mnemonic;
+                e.result = "Alt+" ~ tango.text.convert.Utf.toString(d); //$NON-NLS-1$
+            }
+        }
+    });
+
+    accessible.addAccessibleControlListener(new class() AccessibleControlAdapter {
+        public void getChildAtPoint(AccessibleControlEvent e) {
+            e.childID = ACC.CHILDID_SELF;
         }
 
-        GC gc = new GC(this);
-        if (text !is null && text.length() > 0)
-        {
-            Point e = gc.textExtent(text, DRAW_FLAGS);
-            size.x += e.x;
-            size.y = Math.max(size.y, e.y);
-            if (image !is null)
-                size.x += GAP;
+        public void getLocation(AccessibleControlEvent e) {
+            Rectangle rect = getDisplay().map(getParent(), null, getBounds());
+            e.x = rect.x;
+            e.y = rect.y;
+            e.width = rect.width;
+            e.height = rect.height;
         }
-        else
-        {
-            size.y = Math.max(size.y, gc.getFontMetrics().getHeight());
-        }
-        gc.dispose();
-
-        return size;
-    }
 
-    public int getStyle ()
-    {
-        int style = super.getStyle();
-        switch (alignn)
-        {
-            case DWT.RIGHT:
-                style |= DWT.RIGHT;
-            break;
-            case DWT.CENTER:
-                style |= DWT.CENTER;
-            break;
-            case DWT.LEFT:
-                style |= DWT.LEFT;
-            break;
+        public void getChildCount(AccessibleControlEvent e) {
+            e.detail = 0;
         }
-        return style;
-    }
+
+        public void getRole(AccessibleControlEvent e) {
+            e.detail = ACC.ROLE_LABEL;
+        }
 
-    /**
-     * Return the Label's text.
-     * 
-     * @return the text of the label or null
-     */
-    public String getText ()
-    {
-        //checkWidget();
-        return text;
-    }
-
-    public String getToolTipText ()
-    {
-        checkWidget();
-        return appToolTipText;
-    }
-
-    private void initAccessible ()
-    {
-        Accessible accessible = getAccessible();
-        accessible.addAccessibleListener(new class AccessibleAdapter
-        {
-            public void getName (AccessibleEvent e)
-            {
-                e.result = getText();
-            }
-
-            public void getHelp (AccessibleEvent e)
-            {
-                e.result = getToolTipText();
-            }
-
-            public void getKeyboardShortcut (AccessibleEvent e)
-            {
-                char mnemonic = _findMnemonic(this.text);
-                if (mnemonic !is '\0')
-                {
-                    e.result = "Alt+" + mnemonic; //$NON-NLS-1$
+        public void getState(AccessibleControlEvent e) {
+            e.detail = ACC.STATE_READONLY;
+        }
+    });
+}
+void onDispose(DisposeEvent event) {
+    gradientColors = null;
+    gradientPercents = null;
+    backgroundImage = null;
+    text = null;
+    image = null;
+    appToolTipText = null;
+}
+void onMnemonic(TraverseEvent event) {
+    dchar mnemonic = _findMnemonic(text);
+    if (mnemonic is '\0') return;
+    dchar[1] d; uint ate;
+    auto r = tango.text.convert.Utf.toString32( [event.character][], d, &ate );
+    if (tango.text.Unicode.toLower(r)[0] !is mnemonic) return;
+    Composite control = this.getParent();
+    while (control !is null) {
+        Control [] children = control.getChildren();
+        int index = 0;
+        while (index < children.length) {
+            if (children [index] is this) break;
+            index++;
+        }
+        index++;
+        if (index < children.length) {
+            if (children [index].setFocus ()) {
+                event.doit = true;
+                event.detail = DWT.TRAVERSE_NONE;
             }
         }
-    }   );
-
-        accessible.addAccessibleControlListener(new class
-                AccessibleControlAdapter
-        {
-            public void getChildAtPoint (AccessibleControlEvent e)
-            {
-                e.childID = ACC.CHILDID_SELF;
-            }
+        control = control.getParent();
+    }
+}
 
-            public void getLocation (AccessibleControlEvent e)
-            {
-                Rectangle rect = getDisplay().map(getParent(), null,
-                        getBounds());
-                e.x = rect.x;
-                e.y = rect.y;
-                e.width = rect.width;
-                e.height = rect.height;
-            }
-
-            public void getChildCount (AccessibleControlEvent e)
-            {
-                e.detail = 0;
-            }
-
-            public void getRole (AccessibleControlEvent e)
-            {
-                e.detail = ACC.ROLE_LABEL;
-            }
-
-            public void getState (AccessibleControlEvent e)
-            {
-                e.detail = ACC.STATE_READONLY;
-            }
-        });
-    }
+void onPaint(PaintEvent event) {
+    Rectangle rect = getClientArea();
+    if (rect.width is 0 || rect.height is 0) return;
 
-    void onDispose (DisposeEvent event)
-    {
-        gradientColors = null;
-        gradientPercents = null;
-        backgroundImage = null;
-        text = null;
-        image = null;
-        appToolTipText = null;
-    }
-
-    void onMnemonic (TraverseEvent event)
-    {
-        char mnemonic = _findMnemonic(text);
-        if (mnemonic is '\0')
-            return;
-        if (CharacterToLower(event.character) !is mnemonic)
-            return;
-        Composite control = this.getParent();
-        while (control !is null)
-        {
-            Control[] children = control.getChildren();
-            int index = 0;
-            while (index < children.length)
-            {
-                if (children[index] is this)
-                    break;
-                index++;
-            }
-            index++;
-            if (index < children.length)
-            {
-                if (children[index].setFocus())
-                {
-                    event.doit = true;
-                    event.detail = DWT.TRAVERSE_NONE;
-                }
-            }
-            control = control.getParent();
+    bool shortenText_ = false;
+    String t = text;
+    Image img = image;
+    int availableWidth = Math.max(0, rect.width - 2*hIndent);
+    Point extent = getTotalSize(img, t);
+    if (extent.x > availableWidth) {
+        img = null;
+        extent = getTotalSize(img, t);
+        if (extent.x > availableWidth) {
+            shortenText_ = true;
         }
     }
 
-    void onPaint (PaintEvent event)
-    {
-        Rectangle rect = getClientArea();
-        if (rect.width is 0 || rect.height is 0)
-            return;
-
-        bool shortenText = false;
-        String t = text;
-        Image img = image;
-        int availableWidth = Math.max(0, rect.width - 2 * hIndent);
-        Point extent = getTotalSize(img, t);
-        if (extent.x > availableWidth)
-        {
-            img = null;
-            extent = getTotalSize(img, t);
-            if (extent.x > availableWidth)
-            {
-                shortenText = true;
-            }
-        }
+    GC gc = event.gc;
+    String[] lines = text is null ? null : splitString(text);
 
-        GC gc = event.gc;
-        String[] lines = text is null ? null : splitString(text);
-
-        // shorten the text
-        if (shortenText)
-        {
-            extent.x = 0;
-            for (int i = 0; i < lines.length; i++)
-            {
-                Point e = gc.textExtent(lines[i], DRAW_FLAGS);
-                if (e.x > availableWidth)
-                {
-                    lines[i] = shortenText(gc, lines[i], availableWidth);
-                    extent.x = Math.max(extent.x,
-                            getTotalSize(null, lines[i]).x);
-                }
-                else
-                {
-                    extent.x = Math.max(extent.x, e.x);
-                }
-            }
-            if (appToolTipText is null)
-            {
-                super.setToolTipText(text);
+    // shorten the text
+    if (shortenText_) {
+        extent.x = 0;
+        for(int i = 0; i < lines.length; i++) {
+            Point e = gc.textExtent(lines[i], DRAW_FLAGS);
+            if (e.x > availableWidth) {
+                lines[i] = shortenText(gc, lines[i], availableWidth);
+                extent.x = Math.max(extent.x, getTotalSize(null, lines[i]).x);
+            } else {
+                extent.x = Math.max(extent.x, e.x);
             }
         }
-        else
-        {
-            super.setToolTipText(appToolTipText);
+        if (appToolTipText is null) {
+            super.setToolTipText(text);
         }
-
-        // determine horizontal position
-        int x = rect.x + hIndent;
-        if (alignn is DWT.CENTER)
-        {
-            x = (rect.width - extent.x) / 2;
-        }
-        if (alignn is DWT.RIGHT)
-        {
-            x = rect.width - hIndent - extent.x;
-        }
+    } else {
+        super.setToolTipText(appToolTipText);
+    }
 
-        // draw a background image behind the text
-        try
-        {
-            if (backgroundImage !is null)
-            {
-                // draw a background image behind the text
-                Rectangle imageRect = backgroundImage.getBounds();
-                // tile image to fill space
-                gc.setBackground(getBackground());
-                gc.fillRectangle(rect);
-                int xPos = 0;
-                while (xPos < rect.width)
-                {
-                    int yPos = 0;
-                    while (yPos < rect.height)
-                    {
-                        gc.drawImage(backgroundImage, xPos, yPos);
-                        yPos += imageRect.height;
-                    }
-                    xPos += imageRect.width;
-                }
-            }
-            else if (gradientColors !is null)
-            {
-                // draw a gradient behind the text
-                const Color oldBackground = gc.getBackground();
-                if (gradientColors.length is 1)
-                {
-                    if (gradientColors[0] !is null)
-                        gc.setBackground(gradientColors[0]);
-                    gc.fillRectangle(0, 0, rect.width, rect.height);
+    // determine horizontal position
+    int x = rect.x + hIndent;
+    if (align_ is DWT.CENTER) {
+        x = (rect.width - extent.x)/2;
+    }
+    if (align_ is DWT.RIGHT) {
+        x = rect.width - hIndent - extent.x;
+    }
+
+    // draw a background image behind the text
+    try {
+        if (backgroundImage !is null) {
+            // draw a background image behind the text
+            Rectangle imageRect = backgroundImage.getBounds();
+            // tile image to fill space
+            gc.setBackground(getBackground());
+            gc.fillRectangle(rect);
+            int xPos = 0;
+            while (xPos < rect.width) {
+                int yPos = 0;
+                while (yPos < rect.height) {
+                    gc.drawImage(backgroundImage, xPos, yPos);
+                    yPos += imageRect.height;
                 }
-                else
-                {
-                    const Color oldForeground = gc.getForeground();
-                    Color lastColor = gradientColors[0];
-                    if (lastColor is null)
-                        lastColor = oldBackground;
-                    int pos = 0;
-                    for (int i = 0; i < gradientPercents.length; ++i)
-                    {
-                        gc.setForeground(lastColor);
-                        lastColor = gradientColors[i + 1];
-                        if (lastColor is null)
-                            lastColor = oldBackground;
-                        gc.setBackground(lastColor);
-                        if (gradientVertical)
-                        {
-                            const int
-                                    gradientHeight = (gradientPercents[i] * rect.height / 100) - pos;
-                            gc.fillGradientRectangle(0, pos, rect.width,
-                                    gradientHeight, true);
-                            pos += gradientHeight;
-                        }
-                        else
-                        {
-                            const int
-                                    gradientWidth = (gradientPercents[i] * rect.width / 100) - pos;
-                            gc.fillGradientRectangle(pos, 0, gradientWidth,
-                                    rect.height, false);
-                            pos += gradientWidth;
-                        }
+                xPos += imageRect.width;
+            }
+        } else if (gradientColors !is null) {
+            // draw a gradient behind the text
+            final Color oldBackground = gc.getBackground();
+            if (gradientColors.length is 1) {
+                if (gradientColors[0] !is null) gc.setBackground(gradientColors[0]);
+                gc.fillRectangle(0, 0, rect.width, rect.height);
+            } else {
+                final Color oldForeground = gc.getForeground();
+                Color lastColor = gradientColors[0];
+                if (lastColor is null) lastColor = oldBackground;
+                int pos = 0;
+                for (int i = 0; i < gradientPercents.length; ++i) {
+                    gc.setForeground(lastColor);
+                    lastColor = gradientColors[i + 1];
+                    if (lastColor is null) lastColor = oldBackground;
+                    gc.setBackground(lastColor);
+                    if (gradientVertical) {
+                        final int gradientHeight = (gradientPercents[i] * rect.height / 100) - pos;
+                        gc.fillGradientRectangle(0, pos, rect.width, gradientHeight, true);
+                        pos += gradientHeight;
+                    } else {
+                        final int gradientWidth = (gradientPercents[i] * rect.width / 100) - pos;
+                        gc.fillGradientRectangle(pos, 0, gradientWidth, rect.height, false);
+                        pos += gradientWidth;
                     }
-                    if (gradientVertical && pos < rect.height)
-                    {
-                        gc.setBackground(getBackground());
-                        gc.fillRectangle(0, pos, rect.width, rect.height - pos);
-                    }
-                    if (!gradientVertical && pos < rect.width)
-                    {
-                        gc.setBackground(getBackground());
-                        gc.fillRectangle(pos, 0, rect.width - pos, rect.height);
-                    }
-                    gc.setForeground(oldForeground);
+                }
+                if (gradientVertical && pos < rect.height) {
+                    gc.setBackground(getBackground());
+                    gc.fillRectangle(0, pos, rect.width, rect.height - pos);
                 }
-                gc.setBackground(oldBackground);
+                if (!gradientVertical && pos < rect.width) {
+                    gc.setBackground(getBackground());
+                    gc.fillRectangle(pos, 0, rect.width - pos, rect.height);
+                }
+                gc.setForeground(oldForeground);
             }
-            else
-            {
-                if (background !is null || (getStyle() & DWT.DOUBLE_BUFFERED) is 0)
-                {
-                    gc.setBackground(getBackground());
-                    gc.fillRectangle(rect);
-                }
-            }
-        }
-        catch (DWTException e)
-        {
-            if ((getStyle() & DWT.DOUBLE_BUFFERED) is 0)
-            {
+            gc.setBackground(oldBackground);
+        } else {
+            if (background !is null || (getStyle() & DWT.DOUBLE_BUFFERED) is 0) {
                 gc.setBackground(getBackground());
                 gc.fillRectangle(rect);
             }
         }
+    } catch (DWTException e) {
+        if ((getStyle() & DWT.DOUBLE_BUFFERED) is 0) {
+            gc.setBackground(getBackground());
+            gc.fillRectangle(rect);
+        }
+    }
 
-        // draw border
-        int style = getStyle();
-        if ((style & DWT.SHADOW_IN) !is 0 || (style & DWT.SHADOW_OUT) !is 0)
-        {
-            paintBorder(gc, rect);
-        }
+    // draw border
+    int style = getStyle();
+    if ((style & DWT.SHADOW_IN) !is 0 || (style & DWT.SHADOW_OUT) !is 0) {
+        paintBorder(gc, rect);
+    }
 
-        // draw the image
-        if (img !is null)
-        {
-            Rectangle imageRect = img.getBounds();
-            gc.drawImage(img, 0, 0, imageRect.width, imageRect.height, x,
-                    (rect.height - imageRect.height) / 2, imageRect.width,
-                    imageRect.height);
-            x += imageRect.width + GAP;
-            extent.x -= imageRect.width + GAP;
+    // draw the image
+    if (img !is null) {
+        Rectangle imageRect = img.getBounds();
+        gc.drawImage(img, 0, 0, imageRect.width, imageRect.height,
+                        x, (rect.height-imageRect.height)/2, imageRect.width, imageRect.height);
+        x +=  imageRect.width + GAP;
+        extent.x -= imageRect.width + GAP;
+    }
+    // draw the text
+    if (lines !is null) {
+        int lineHeight = gc.getFontMetrics().getHeight();
+        int textHeight = lines.length * lineHeight;
+        int lineY = Math.max(vIndent, rect.y + (rect.height - textHeight) / 2);
+        gc.setForeground(getForeground());
+        for (int i = 0; i < lines.length; i++) {
+            int lineX = x;
+            if (lines.length > 1) {
+                if (align_ is DWT.CENTER) {
+                    int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
+                    lineX = x + Math.max(0, (extent.x - lineWidth) / 2);
+                }
+                if (align_ is DWT.RIGHT) {
+                    int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
+                    lineX = Math.max(x, rect.x + rect.width - hIndent - lineWidth);
+                }
+            }
+            gc.drawText(lines[i], lineX, lineY, DRAW_FLAGS);
+            lineY += lineHeight;
         }
-        // draw the text
-        if (lines !is null)
-        {
-            int lineHeight = gc.getFontMetrics().getHeight();
-            int textHeight = lines.length * lineHeight;
-            int lineY = Math.max(vIndent,
-                    rect.y + (rect.height - textHeight) / 2);
-            gc.setForeground(getForeground());
-            for (int i = 0; i < lines.length; i++)
-            {
-                int lineX = x;
-                if (lines.length > 1)
-                {
-                    if (alignn is DWT.CENTER)
-                    {
-                        int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
-                        lineX = x + Math.max(0, (extent.x - lineWidth) / 2);
-                    }
-                    if (alignn is DWT.RIGHT)
-                    {
-                        int lineWidth = gc.textExtent(lines[i], DRAW_FLAGS).x;
-                        lineX = Math.max(x,
-                                rect.x + rect.width - hIndent - lineWidth);
-                    }
-                }
-                gc.drawText(lines[i], lineX, lineY, DRAW_FLAGS);
-                lineY += lineHeight;
+    }
+}
+/**
+ * Paint the Label's border.
+ */
+private void paintBorder(GC gc, Rectangle r) {
+    Display disp= getDisplay();
+
+    Color c1 = null;
+    Color c2 = null;
+
+    int style = getStyle();
+    if ((style & DWT.SHADOW_IN) !is 0) {
+        c1 = disp.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW);
+        c2 = disp.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
+    }
+    if ((style & DWT.SHADOW_OUT) !is 0) {
+        c1 = disp.getSystemColor(DWT.COLOR_WIDGET_LIGHT_SHADOW);
+        c2 = disp.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW);
+    }
+
+    if (c1 !is null && c2 !is null) {
+        gc.setLineWidth(1);
+        drawBevelRect(gc, r.x, r.y, r.width-1, r.height-1, c1, c2);
+    }
+}
+/**
+ * Set the alignment of the CLabel.
+ * Use the values LEFT, CENTER and RIGHT to align image and text within the available space.
+ *
+ * @param align the alignment style of LEFT, RIGHT or CENTER
+ *
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the value of align is not one of DWT.LEFT, DWT.RIGHT or DWT.CENTER</li>
+ * </ul>
+ */
+public void setAlignment(int align_) {
+    checkWidget();
+    if (align_ !is DWT.LEFT && align_ !is DWT.RIGHT && align_ !is DWT.CENTER) {
+        DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+    }
+    if (this.align_ !is align_) {
+        this.align_ = align_;
+        redraw();
+    }
+}
+
+public override void setBackground (Color color) {
+    super.setBackground (color);
+    // Are these settings the same as before?
+    if (backgroundImage is null &&
+        gradientColors is null &&
+        gradientPercents is null) {
+        if (color is null) {
+            if (background is null) return;
+        } else {
+            if (color ==/*eq*/ background) return;
+        }
+    }
+    background = color;
+    backgroundImage = null;
+    gradientColors = null;
+    gradientPercents = null;
+    redraw ();
+}
+
+/**
+ * Specify a gradient of colours to be drawn in the background of the CLabel.
+ * <p>For example, to draw a gradient that varies from dark blue to blue and then to
+ * white and stays white for the right half of the label, use the following call
+ * to setBackground:</p>
+ * <pre>
+ *  clabel.setBackground(new Color[]{display.getSystemColor(DWT.COLOR_DARK_BLUE),
+ *                                 display.getSystemColor(DWT.COLOR_BLUE),
+ *                                 display.getSystemColor(DWT.COLOR_WHITE),
+ *                                 display.getSystemColor(DWT.COLOR_WHITE)},
+ *                     new int[] {25, 50, 100});
+ * </pre>
+ *
+ * @param colors an array of Color that specifies the colors to appear in the gradient
+ *               in order of appearance from left to right;  The value <code>null</code>
+ *               clears the background gradient; the value <code>null</code> can be used
+ *               inside the array of Color to specify the background color.
+ * @param percents an array of integers between 0 and 100 specifying the percent of the width
+ *                 of the widget at which the color should change; the size of the percents
+ *                 array must be one less than the size of the colors array.
+ *
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the values of colors and percents are not consistent</li>
+ * </ul>
+ */
+public void setBackground(Color[] colors, int[] percents) {
+    setBackground(colors, percents, false);
+}
+/**
+ * Specify a gradient of colours to be drawn in the background of the CLabel.
+ * <p>For example, to draw a gradient that varies from dark blue to white in the vertical,
+ * direction use the following call
+ * to setBackground:</p>
+ * <pre>
+ *  clabel.setBackground(new Color[]{display.getSystemColor(DWT.COLOR_DARK_BLUE),
+ *                                 display.getSystemColor(DWT.COLOR_WHITE)},
+ *                       new int[] {100}, true);
+ * </pre>
+ *
+ * @param colors an array of Color that specifies the colors to appear in the gradient
+ *               in order of appearance from left/top to right/bottom;  The value <code>null</code>
+ *               clears the background gradient; the value <code>null</code> can be used
+ *               inside the array of Color to specify the background color.
+ * @param percents an array of integers between 0 and 100 specifying the percent of the width/height
+ *                 of the widget at which the color should change; the size of the percents
+ *                 array must be one less than the size of the colors array.
+ * @param vertical indicate the direction of the gradient.  True is vertical and false is horizontal.
+ *
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ *    <li>ERROR_INVALID_ARGUMENT - if the values of colors and percents are not consistent</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public void setBackground(Color[] colors, int[] percents, bool vertical) {
+    checkWidget();
+    if (colors !is null) {
+        if (percents is null || percents.length !is colors.length - 1) {
+            DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+        }
+        if (getDisplay().getDepth() < 15) {
+            // Don't use gradients on low color displays
+            colors = [colors[colors.length - 1]];
+            percents = null;
+        }
+        for (int i = 0; i < percents.length; i++) {
+            if (percents[i] < 0 || percents[i] > 100) {
+                DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+            }
+            if (i > 0 && percents[i] < percents[i-1]) {
+                DWT.error(DWT.ERROR_INVALID_ARGUMENT);
             }
         }
     }
 
-    /**
-     * Paint the Label's border.
-     */
-    private void paintBorder (GC gc, Rectangle r)
-    {
-        Display disp = getDisplay();
-
-        Color c1 = null;
-        Color c2 = null;
-
-        int style = getStyle();
-        if ((style & DWT.SHADOW_IN) !is 0)
-        {
-            c1 = disp.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW);
-            c2 = disp.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
-        }
-        if ((style & DWT.SHADOW_OUT) !is 0)
-        {
-            c1 = disp.getSystemColor(DWT.COLOR_WIDGET_LIGHT_SHADOW);
-            c2 = disp.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW);
-        }
-
-        if (c1 !is null && c2 !is null)
-        {
-            gc.setLineWidth(1);
-            drawBevelRect(gc, r.x, r.y, r.width - 1, r.height - 1, c1, c2);
-        }
-    }
-
-    /**
-     * Set the alignnment of the CLabel.
-     * Use the values LEFT, CENTER and RIGHT to alignn image and text within the available space.
-     * 
-     * @param alignn the alignnment style of LEFT, RIGHT or CENTER
-     * 
-     * @exception DWTException <ul>
-     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
-     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
-     *    <li>ERROR_INVALID_ARGUMENT - if the value of alignn is not one of DWT.LEFT, DWT.RIGHT or DWT.CENTER</li>
-     * </ul>
-     */
-    public void setAlignment (int alignn)
-    {
-        checkWidget();
-        if (alignn !is DWT.LEFT && alignn !is DWT.RIGHT && alignn !is DWT.CENTER)
-        {
-            DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-        }
-        if (this.alignn !is alignn)
-        {
-            this.alignn = alignn;
-            redraw();
-        }
-    }
-
-    public void setBackground (Color color)
-    {
-        super.setBackground(color);
-        // Are these settings the same as before?
-        if (backgroundImage is null && gradientColors is null && gradientPercents is null)
-        {
-            if (color is null)
-            {
-                if (background is null)
-                    return;
-            }
-            else
-            {
-                if (color.opEquals(background))
-                    return;
+    // Are these settings the same as before?
+    final Color background = getBackground();
+    if (backgroundImage is null) {
+        if ((gradientColors !is null) && (colors !is null) &&
+            (gradientColors.length is colors.length)) {
+            bool same = false;
+            for (int i = 0; i < gradientColors.length; i++) {
+                same = (gradientColors[i] is colors[i]) ||
+                    ((gradientColors[i] is null) && (colors[i] is background)) ||
+                    ((gradientColors[i] is background) && (colors[i] is null));
+                if (!same) break;
             }
-        }
-        background = color;
-        backgroundImage = null;
-        gradientColors = null;
-        gradientPercents = null;
-        redraw();
-    }
-
-    /**
-     * Specify a gradient of colours to be drawn in the background of the CLabel.
-     * <p>For example, to draw a gradient that varies from dark blue to blue and then to
-     * white and stays white for the right half of the label, use the following call 
-     * to setBackground:</p>
-     * <pre>
-     *  clabel.setBackground(new Color[]{display.getSystemColor(DWT.COLOR_DARK_BLUE), 
-     *                                 display.getSystemColor(DWT.COLOR_BLUE),
-     *                                 display.getSystemColor(DWT.COLOR_WHITE), 
-     *                                 display.getSystemColor(DWT.COLOR_WHITE)},
-     *                     new int[] {25, 50, 100});
-     * </pre>
-     *
-     * @param colors an array of Color that specifies the colors to appear in the gradient 
-     *               in order of appearance from left to right;  The value <code>null</code> 
-     *               clears the background gradient; the value <code>null</code> can be used 
-     *               inside the array of Color to specify the background color.
-     * @param percents an array of integers between 0 and 100 specifying the percent of the width 
-     *                 of the widget at which the color should change; the size of the percents 
-     *                 array must be one less than the size of the colors array.
-     * 
-     * @exception DWTException <ul>
-     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
-     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
-     *    <li>ERROR_INVALID_ARGUMENT - if the values of colors and percents are not consistent</li>
-     * </ul>
-     */
-    public void setBackground (Color[] colors, int[] percents)
-    {
-        setBackground(colors, percents, false);
-    }
-
-    /**
-     * Specify a gradient of colours to be drawn in the background of the CLabel.
-     * <p>For example, to draw a gradient that varies from dark blue to white in the vertical,
-     * direction use the following call 
-     * to setBackground:</p>
-     * <pre>
-     *  clabel.setBackground(new Color[]{display.getSystemColor(DWT.COLOR_DARK_BLUE), 
-     *                                 display.getSystemColor(DWT.COLOR_WHITE)},
-     *                       new int[] {100}, true);
-     * </pre>
-     *
-     * @param colors an array of Color that specifies the colors to appear in the gradient 
-     *               in order of appearance from left/top to right/bottom;  The value <code>null</code> 
-     *               clears the background gradient; the value <code>null</code> can be used 
-     *               inside the array of Color to specify the background color.
-     * @param percents an array of integers between 0 and 100 specifying the percent of the width/height 
-     *                 of the widget at which the color should change; the size of the percents 
-     *                 array must be one less than the size of the colors array.
-     * @param vertical indicate the direction of the gradient.  True is vertical and false is horizontal.
-     * 
-     * @exception DWTException <ul>
-     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
-     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
-     *    <li>ERROR_INVALID_ARGUMENT - if the values of colors and percents are not consistent</li>
-     * </ul>
-     * 
-     * @since 3.0
-     */
-    public void setBackground (Color[] colors, int[] percents, bool vertical)
-    {
-        checkWidget();
-        if (colors !is null)
-        {
-            if (percents is null || percents.length !is colors.length - 1)
-            {
-                DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-            }
-            if (getDisplay().getDepth() < 15)
-            {
-                // Don't use gradients on low color displays
-                colors = new Color[][colors[colors.length - 1]];
-                percents = new int[][];
-            }
-            for (int i = 0; i < percents.length; i++)
-            {
-                if (percents[i] < 0 || percents[i] > 100)
-                {
-                    DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-                }
-                if (i > 0 && percents[i] < percents[i - 1])
-                {
-                    DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+            if (same) {
+                for (int i = 0; i < gradientPercents.length; i++) {
+                    same = gradientPercents[i] is percents[i];
+                    if (!same) break;
                 }
             }
+            if (same && this.gradientVertical is vertical) return;
         }
+    } else {
+        backgroundImage = null;
+    }
+    // Store the new settings
+    if (colors is null) {
+        gradientColors = null;
+        gradientPercents = null;
+        gradientVertical = false;
+    } else {
+        gradientColors = new Color[colors.length];
+        for (int i = 0; i < colors.length; ++i)
+            gradientColors[i] = (colors[i] !is null) ? colors[i] : background;
+        gradientPercents = new int[percents.length];
+        for (int i = 0; i < percents.length; ++i)
+            gradientPercents[i] = percents[i];
+        gradientVertical = vertical;
+    }
+    // Refresh with the new settings
+    redraw();
+}
+/**
+ * Set the image to be drawn in the background of the label.
+ *
+ * @param image the image to be drawn in the background
+ *
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setBackground(Image image) {
+    checkWidget();
+    if (image is backgroundImage) return;
+    if (image !is null) {
+        gradientColors = null;
+        gradientPercents = null;
+    }
+    backgroundImage = image;
+    redraw();
 
-        // Are these settings the same as before?
-        const Color background = getBackground();
-        if (backgroundImage is null)
-        {
-            if ((gradientColors !is null) && (colors !is null) && (gradientColors.length is colors.length))
-            {
-                bool same = false;
-                for (int i = 0; i < gradientColors.length; i++)
-                {
-                    same = (gradientColors[i] is colors[i]) || ((gradientColors[i] is null) && (colors[i] is background)) || ((gradientColors[i] is background) && (colors[i] is null));
-                    if (!same)
-                        break;
-                }
-                if (same)
-                {
-                    for (int i = 0; i < gradientPercents.length; i++)
-                    {
-                        same = gradientPercents[i] is percents[i];
-                        if (!same)
-                            break;
-                    }
-                }
-                if (same && this.gradientVertical is vertical)
-                    return;
-            }
-        }
-        else
-        {
-            backgroundImage = null;
-        }
-        // Store the new settings
-        if (colors is null)
-        {
-            gradientColors = null;
-            gradientPercents = null;
-            gradientVertical = false;
-        }
-        else
-        {
-            gradientColors = new Color[colors.length];
-            for (int i = 0; i < colors.length; ++i)
-                gradientColors[i] = (colors[i] !is null) ? colors[i] : background;
-            gradientPercents = new int[percents.length];
-            for (int i = 0; i < percents.length; ++i)
-                gradientPercents[i] = percents[i];
-            gradientVertical = vertical;
-        }
-        // Refresh with the new settings
+}
+public override void setFont(Font font) {
+    super.setFont(font);
+    redraw();
+}
+/**
+ * Set the label's Image.
+ * The value <code>null</code> clears it.
+ *
+ * @param image the image to be displayed in the label or null
+ *
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setImage(Image image) {
+    checkWidget();
+    if (image !is this.image) {
+        this.image = image;
         redraw();
     }
-
-    /**
-     * Set the image to be drawn in the background of the label.
-     * 
-     * @param image the image to be drawn in the background
-     * 
-     * @exception DWTException <ul>
-     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
-     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
-     * </ul>
-     */
-    public void setBackground (Image image)
-    {
-        checkWidget();
-        if (image is backgroundImage)
-            return;
-        if (image !is null)
-        {
-            gradientColors = null;
-            gradientPercents = null;
-        }
-        backgroundImage = image;
-        redraw();
-
-    }
-
-    public void setFont (Font font)
-    {
-        super.setFont(font);
+}
+/**
+ * Set the label's text.
+ * The value <code>null</code> clears it.
+ *
+ * @param text the text to be displayed in the label or null
+ *
+ * @exception DWTException <ul>
+ *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ */
+public void setText(String text) {
+    checkWidget();
+    if (text is null) text = ""; //$NON-NLS-1$
+    if ( text !=/*eq*/ this.text) {
+        this.text = text;
         redraw();
     }
-
-    /**
-     * Set the label's Image.
-     * The value <code>null</code> clears it.
-     * 
-     * @param image the image to be displayed in the label or null
-     * 
-     * @exception DWTException <ul>
-     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
-     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
-     * </ul>
-     */
-    public void setImage (Image image)
-    {
-        checkWidget();
-        if (image !is this.image)
-        {
-            this.image = image;
-            redraw();
+}
+public override void setToolTipText (String string) {
+    super.setToolTipText (string);
+    appToolTipText = super.getToolTipText();
+}
+/**
+ * Shorten the given text <code>t</code> so that its length doesn't exceed
+ * the given width. The default implementation replaces characters in the
+ * center of the original string with an ellipsis ("...").
+ * Override if you need a different strategy.
+ *
+ * @param gc the gc to use for text measurement
+ * @param t the text to shorten
+ * @param width the width to shorten the text to, in pixels
+ * @return the shortened text
+ */
+protected String shortenText(GC gc, String t, int width) {
+    if (t is null) return null;
+    int w = gc.textExtent(ELLIPSIS, DRAW_FLAGS).x;
+    if (width<=w) return t;
+    int l = t.length;
+    int max = l/2;
+    int min = 0;
+    int mid = (max+min)/2 - 1;
+    if (mid <= 0) return t;
+    TextLayout layout = new TextLayout (getDisplay());
+    layout.setText(t);
+    mid = validateOffset(layout, mid);
+    while (min < mid && mid < max) {
+        String s1 = t[0 .. mid].dup;
+        String s2 = t.substring(validateOffset(layout, l-mid), l);
+        int l1 = gc.textExtent(s1, DRAW_FLAGS).x;
+        int l2 = gc.textExtent(s2, DRAW_FLAGS).x;
+        if (l1+w+l2 > width) {
+            max = mid;
+            mid = validateOffset(layout, (max+min)/2);
+        } else if (l1+w+l2 < width) {
+            min = mid;
+            mid = validateOffset(layout, (max+min)/2);
+        } else {
+            min = max;
         }
     }
-
-    /**
-     * Set the label's text.
-     * The value <code>null</code> clears it.
-     * 
-     * @param text the text to be displayed in the label or null
-     * 
-     * @exception DWTException <ul>
-     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
-     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
-     * </ul>
-     */
-    public void setText (String text)
-    {
-        checkWidget();
-        if (text is null)
-            text = ""; //$NON-NLS-1$
-        if (!text.opEquals(this.text))
-        {
-            this.text = text;
-            redraw();
+    String result = mid is 0 ? t : t.substring(0, mid) ~ ELLIPSIS ~ t.substring(validateOffset(layout, l-mid), l);
+    layout.dispose();
+    return result;
+}
+int validateOffset(TextLayout layout, int offset) {
+    int nextOffset = layout.getNextOffset(offset, DWT.MOVEMENT_CLUSTER);
+    if (nextOffset !is offset) return layout.getPreviousOffset(nextOffset, DWT.MOVEMENT_CLUSTER);
+    return offset;
+}
+private String[] splitString(String text) {
+    String[] lines = new String[1];
+    int start = 0, pos;
+    do {
+        pos = tango.text.Util.locate( text, '\n', start);
+        if (pos is text.length ) {
+            lines[lines.length - 1] = text[start .. $ ];
+        } else {
+            bool crlf = (pos > 0) && (text[ pos - 1 ] is '\r');
+            lines[lines.length - 1] = text[ start .. pos - (crlf ? 1 : 0)];
+            start = pos + 1;
+            String[] newLines = new String[lines.length+1];
+            System.arraycopy(lines, 0, newLines, 0, lines.length);
+            lines = newLines;
         }
-    }
-
-    public void setToolTipText (String String)
-    {
-        super.setToolTipText(String);
-        appToolTipText = super.getToolTipText();
-    }
-
-    /**
-     * Shorten the given text <code>t</code> so that its length doesn't exceed
-     * the given width. The default implementation replaces characters in the
-     * center of the original String with an ellipsis ("...").
-     * Override if you need a different strategy.
-     * 
-     * @param gc the gc to use for text measurement
-     * @param t the text to shorten
-     * @param width the width to shorten the text to, in pixels
-     * @return the shortened text
-     */
-    protected String shortenText (GC gc, String t, int width)
-    {
-        if (t is null)
-            return null;
-        int w = gc.textExtent(ELLIPSIS, DRAW_FLAGS).x;
-        if (width <= w)
-            return t;
-        int l = t.length();
-        int max = l / 2;
-        int min = 0;
-        int mid = (max + min) / 2 - 1;
-        if (mid <= 0)
-            return t;
-        TextLayout layout = new TextLayout(getDisplay());
-        layout.setText(t);
-        mid = validateOffset(layout, mid);
-        while (min < mid && mid < max)
-        {
-            String s1 = t.substring(0, mid);
-            String s2 = t.substring(validateOffset(layout, l - mid), l);
-            int l1 = gc.textExtent(s1, DRAW_FLAGS).x;
-            int l2 = gc.textExtent(s2, DRAW_FLAGS).x;
-            if (l1 + w + l2 > width)
-            {
-                max = mid;
-                mid = validateOffset(layout, (max + min) / 2);
-            }
-            else if (l1 + w + l2 < width)
-            {
-                min = mid;
-                mid = validateOffset(layout, (max + min) / 2);
-            }
-            else
-            {
-                min = max;
-            }
-        }
-        String
-                result = mid is 0 ? t : t.substring(0, mid) + ELLIPSIS + t.substring(
-                        validateOffset(layout, l - mid), l);
-        layout.dispose();
-        return result;
-    }
-
-    int validateOffset (TextLayout layout, int offset)
-    {
-        int nextOffset = layout.getNextOffset(offset, DWT.MOVEMENT_CLUSTER);
-        if (nextOffset !is offset)
-            return layout.getPreviousOffset(nextOffset, DWT.MOVEMENT_CLUSTER);
-        return offset;
-    }
-
-    private String[] splitString (String text)
-    {
-        String[] lines = new String[1];
-        int start = 0, pos;
-        do
-        {
-            pos = text.indexOf('\n', start);
-            if (pos is -1)
-            {
-                lines[lines.length - 1] = text.substring(start);
-            }
-            else
-            {
-                bool crlf = (pos > 0) && (text.charAt(pos - 1) is '\r');
-                lines[lines.length - 1] = text.substring(start,
-                        pos - (crlf ? 1 : 0));
-                start = pos + 1;
-                String[] newLines = new String[lines.length + 1];
-                System.arraycopy(lines, 0, newLines, 0, lines.length);
-                lines = newLines;
-            }
-        } while (pos !is -1);
-        return lines;
-    }
+    } while (pos !is text.length);
+    return lines;
 }
+}