diff dwtx/ui/forms/widgets/Section.d @ 75:5d489b9f966c

Fix continue porting
author Frank Benoit <benoit@tionex.de>
date Sat, 24 May 2008 05:11:16 +0200
parents
children 0953c252a764
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/ui/forms/widgets/Section.d	Sat May 24 05:11:16 2008 +0200
@@ -0,0 +1,484 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 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
+ *     Michael Williamson (eclipse-bugs@magnaworks.com) - patch (see Bugzilla #92545)
+ *
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.ui.forms.widgets.Section;
+
+import dwtx.ui.forms.widgets.ExpandableComposite;
+import dwtx.ui.forms.widgets.SharedScrolledComposite;
+
+import dwt.DWT;
+import dwt.events.PaintEvent;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Text;
+import dwtx.core.runtime.Assert;
+import dwtx.ui.internal.forms.widgets.FormImages;
+import dwtx.ui.internal.forms.widgets.FormUtil;
+
+import dwt.dwthelper.utils;
+
+import tango.util.collection.HashMap;
+
+/**
+ * A variation of the expandable composite that adds optional description below
+ * the title. Section is often used as a basic building block in forms because
+ * it provides for logical grouping of information.
+ * <p>
+ * In case of the TITLE_BAR style, Section renders the title bar in a way
+ * compatible with the rest of the workbench. Since it is a widget, all the
+ * colors must be supplied directly. When created by the form toolkit, these
+ * colors are supplied by the toolkit. The toolkit initializes these colors
+ * based on the system colors. For this reason, it is recommended to create the
+ * section by the toolkit instead of through its own constructor.
+ * <p>
+ * Since 3.1, it is possible to set a control to be used for section
+ * description. If used, <code>DESCRIPTION</code> style should not be set. A
+ * typical way to take advantage of the new method is to set an instance of
+ * <code>FormText</code> to provide for hyperlinks and images in the
+ * description area.
+ *
+ * @since 3.0
+ */
+public class Section : ExpandableComposite {
+    /**
+     * Description style. If used, description will be rendered below the title.
+     */
+    public static const int DESCRIPTION = 1 << 7;
+
+    private Control descriptionControl;
+
+    private Control separator;
+
+    private HashMap!(String,Object) titleColors;
+
+    private static const String COLOR_BG = "bg"; //$NON-NLS-1$
+
+    private static const String COLOR_GBG = "gbg"; //$NON-NLS-1$
+
+    private static const String COLOR_BORDER = "border"; //$NON-NLS-1$
+
+    /**
+     * Creates a new section instance in the provided parent.
+     *
+     * @param parent
+     *            the parent composite
+     * @param style
+     *            the style to use
+     */
+    public this(Composite parent, int style) {
+        this(parent, DWT.NULL, style);
+    }
+
+    this(Composite parent, int cstyle, int style) {
+        super(parent, cstyle | getBackgroundStyle(style), style);
+        int rtl = cstyle & DWT.RIGHT_TO_LEFT;
+        if ((style & DESCRIPTION) !is 0) {
+            descriptionControl = new Text(this, DWT.READ_ONLY | DWT.WRAP | rtl);
+        }
+        if ((style & TITLE_BAR) !is 0) {
+            Listener listener = new class Listener{
+                public void handleEvent(Event e) {
+                    Image image = this.outer.callSuperGetBackgroundImage();
+                    if (image !is null) {
+                        FormImages.getInstance().markFinished(image);
+                    }
+                    this.outer.callSuperSetBackgroundImage(null);
+                }
+            };
+            addListener(DWT.Dispose, listener);
+            addListener(DWT.Resize, listener);
+        }
+    }
+
+    private static int getBackgroundStyle(int estyle) {
+        return ((estyle & TITLE_BAR) !is 0) ? DWT.NO_BACKGROUND : DWT.NULL;
+    }
+
+    private Image callSuperGetBackgroundImage(){
+        return super.getBackgroundImage();
+    }
+    private void callSuperSetBackgroundImage(Image image){
+        return super.setBackgroundImage(image);
+    }
+    protected void internalSetExpanded(bool expanded) {
+        super.internalSetExpanded(expanded);
+        if ((getExpansionStyle() & TITLE_BAR) !is 0) {
+            if (!expanded)
+                super.setBackgroundImage(null);
+        }
+        reflow();
+    }
+
+    /**
+     * Reflows this section and all the parents up the hierarchy until a
+     * SharedScrolledComposite is reached.
+     */
+    protected void reflow() {
+        Composite c = this;
+        while (c !is null) {
+            c.setRedraw(false);
+            c = c.getParent();
+            if (null !is cast(SharedScrolledComposite)c ) {
+                break;
+            }
+        }
+        c = this;
+        while (c !is null) {
+            c.layout(true);
+            c = c.getParent();
+            if (null !is cast(SharedScrolledComposite)c ) {
+                (cast(SharedScrolledComposite) c).reflow(true);
+                break;
+            }
+        }
+        c = this;
+        while (c !is null) {
+            c.setRedraw(true);
+            c = c.getParent();
+            if (null !is cast(SharedScrolledComposite)c ) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Sets the description text. Has no effect if DESCRIPTION style was not
+     * used to create the control.
+     *
+     * @param description
+     */
+    public void setDescription(String description) {
+        if (null !is cast(Text)descriptionControl )
+            (cast(Text) descriptionControl).setText(description);
+    }
+
+    /**
+     * Returns the current description text.
+     *
+     * @return description text or <code>null</code> if DESCRIPTION style was
+     *         not used to create the control.
+     */
+    public String getDescription() {
+        if (null !is cast(Text)descriptionControl )
+            return (cast(Text) descriptionControl).getText();
+        return null;
+    }
+
+    /**
+     * Sets the separator control of this section. The separator must not be
+     * <samp>null </samp> and must be a direct child of this container. If
+     * defined, separator will be placed below the title text and will remain
+     * visible regardless of the expansion state.
+     *
+     * @param separator
+     *            the separator that will be placed below the title text.
+     */
+    public void setSeparatorControl(Control separator) {
+        Assert.isTrue(separator !is null && separator.getParent().opEquals(this));
+        this.separator = separator;
+    }
+
+    /**
+     * Returns the control that is used as a separator betweeen the title and
+     * the client, or <samp>null </samp> if not set.
+     *
+     * @return separator control or <samp>null </samp> if not set.
+     */
+    public Control getSeparatorControl() {
+        return separator;
+    }
+
+    /**
+     * Sets the background of the section.
+     *
+     * @param bg
+     *            the new background
+     */
+    public void setBackground(Color bg) {
+        super.setBackground(bg);
+        if (descriptionControl !is null
+                && (getExpansionStyle() & DESCRIPTION) !is 0)
+            descriptionControl.setBackground(bg);
+    }
+
+    /**
+     * Sets the foreground of the section.
+     *
+     * @param fg
+     *            the new foreground.
+     */
+    public void setForeground(Color fg) {
+        super.setForeground(fg);
+        if (descriptionControl !is null
+                && (getExpansionStyle() & DESCRIPTION) !is 0)
+            descriptionControl.setForeground(fg);
+    }
+
+    /**
+     * Returns the control used to render the description. In 3.1, this method
+     * was promoted to public.
+     *
+     * @return description control or <code>null</code> if DESCRIPTION style
+     *         was not used to create the control and description control was
+     *         not set by the client.
+     * @see #setDescriptionControl(dwt.widgets.Control)
+     */
+    public Control getDescriptionControl() {
+        return descriptionControl;
+    }
+
+    /**
+     * Sets the description control of this section. The control must not be
+     * <samp>null</samp> and must be a direct child of this container. If
+     * defined, contol will be placed below the title text and the separator and
+     * will be hidden int he collapsed state.
+     * <p>
+     * This method and <code>DESCRIPTION</code> style are mutually exclusive.
+     * Use the method only if you want to create the description control
+     * yourself.
+     *
+     * @since 3.1
+     * @param descriptionControl
+     *            the control that will be placed below the title text.
+     */
+    public void setDescriptionControl(Control descriptionControl) {
+        Assert.isTrue((getExpansionStyle() & DESCRIPTION) is 0);
+        Assert.isTrue(descriptionControl !is null
+                && descriptionControl.getParent().opEquals(this));
+        this.descriptionControl = descriptionControl;
+    }
+
+    /**
+     * Sets the color of the title bar border when TITLE_BAR style is used.
+     *
+     * @param color
+     *            the title bar border color
+     */
+    public void setTitleBarBorderColor(Color color) {
+        putTitleBarColor(COLOR_BORDER, color);
+    }
+
+    /**
+     * Sets the color of the title bar background when TITLE_BAR style is used.
+     * This color is used as a starting color for the vertical gradient.
+     *
+     * @param color
+     *            the title bar border background
+     */
+    public void setTitleBarBackground(Color color) {
+        putTitleBarColor(COLOR_BG, color);
+    }
+
+    /**
+     * Sets the color of the title bar gradient background when TITLE_BAR style
+     * is used. This color is used at the height where title controls end
+     * (toggle, tool bar).
+     *
+     * @param color
+     *            the title bar gradient background
+     */
+    public void setTitleBarGradientBackground(Color color) {
+        putTitleBarColor(COLOR_GBG, color);
+    }
+
+    /**
+     * Returns the title bar border color when TITLE_BAR style is used.
+     *
+     * @return the title bar border color
+     */
+    public Color getTitleBarBorderColor() {
+        if (titleColors is null)
+            return null;
+        return cast(Color) titleColors.get(COLOR_BORDER);
+    }
+
+    /**
+     * Returns the title bar gradient background color when TITLE_BAR style is
+     * used.
+     *
+     * @return the title bar gradient background
+     */
+    public Color getTitleBarGradientBackground() {
+        if (titleColors is null)
+            return null;
+        if ((getExpansionStyle() & SHORT_TITLE_BAR) !is 0)
+            return getBackground();
+        return cast(Color) titleColors.get(COLOR_GBG);
+    }
+
+    /**
+     * Returns the title bar background when TITLE_BAR style is used.
+     *
+     * @return the title bar background
+     */
+    public Color getTitleBarBackground() {
+        if (titleColors is null)
+            return null;
+        return cast(Color) titleColors.get(COLOR_BG);
+    }
+
+    private void putTitleBarColor(String key, Color color) {
+        if (color is null)
+            return;
+        if (titleColors is null)
+            titleColors = new HashMap!(String,Object);
+        titleColors.add(key, color);
+    }
+
+    protected void onPaint(PaintEvent e) {
+        Color bg = null;
+        Color fg = null;
+        Color border = null;
+
+        GC gc = e.gc;
+        Image buffer = null;
+        Rectangle bounds = getClientArea();
+
+        if ((getExpansionStyle() & TITLE_BAR) !is 0) {
+            buffer = new Image(getDisplay(), bounds.width, bounds.height);
+            buffer.setBackground(getBackground());
+            gc = new GC(buffer);
+        }
+        if (titleColors !is null) {
+            bg = cast(Color) titleColors.get(COLOR_BG);
+            fg = getTitleBarForeground();
+            border = cast(Color) titleColors.get(COLOR_BORDER);
+        }
+        if (bg is null)
+            bg = getBackground();
+        if (fg is null)
+            fg = getForeground();
+        if (border is null)
+            border = fg;
+        int theight = 0;
+        int gradientheight = 0;
+        int tvmargin = IGAP;
+        if ((getExpansionStyle() & TITLE_BAR) !is 0) {
+            Point tsize = null;
+            Point tcsize = null;
+            if (toggle !is null)
+                tsize = toggle.getSize();
+            int twidth = bounds.width - marginWidth - marginWidth;
+            if (tsize !is null)
+                twidth -= tsize.x + IGAP;
+            if (getTextClient() !is null)
+                tcsize = getTextClient().getSize();
+            if (tcsize !is null)
+                twidth -= tcsize.x + IGAP;
+            Point size = textLabel.getSize();
+            if (tsize !is null)
+                theight += Math.max(theight, tsize.y);
+            gradientheight = theight;
+            if (tcsize !is null) {
+                theight = Math.max(theight, tcsize.y);
+            }
+            theight = Math.max(theight, size.y);
+            gradientheight = Math.max(gradientheight, size.y);
+            theight += tvmargin + tvmargin;
+            gradientheight += tvmargin + tvmargin;
+        } else {
+            theight = 5;
+        }
+        if ((getExpansionStyle() & TITLE_BAR) !is 0) {
+            if (getBackgroundImage() is null)
+                updateHeaderImage(bg, bounds, gradientheight, theight);
+            gc.setBackground(getBackground());
+            gc.fillRectangle(bounds.x, bounds.y, bounds.width, bounds.height);
+            drawBackground(gc, bounds.x, bounds.y, bounds.width, theight);
+            if (marginWidth > 0) {
+                // fix up margins
+                gc.setBackground(getBackground());
+                gc.fillRectangle(0, 0, marginWidth, theight);
+                gc.fillRectangle(bounds.x + bounds.width - marginWidth, 0,
+                        marginWidth, theight);
+            }
+        } else if (isExpanded()) {
+            gc.setForeground(bg);
+            gc.setBackground(getBackground());
+            gc.fillGradientRectangle(marginWidth, marginHeight, bounds.width
+                    - marginWidth - marginWidth, theight, true);
+        }
+        gc.setBackground(getBackground());
+        FormUtil.setAntialias(gc, DWT.ON);
+        // repair the upper left corner
+        gc.fillPolygon([ marginWidth, marginHeight, marginWidth,
+                marginHeight + 2, marginWidth + 2, marginHeight ]);
+        // repair the upper right corner
+        gc.fillPolygon([ bounds.width - marginWidth - 3,
+                marginHeight, bounds.width - marginWidth, marginHeight,
+                bounds.width - marginWidth, marginHeight + 3 ]);
+        gc.setForeground(border);
+        if (isExpanded() || (getExpansionStyle() & TITLE_BAR) !is 0) {
+            // top left curve
+            gc.drawLine(marginWidth, marginHeight + 2, marginWidth + 2,
+                    marginHeight);
+            // top edge
+            gc.drawLine(marginWidth + 2, marginHeight, bounds.width
+                    - marginWidth - 3, marginHeight);
+            // top right curve
+            gc.drawLine(bounds.width - marginWidth - 3, marginHeight,
+                    bounds.width - marginWidth - 1, marginHeight + 2);
+        } else {
+            // collapsed short title bar
+            // top edge
+            gc.drawLine(marginWidth, marginHeight, bounds.width - 1,
+                    marginHeight);
+        }
+        if ((getExpansionStyle() & TITLE_BAR) !is 0 || isExpanded()) {
+            // left vertical edge gradient
+            gc.fillGradientRectangle(marginWidth, marginHeight + 2, 1,
+                    gradientheight - 2, true);
+            // right vertical edge gradient
+            gc.fillGradientRectangle(bounds.width - marginWidth - 1,
+                    marginHeight + 2, 1, gradientheight - 2, true);
+        }
+        if ((getExpansionStyle() & TITLE_BAR) !is 0) {
+            // New in 3.3 - edge treatmant
+            gc.setForeground(getDisplay().getSystemColor(DWT.COLOR_WHITE));
+            gc.drawPolyline([ marginWidth + 1,
+                    marginHeight + gradientheight - 1, marginWidth + 1,
+                    marginHeight + 2, marginWidth + 2, marginHeight + 2,
+                    marginWidth + 2, marginHeight + 1,
+                    bounds.width - marginWidth - 3, marginHeight + 1,
+                    bounds.width - marginWidth - 3, marginHeight + 2,
+                    bounds.width - marginWidth - 2, marginHeight + 2,
+                    bounds.width - marginWidth - 2,
+                    marginHeight + gradientheight - 1 ]);
+        }
+        if (buffer !is null) {
+            gc.dispose();
+            e.gc.drawImage(buffer, 0, 0);
+            buffer.dispose();
+        }
+    }
+
+    private void updateHeaderImage(Color bg, Rectangle bounds, int theight,
+            int realtheight) {
+        Image image = FormImages.getInstance().getGradient(getDisplay(), getBackground(), bg, realtheight, theight, marginHeight);
+        super.setBackgroundImage(image);
+    }
+
+    /**
+     * Background image is used for the title gradient - does nothing.
+     */
+    public final void setBackgroundImage(Image image) {
+    }
+}