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

Fix continue porting
author Frank Benoit <benoit@tionex.de>
date Sat, 24 May 2008 05:11:16 +0200
parents
children 4ac9946b9fb5
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/ui/forms/widgets/SharedScrolledComposite.d	Sat May 24 05:11:16 2008 +0200
@@ -0,0 +1,282 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.ui.forms.widgets.SharedScrolledComposite;
+
+import dwtx.ui.forms.widgets.SizeCache;
+
+import dwt.DWT;
+import dwt.custom.ScrolledComposite;
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+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.ScrollBar;
+import dwtx.ui.internal.forms.widgets.FormUtil;
+
+import dwt.dwthelper.utils;
+import dwt.dwthelper.Runnable;
+
+/**
+ * This class is used to provide common scrolling services to a number of
+ * controls in the toolkit. Classes that extend it are not required to implement
+ * any method.
+ *
+ * @since 3.0
+ */
+public abstract class SharedScrolledComposite : ScrolledComposite {
+    private static const int H_SCROLL_INCREMENT = 5;
+
+    private static const int V_SCROLL_INCREMENT = 64;
+
+    private bool ignoreLayouts = true;
+
+    private bool ignoreResizes = false;
+
+    private bool expandHorizontal = false;
+
+    private bool expandVertical = false;
+
+    private SizeCache contentCache;
+
+    private bool reflowPending = false;
+
+    private bool delayedReflow = true;
+
+    /**
+     * Creates the new instance.
+     *
+     * @param parent
+     *            the parent composite
+     * @param style
+     *            the style to use
+     */
+    public this(Composite parent, int style) {
+        contentCache = new SizeCache();
+        super(parent, style);
+        addListener(DWT.Resize, new class Listener {
+            public void handleEvent(Event e) {
+                if (!ignoreResizes) {
+                    scheduleReflow(false);
+                }
+            }
+        });
+        initializeScrollBars();
+    }
+
+    /**
+     * Sets the foreground of the control and its content.
+     *
+     * @param fg
+     *            the new foreground color
+     */
+    public void setForeground(Color fg) {
+        super.setForeground(fg);
+        if (getContent() !is null)
+            getContent().setForeground(fg);
+    }
+
+    /**
+     * Sets the background of the control and its content.
+     *
+     * @param bg
+     *            the new background color
+     */
+    public void setBackground(Color bg) {
+        super.setBackground(bg);
+        if (getContent() !is null)
+            getContent().setBackground(bg);
+    }
+
+    /**
+     * Sets the font of the form. This font will be used to render the title
+     * text. It will not affect the body.
+     */
+    public void setFont(Font font) {
+        super.setFont(font);
+        if (getContent() !is null)
+            getContent().setFont(font);
+    }
+
+    /**
+     * Overrides 'super' to pass the proper colors and font
+     */
+    public void setContent(Control content) {
+        super.setContent(content);
+        if (content !is null) {
+            content.setForeground(getForeground());
+            content.setBackground(getBackground());
+            content.setFont(getFont());
+        }
+    }
+
+    /**
+     * If content is set, transfers focus to the content.
+     */
+    public bool setFocus() {
+        bool result;
+        FormUtil.setFocusScrollingEnabled(this, false);
+        if (getContent() !is null)
+            result = getContent().setFocus();
+        else
+            result = super.setFocus();
+        FormUtil.setFocusScrollingEnabled(this, true);
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see dwt.widgets.Composite#layout(bool)
+     */
+    public void layout(bool changed) {
+        if (ignoreLayouts) {
+            return;
+        }
+
+        ignoreLayouts = true;
+        ignoreResizes = true;
+        super.layout(changed);
+        ignoreResizes = false;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see dwt.custom.ScrolledComposite#setExpandHorizontal(bool)
+     */
+    public void setExpandHorizontal(bool expand) {
+        expandHorizontal = expand;
+        super.setExpandHorizontal(expand);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see dwt.custom.ScrolledComposite#setExpandVertical(bool)
+     */
+    public void setExpandVertical(bool expand) {
+        expandVertical = expand;
+        super.setExpandVertical(expand);
+    }
+
+    /**
+     * Recomputes the body layout and the scroll bars. The method should be used
+     * when changes somewhere in the form body invalidate the current layout
+     * and/or scroll bars.
+     *
+     * @param flushCache
+     *            if <code>true</code>, drop the cached data
+     */
+    public void reflow(bool flushCache) {
+        Composite c = cast(Composite) getContent();
+        Rectangle clientArea = getClientArea();
+        if (c is null)
+            return;
+
+        contentCache.setControl(c);
+        if (flushCache) {
+            contentCache.flush();
+        }
+        try {
+            setRedraw(false);
+            Point newSize = contentCache.computeSize(FormUtil.getWidthHint(
+                    clientArea.width, c), FormUtil.getHeightHint(clientArea.height,
+                    c));
+
+            // Point currentSize = c.getSize();
+            if (!(expandHorizontal && expandVertical)) {
+                c.setSize(newSize);
+            }
+
+            setMinSize(newSize);
+            FormUtil.updatePageIncrement(this);
+
+            // reduce vertical scroll increment if necessary
+            ScrollBar vbar = getVerticalBar();
+            if (vbar !is null) {
+                if (getClientArea().height - 5 < V_SCROLL_INCREMENT)
+                    getVerticalBar().setIncrement(getClientArea().height - 5);
+                else
+                    getVerticalBar().setIncrement(V_SCROLL_INCREMENT);
+            }
+
+            ignoreLayouts = false;
+            layout(flushCache);
+            ignoreLayouts = true;
+
+            contentCache.layoutIfNecessary();
+        } finally {
+            setRedraw(true);
+        }
+    }
+
+    private void updateSizeWhilePending() {
+        Control c = getContent();
+        Rectangle area = getClientArea();
+        setMinSize(area.width, c.getSize().y);
+    }
+
+    private void scheduleReflow(bool flushCache) {
+        if (delayedReflow) {
+            if (reflowPending) {
+                updateSizeWhilePending();
+                return;
+            }
+            getDisplay().asyncExec( dgRunnable( (bool flushCache) {
+                if (!isDisposed())
+                    reflow(flushCache);
+                reflowPending = false;
+            }, flushCache));
+            reflowPending = true;
+        } else
+            reflow(flushCache);
+    }
+
+    private void initializeScrollBars() {
+        ScrollBar hbar = getHorizontalBar();
+        if (hbar !is null) {
+            hbar.setIncrement(H_SCROLL_INCREMENT);
+        }
+        ScrollBar vbar = getVerticalBar();
+        if (vbar !is null) {
+            vbar.setIncrement(V_SCROLL_INCREMENT);
+        }
+        FormUtil.updatePageIncrement(this);
+    }
+
+    /**
+     * Tests if the control uses delayed reflow.
+     * @return <code>true</code> if reflow requests will
+     * be delayed, <code>false</code> otherwise.
+     */
+    public bool isDelayedReflow() {
+        return delayedReflow;
+    }
+
+    /**
+     * Sets the delayed reflow feature. When used,
+     * it will schedule a reflow on resize requests
+     * and reject subsequent reflows until the
+     * scheduled one is performed. This improves
+     * performance by
+     * @param delayedReflow
+     *            The delayedReflow to set.
+     */
+    public void setDelayedReflow(bool delayedReflow) {
+        this.delayedReflow = delayedReflow;
+    }
+}