# HG changeset patch # User Frank Benoit # Date 1225029881 -3600 # Node ID df4e66472aff3ea0b9d1263ee8b2079b5c769f24 # Parent 71ca5bcf2307ea4733f7e766bbf4e548fe6936da novocode line endings, indention diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/CustomSeparator.d --- a/dwtx/novocode/CustomSeparator.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/CustomSeparator.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,139 +1,139 @@ -/** - Original: com.novocode.naf.swt.custom.CustomSeparator -***/ - -/******************************************************************************* - * Copyright (c) 2004 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - *******************************************************************************/ - -module dwtx.novocode.CustomSeparator; - -import dwt.DWT; -/**import dwt.events.PaintEvent;**/ -/**import dwt.events.PaintListener;**/ -import dwt.graphics.Color; -import dwt.graphics.Point; -import dwt.graphics.Rectangle; -import dwt.widgets.Canvas; -import dwt.widgets.Composite; -import dwt.widgets.Display; -import dwt.widgets.Event; -import dwt.widgets.Listener; - - -/** - * Instances of this class are non-native separator lines. - *
- *
Styles:
- *
SHADOW_IN, SHADOW_OUT, SHADOW_NONE, HORIZONTAL, VERTICAL
- *
Events:
- *
(none)
- *
- *

- * Note: Only one of SHADOW_IN, SHADOW_OUT and SHADOW_NONE may be specified. - * If neither ist specified, the default value SHADOW_IN is used. If SHADOW_NONE - * is specified, a single line is drawn with the control's foreground color. - * Only one of HORIZONTAL and VERTICAL may be specified. The default is VERTICAL. - *

- * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Feb 12, 2004 - * @version $Id: CustomSeparator.java 199 2004-10-08 13:20:36 +0000 (Fri, 08 Oct 2004) szeiger $ - */ - -class CustomSeparator : Canvas -{ - private int lineSize; - private int style; - - - this(Composite parent, int style) - { - super(parent, style = checkStyle (style)); - - this.style = style; - - if((style & DWT.SHADOW_IN) !is 0 || (style & DWT.SHADOW_OUT) !is 0) lineSize = 2; - else lineSize = 1; - - /**addPaintListener(new class() PaintListener - { - public void paintControl(PaintEvent event) { onPaint(event); } - });*/ - addListener(DWT.Paint, dgListener(&onPaint)); - } - - - private int checkStyle(int style) - { - int mask = DWT.SHADOW_IN | DWT.SHADOW_OUT| DWT.SHADOW_NONE | DWT.HORIZONTAL | DWT.VERTICAL; - style &= mask; - if((style & (DWT.SHADOW_IN | DWT.SHADOW_OUT| DWT.SHADOW_NONE)) is 0) style |= DWT.SHADOW_IN; - if((style & (DWT.HORIZONTAL | DWT.VERTICAL)) is 0) style |= DWT.VERTICAL; - return style; - } - - - public Point computeSize(int wHint, int hHint, bool changed) - { - checkWidget(); - if(wHint is DWT.DEFAULT) wHint = lineSize; - if(hHint is DWT.DEFAULT) hHint = lineSize; - return new Point(wHint, hHint); - } - - - public bool setFocus() - { - checkWidget(); - return false; - } - - - private void onPaint(PaintEvent event) - { - Rectangle r = getClientArea(); - if(r.width is 0 || r.height is 0) return; - bool horiz = ((style & DWT.HORIZONTAL) !is 0); - int mid = horiz ? r.y + (r.height/2) : r.x + (r.width/2); - - Display disp = getDisplay(); - event.gc.setLineWidth(1); - - if((style & DWT.SHADOW_IN) !is 0) - { - Color shadow = disp.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); - Color highlight = disp.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); - event.gc.setForeground(shadow); - if(horiz) event.gc.drawLine(r.x, mid-1, r.x+r.width-1, mid-1); - else event.gc.drawLine(mid-1, r.y, mid-1, r.y+r.height-1); - event.gc.setForeground(highlight); - if(horiz) event.gc.drawLine(r.x, mid, r.x+r.width-1, mid); - else event.gc.drawLine(mid, r.y, mid, r.y+r.height-1); - } - else if((style & DWT.SHADOW_OUT) !is 0) - { - Color shadow = disp.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); - Color highlight = disp.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); - event.gc.setForeground(highlight); - if(horiz) event.gc.drawLine(r.x, mid-1, r.x+r.width-1, mid-1); - else event.gc.drawLine(mid-1, r.y, mid-1, r.y+r.height-1); - event.gc.setForeground(shadow); - if(horiz) event.gc.drawLine(r.x, mid, r.x+r.width-1, mid); - else event.gc.drawLine(mid, r.y, mid, r.y+r.height-1); - } - else - { - event.gc.setForeground(getForeground()); - if(horiz) event.gc.drawLine(r.x, mid, r.x+r.width-1, mid); - else event.gc.drawLine(mid, r.y, mid, r.y+r.height-1); - } - } -} +/** +Original: com.novocode.naf.swt.custom.CustomSeparator + ***/ + +/******************************************************************************* + * Copyright (c) 2004 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + *******************************************************************************/ + +module dwtx.novocode.CustomSeparator; + +import dwt.DWT; +/**import dwt.events.PaintEvent;**/ +/**import dwt.events.PaintListener;**/ +import dwt.graphics.Color; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; + + +/** + * Instances of this class are non-native separator lines. + *
+ *
Styles:
+ *
SHADOW_IN, SHADOW_OUT, SHADOW_NONE, HORIZONTAL, VERTICAL
+ *
Events:
+ *
(none)
+ *
+ *

+ * Note: Only one of SHADOW_IN, SHADOW_OUT and SHADOW_NONE may be specified. + * If neither ist specified, the default value SHADOW_IN is used. If SHADOW_NONE + * is specified, a single line is drawn with the control's foreground color. + * Only one of HORIZONTAL and VERTICAL may be specified. The default is VERTICAL. + *

+ * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Feb 12, 2004 + * @version $Id: CustomSeparator.java 199 2004-10-08 13:20:36 +0000 (Fri, 08 Oct 2004) szeiger $ + */ + +class CustomSeparator : Canvas +{ + private int lineSize; + private int style; + + + this(Composite parent, int style) + { + super(parent, style = checkStyle (style)); + + this.style = style; + + if((style & DWT.SHADOW_IN) !is 0 || (style & DWT.SHADOW_OUT) !is 0) lineSize = 2; + else lineSize = 1; + + /**addPaintListener(new class() PaintListener + { + public void paintControl(PaintEvent event) { onPaint(event); } + });*/ + addListener(DWT.Paint, dgListener(&onPaint)); + } + + + private int checkStyle(int style) + { + int mask = DWT.SHADOW_IN | DWT.SHADOW_OUT| DWT.SHADOW_NONE | DWT.HORIZONTAL | DWT.VERTICAL; + style &= mask; + if((style & (DWT.SHADOW_IN | DWT.SHADOW_OUT| DWT.SHADOW_NONE)) is 0) style |= DWT.SHADOW_IN; + if((style & (DWT.HORIZONTAL | DWT.VERTICAL)) is 0) style |= DWT.VERTICAL; + return style; + } + + + public Point computeSize(int wHint, int hHint, bool changed) + { + checkWidget(); + if(wHint is DWT.DEFAULT) wHint = lineSize; + if(hHint is DWT.DEFAULT) hHint = lineSize; + return new Point(wHint, hHint); + } + + + public bool setFocus() + { + checkWidget(); + return false; + } + + + private void onPaint(PaintEvent event) + { + Rectangle r = getClientArea(); + if(r.width is 0 || r.height is 0) return; + bool horiz = ((style & DWT.HORIZONTAL) !is 0); + int mid = horiz ? r.y + (r.height/2) : r.x + (r.width/2); + + Display disp = getDisplay(); + event.gc.setLineWidth(1); + + if((style & DWT.SHADOW_IN) !is 0) + { + Color shadow = disp.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); + Color highlight = disp.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); + event.gc.setForeground(shadow); + if(horiz) event.gc.drawLine(r.x, mid-1, r.x+r.width-1, mid-1); + else event.gc.drawLine(mid-1, r.y, mid-1, r.y+r.height-1); + event.gc.setForeground(highlight); + if(horiz) event.gc.drawLine(r.x, mid, r.x+r.width-1, mid); + else event.gc.drawLine(mid, r.y, mid, r.y+r.height-1); + } + else if((style & DWT.SHADOW_OUT) !is 0) + { + Color shadow = disp.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); + Color highlight = disp.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); + event.gc.setForeground(highlight); + if(horiz) event.gc.drawLine(r.x, mid-1, r.x+r.width-1, mid-1); + else event.gc.drawLine(mid-1, r.y, mid-1, r.y+r.height-1); + event.gc.setForeground(shadow); + if(horiz) event.gc.drawLine(r.x, mid, r.x+r.width-1, mid); + else event.gc.drawLine(mid, r.y, mid, r.y+r.height-1); + } + else + { + event.gc.setForeground(getForeground()); + if(horiz) event.gc.drawLine(r.x, mid, r.x+r.width-1, mid); + else event.gc.drawLine(mid, r.y, mid, r.y+r.height-1); + } + } +} diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/ScaledImage.d --- a/dwtx/novocode/ScaledImage.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/ScaledImage.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,271 +1,271 @@ -/******************************************************************************* - * Copyright (c) 2004 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - * IBM Corporation - original SWT CLabel implementation on which this class is based - *******************************************************************************/ - -module dwtx.novocode.ScaledImage; - -import dwt.DWT; -import dwt.graphics.Color; -import dwt.graphics.GC; -import dwt.graphics.Image; -import dwt.graphics.Point; -import dwt.graphics.Rectangle; -import dwt.widgets.Canvas; -import dwt.widgets.Composite; -import dwt.widgets.Event; -import dwt.widgets.Listener; - - -/** - * An image / gradient component. Under development. - * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Mar 21, 2005 - * @version $Id: ScaledImage.java 346 2005-07-11 20:15:57 +0000 (Mon, 11 Jul 2005) szeiger $ - */ - -class ScaledImage : Canvas -{ - private const Rectangle DEFAULT_BOUNDS; - - public static const int IMAGE_PLACEMENT_STRETCH = 0; - public static const int IMAGE_PLACEMENT_TILE = 1; - - private Image image; - - private Color[] gradientColors; - - private int[] gradientPercents; - - private bool gradientVertical; - - private int imagePlacement = IMAGE_PLACEMENT_STRETCH; - - - this(Composite parent, int style) - { - super(parent, style | DWT.NO_BACKGROUND); - this.DEFAULT_BOUNDS = new Rectangle(0, 0, 32, 32); - - addListener(DWT.Paint, dgListener(&onPaint)); - } - - - private void onPaint(Event event) - { - Rectangle rect = getClientArea(); - GC gc = event.gc; - if(image is null - || image.getImageData().getTransparencyType() !is DWT.TRANSPARENCY_NONE) - { - - if(gradientColors !is null) - { - // draw a gradient behind the text - 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 - { - 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) - { - int gradientHeight = (gradientPercents[i] * rect.height / 100) - - pos; - gc.fillGradientRectangle(0, pos, rect.width, gradientHeight, - true); - pos += gradientHeight; - } - else - { - 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); - } - gc.setBackground(oldBackground); - } - else - { - if((getStyle() & DWT.NO_BACKGROUND) !is 0) - { - gc.setBackground(getBackground()); - gc.fillRectangle(rect); - } - } - - } - if(image !is null) - { - Rectangle ib = image.getBounds(); - if(imagePlacement is IMAGE_PLACEMENT_TILE) - { - int maxStartX = rect.x + rect.width; - int maxStartY = rect.y + rect.height; - for(int x = rect.x; x < maxStartX; x += ib.width) - for(int y = rect.y; y < maxStartY; y += ib.height) - event.gc.drawImage(image, x, y); - } - else // IMAGE_PLACEMENT_STRETCH - { - event.gc.drawImage(image, ib.x, ib.y, ib.width, ib.height, rect.x, - rect.y, rect.width, rect.height); - } - } - } - - - public void setImage(Image image) - { - this.image = image; - redraw(); - } - - - public void setImagePlacement(int imagePlacement) - { - this.imagePlacement = imagePlacement; - redraw(); - } - - - public Point computeSize(int wHint, int hHint, bool changed) - { - checkWidget(); - Rectangle ib = image !is null ? image.getBounds() : DEFAULT_BOUNDS; - if(wHint == DWT.DEFAULT) wHint = ib.width; - if(hHint == DWT.DEFAULT) hHint = ib.height; - return new Point(wHint, hHint); - } - - - public void setBackground(Color color) - { - super.setBackground(color); - // Are these settings the same as before? - if(color !is null && gradientColors is null && gradientPercents is null) - { - Color background = getBackground(); - if(color is background) - { - return; - } - } - gradientColors = null; - gradientPercents = null; - redraw(); - } - - - public void setBackground(Color[] colors, int[] percents) - { - setBackground(colors, percents, false); - } - - - 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 = []; - } - 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); - } - } - } - - // Are these settings the same as before? - Color background = getBackground(); - 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; - } - // 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(); - } -} +/******************************************************************************* + * Copyright (c) 2004 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + * IBM Corporation - original SWT CLabel implementation on which this class is based + *******************************************************************************/ + +module dwtx.novocode.ScaledImage; + +import dwt.DWT; +import dwt.graphics.Color; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Event; +import dwt.widgets.Listener; + + +/** + * An image / gradient component. Under development. + * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Mar 21, 2005 + * @version $Id: ScaledImage.java 346 2005-07-11 20:15:57 +0000 (Mon, 11 Jul 2005) szeiger $ + */ + +class ScaledImage : Canvas +{ + private const Rectangle DEFAULT_BOUNDS; + + public static const int IMAGE_PLACEMENT_STRETCH = 0; + public static const int IMAGE_PLACEMENT_TILE = 1; + + private Image image; + + private Color[] gradientColors; + + private int[] gradientPercents; + + private bool gradientVertical; + + private int imagePlacement = IMAGE_PLACEMENT_STRETCH; + + + this(Composite parent, int style) + { + super(parent, style | DWT.NO_BACKGROUND); + this.DEFAULT_BOUNDS = new Rectangle(0, 0, 32, 32); + + addListener(DWT.Paint, dgListener(&onPaint)); + } + + + private void onPaint(Event event) + { + Rectangle rect = getClientArea(); + GC gc = event.gc; + if(image is null + || image.getImageData().getTransparencyType() !is DWT.TRANSPARENCY_NONE) + { + + if(gradientColors !is null) + { + // draw a gradient behind the text + 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 + { + 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) + { + int gradientHeight = (gradientPercents[i] * rect.height / 100) + - pos; + gc.fillGradientRectangle(0, pos, rect.width, gradientHeight, + true); + pos += gradientHeight; + } + else + { + 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); + } + gc.setBackground(oldBackground); + } + else + { + if((getStyle() & DWT.NO_BACKGROUND) !is 0) + { + gc.setBackground(getBackground()); + gc.fillRectangle(rect); + } + } + + } + if(image !is null) + { + Rectangle ib = image.getBounds(); + if(imagePlacement is IMAGE_PLACEMENT_TILE) + { + int maxStartX = rect.x + rect.width; + int maxStartY = rect.y + rect.height; + for(int x = rect.x; x < maxStartX; x += ib.width) + for(int y = rect.y; y < maxStartY; y += ib.height) + event.gc.drawImage(image, x, y); + } + else // IMAGE_PLACEMENT_STRETCH + { + event.gc.drawImage(image, ib.x, ib.y, ib.width, ib.height, rect.x, + rect.y, rect.width, rect.height); + } + } + } + + + public void setImage(Image image) + { + this.image = image; + redraw(); + } + + + public void setImagePlacement(int imagePlacement) + { + this.imagePlacement = imagePlacement; + redraw(); + } + + + public Point computeSize(int wHint, int hHint, bool changed) + { + checkWidget(); + Rectangle ib = image !is null ? image.getBounds() : DEFAULT_BOUNDS; + if(wHint == DWT.DEFAULT) wHint = ib.width; + if(hHint == DWT.DEFAULT) hHint = ib.height; + return new Point(wHint, hHint); + } + + + public void setBackground(Color color) + { + super.setBackground(color); + // Are these settings the same as before? + if(color !is null && gradientColors is null && gradientPercents is null) + { + Color background = getBackground(); + if(color is background) + { + return; + } + } + gradientColors = null; + gradientPercents = null; + redraw(); + } + + + public void setBackground(Color[] colors, int[] percents) + { + setBackground(colors, percents, false); + } + + + 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 = []; + } + 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); + } + } + } + + // Are these settings the same as before? + Color background = getBackground(); + 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; + } + // 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(); + } +} diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/SizeBorder.d --- a/dwtx/novocode/SizeBorder.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/SizeBorder.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,406 +1,406 @@ -/******************************************************************************* - * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - *******************************************************************************/ - -module dwtx.novocode.SizeBorder; - -import dwt.dwthelper.utils; -import dwt.dwthelper.Runnable; -import dwtx.dwtxhelper.Timer; -import dwtx.dwtxhelper.TimerTask; - -import dwt.DWT; -import dwt.graphics.Color; -import dwt.graphics.Cursor; -import dwt.graphics.GC; -import dwt.graphics.Point; -import dwt.graphics.Rectangle; -import dwt.widgets.Canvas; -import dwt.widgets.Composite; -import dwt.widgets.Display; -import dwt.widgets.Event; -import dwt.widgets.Listener; -import dwt.widgets.Shell; - - -/** - * A border for a resizable container. This border control usually fills the - * entire container, with a content pane above it (not covering the actual - * border area). - * - *

If the style SWT.BORDER ist set, a beveled border (as used on Windows - * Classic window decorations) will be drawn. Without this style, no drawing - * is done.

- * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Jan 21, 2005 - * @version $Id: SizeBorder.java 321 2005-02-26 15:44:24 +0000 (Sat, 26 Feb 2005) szeiger $ - */ - -class SizeBorder : Canvas -{ - private static const long UPDATE_DELAY = 25; - - private static const int AREA_NONE = 0; - private static const int AREA_N = 1; - private static const int AREA_S = 2; - private static const int AREA_E = 4; - private static const int AREA_W = 8; - private static const int AREA_NW = 9; - private static const int AREA_NE = 5; - private static const int AREA_SE = 6; - private static const int AREA_SW = 10; - - private Rectangle snapBack; - private bool cancelled = true; - private /**volatile*/ long lastUpdate; - private Timer timer; - private TimerTask timerTask; - private Composite resizableParent; - private Point minSize, mouseDownOffset; - private int borderWidth = 4, cornerSize = 16; - private Display display; - private Cursor cursor, cursorNWSE, cursorNESW, cursorWE, cursorNS; - private int currentArea; - private Color highlightShadowColor, lightShadowColor, normalShadowColor,darkShadowColor; - - - this(Composite parent, int style) - { - this(parent, parent.getShell(), style); - } - - - this(Composite parent, Composite resizableParent, int style) - { - super(parent, checkStyle (style)); - this.timer = new Timer(true); - this.resizableParent = resizableParent; - this.display = getDisplay(); - - cursorNWSE = new Cursor(getDisplay(), DWT.CURSOR_SIZENWSE); - cursorNESW = new Cursor(getDisplay(), DWT.CURSOR_SIZENESW); - cursorWE = new Cursor(getDisplay(), DWT.CURSOR_SIZEWE); - cursorNS = new Cursor(getDisplay(), DWT.CURSOR_SIZENS); - - addListener(DWT.Dispose, dgListener(&onDispose)); - - if((style & DWT.BORDER) !is 0) - { - highlightShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); - lightShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_LIGHT_SHADOW); - normalShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); - darkShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW); - - addListener(DWT.Paint, dgListener(&onPaint)); - } - - addListener(DWT.MouseDown, dgListener(&onMouseDown)); - - addListener(DWT.MouseMove, dgListener(&onMouseMove)); - - addListener(DWT.MouseUp, dgListener(&onMouseUp)); - - addListener(DWT.Show, dgListener(&onShow)); - } - - private void onDispose(Event event) - { - cursorNWSE.dispose(); - cursorNESW.dispose(); - cursorWE.dispose(); - cursorNS.dispose(); - - timer.cancel(); - } - - - private void onPaint(Event event) - { - Rectangle r = getClientArea(); - if(r.width is 0 || r.height is 0) return; - drawBevelRect(event.gc, r.x, r.y, r.width-1, r.height-1, lightShadowColor, darkShadowColor); - drawBevelRect(event.gc, r.x+1, r.y+1, r.width-3, r.height-3, highlightShadowColor, normalShadowColor); - } - - - private void onMouseDown(Event event) - { - if(event.button is 1) - { - currentArea = areaAtPoint(event.x, event.y); - if(currentArea is AREA_NONE) return; - if(cast(Shell)resizableParent !is null) - mouseDownOffset = toDisplay(event.x, event.y); - else - mouseDownOffset = display.map(/**SizeBorder.this*/getSizeBorder(), resizableParent.getParent(), event.x, event.y); - snapBack = resizableParent.getBounds(); - cancelled = false; - } - else if(event.button is 3 && (event.stateMask & DWT.BUTTON1) !is 0) // chord click - { - if(snapBack !is null) - { - resizableParent.setBounds(snapBack); - snapBack = null; - cancelled = true; - } - } - } - - - private void onMouseMove(Event event) - { - if((event.stateMask & DWT.BUTTON1) is 0) updateCursor(areaAtPoint(event.x, event.y)); - - if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0) - { - if(timerTask !is null) - { - timerTask.cancel(); - timerTask = null; - } - long now = System.currentTimeMillis(); - if(lastUpdate + UPDATE_DELAY < now) - { - performResize(event); - lastUpdate = now; - } - else - { - timerTask = new class() TimerTask - { - public void run() - { - TimerTask executingTask = this; - event.display.asyncExec(new class() Runnable - { - public void run() - { - if(executingTask !is timerTask) return; - performResize(event); - } - }); - } - }; - timer.schedule(timerTask, UPDATE_DELAY); - } - } - } - - - private void onMouseUp(Event event) - { - if(timerTask !is null) - { - timerTask.cancel(); - timerTask = null; - } - if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0) - { - performResize(event); - } - } - - - private void onShow(Event event) - { - Point p = toControl(display.getCursorLocation()); - updateCursor(areaAtPoint(p.x, p.y)); - } - - - private SizeBorder getSizeBorder() - { - return this; - } - - private static int checkStyle(int style) - { - //int mask = DWT.NONE; - //style &= mask; - style = DWT.NO_FOCUS; - return style; - } - - - private void performResize(Event event) - { - // Make sure we stay within the container parent's client area - Rectangle ca; - if(cast(Shell)resizableParent !is null) ca = getDisplay().getClientArea(); - else ca = getDisplay().map(resizableParent.getParent(), null, resizableParent.getParent().getClientArea()); - Point caOffset = toControl(ca.x, ca.y); - event.x = Math.max(Math.min(event.x, caOffset.x + ca.width - 1), caOffset.x); - event.y = Math.max(Math.min(event.y, caOffset.y + ca.height - 1), caOffset.y); - - // Compute movement relative to position at MouseDown event - Point movement = (cast(Shell)resizableParent !is null) - ? toDisplay(event.x, event.y) - : display.map(this, resizableParent.getParent(), event.x, event.y); - movement.x -= mouseDownOffset.x; - movement.y -= mouseDownOffset.y; - - // Compute new size and position - int newW = snapBack.width, newH = snapBack.height, newX = snapBack.x, newY = snapBack.y; - if((currentArea & AREA_E) !is 0) newW += movement.x; - else if((currentArea & AREA_W) !is 0) { newW -= movement.x; newX += snapBack.width - newW; } - if((currentArea & AREA_S) !is 0) newH += movement.y; - else if((currentArea & AREA_N) !is 0) { newH -= movement.y; newY += snapBack.height - newH; } - - // Do not go below the container's minimum size - int minW, minH; - if(minSize !is null) { minW = minSize.x; minH = minSize.y; } - else { minW = 0; minH = 0; } - int maxX = snapBack.x + snapBack.width - minW; - int maxY = snapBack.y + snapBack.height - minH; - - newW = Math.max(minW, newW); - newH = Math.max(minH, newH); - newX = Math.min(maxX, newX); - newY = Math.min(maxY, newY); - - resizableParent.setBounds(newX, newY, newW, newH); - } - - - private void updateCursor(int area) - { - Cursor c = null; - switch(area) - { - case AREA_N: case AREA_S: c = cursorNS; break; - case AREA_W: case AREA_E: c = cursorWE; break; - case AREA_NW: case AREA_SE: c = cursorNWSE; break; - case AREA_NE: case AREA_SW: c = cursorNESW; break; - } - if(cursor is c) return; - cursor = c; - setCursor(c); - } - - - private int areaAtPoint(int x, int y) - { - Point size = getSize(); - if(x < borderWidth) // left edge - { - if(y < cornerSize) return AREA_NW; - else if(y >= size.y-cornerSize) return AREA_SW; - else return AREA_W; - } - else if(x >= size.x-borderWidth) // right edge - { - if(y >= size.y-cornerSize) return AREA_SE; - else if(y < cornerSize) return AREA_NE; - else return AREA_E; - } - else if(y < borderWidth) // top edge - { - if(x < cornerSize) return AREA_NW; - else if(x >= size.x-cornerSize) return AREA_NE; - else return AREA_N; - } - else if(y >= size.y-borderWidth) // bottom edge - { - if(x >= size.x-cornerSize) return AREA_SE; - else if(x < cornerSize) return AREA_SW; - else return AREA_S; - } - else return AREA_NONE; - } - - - public Point computeSize(int wHint, int hHint, bool changed) - { - checkWidget(); - if(wHint == DWT.DEFAULT) wHint = 0; - if(hHint == DWT.DEFAULT) hHint = 0; - return new Point(wHint, hHint); - } - - - public bool setFocus() - { - checkWidget(); - return false; - } - - - public bool isReparentable () - { - checkWidget(); - return false; - } - - - /** - * Set the allowed minimum size for the shell. The SizeGrip will - * not resize the shell to a smaller size. - *

- * Note: This does not affect other ways of resizing the shell, - * like using the size controls which are placed on the trimmings by - * the window manager. - *

- */ - - public void setMinimumShellSize(Point p) - { - checkWidget(); - this.minSize = p; - } - - - /** - * Set the allowed minimum size for the shell. The SizeGrip will - * not resize the shell to a smaller size. - *

- * Note: This does not affect other ways of resizing the shell, - * like using the size controls which are placed on the trimmings by - * the window manager. - *

- */ - - public void setMinimumShellSize(int width, int height) - { - checkWidget(); - this.minSize = new Point(width, height); - } - - - public void setBorderWidth(int width) - { - checkWidget(); - borderWidth = width; - Point p = toControl(display.getCursorLocation()); - updateCursor(areaAtPoint(p.x, p.y)); - } - - - public void setCornerSize(int size) - { - checkWidget(); - cornerSize = size; - Point p = toControl(display.getCursorLocation()); - updateCursor(areaAtPoint(p.x, p.y)); - } - - - private static 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); - } -} +/******************************************************************************* + * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + *******************************************************************************/ + +module dwtx.novocode.SizeBorder; + +import dwt.dwthelper.utils; +import dwt.dwthelper.Runnable; +import dwtx.dwtxhelper.Timer; +import dwtx.dwtxhelper.TimerTask; + +import dwt.DWT; +import dwt.graphics.Color; +import dwt.graphics.Cursor; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Shell; + + +/** + * A border for a resizable container. This border control usually fills the + * entire container, with a content pane above it (not covering the actual + * border area). + * + *

If the style SWT.BORDER ist set, a beveled border (as used on Windows + * Classic window decorations) will be drawn. Without this style, no drawing + * is done.

+ * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Jan 21, 2005 + * @version $Id: SizeBorder.java 321 2005-02-26 15:44:24 +0000 (Sat, 26 Feb 2005) szeiger $ + */ + +class SizeBorder : Canvas +{ + private static const long UPDATE_DELAY = 25; + + private static const int AREA_NONE = 0; + private static const int AREA_N = 1; + private static const int AREA_S = 2; + private static const int AREA_E = 4; + private static const int AREA_W = 8; + private static const int AREA_NW = 9; + private static const int AREA_NE = 5; + private static const int AREA_SE = 6; + private static const int AREA_SW = 10; + + private Rectangle snapBack; + private bool cancelled = true; + private /**volatile*/ long lastUpdate; + private Timer timer; + private TimerTask timerTask; + private Composite resizableParent; + private Point minSize, mouseDownOffset; + private int borderWidth = 4, cornerSize = 16; + private Display display; + private Cursor cursor, cursorNWSE, cursorNESW, cursorWE, cursorNS; + private int currentArea; + private Color highlightShadowColor, lightShadowColor, normalShadowColor,darkShadowColor; + + + this(Composite parent, int style) + { + this(parent, parent.getShell(), style); + } + + + this(Composite parent, Composite resizableParent, int style) + { + super(parent, checkStyle (style)); + this.timer = new Timer(true); + this.resizableParent = resizableParent; + this.display = getDisplay(); + + cursorNWSE = new Cursor(getDisplay(), DWT.CURSOR_SIZENWSE); + cursorNESW = new Cursor(getDisplay(), DWT.CURSOR_SIZENESW); + cursorWE = new Cursor(getDisplay(), DWT.CURSOR_SIZEWE); + cursorNS = new Cursor(getDisplay(), DWT.CURSOR_SIZENS); + + addListener(DWT.Dispose, dgListener(&onDispose)); + + if((style & DWT.BORDER) !is 0) + { + highlightShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); + lightShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_LIGHT_SHADOW); + normalShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); + darkShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW); + + addListener(DWT.Paint, dgListener(&onPaint)); + } + + addListener(DWT.MouseDown, dgListener(&onMouseDown)); + + addListener(DWT.MouseMove, dgListener(&onMouseMove)); + + addListener(DWT.MouseUp, dgListener(&onMouseUp)); + + addListener(DWT.Show, dgListener(&onShow)); + } + + private void onDispose(Event event) + { + cursorNWSE.dispose(); + cursorNESW.dispose(); + cursorWE.dispose(); + cursorNS.dispose(); + + timer.cancel(); + } + + + private void onPaint(Event event) + { + Rectangle r = getClientArea(); + if(r.width is 0 || r.height is 0) return; + drawBevelRect(event.gc, r.x, r.y, r.width-1, r.height-1, lightShadowColor, darkShadowColor); + drawBevelRect(event.gc, r.x+1, r.y+1, r.width-3, r.height-3, highlightShadowColor, normalShadowColor); + } + + + private void onMouseDown(Event event) + { + if(event.button is 1) + { + currentArea = areaAtPoint(event.x, event.y); + if(currentArea is AREA_NONE) return; + if(cast(Shell)resizableParent !is null) + mouseDownOffset = toDisplay(event.x, event.y); + else + mouseDownOffset = display.map(/**SizeBorder.this*/getSizeBorder(), resizableParent.getParent(), event.x, event.y); + snapBack = resizableParent.getBounds(); + cancelled = false; + } + else if(event.button is 3 && (event.stateMask & DWT.BUTTON1) !is 0) // chord click + { + if(snapBack !is null) + { + resizableParent.setBounds(snapBack); + snapBack = null; + cancelled = true; + } + } + } + + + private void onMouseMove(Event event) + { + if((event.stateMask & DWT.BUTTON1) is 0) updateCursor(areaAtPoint(event.x, event.y)); + + if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0) + { + if(timerTask !is null) + { + timerTask.cancel(); + timerTask = null; + } + long now = System.currentTimeMillis(); + if(lastUpdate + UPDATE_DELAY < now) + { + performResize(event); + lastUpdate = now; + } + else + { + timerTask = new class() TimerTask + { + public void run() + { + TimerTask executingTask = this; + event.display.asyncExec(new class() Runnable + { + public void run() + { + if(executingTask !is timerTask) return; + performResize(event); + } + }); + } + }; + timer.schedule(timerTask, UPDATE_DELAY); + } + } + } + + + private void onMouseUp(Event event) + { + if(timerTask !is null) + { + timerTask.cancel(); + timerTask = null; + } + if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0) + { + performResize(event); + } + } + + + private void onShow(Event event) + { + Point p = toControl(display.getCursorLocation()); + updateCursor(areaAtPoint(p.x, p.y)); + } + + + private SizeBorder getSizeBorder() + { + return this; + } + + private static int checkStyle(int style) + { + //int mask = DWT.NONE; + //style &= mask; + style = DWT.NO_FOCUS; + return style; + } + + + private void performResize(Event event) + { + // Make sure we stay within the container parent's client area + Rectangle ca; + if(cast(Shell)resizableParent !is null) ca = getDisplay().getClientArea(); + else ca = getDisplay().map(resizableParent.getParent(), null, resizableParent.getParent().getClientArea()); + Point caOffset = toControl(ca.x, ca.y); + event.x = Math.max(Math.min(event.x, caOffset.x + ca.width - 1), caOffset.x); + event.y = Math.max(Math.min(event.y, caOffset.y + ca.height - 1), caOffset.y); + + // Compute movement relative to position at MouseDown event + Point movement = (cast(Shell)resizableParent !is null) + ? toDisplay(event.x, event.y) + : display.map(this, resizableParent.getParent(), event.x, event.y); + movement.x -= mouseDownOffset.x; + movement.y -= mouseDownOffset.y; + + // Compute new size and position + int newW = snapBack.width, newH = snapBack.height, newX = snapBack.x, newY = snapBack.y; + if((currentArea & AREA_E) !is 0) newW += movement.x; + else if((currentArea & AREA_W) !is 0) { newW -= movement.x; newX += snapBack.width - newW; } + if((currentArea & AREA_S) !is 0) newH += movement.y; + else if((currentArea & AREA_N) !is 0) { newH -= movement.y; newY += snapBack.height - newH; } + + // Do not go below the container's minimum size + int minW, minH; + if(minSize !is null) { minW = minSize.x; minH = minSize.y; } + else { minW = 0; minH = 0; } + int maxX = snapBack.x + snapBack.width - minW; + int maxY = snapBack.y + snapBack.height - minH; + + newW = Math.max(minW, newW); + newH = Math.max(minH, newH); + newX = Math.min(maxX, newX); + newY = Math.min(maxY, newY); + + resizableParent.setBounds(newX, newY, newW, newH); + } + + + private void updateCursor(int area) + { + Cursor c = null; + switch(area) + { + case AREA_N: case AREA_S: c = cursorNS; break; + case AREA_W: case AREA_E: c = cursorWE; break; + case AREA_NW: case AREA_SE: c = cursorNWSE; break; + case AREA_NE: case AREA_SW: c = cursorNESW; break; + } + if(cursor is c) return; + cursor = c; + setCursor(c); + } + + + private int areaAtPoint(int x, int y) + { + Point size = getSize(); + if(x < borderWidth) // left edge + { + if(y < cornerSize) return AREA_NW; + else if(y >= size.y-cornerSize) return AREA_SW; + else return AREA_W; + } + else if(x >= size.x-borderWidth) // right edge + { + if(y >= size.y-cornerSize) return AREA_SE; + else if(y < cornerSize) return AREA_NE; + else return AREA_E; + } + else if(y < borderWidth) // top edge + { + if(x < cornerSize) return AREA_NW; + else if(x >= size.x-cornerSize) return AREA_NE; + else return AREA_N; + } + else if(y >= size.y-borderWidth) // bottom edge + { + if(x >= size.x-cornerSize) return AREA_SE; + else if(x < cornerSize) return AREA_SW; + else return AREA_S; + } + else return AREA_NONE; + } + + + public Point computeSize(int wHint, int hHint, bool changed) + { + checkWidget(); + if(wHint == DWT.DEFAULT) wHint = 0; + if(hHint == DWT.DEFAULT) hHint = 0; + return new Point(wHint, hHint); + } + + + public bool setFocus() + { + checkWidget(); + return false; + } + + + public bool isReparentable () + { + checkWidget(); + return false; + } + + + /** + * Set the allowed minimum size for the shell. The SizeGrip will + * not resize the shell to a smaller size. + *

+ * Note: This does not affect other ways of resizing the shell, + * like using the size controls which are placed on the trimmings by + * the window manager. + *

+ */ + + public void setMinimumShellSize(Point p) + { + checkWidget(); + this.minSize = p; + } + + + /** + * Set the allowed minimum size for the shell. The SizeGrip will + * not resize the shell to a smaller size. + *

+ * Note: This does not affect other ways of resizing the shell, + * like using the size controls which are placed on the trimmings by + * the window manager. + *

+ */ + + public void setMinimumShellSize(int width, int height) + { + checkWidget(); + this.minSize = new Point(width, height); + } + + + public void setBorderWidth(int width) + { + checkWidget(); + borderWidth = width; + Point p = toControl(display.getCursorLocation()); + updateCursor(areaAtPoint(p.x, p.y)); + } + + + public void setCornerSize(int size) + { + checkWidget(); + cornerSize = size; + Point p = toControl(display.getCursorLocation()); + updateCursor(areaAtPoint(p.x, p.y)); + } + + + private static 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); + } +} diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/SizeGrip.d --- a/dwtx/novocode/SizeGrip.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/SizeGrip.d Sun Oct 26 15:04:41 2008 +0100 @@ -11,8 +11,8 @@ * Frank Benoit *******************************************************************************/ /++ - + This code was take from http://www.novocode.com/swt/ - +/ ++ This code was take from http://www.novocode.com/swt/ ++/ module dwtx.novocode.SizeGrip; import dwt.dwthelper.utils; @@ -195,10 +195,10 @@ { TimerTask executingTask = this; event.display.asyncExec( dgRunnable( (Event event_, TimerTask executingTask_ ) - { - if(executingTask_ !is timerTask) return; - performResize(event_); - }, event, executingTask )); + { + if(executingTask_ !is timerTask) return; + performResize(event_); + }, event, executingTask )); } }; timer.schedule(timerTask, UPDATE_DELAY); @@ -216,7 +216,7 @@ performResize(event); } } - + public this(Composite parent, Composite resizableParent_, int style) { super(parent, style = checkStyle (style)); diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/ishell/DesktopForm.d --- a/dwtx/novocode/ishell/DesktopForm.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/ishell/DesktopForm.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,512 +1,512 @@ -/******************************************************************************* - * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - *******************************************************************************/ - -module dwtx.novocode.ishell.DesktopForm; - -import dwt.DWT; -import dwt.graphics.Color; -import dwt.graphics.Rectangle; -import dwt.widgets.Composite; -import dwt.widgets.Control; -import dwt.widgets.Display; -import dwt.widgets.Event; -import dwt.widgets.Listener; -import dwt.widgets.Shell; - -import dwtx.novocode.ishell.internal.DesktopListener; -import dwtx.novocode.ishell.InternalShell; - -import tango.core.Array; - - -/** - * A desktop which manages internal shells. - * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Jan 21, 2005 - * @version $Id: DesktopForm.java 344 2005-07-09 22:37:51 +0000 (Sat, 09 Jul 2005) szeiger $ - */ - -class DesktopForm : Composite -{ - private static const InternalShell[] EMPTY_INTERNALSHELL_ARRAY/** = new InternalShell[0]*/; - private static const int FIRST_SHELL_LOCATION = 32; - private static const int SHELL_LOCATION_OFFSET = 16; - - private InternalShell activeShell; - private DesktopListener[] desktopListeners; - private InternalShell[] allShells; - private InternalShell[] visibleShells; - private int nextShellLocation = FIRST_SHELL_LOCATION; - private bool showMaximizedTitle; - private bool autoMaximize = true; - private bool enableCtrlTab = true; - private bool allowDeactivate; - private Shell shell; - private InternalShell ishell; - private Listener mouseDownFilter, focusInFilter, traverseFilter; - - - this(Composite parent, int style) - { - super(parent, style); - Display display = getDisplay(); - shell = getShell(); - - Color bg = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND); - setBackground(bg); - int brightness = bg.getRed() + bg.getGreen() + bg.getBlue(); - setForeground(display.getSystemColor(brightness > 400 ? DWT.COLOR_BLACK : DWT.COLOR_WHITE)); - - addListener(DWT.Resize, dgListener(&onResize)); - - mouseDownFilter = dgListener(&onMouseDownFilter); - focusInFilter = dgListener(&onFocusInFilter); - traverseFilter = dgListener(&onTraverseFilter); - - display.addFilter(DWT.MouseDown, mouseDownFilter); - display.addFilter(DWT.FocusIn, focusInFilter); - display.addFilter(DWT.Traverse, traverseFilter); - - addListener(DWT.Dispose, dgListener(&onDispose)); - } - - - private void onResize(Event event) - { - Rectangle ca = getClientArea(); - foreach(c; getChildren()) - { - if(cast(InternalShell)c !is null) - (cast(InternalShell)c).desktopResized(ca); - } - } - - - private void onMouseDownFilter(Event event) - { - if(!(cast(Control)event.widget !is null)) return; - Control c = cast(Control)event.widget; - if(c.getShell() !is shell) return; - bool[] desktopHit = new bool[1]; - InternalShell ishell = getInternalShell(c, desktopHit); - if(desktopHit[0] && allowDeactivate) activate(null); - if(ishell is null) return; - activate(ishell); - } - - - private void onFocusInFilter(Event event) - { - if(!(cast(Control)event.widget !is null)) return; - Control c = cast(Control)event.widget; - if(c.getShell() !is shell) return; - bool[] desktopHit = new bool[1]; - ishell = getInternalShell(c, desktopHit); - if(desktopHit[0] && allowDeactivate) activate(null); - if(ishell is null) return; - ishell.focusControl = c; - } - - - private void onTraverseFilter(Event event) - { - if(!enableCtrlTab) return; - if(!event.doit) return; // don't steal traverse event if a control wants to handle it directly - if((event.stateMask & DWT.CTRL) is 0) return; - if(event.detail !is DWT.TRAVERSE_TAB_NEXT && event.detail !is DWT.TRAVERSE_TAB_PREVIOUS) return; - if(!(cast(Control)event.widget !is null)) return; - Control c = cast(Control)event.widget; - if(c.getShell() !is shell) return; - bool[] desktopHit = new bool[1]; - InternalShell ishell = getInternalShell(c, desktopHit); - if(ishell !is null || desktopHit[0]) - { - if(event.detail is DWT.TRAVERSE_TAB_NEXT) activateNextShell(); - else activatePreviousShell(); - event.doit = false; - } - } - - - private void onDispose(Event event) - { - display.removeFilter(DWT.MouseDown, mouseDownFilter); - display.removeFilter(DWT.FocusIn, focusInFilter); - display.removeFilter(DWT.Traverse, traverseFilter); - } - - - void manage(InternalShell ishell) - { - Rectangle bounds = getBounds(); - if(nextShellLocation > bounds.height-100 || nextShellLocation > bounds.width-100) - nextShellLocation = FIRST_SHELL_LOCATION; - ishell.setLocation(bounds.x+nextShellLocation, bounds.y+nextShellLocation); - nextShellLocation += SHELL_LOCATION_OFFSET; - - ishell.addListener(DWT.Dispose, dgListener(&onIshellDispose)); - allShells ~= ishell; - if(ishell.isVisible()) visibleShells ~= ishell; - notifyDesktopListenersCreate(ishell); - } - - - private void onIshellDispose(Event event) - { - allShells.remove(ishell); - visibleShells.remove(ishell); - if(ishell is activeShell) - { - activateTopmostVisibleShellExcept(ishell); - if(autoMaximize && !hasVisibleMaximizedShell()) - setAllVisibleMaximized(false); - } - notifyDesktopListenersDispose(ishell); - } - - - private InternalShell activateTopmostVisibleShellExcept(InternalShell except) - { - Control[] children = getChildren(); - for(int i=0; i 0) ishell.moveAbove(children[0]); - } - } - } - InternalShell oldActiveShell = activeShell; - activeShell = ishell; - if(oldActiveShell !is null) oldActiveShell.redrawDecorationsAfterActivityChange(); - if(ishell !is null) - { - if(activeShell.isVisible()) activeShell.redrawDecorationsAfterActivityChange(); - setTabList(/**new Control[] { activeShell }*/[ activeShell ]); - activeShell.setFocus(); - } - else - { - setTabList(/**new Control[] {}*/[]); - forceFocus(); - } - notifyDesktopListenersActivate(ishell); - } - - - private InternalShell getTopmostRegularShell() - { - foreach(c; getChildren()) - { - if(!(cast(InternalShell)c !is null)) continue; - if((c.getStyle() & DWT.ON_TOP) is 0) return cast(InternalShell)c; - } - return null; - } - - - private InternalShell getBottommostOnTopShell() - { - Control[] ch = getChildren(); - for(int i=ch.length-1; i>=0; i--) - { - Control c = ch[i]; - if(!(cast(InternalShell)c !is null)) continue; - if((c.getStyle() & DWT.ON_TOP) !is 0) return cast(InternalShell)c; - } - return null; - } - - - void shellVisibilityChanged(InternalShell ishell, bool visible) - { - if(visible) - { - if(!contains(visibleShells, ishell)) - { - visibleShells ~= ishell; - if(autoMaximize && !ishell.getMaximized() && (ishell.getStyle() & DWT.MAX) !is 0 && hasVisibleMaximizedShell()) - ishell.setMaximizedWithoutNotification(true); - } - if(ishell.getMaximized()) - ishell.desktopResized(getClientArea()); - } - else - { - visibleShells.remove(ishell); - if(ishell is activeShell) - { - activateTopmostVisibleShellExcept(ishell); - if(autoMaximize && !hasVisibleMaximizedShell()) - setAllVisibleMaximized(false); - } - } - } - - - private InternalShell getInternalShell(Control c, bool[] desktopHit) - { - while(c !is null && c !is /**DesktopForm.*/this) - { - if(cast(InternalShell)c !is null && (cast(InternalShell)c).getParent() is this) - return cast(InternalShell)c; - c = c.getParent(); - } - if(desktopHit !is null && c is /**DesktopForm.*/this) desktopHit[0] = true; - return null; - } - - - public InternalShell getActiveShell() - { - return activeShell; - } - - - public InternalShell[] getVisibleShells() - { - checkWidget(); - return visibleShells; - } - - - public InternalShell[] getShells() - { - checkWidget(); - return allShells; - } - - - public void setShowMaximizedTitle(bool b) - { - checkWidget(); - showMaximizedTitle = b; - Rectangle ca = getClientArea(); - foreach(c; getChildren()) - { - if(cast(InternalShell)c !is null) - (cast(InternalShell)c).desktopResized(ca); - } - } - - - public bool getShowMaximizedTitle() - { - checkWidget(); - return showMaximizedTitle; - } - - - public void setAutoMaximize(bool b) - { - checkWidget(); - autoMaximize = b; - bool hasMax = false; - foreach(ins; visibleShells) - { - if(ins.getMaximized()) - { - hasMax = true; - break; - } - } - if(hasMax) - { - // Maximize all shells - foreach(ins; visibleShells) - { - if((ins.getStyle() & DWT.MAX) !is 0) ins.setMaximized(true); - } - } - } - - - public bool getAutoMaximize() - { - checkWidget(); - return autoMaximize; - } - - - public void setEnableCtrlTab(bool b) - { - checkWidget(); - this.enableCtrlTab = b; - } - - - public bool getEnableCtrlTab() - { - return enableCtrlTab; - } - - - public void setAllowDeactivate(bool b) - { - checkWidget(); - this.allowDeactivate = b; - if(!allowDeactivate && activeShell is null) - activateTopmostVisibleShellExcept(null); - } - - - public bool getAllowDeactivate() - { - return allowDeactivate; - } - - - void shellMaximizedOrRestored(InternalShell ishell, bool maximized) - { - setAllVisibleMaximized(maximized); - } - - - private void setAllVisibleMaximized(bool maximized) - { - if(autoMaximize) // maximize or restore all shells - { - foreach(c; getChildren()) - { - if(cast(InternalShell)c !is null) - { - InternalShell ishell = cast(InternalShell)c; - if((ishell.getStyle() & DWT.MAX) !is 0 && ishell.isVisible()) - (cast(InternalShell)c).setMaximizedWithoutNotification(maximized); - } - } - } - } - - - private void activateNextShell() - { - if(activeShell is null) - { - activateTopmostVisibleShellExcept(null); - return; - } - if(visibleShells.length < 2) return; - InternalShell topReg = getTopmostRegularShell(); - InternalShell botTop = getBottommostOnTopShell(); - if((activeShell.getStyle() & DWT.ON_TOP) !is 0) - { - activeShell.moveBelow(botTop); - if(topReg !is null) activate(topReg); - else activateTopmostVisibleShellExcept(null); - } - else - { - activeShell.moveBelow(null); - activateTopmostVisibleShellExcept(null); - } - } - - - private void activatePreviousShell() - { - if(activeShell is null) - { - activateTopmostVisibleShellExcept(null); - return; - } - if(visibleShells.length < 2) return; - InternalShell topReg = getTopmostRegularShell(); - InternalShell botTop = getBottommostOnTopShell(); - if(activeShell is topReg && botTop !is null) activate(botTop); - else - { - Control[] ch = getChildren(); - for(int i=ch.length-1; i>=0; i--) - { - if(cast(InternalShell)ch[i] !is null && ch[i].isVisible()) - { - activate(cast(InternalShell)ch[i]); - break; - } - } - } - } - - - public void addDesktopListener(DesktopListener l) - { - desktopListeners ~= l; - } - - - public void removeDesktopListener(DesktopListener l) - { - desktopListeners.remove(l); - } - - - private void notifyDesktopListenersCreate(InternalShell ishell) - { - Event event = new Event(); - event.widget = ishell; - foreach(l; desktopListeners) l.shellCreated(event); - } - - - private void notifyDesktopListenersDispose(InternalShell ishell) - { - Event event = new Event(); - event.widget = ishell; - foreach(l; desktopListeners) l.shellDisposed(event); - } - - - private void notifyDesktopListenersActivate(InternalShell ishell) - { - Event event = new Event(); - event.widget = ishell; - foreach(l; desktopListeners) l.shellActivated(event); - } - - - private bool hasVisibleMaximizedShell() - { - foreach(ins; visibleShells) - if(ins.getMaximized()) return true; - return false; - } -} +/******************************************************************************* + * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + *******************************************************************************/ + +module dwtx.novocode.ishell.DesktopForm; + +import dwt.DWT; +import dwt.graphics.Color; +import dwt.graphics.Rectangle; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Shell; + +import dwtx.novocode.ishell.internal.DesktopListener; +import dwtx.novocode.ishell.InternalShell; + +import tango.core.Array; + + +/** + * A desktop which manages internal shells. + * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Jan 21, 2005 + * @version $Id: DesktopForm.java 344 2005-07-09 22:37:51 +0000 (Sat, 09 Jul 2005) szeiger $ + */ + +class DesktopForm : Composite +{ + private static const InternalShell[] EMPTY_INTERNALSHELL_ARRAY/** = new InternalShell[0]*/; + private static const int FIRST_SHELL_LOCATION = 32; + private static const int SHELL_LOCATION_OFFSET = 16; + + private InternalShell activeShell; + private DesktopListener[] desktopListeners; + private InternalShell[] allShells; + private InternalShell[] visibleShells; + private int nextShellLocation = FIRST_SHELL_LOCATION; + private bool showMaximizedTitle; + private bool autoMaximize = true; + private bool enableCtrlTab = true; + private bool allowDeactivate; + private Shell shell; + private InternalShell ishell; + private Listener mouseDownFilter, focusInFilter, traverseFilter; + + + this(Composite parent, int style) + { + super(parent, style); + Display display = getDisplay(); + shell = getShell(); + + Color bg = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND); + setBackground(bg); + int brightness = bg.getRed() + bg.getGreen() + bg.getBlue(); + setForeground(display.getSystemColor(brightness > 400 ? DWT.COLOR_BLACK : DWT.COLOR_WHITE)); + + addListener(DWT.Resize, dgListener(&onResize)); + + mouseDownFilter = dgListener(&onMouseDownFilter); + focusInFilter = dgListener(&onFocusInFilter); + traverseFilter = dgListener(&onTraverseFilter); + + display.addFilter(DWT.MouseDown, mouseDownFilter); + display.addFilter(DWT.FocusIn, focusInFilter); + display.addFilter(DWT.Traverse, traverseFilter); + + addListener(DWT.Dispose, dgListener(&onDispose)); + } + + + private void onResize(Event event) + { + Rectangle ca = getClientArea(); + foreach(c; getChildren()) + { + if(cast(InternalShell)c !is null) + (cast(InternalShell)c).desktopResized(ca); + } + } + + + private void onMouseDownFilter(Event event) + { + if(!(cast(Control)event.widget !is null)) return; + Control c = cast(Control)event.widget; + if(c.getShell() !is shell) return; + bool[] desktopHit = new bool[1]; + InternalShell ishell = getInternalShell(c, desktopHit); + if(desktopHit[0] && allowDeactivate) activate(null); + if(ishell is null) return; + activate(ishell); + } + + + private void onFocusInFilter(Event event) + { + if(!(cast(Control)event.widget !is null)) return; + Control c = cast(Control)event.widget; + if(c.getShell() !is shell) return; + bool[] desktopHit = new bool[1]; + ishell = getInternalShell(c, desktopHit); + if(desktopHit[0] && allowDeactivate) activate(null); + if(ishell is null) return; + ishell.focusControl = c; + } + + + private void onTraverseFilter(Event event) + { + if(!enableCtrlTab) return; + if(!event.doit) return; // don't steal traverse event if a control wants to handle it directly + if((event.stateMask & DWT.CTRL) is 0) return; + if(event.detail !is DWT.TRAVERSE_TAB_NEXT && event.detail !is DWT.TRAVERSE_TAB_PREVIOUS) return; + if(!(cast(Control)event.widget !is null)) return; + Control c = cast(Control)event.widget; + if(c.getShell() !is shell) return; + bool[] desktopHit = new bool[1]; + InternalShell ishell = getInternalShell(c, desktopHit); + if(ishell !is null || desktopHit[0]) + { + if(event.detail is DWT.TRAVERSE_TAB_NEXT) activateNextShell(); + else activatePreviousShell(); + event.doit = false; + } + } + + + private void onDispose(Event event) + { + display.removeFilter(DWT.MouseDown, mouseDownFilter); + display.removeFilter(DWT.FocusIn, focusInFilter); + display.removeFilter(DWT.Traverse, traverseFilter); + } + + + void manage(InternalShell ishell) + { + Rectangle bounds = getBounds(); + if(nextShellLocation > bounds.height-100 || nextShellLocation > bounds.width-100) + nextShellLocation = FIRST_SHELL_LOCATION; + ishell.setLocation(bounds.x+nextShellLocation, bounds.y+nextShellLocation); + nextShellLocation += SHELL_LOCATION_OFFSET; + + ishell.addListener(DWT.Dispose, dgListener(&onIshellDispose)); + allShells ~= ishell; + if(ishell.isVisible()) visibleShells ~= ishell; + notifyDesktopListenersCreate(ishell); + } + + + private void onIshellDispose(Event event) + { + allShells.remove(ishell); + visibleShells.remove(ishell); + if(ishell is activeShell) + { + activateTopmostVisibleShellExcept(ishell); + if(autoMaximize && !hasVisibleMaximizedShell()) + setAllVisibleMaximized(false); + } + notifyDesktopListenersDispose(ishell); + } + + + private InternalShell activateTopmostVisibleShellExcept(InternalShell except) + { + Control[] children = getChildren(); + for(int i=0; i 0) ishell.moveAbove(children[0]); + } + } + } + InternalShell oldActiveShell = activeShell; + activeShell = ishell; + if(oldActiveShell !is null) oldActiveShell.redrawDecorationsAfterActivityChange(); + if(ishell !is null) + { + if(activeShell.isVisible()) activeShell.redrawDecorationsAfterActivityChange(); + setTabList(/**new Control[] { activeShell }*/[ activeShell ]); + activeShell.setFocus(); + } + else + { + setTabList(/**new Control[] {}*/[]); + forceFocus(); + } + notifyDesktopListenersActivate(ishell); + } + + + private InternalShell getTopmostRegularShell() + { + foreach(c; getChildren()) + { + if(!(cast(InternalShell)c !is null)) continue; + if((c.getStyle() & DWT.ON_TOP) is 0) return cast(InternalShell)c; + } + return null; + } + + + private InternalShell getBottommostOnTopShell() + { + Control[] ch = getChildren(); + for(int i=ch.length-1; i>=0; i--) + { + Control c = ch[i]; + if(!(cast(InternalShell)c !is null)) continue; + if((c.getStyle() & DWT.ON_TOP) !is 0) return cast(InternalShell)c; + } + return null; + } + + + void shellVisibilityChanged(InternalShell ishell, bool visible) + { + if(visible) + { + if(!contains(visibleShells, ishell)) + { + visibleShells ~= ishell; + if(autoMaximize && !ishell.getMaximized() && (ishell.getStyle() & DWT.MAX) !is 0 && hasVisibleMaximizedShell()) + ishell.setMaximizedWithoutNotification(true); + } + if(ishell.getMaximized()) + ishell.desktopResized(getClientArea()); + } + else + { + visibleShells.remove(ishell); + if(ishell is activeShell) + { + activateTopmostVisibleShellExcept(ishell); + if(autoMaximize && !hasVisibleMaximizedShell()) + setAllVisibleMaximized(false); + } + } + } + + + private InternalShell getInternalShell(Control c, bool[] desktopHit) + { + while(c !is null && c !is /**DesktopForm.*/this) + { + if(cast(InternalShell)c !is null && (cast(InternalShell)c).getParent() is this) + return cast(InternalShell)c; + c = c.getParent(); + } + if(desktopHit !is null && c is /**DesktopForm.*/this) desktopHit[0] = true; + return null; + } + + + public InternalShell getActiveShell() + { + return activeShell; + } + + + public InternalShell[] getVisibleShells() + { + checkWidget(); + return visibleShells; + } + + + public InternalShell[] getShells() + { + checkWidget(); + return allShells; + } + + + public void setShowMaximizedTitle(bool b) + { + checkWidget(); + showMaximizedTitle = b; + Rectangle ca = getClientArea(); + foreach(c; getChildren()) + { + if(cast(InternalShell)c !is null) + (cast(InternalShell)c).desktopResized(ca); + } + } + + + public bool getShowMaximizedTitle() + { + checkWidget(); + return showMaximizedTitle; + } + + + public void setAutoMaximize(bool b) + { + checkWidget(); + autoMaximize = b; + bool hasMax = false; + foreach(ins; visibleShells) + { + if(ins.getMaximized()) + { + hasMax = true; + break; + } + } + if(hasMax) + { + // Maximize all shells + foreach(ins; visibleShells) + { + if((ins.getStyle() & DWT.MAX) !is 0) ins.setMaximized(true); + } + } + } + + + public bool getAutoMaximize() + { + checkWidget(); + return autoMaximize; + } + + + public void setEnableCtrlTab(bool b) + { + checkWidget(); + this.enableCtrlTab = b; + } + + + public bool getEnableCtrlTab() + { + return enableCtrlTab; + } + + + public void setAllowDeactivate(bool b) + { + checkWidget(); + this.allowDeactivate = b; + if(!allowDeactivate && activeShell is null) + activateTopmostVisibleShellExcept(null); + } + + + public bool getAllowDeactivate() + { + return allowDeactivate; + } + + + void shellMaximizedOrRestored(InternalShell ishell, bool maximized) + { + setAllVisibleMaximized(maximized); + } + + + private void setAllVisibleMaximized(bool maximized) + { + if(autoMaximize) // maximize or restore all shells + { + foreach(c; getChildren()) + { + if(cast(InternalShell)c !is null) + { + InternalShell ishell = cast(InternalShell)c; + if((ishell.getStyle() & DWT.MAX) !is 0 && ishell.isVisible()) + (cast(InternalShell)c).setMaximizedWithoutNotification(maximized); + } + } + } + } + + + private void activateNextShell() + { + if(activeShell is null) + { + activateTopmostVisibleShellExcept(null); + return; + } + if(visibleShells.length < 2) return; + InternalShell topReg = getTopmostRegularShell(); + InternalShell botTop = getBottommostOnTopShell(); + if((activeShell.getStyle() & DWT.ON_TOP) !is 0) + { + activeShell.moveBelow(botTop); + if(topReg !is null) activate(topReg); + else activateTopmostVisibleShellExcept(null); + } + else + { + activeShell.moveBelow(null); + activateTopmostVisibleShellExcept(null); + } + } + + + private void activatePreviousShell() + { + if(activeShell is null) + { + activateTopmostVisibleShellExcept(null); + return; + } + if(visibleShells.length < 2) return; + InternalShell topReg = getTopmostRegularShell(); + InternalShell botTop = getBottommostOnTopShell(); + if(activeShell is topReg && botTop !is null) activate(botTop); + else + { + Control[] ch = getChildren(); + for(int i=ch.length-1; i>=0; i--) + { + if(cast(InternalShell)ch[i] !is null && ch[i].isVisible()) + { + activate(cast(InternalShell)ch[i]); + break; + } + } + } + } + + + public void addDesktopListener(DesktopListener l) + { + desktopListeners ~= l; + } + + + public void removeDesktopListener(DesktopListener l) + { + desktopListeners.remove(l); + } + + + private void notifyDesktopListenersCreate(InternalShell ishell) + { + Event event = new Event(); + event.widget = ishell; + foreach(l; desktopListeners) l.shellCreated(event); + } + + + private void notifyDesktopListenersDispose(InternalShell ishell) + { + Event event = new Event(); + event.widget = ishell; + foreach(l; desktopListeners) l.shellDisposed(event); + } + + + private void notifyDesktopListenersActivate(InternalShell ishell) + { + Event event = new Event(); + event.widget = ishell; + foreach(l; desktopListeners) l.shellActivated(event); + } + + + private bool hasVisibleMaximizedShell() + { + foreach(ins; visibleShells) + if(ins.getMaximized()) return true; + return false; + } +} diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/ishell/InternalShell.d --- a/dwtx/novocode/ishell/InternalShell.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/ishell/InternalShell.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,398 +1,398 @@ -/******************************************************************************* - * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - *******************************************************************************/ - -module dwtx.novocode.ishell.InternalShell; - -import dwt.dwthelper.utils; -import dwt.DWT; -import dwt.DWTException; -import dwt.graphics.Image; -import dwt.graphics.Point; -import dwt.graphics.Rectangle; -import dwt.layout.FormAttachment; -import dwt.layout.FormData; -import dwt.layout.FormLayout; -import dwt.widgets.Composite; -import dwt.widgets.Control; -import dwt.widgets.Event; -import dwt.widgets.Listener; -import dwt.widgets.Menu; - -import dwtx.novocode.SizeBorder; -import dwtx.novocode.SizeGrip; -import dwtx.novocode.ishell.DesktopForm; -import dwtx.novocode.ishell.internal.TitleBar; -import dwtx.novocode.ishell.internal.TitleBarButton; - - -/** - * An internal shell which can be placed on a DesktopForm. - *

- *

- *
Styles:
- *
RESIZE, CLOSE, MAX, ON_TOP, TOOL, NO_RADIO_GROUP
- *
Events:
- *
(none)
- *
- *

- * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Jan 21, 2005 - * @version $Id: InternalShell.java 344 2005-07-09 22:37:51 +0000 (Sat, 09 Jul 2005) szeiger $ - */ - -// [TODO] Support styles NO_TRIM, BORDER, TITLE -// [TODO] Separate "minimized" from "not visible" - -class InternalShell : Composite -{ - private static const int BORDER_SIZE = 4; - - private Composite contentPane; - private TitleBar titleBar; - private SizeGrip sizeGrip; - private SizeBorder sizeBorder; - private int minWidth = 112; - private int minHeight; - private DesktopForm desktop; - private bool maximized; - private Rectangle pluralizedBounds; - private int titleHeight; - private int style; - private TitleBarButton closeButton, maxButton, minButton; - - Control focusControl; - - - this(DesktopForm parent, int style) - { - super(parent, checkStyle(style)); - this.desktop = parent; - this.style = style; - setBackground(getDisplay().getSystemColor(DWT.COLOR_WIDGET_BACKGROUND)); - FormLayout layout = new FormLayout(); - setLayout(layout); - FormData fd; - - titleBar = new TitleBar(this, style & (DWT.CLOSE | DWT.RESIZE | DWT.MAX | DWT.TOOL | DWT.MIN)); - titleHeight = titleBar.computeSize(DWT.DEFAULT, DWT.DEFAULT, true).y; - - Control leftButton = null; - - if((style & (DWT.CLOSE | DWT.MAX | DWT.MIN)) !is 0) - { - closeButton = new TitleBarButton(this, DWT.CLOSE); - if((style & DWT.CLOSE) is 0) closeButton.setEnabled(false); - closeButton.addListener(DWT.Selection, dgListener(&closeListener)); - fd = new FormData(titleHeight, titleHeight); - if(leftButton !is null) fd.right = new FormAttachment(leftButton); - else fd.right = new FormAttachment(100, -BORDER_SIZE); - fd.top = new FormAttachment(0, BORDER_SIZE); - closeButton.setLayoutData(fd); - leftButton = closeButton; - - if((style & (DWT.MAX|DWT.MIN)) !is 0) - { - maxButton = new TitleBarButton(this, DWT.MAX); - if((style & DWT.MAX) is 0) maxButton.setEnabled(false); - maxButton.addListener(DWT.Selection, dgListener(&maximizeListener)); - fd = new FormData(titleHeight, titleHeight); - if(leftButton !is null) fd.right = new FormAttachment(leftButton); - else fd.right = new FormAttachment(100, -BORDER_SIZE); - fd.top = new FormAttachment(0, BORDER_SIZE); - maxButton.setLayoutData(fd); - leftButton = maxButton; - - minButton = new TitleBarButton(this, DWT.MIN); - if((style & DWT.MIN) is 0) minButton.setEnabled(false); - minButton.addListener(DWT.Selection, dgListener(&minimizeListener)); - fd = new FormData(titleHeight, titleHeight); - if(leftButton !is null) fd.right = new FormAttachment(leftButton); - else fd.right = new FormAttachment(100, -BORDER_SIZE); - fd.top = new FormAttachment(0, BORDER_SIZE); - minButton.setLayoutData(fd); - leftButton = minButton; - } - } - - fd = new FormData(); - fd.left = new FormAttachment(0, BORDER_SIZE); - if(leftButton !is null) fd.right = new FormAttachment(leftButton); - else fd.right = new FormAttachment(100, -BORDER_SIZE); - fd.top = new FormAttachment(0, BORDER_SIZE); - titleBar.setLayoutData(fd); - - contentPane = new Composite(this, DWT.NONE); - fd = new FormData(); - fd.left = new FormAttachment(0, BORDER_SIZE); - fd.right = new FormAttachment(100, -BORDER_SIZE); - fd.top = new FormAttachment(titleBar, 1); - fd.bottom = new FormAttachment(100, -BORDER_SIZE); - contentPane.setLayoutData(fd); - - sizeBorder = new SizeBorder(this, this, DWT.BORDER); - sizeBorder.setBorderWidth(BORDER_SIZE); - fd = new FormData(); - fd.left = new FormAttachment(0); - fd.right = new FormAttachment(100); - fd.top = new FormAttachment(0); - fd.bottom = new FormAttachment(100); - sizeBorder.setLayoutData(fd); - - minHeight = titleHeight + 2*BORDER_SIZE; - sizeBorder.setMinimumShellSize(minWidth, minHeight); - sizeBorder.setCornerSize(titleHeight + BORDER_SIZE); - if((style & DWT.RESIZE) is 0) sizeBorder.setEnabled(false); - - setSize(320, 240); - setVisible(false); - - desktop.manage(this); - } - - - private void closeListener(Event event) - { - close(); - } - - - private void maximizeListener(Event event) - { - setMaximized(!maximized); - } - - - private void minimizeListener(Event event) - { - setMinimized(true); - } - - - private static int checkStyle(int style) - { - int mask = DWT.NO_RADIO_GROUP; - style &= mask; - return style; - } - - - public int getStyle() - { - return style; - } - - - public Composite getContentPane() { return contentPane; } - - - public void setText(String s) { titleBar.setText(s); } - - public String getText() { return titleBar.getText(); } - - - public void setCustomMenu(Menu menu) { titleBar.setMenu(menu); } - - public Menu getCustomMenu() { return titleBar.getMenu(); } - - - public void setImage(Image image) { titleBar.setImage(image); } - - public Image getImage() { return titleBar.getImage(); } - - - public void createSizeGrip(int style) - { - checkWidget(); - if(sizeGrip !is null) - throw new DWTException("SizeGrip was already created"); - if((this.style & DWT.RESIZE) is 0) - throw new DWTException("Cannot create SizeGrip for InternalShell without style RESIZE"); - sizeGrip = new SizeGrip(this, this, style); - sizeGrip.setBackground(contentPane.getBackground()); - sizeGrip.moveAbove(contentPane); - FormData fd = new FormData(); - fd.right = new FormAttachment(100, -BORDER_SIZE); - fd.bottom = new FormAttachment(100, -BORDER_SIZE); - sizeGrip.setLayoutData(fd); - sizeGrip.setMinimumShellSize(minWidth, minHeight); - if(isVisible()) layout(true); - } - - - public Point computeSize(int wHint, int hHint, bool changed) - { - Point p = super.computeSize(wHint, hHint, changed); - if(p.x < minWidth) p.x = minWidth; - if(p.y < minHeight) p.y = minHeight; - return p; - } - - - public void setSize(int width, int height) - { - if(width < minWidth) width = minWidth; - if(height < minHeight) height = minHeight; - super.setSize(width, height); - } - - - public void setBounds(int x, int y, int width, int height) - { - if(width < minWidth) width = minWidth; - if(height < minHeight) height = minHeight; - super.setBounds(x, y, width, height); - } - - - public void setMinimumSize(int width, int height) - { - checkWidget(); - minWidth = width; - minHeight = height; - sizeGrip.setMinimumShellSize(minWidth, minHeight); - sizeBorder.setMinimumShellSize(minWidth, minHeight); - Point size = getSize(); - if(size.x < minWidth || size.y < minHeight) - setSize(Math.max(minWidth, size.x), Math.max(minHeight, size.y)); - } - - - public void close() - { - Event event = new Event(); - notifyListeners(DWT.Close, event); - if(event.doit && !isDisposed()) dispose(); - } - - - public void open() - { - desktop.activate(this); - setVisible(true); - setFocus(); - } - - - public void setVisible(bool visible) - { - if(!visible) desktop.shellVisibilityChanged(this, false); - super.setVisible(visible); - if(visible) desktop.shellVisibilityChanged(this, true); - } - - - public void setActive() - { - desktop.activate(this); - } - - - public void setMaximized(bool maximized) - { - checkWidget(); - if(this.maximized is maximized) return; - setMaximizedWithoutNotification(maximized); - desktop.shellMaximizedOrRestored(this, maximized); - } - - - public void setMinimized(bool minimized) - { - checkWidget(); - bool wasMaximized = maximized; - setVisible(!minimized); - maximized = wasMaximized; - } - - - public bool getMinimized() - { - return getVisible(); - } - - - void setMaximizedWithoutNotification(bool maximized) - { - if(this.maximized is maximized) return; - this.maximized = maximized; - if(maximized) - { - pluralizedBounds = getBounds(); - desktopResized(desktop.getClientArea()); - } - else - { - setBounds(pluralizedBounds.x,pluralizedBounds.y,pluralizedBounds.width,pluralizedBounds.height); - } - // Note: This method may be called in a Dispose event for this object - if(sizeGrip !is null && !sizeGrip.isDisposed()) sizeGrip.setVisible(!maximized); - if(!sizeBorder.isDisposed()) sizeBorder.setEnabled(!maximized && (style & DWT.RESIZE) !is 0); - if(maxButton !is null && !maxButton.isDisposed()) maxButton.redraw(); - } - - - public bool getMaximized() - { - checkWidget(); - return maximized; - } - - - void redrawDecorationsAfterActivityChange() - { - // Note: This method may be called in a Dispose event for this object - if(!titleBar.isDisposed()) titleBar.redraw(); - if(closeButton !is null && !closeButton.isDisposed()) closeButton.redraw(); - if(maxButton !is null && !maxButton.isDisposed()) maxButton.redraw(); - if(minButton !is null && !minButton.isDisposed()) minButton.redraw(); - } - - - void desktopResized(Rectangle deskCA) - { - if(maximized) - { - int hideTitle = desktop.getShowMaximizedTitle() ? 0 : (titleHeight+1); - setBounds(deskCA.x - BORDER_SIZE, - deskCA.y - BORDER_SIZE - hideTitle, - deskCA.width + 2*BORDER_SIZE, - deskCA.height + 2*BORDER_SIZE + hideTitle); - } - else forceVisibleLocation(deskCA); - } - - - public bool setFocus() - { - if(focusControl !is null && focusControl !is this && !focusControl.isDisposed()) - return focusControl.setFocus(); - return super.setFocus(); - } - - - public bool isActiveShell() - { - return desktop.getActiveShell() is this; - } - - - private void forceVisibleLocation(Rectangle deskCA) - { - Point p = getLocation(); - Point minGrabSize = titleBar.getMinGrabSize(); - int x = p.x, y = p.y; - int minX = minGrabSize.x + BORDER_SIZE, minY = minGrabSize.y + BORDER_SIZE; - x = Math.min(Math.max(x, deskCA.x+minY), deskCA.x+deskCA.width-minX); - y = Math.min(Math.max(y, deskCA.y+minY), deskCA.y+deskCA.height-minY); - if(x != p.x || y != p.y) setLocation(x, y); - } -} +/******************************************************************************* + * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + *******************************************************************************/ + +module dwtx.novocode.ishell.InternalShell; + +import dwt.dwthelper.utils; +import dwt.DWT; +import dwt.DWTException; +import dwt.graphics.Image; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.layout.FormAttachment; +import dwt.layout.FormData; +import dwt.layout.FormLayout; +import dwt.widgets.Composite; +import dwt.widgets.Control; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Menu; + +import dwtx.novocode.SizeBorder; +import dwtx.novocode.SizeGrip; +import dwtx.novocode.ishell.DesktopForm; +import dwtx.novocode.ishell.internal.TitleBar; +import dwtx.novocode.ishell.internal.TitleBarButton; + + +/** + * An internal shell which can be placed on a DesktopForm. + *

+ *

+ *
Styles:
+ *
RESIZE, CLOSE, MAX, ON_TOP, TOOL, NO_RADIO_GROUP
+ *
Events:
+ *
(none)
+ *
+ *

+ * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Jan 21, 2005 + * @version $Id: InternalShell.java 344 2005-07-09 22:37:51 +0000 (Sat, 09 Jul 2005) szeiger $ + */ + +// [TODO] Support styles NO_TRIM, BORDER, TITLE +// [TODO] Separate "minimized" from "not visible" + +class InternalShell : Composite +{ + private static const int BORDER_SIZE = 4; + + private Composite contentPane; + private TitleBar titleBar; + private SizeGrip sizeGrip; + private SizeBorder sizeBorder; + private int minWidth = 112; + private int minHeight; + private DesktopForm desktop; + private bool maximized; + private Rectangle pluralizedBounds; + private int titleHeight; + private int style; + private TitleBarButton closeButton, maxButton, minButton; + + Control focusControl; + + + this(DesktopForm parent, int style) + { + super(parent, checkStyle(style)); + this.desktop = parent; + this.style = style; + setBackground(getDisplay().getSystemColor(DWT.COLOR_WIDGET_BACKGROUND)); + FormLayout layout = new FormLayout(); + setLayout(layout); + FormData fd; + + titleBar = new TitleBar(this, style & (DWT.CLOSE | DWT.RESIZE | DWT.MAX | DWT.TOOL | DWT.MIN)); + titleHeight = titleBar.computeSize(DWT.DEFAULT, DWT.DEFAULT, true).y; + + Control leftButton = null; + + if((style & (DWT.CLOSE | DWT.MAX | DWT.MIN)) !is 0) + { + closeButton = new TitleBarButton(this, DWT.CLOSE); + if((style & DWT.CLOSE) is 0) closeButton.setEnabled(false); + closeButton.addListener(DWT.Selection, dgListener(&closeListener)); + fd = new FormData(titleHeight, titleHeight); + if(leftButton !is null) fd.right = new FormAttachment(leftButton); + else fd.right = new FormAttachment(100, -BORDER_SIZE); + fd.top = new FormAttachment(0, BORDER_SIZE); + closeButton.setLayoutData(fd); + leftButton = closeButton; + + if((style & (DWT.MAX|DWT.MIN)) !is 0) + { + maxButton = new TitleBarButton(this, DWT.MAX); + if((style & DWT.MAX) is 0) maxButton.setEnabled(false); + maxButton.addListener(DWT.Selection, dgListener(&maximizeListener)); + fd = new FormData(titleHeight, titleHeight); + if(leftButton !is null) fd.right = new FormAttachment(leftButton); + else fd.right = new FormAttachment(100, -BORDER_SIZE); + fd.top = new FormAttachment(0, BORDER_SIZE); + maxButton.setLayoutData(fd); + leftButton = maxButton; + + minButton = new TitleBarButton(this, DWT.MIN); + if((style & DWT.MIN) is 0) minButton.setEnabled(false); + minButton.addListener(DWT.Selection, dgListener(&minimizeListener)); + fd = new FormData(titleHeight, titleHeight); + if(leftButton !is null) fd.right = new FormAttachment(leftButton); + else fd.right = new FormAttachment(100, -BORDER_SIZE); + fd.top = new FormAttachment(0, BORDER_SIZE); + minButton.setLayoutData(fd); + leftButton = minButton; + } + } + + fd = new FormData(); + fd.left = new FormAttachment(0, BORDER_SIZE); + if(leftButton !is null) fd.right = new FormAttachment(leftButton); + else fd.right = new FormAttachment(100, -BORDER_SIZE); + fd.top = new FormAttachment(0, BORDER_SIZE); + titleBar.setLayoutData(fd); + + contentPane = new Composite(this, DWT.NONE); + fd = new FormData(); + fd.left = new FormAttachment(0, BORDER_SIZE); + fd.right = new FormAttachment(100, -BORDER_SIZE); + fd.top = new FormAttachment(titleBar, 1); + fd.bottom = new FormAttachment(100, -BORDER_SIZE); + contentPane.setLayoutData(fd); + + sizeBorder = new SizeBorder(this, this, DWT.BORDER); + sizeBorder.setBorderWidth(BORDER_SIZE); + fd = new FormData(); + fd.left = new FormAttachment(0); + fd.right = new FormAttachment(100); + fd.top = new FormAttachment(0); + fd.bottom = new FormAttachment(100); + sizeBorder.setLayoutData(fd); + + minHeight = titleHeight + 2*BORDER_SIZE; + sizeBorder.setMinimumShellSize(minWidth, minHeight); + sizeBorder.setCornerSize(titleHeight + BORDER_SIZE); + if((style & DWT.RESIZE) is 0) sizeBorder.setEnabled(false); + + setSize(320, 240); + setVisible(false); + + desktop.manage(this); + } + + + private void closeListener(Event event) + { + close(); + } + + + private void maximizeListener(Event event) + { + setMaximized(!maximized); + } + + + private void minimizeListener(Event event) + { + setMinimized(true); + } + + + private static int checkStyle(int style) + { + int mask = DWT.NO_RADIO_GROUP; + style &= mask; + return style; + } + + + public int getStyle() + { + return style; + } + + + public Composite getContentPane() { return contentPane; } + + + public void setText(String s) { titleBar.setText(s); } + + public String getText() { return titleBar.getText(); } + + + public void setCustomMenu(Menu menu) { titleBar.setMenu(menu); } + + public Menu getCustomMenu() { return titleBar.getMenu(); } + + + public void setImage(Image image) { titleBar.setImage(image); } + + public Image getImage() { return titleBar.getImage(); } + + + public void createSizeGrip(int style) + { + checkWidget(); + if(sizeGrip !is null) + throw new DWTException("SizeGrip was already created"); + if((this.style & DWT.RESIZE) is 0) + throw new DWTException("Cannot create SizeGrip for InternalShell without style RESIZE"); + sizeGrip = new SizeGrip(this, this, style); + sizeGrip.setBackground(contentPane.getBackground()); + sizeGrip.moveAbove(contentPane); + FormData fd = new FormData(); + fd.right = new FormAttachment(100, -BORDER_SIZE); + fd.bottom = new FormAttachment(100, -BORDER_SIZE); + sizeGrip.setLayoutData(fd); + sizeGrip.setMinimumShellSize(minWidth, minHeight); + if(isVisible()) layout(true); + } + + + public Point computeSize(int wHint, int hHint, bool changed) + { + Point p = super.computeSize(wHint, hHint, changed); + if(p.x < minWidth) p.x = minWidth; + if(p.y < minHeight) p.y = minHeight; + return p; + } + + + public void setSize(int width, int height) + { + if(width < minWidth) width = minWidth; + if(height < minHeight) height = minHeight; + super.setSize(width, height); + } + + + public void setBounds(int x, int y, int width, int height) + { + if(width < minWidth) width = minWidth; + if(height < minHeight) height = minHeight; + super.setBounds(x, y, width, height); + } + + + public void setMinimumSize(int width, int height) + { + checkWidget(); + minWidth = width; + minHeight = height; + sizeGrip.setMinimumShellSize(minWidth, minHeight); + sizeBorder.setMinimumShellSize(minWidth, minHeight); + Point size = getSize(); + if(size.x < minWidth || size.y < minHeight) + setSize(Math.max(minWidth, size.x), Math.max(minHeight, size.y)); + } + + + public void close() + { + Event event = new Event(); + notifyListeners(DWT.Close, event); + if(event.doit && !isDisposed()) dispose(); + } + + + public void open() + { + desktop.activate(this); + setVisible(true); + setFocus(); + } + + + public void setVisible(bool visible) + { + if(!visible) desktop.shellVisibilityChanged(this, false); + super.setVisible(visible); + if(visible) desktop.shellVisibilityChanged(this, true); + } + + + public void setActive() + { + desktop.activate(this); + } + + + public void setMaximized(bool maximized) + { + checkWidget(); + if(this.maximized is maximized) return; + setMaximizedWithoutNotification(maximized); + desktop.shellMaximizedOrRestored(this, maximized); + } + + + public void setMinimized(bool minimized) + { + checkWidget(); + bool wasMaximized = maximized; + setVisible(!minimized); + maximized = wasMaximized; + } + + + public bool getMinimized() + { + return getVisible(); + } + + + void setMaximizedWithoutNotification(bool maximized) + { + if(this.maximized is maximized) return; + this.maximized = maximized; + if(maximized) + { + pluralizedBounds = getBounds(); + desktopResized(desktop.getClientArea()); + } + else + { + setBounds(pluralizedBounds.x,pluralizedBounds.y,pluralizedBounds.width,pluralizedBounds.height); + } + // Note: This method may be called in a Dispose event for this object + if(sizeGrip !is null && !sizeGrip.isDisposed()) sizeGrip.setVisible(!maximized); + if(!sizeBorder.isDisposed()) sizeBorder.setEnabled(!maximized && (style & DWT.RESIZE) !is 0); + if(maxButton !is null && !maxButton.isDisposed()) maxButton.redraw(); + } + + + public bool getMaximized() + { + checkWidget(); + return maximized; + } + + + void redrawDecorationsAfterActivityChange() + { + // Note: This method may be called in a Dispose event for this object + if(!titleBar.isDisposed()) titleBar.redraw(); + if(closeButton !is null && !closeButton.isDisposed()) closeButton.redraw(); + if(maxButton !is null && !maxButton.isDisposed()) maxButton.redraw(); + if(minButton !is null && !minButton.isDisposed()) minButton.redraw(); + } + + + void desktopResized(Rectangle deskCA) + { + if(maximized) + { + int hideTitle = desktop.getShowMaximizedTitle() ? 0 : (titleHeight+1); + setBounds(deskCA.x - BORDER_SIZE, + deskCA.y - BORDER_SIZE - hideTitle, + deskCA.width + 2*BORDER_SIZE, + deskCA.height + 2*BORDER_SIZE + hideTitle); + } + else forceVisibleLocation(deskCA); + } + + + public bool setFocus() + { + if(focusControl !is null && focusControl !is this && !focusControl.isDisposed()) + return focusControl.setFocus(); + return super.setFocus(); + } + + + public bool isActiveShell() + { + return desktop.getActiveShell() is this; + } + + + private void forceVisibleLocation(Rectangle deskCA) + { + Point p = getLocation(); + Point minGrabSize = titleBar.getMinGrabSize(); + int x = p.x, y = p.y; + int minX = minGrabSize.x + BORDER_SIZE, minY = minGrabSize.y + BORDER_SIZE; + x = Math.min(Math.max(x, deskCA.x+minY), deskCA.x+deskCA.width-minX); + y = Math.min(Math.max(y, deskCA.y+minY), deskCA.y+deskCA.height-minY); + if(x != p.x || y != p.y) setLocation(x, y); + } +} diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/ishell/internal/CustomDrawnButton.d --- a/dwtx/novocode/ishell/internal/CustomDrawnButton.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/ishell/internal/CustomDrawnButton.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,134 +1,134 @@ -/******************************************************************************* - * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - *******************************************************************************/ - -module dwtx.novocode.ishell.internal.CustomDrawnButton; - -import dwt.DWT; -import dwt.graphics.Point; -import dwt.widgets.Canvas; -import dwt.widgets.Composite; -import dwt.widgets.Display; -import dwt.widgets.Event; -import dwt.widgets.Listener; - - -/** - * A simple button control which needs to be subclassed to draw a specific - * kind of button. This base class provides the event handling. - * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Jan 30, 2005 - * @version $Id: CustomDrawnButton.java 320 2005-02-26 13:37:02 +0000 (Sat, 26 Feb 2005) szeiger $ - */ - -class CustomDrawnButton : Canvas -{ - private bool pressed; - private Display display; - private bool drawnMouseIn = false; - - - this(Composite parent, int style) - { - super(parent, style); - this.display = getDisplay(); - - addListener(DWT.Paint, dgListener(&paintListener)); - - addListener(DWT.MouseDown, dgListener(&onMouseDown)); - - addListener(DWT.MouseUp, dgListener(&onMouseUp)); - - addListener(DWT.MouseMove, dgListener(&onMouseMove)); - } - - - private void paintListener(Event event) - { - bool mouseIn = mouseIn(); - onPaint(event, pressed && mouseIn); - drawnMouseIn = mouseIn; - } - - - private void onMouseDown(Event event) - { - if(event.button is 1) - { - pressed = true; - redraw(); - } - else if(event.button is 3 && (event.stateMask & DWT.BUTTON1) !is 0) // chord click - { - pressed = false; - redraw(); - } - } - - - private void onMouseUp(Event event) - { - if(pressed && (event.stateMask & DWT.BUTTON1) !is 0) - { - pressed = false; - if(mouseIn()) - { - Event selectionEvent = new Event(); - notifyListeners(DWT.Selection, selectionEvent); - } - if(!isDisposed()) redraw(); - } - } - - - private void onMouseMove(Event event) - { - if(!pressed) return; - bool mouseIn = mouseIn(); - if(mouseIn is drawnMouseIn) return; - redraw(); - } - - - private bool mouseIn() - { - Point p = toControl(display.getCursorLocation()); - if(p.x < -1 || p.y < -1) return false; - Point size = getSize(); - return p.x <= size.x+1 && p.y <= size.y+1; - } - - - public Point computeSize(int wHint, int hHint, bool changed) - { - checkWidget(); - if(wHint is DWT.DEFAULT) wHint = 0; - if(hHint is DWT.DEFAULT) hHint = 0; - return new Point(wHint, hHint); - } - - - public bool setFocus() - { - checkWidget(); - return false; - } - - - public bool isReparentable () - { - checkWidget(); - return false; - } - - - protected abstract void onPaint(Event event, bool pressed); -} +/******************************************************************************* + * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + *******************************************************************************/ + +module dwtx.novocode.ishell.internal.CustomDrawnButton; + +import dwt.DWT; +import dwt.graphics.Point; +import dwt.widgets.Canvas; +import dwt.widgets.Composite; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; + + +/** + * A simple button control which needs to be subclassed to draw a specific + * kind of button. This base class provides the event handling. + * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Jan 30, 2005 + * @version $Id: CustomDrawnButton.java 320 2005-02-26 13:37:02 +0000 (Sat, 26 Feb 2005) szeiger $ + */ + +class CustomDrawnButton : Canvas +{ + private bool pressed; + private Display display; + private bool drawnMouseIn = false; + + + this(Composite parent, int style) + { + super(parent, style); + this.display = getDisplay(); + + addListener(DWT.Paint, dgListener(&paintListener)); + + addListener(DWT.MouseDown, dgListener(&onMouseDown)); + + addListener(DWT.MouseUp, dgListener(&onMouseUp)); + + addListener(DWT.MouseMove, dgListener(&onMouseMove)); + } + + + private void paintListener(Event event) + { + bool mouseIn = mouseIn(); + onPaint(event, pressed && mouseIn); + drawnMouseIn = mouseIn; + } + + + private void onMouseDown(Event event) + { + if(event.button is 1) + { + pressed = true; + redraw(); + } + else if(event.button is 3 && (event.stateMask & DWT.BUTTON1) !is 0) // chord click + { + pressed = false; + redraw(); + } + } + + + private void onMouseUp(Event event) + { + if(pressed && (event.stateMask & DWT.BUTTON1) !is 0) + { + pressed = false; + if(mouseIn()) + { + Event selectionEvent = new Event(); + notifyListeners(DWT.Selection, selectionEvent); + } + if(!isDisposed()) redraw(); + } + } + + + private void onMouseMove(Event event) + { + if(!pressed) return; + bool mouseIn = mouseIn(); + if(mouseIn is drawnMouseIn) return; + redraw(); + } + + + private bool mouseIn() + { + Point p = toControl(display.getCursorLocation()); + if(p.x < -1 || p.y < -1) return false; + Point size = getSize(); + return p.x <= size.x+1 && p.y <= size.y+1; + } + + + public Point computeSize(int wHint, int hHint, bool changed) + { + checkWidget(); + if(wHint is DWT.DEFAULT) wHint = 0; + if(hHint is DWT.DEFAULT) hHint = 0; + return new Point(wHint, hHint); + } + + + public bool setFocus() + { + checkWidget(); + return false; + } + + + public bool isReparentable () + { + checkWidget(); + return false; + } + + + protected abstract void onPaint(Event event, bool pressed); +} diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/ishell/internal/DesktopListener.d --- a/dwtx/novocode/ishell/internal/DesktopListener.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/ishell/internal/DesktopListener.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,33 +1,33 @@ -/******************************************************************************* - * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - *******************************************************************************/ - -module dwtx.novocode.ishell.internal.DesktopListener; - -import dwt.internal.DWTEventListener; -import dwt.widgets.Event; - - -/** - * A listener which receives events when a change occurs on a DesktopForm. - * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Jan 23, 2005 - * @version $Id: DesktopListener.java 320 2005-02-26 13:37:02 +0000 (Sat, 26 Feb 2005) szeiger $ - */ - -interface DesktopListener : DWTEventListener -{ - public void shellCreated(Event event); - - public void shellDisposed(Event event); - - public void shellActivated(Event event); -} +/******************************************************************************* + * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + *******************************************************************************/ + +module dwtx.novocode.ishell.internal.DesktopListener; + +import dwt.internal.DWTEventListener; +import dwt.widgets.Event; + + +/** + * A listener which receives events when a change occurs on a DesktopForm. + * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Jan 23, 2005 + * @version $Id: DesktopListener.java 320 2005-02-26 13:37:02 +0000 (Sat, 26 Feb 2005) szeiger $ + */ + +interface DesktopListener : DWTEventListener +{ + public void shellCreated(Event event); + + public void shellDisposed(Event event); + + public void shellActivated(Event event); +} diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/ishell/internal/TitleBar.d --- a/dwtx/novocode/ishell/internal/TitleBar.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/ishell/internal/TitleBar.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,567 +1,567 @@ -/******************************************************************************* - * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - *******************************************************************************/ - -module dwtx.novocode.ishell.internal.TitleBar; - -import dwt.dwthelper.utils; -import dwt.dwthelper.Runnable; -import dwtx.dwtxhelper.Timer; -import dwtx.dwtxhelper.TimerTask; - -import dwt.DWT; -import dwt.graphics.Color; -import dwt.graphics.Font; -import dwt.graphics.FontData; -import dwt.graphics.GC; -import dwt.graphics.Image; -import dwt.graphics.ImageData; -import dwt.graphics.PaletteData; -import dwt.graphics.Point; -import dwt.graphics.Rectangle; -import dwt.graphics.RGB; -import dwt.widgets.Canvas; -import dwt.widgets.Display; -import dwt.widgets.Event; -import dwt.widgets.Listener; -import dwt.widgets.Menu; -import dwt.widgets.MenuItem; -import dwt.widgets.Shell; - -import dwtx.novocode.ishell.DesktopForm; -import dwtx.novocode.ishell.InternalShell; - -import dwt.dwthelper.utils; - - -/** - * A title bar for an InternalShell. - * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Jan 21, 2005 - * @version $Id: TitleBar.java 342 2005-07-09 20:37:13 +0000 (Sat, 09 Jul 2005) szeiger $ - */ - -class TitleBar : Canvas -{ - private static const long UPDATE_DELAY = 25; - private static const int MINIMUM_GRAB_AREA = 2; - private static const String ELLIPSIS = "..."; - private static const int LEFT_PADDING = 2; - private static const int RIGHT_PADDING = 2; - private static const int IMAGE_SIZE = 16; - private static const int TOOL_SIZE = 14; - private static const int TOP_PADDING = 1; - private static const int BOTTOM_PADDING = 1; - - private int mouseDownOffsetX, mouseDownOffsetY, snapBackX, snapBackY; - private bool cancelled; - private /**volatile*/ long lastUpdate; - private Timer timer; - private TimerTask timerTask; - private InternalShell ishell; - private DesktopForm desktop; - private String text; - private Image image; - private bool styleClose, styleMax, styleTool, styleMin; - private Image closeImage, restoreImage, maximizeImage, minimizeImage; - private MenuItem restoreItem, closeItem, maximizeItem; - private Menu defaultPopup; - private Point minGrabSize; - private Shell shell; - private Color gradStartColor, gradEndColor, textColor, inactiveGradStartColor, inactiveGradEndColor, inactiveTextColor; - private Listener activateListener, deactivateListener; - - - this(InternalShell parent, int style) - { - super(parent, checkStyle(style)); - this.timer = new Timer(true); - this.minGrabSize = new Point(MINIMUM_GRAB_AREA, MINIMUM_GRAB_AREA); - this.ishell = parent; - this.desktop = cast(DesktopForm)ishell.getParent(); - this.styleClose = (style & DWT.CLOSE) !is 0; - this.styleMax = (style & DWT.MAX) !is 0; - this.styleMin = (style & DWT.MIN) !is 0; - this.styleTool = (style & DWT.TOOL) !is 0; - - Display display = getDisplay(); - shell = getShell(); - - gradStartColor = display.getSystemColor(DWT.COLOR_TITLE_BACKGROUND); - gradEndColor = display.getSystemColor(DWT.COLOR_TITLE_BACKGROUND_GRADIENT); - textColor = display.getSystemColor(DWT.COLOR_TITLE_FOREGROUND); - inactiveGradStartColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND); - inactiveGradEndColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT); - inactiveTextColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_FOREGROUND); - - GC gc = new GC(this); - int imgHeight = gc.getFontMetrics().getHeight()-1; - if(imgHeight%2 is 0) imgHeight--; - gc.dispose(); - - closeImage = createMenuImage(IMAGE_TYPE_CLOSE, imgHeight); - restoreImage = createMenuImage(IMAGE_TYPE_RESTORE, imgHeight); - maximizeImage = createMenuImage(IMAGE_TYPE_MAXIMIZE, imgHeight); - minimizeImage = createMenuImage(IMAGE_TYPE_MINIMIZE, imgHeight); - - setFont(createTitleFont(getFont(), styleTool)); - - defaultPopup = new Menu(this); - - restoreItem = new MenuItem(defaultPopup, DWT.PUSH); - restoreItem.setText("&Restore"); - restoreItem.setImage(restoreImage); - restoreItem.addListener(DWT.Selection, dgListener(&restoreListener)); - - MenuItem minimizeItem = new MenuItem(defaultPopup, DWT.PUSH); - minimizeItem.setText("Mi&nimize"); - minimizeItem.setEnabled(styleMin); - minimizeItem.setImage(minimizeImage); - minimizeItem.addListener(DWT.Selection, dgListener(&minimizeListener)); - - maximizeItem = new MenuItem(defaultPopup, DWT.PUSH); - maximizeItem.setText("Ma&ximize"); - maximizeItem.setImage(maximizeImage); - maximizeItem.addListener(DWT.Selection, dgListener(&maximizeListener)); - - new MenuItem(defaultPopup, DWT.SEPARATOR); - - closeItem = new MenuItem(defaultPopup, DWT.PUSH); - closeItem.setText("&Close"); - closeItem.setEnabled(styleClose); - closeItem.setImage(closeImage); - closeItem.addListener(DWT.Selection, dgListener(&closeListener)); - - addListener(DWT.Paint, dgListener(&onPaint)); - addListener(DWT.MouseDown, dgListener(&onMouseDown)); - addListener(DWT.MenuDetect, dgListener(&onMenuDetect)); - addListener(DWT.MouseDoubleClick, dgListener(&onMouseDoubleClick)); - addListener(DWT.MouseMove, dgListener(&onMouseMove)); - addListener(DWT.MouseUp, dgListener(&onMouseUp)); - - activateListener = dgListener(&onActivateListener); - deactivateListener = dgListener(&onDeactivateListener); - shell.addListener(DWT.Activate, activateListener); - shell.addListener(DWT.Deactivate, deactivateListener); - - addListener(DWT.Dispose, dgListener(&onDispose)); - } - - - private void restoreListener(Event event) - { - ishell.setMaximized(false); - } - - - private void minimizeListener(Event event) - { - ishell.setMinimized(true); - } - - - private void maximizeListener(Event event) - { - ishell.setMaximized(true); - } - - - private void closeListener(Event event) - { - ishell.close(); - } - - - private void onPaint(Event event) - { - Rectangle r = getClientArea(); - if(r.width is 0 || r.height is 0) return; - - bool active = (shell is display.getActiveShell() && ishell.isActiveShell()); - - GC gc = event.gc; - gc.setForeground(active ? gradStartColor : inactiveGradStartColor); - gc.setBackground(active ? gradEndColor : inactiveGradEndColor); - gc.fillGradientRectangle(r.x, r.y, r.width, r.height, false); - - int textLeftPadding = LEFT_PADDING; - if(image !is null) - { - Rectangle imageBounds = image.getBounds(); - if(imageBounds.width > IMAGE_SIZE || imageBounds.height > IMAGE_SIZE) - gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, LEFT_PADDING, TOP_PADDING, IMAGE_SIZE, IMAGE_SIZE); - else - gc.drawImage(image, LEFT_PADDING + (IMAGE_SIZE-imageBounds.width)/2, (r.height-imageBounds.height)/2); - textLeftPadding += IMAGE_SIZE + LEFT_PADDING; - } - - if(text !is null && text.length() > 0) - { - gc.setForeground(active ? textColor : inactiveTextColor); - String s = text; - int availableWidth = r.width - textLeftPadding - RIGHT_PADDING; - if(gc.textExtent(s, DWT.DRAW_TRANSPARENT).x > availableWidth) - { - int ellipsisWidth = gc.textExtent(ELLIPSIS, DWT.DRAW_TRANSPARENT).x; - while(s.length() > 0) - { - s = s.substring(0, s.length()-1); - if(gc.textExtent(s, DWT.DRAW_TRANSPARENT).x + ellipsisWidth <= availableWidth) - { - s ~= ELLIPSIS; - break; - } - } - setToolTipText(text); - } - else setToolTipText(null); - if(s.length() > 0) gc.drawString(s, textLeftPadding, (r.height-gc.getFontMetrics().getHeight())/2, true); - } - else setToolTipText(null); - } - - - private void onMouseDown(Event event) - { - if(event.button is 1) - { - if(image !is null && event.x < LEFT_PADDING + IMAGE_SIZE) - { - cancelled = true; - // left-clicking on the image always shows the default popup menu - instrumentDefaultPopup(true); - defaultPopup.setLocation(toDisplay(0, getSize().y)); - defaultPopup.setVisible(true); - } - else - { - mouseDownOffsetX = event.x; - mouseDownOffsetY = event.y; - Point p = ishell.getLocation(); - snapBackX = p.x; - snapBackY = p.y; - cancelled = false; - } - } - else if(event.button is 3) - { - if((event.stateMask & DWT.BUTTON1) !is 0 && snapBackX !is Integer.MIN_VALUE && snapBackY !is Integer.MIN_VALUE) - { - ishell.setLocation(snapBackX, snapBackY); - snapBackX = Integer.MIN_VALUE; - snapBackY = Integer.MIN_VALUE; - cancelled = true; - } - else - { - } - } - } - - - private void onMenuDetect(Event event) - { - event.doit = false; - Menu m = getMenu(); - if(m is null || m.isDisposed()) - { - m = defaultPopup; - instrumentDefaultPopup(false); - } - m.setLocation(event.x, event.y); - m.setVisible(true); - } - - - private void onMouseDoubleClick(Event event) - { - if(event.button is 1) - { - if(image !is null && event.x < LEFT_PADDING + IMAGE_SIZE) - { - if(styleClose) ishell.close(); - } - else - { - if(styleMax) ishell.setMaximized(!ishell.getMaximized()); - } - cancelled = true; - } - } - - - private void onMouseMove(Event event) - { - if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0 && !ishell.getMaximized()) - { - if(timerTask !is null) - { - timerTask.cancel(); - timerTask = null; - } - long now = System.currentTimeMillis(); - if(lastUpdate + UPDATE_DELAY < now) - { - performMove(event); - lastUpdate = now; - } - else - { - timerTask = new class() TimerTask - { - public void run() - { - TimerTask executingTask = this; - event.display.asyncExec(new class() Runnable - { - public void run() - { - if(executingTask !is timerTask) return; - performMove(event); - } - }); - } - }; - timer.schedule(timerTask, UPDATE_DELAY); - } - } - } - - - private void onMouseUp(Event event) - { - if(ishell.getMaximized()) return; - if(image is null || event.x >= LEFT_PADDING + IMAGE_SIZE) - { - if(timerTask !is null) - { - timerTask.cancel(); - timerTask = null; - } - if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0) - { - performMove(event); - } - } - } - - - private void onActivateListener(Event event) - { - redraw(); - } - - - private void onDeactivateListener(Event event) - { - redraw(); - } - - - private void onDispose(Event event) - { - timer.cancel(); - shell.removeListener(DWT.Activate, activateListener); - shell.removeListener(DWT.Deactivate, deactivateListener); - closeImage.dispose(); - maximizeImage.dispose(); - restoreImage.dispose(); - minimizeImage.dispose(); - defaultPopup.dispose(); - } - - - private void performMove(Event event) - { - Point p = ishell.getLocation(); - int newX = p.x + event.x - mouseDownOffsetX; - int newY = p.y + event.y - mouseDownOffsetY; - - // Make sure that the minimum grab area stays visible - Rectangle deskCA = desktop.getClientArea(); - Rectangle bounds = getBounds(); - newX = Math.min(Math.max(newX, deskCA.x-bounds.x-bounds.width+MINIMUM_GRAB_AREA), deskCA.x-bounds.x+deskCA.width-minGrabSize.x); - newY = Math.min(Math.max(newY, deskCA.y-bounds.y-bounds.height+MINIMUM_GRAB_AREA), deskCA.y-bounds.y+deskCA.height-MINIMUM_GRAB_AREA); - - if(newX !is p.x || newY !is p.y) ishell.setLocation(newX, newY); - } - - - public Point getMinGrabSize() - { - return minGrabSize; - } - - - public Point computeSize(int wHint, int hHint, bool changed) - { - checkWidget(); - if(wHint is DWT.DEFAULT) wHint = 50; - if(hHint is DWT.DEFAULT) - { - GC gc = new GC(this); - hHint = gc.getFontMetrics().getHeight(); - hHint = Math.max(hHint, styleTool ? TOOL_SIZE : IMAGE_SIZE); - hHint += TOP_PADDING + BOTTOM_PADDING; - gc.dispose(); - } - return new Point(wHint, hHint); - } - - - private static int checkStyle(int style) - { - //int mask = DWT.SHADOW_IN | DWT.FLAT; - //style &= mask; - style = DWT.NO_FOCUS; - return style; - } - - - public bool setFocus() - { - checkWidget(); - return false; - } - - - public bool isReparentable () - { - checkWidget(); - return false; - } - - - public void setText(String text) - { - checkWidget(); - this.text = text; - redraw(); - } - - - public String getText() { return text; } - - - public void setImage(Image image) - { - checkWidget(); - if(styleTool) return; - this.image = image; - minGrabSize.x = MINIMUM_GRAB_AREA; - if(image !is null) minGrabSize.x += LEFT_PADDING + IMAGE_SIZE; - redraw(); - } - - - public Image getImage() { return image; } - - - private Font createTitleFont(Font f, bool tool) - { - FontData[] fds = f.getFontData(); - foreach(fd; fds) - { - fd.setStyle(fd.getStyle() | DWT.BOLD); - if(tool) fd.setHeight(cast(int)(fd.getHeight()*0.9)); - } - return new Font(getDisplay(), fds); - } - - - private void instrumentDefaultPopup(bool onImage) - { - restoreItem.setEnabled(styleMax && ishell.getMaximized()); - maximizeItem.setEnabled(styleMax && !ishell.getMaximized()); - MenuItem def = null; - if(onImage) - { - if(styleClose) def = closeItem; - } - else if(styleMax) - { - def = ishell.getMaximized() ? restoreItem : maximizeItem; - } - defaultPopup.setDefaultItem(def); - } - - - private static const int IMAGE_TYPE_CLOSE = 1; - private static const int IMAGE_TYPE_MAXIMIZE = 2; - private static const int IMAGE_TYPE_RESTORE = 3; - private static const int IMAGE_TYPE_MINIMIZE = 4; - - - private Image createMenuImage(int type, int height) - { - final Point size = new Point(height, height); - final int imgWidth = height + height/2; - final Color fg = getForeground(); - final Color white = getDisplay().getSystemColor(DWT.COLOR_WHITE); - final RGB blackRGB = new RGB(0,0,0); - - ImageData id = new ImageData(imgWidth, size.y, 1, new PaletteData([ blackRGB, fg.getRGB() ])); - ImageData maskid = new ImageData(imgWidth, size.y, 1, new PaletteData([ blackRGB, white.getRGB() ])); - - Image img = new Image(getDisplay(), id); - GC gc = new GC(img); - gc.setForeground(fg); - drawMenuImage(gc, size, type); - gc.dispose(); - - Image maskimg = new Image(getDisplay(), maskid); - gc = new GC(maskimg); - gc.setForeground(white); - drawMenuImage(gc, size, type); - gc.dispose(); - - Image transp = new Image(getDisplay(), img.getImageData(), maskimg.getImageData()); - img.dispose(); - maskimg.dispose(); - return transp; - } - - - private void drawMenuImage(GC gc, Point size, int type) - { - switch(type) - { - case IMAGE_TYPE_CLOSE: - gc.drawLine(1, 1, size.x-2, size.y-2); - gc.drawLine(2, 1, size.x-2, size.y-3); - gc.drawLine(1, 2, size.x-3, size.y-2); - gc.drawLine(1, size.y-2, size.x-2, 1); - gc.drawLine(1, size.y-3, size.x-3, 1); - gc.drawLine(2, size.y-2, size.x-2, 2); - break; - - case IMAGE_TYPE_RESTORE: - gc.drawRectangle(0, 4, size.x-4, size.y-6); - gc.drawLine(1, 5, size.x-5, 5); - gc.drawLine(2, 1, size.x-2, 1); - gc.drawLine(2, 2, size.x-2, 2); - gc.drawPoint(2, 3); - gc.drawLine(size.x-2, 3, size.x-2, size.y-5); - gc.drawPoint(size.x-3, size.y-5); - break; - - case IMAGE_TYPE_MAXIMIZE: - gc.drawRectangle(0, 0, size.x-2, size.y-2); - gc.drawLine(1, 1, size.x-3, 1); - break; - - case IMAGE_TYPE_MINIMIZE: - gc.drawLine(1, size.y-2, size.x-4, size.y-2); - gc.drawLine(1, size.y-3, size.x-4, size.y-3); - break; - } - } -} +/******************************************************************************* + * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + *******************************************************************************/ + +module dwtx.novocode.ishell.internal.TitleBar; + +import dwt.dwthelper.utils; +import dwt.dwthelper.Runnable; +import dwtx.dwtxhelper.Timer; +import dwtx.dwtxhelper.TimerTask; + +import dwt.DWT; +import dwt.graphics.Color; +import dwt.graphics.Font; +import dwt.graphics.FontData; +import dwt.graphics.GC; +import dwt.graphics.Image; +import dwt.graphics.ImageData; +import dwt.graphics.PaletteData; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.graphics.RGB; +import dwt.widgets.Canvas; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Menu; +import dwt.widgets.MenuItem; +import dwt.widgets.Shell; + +import dwtx.novocode.ishell.DesktopForm; +import dwtx.novocode.ishell.InternalShell; + +import dwt.dwthelper.utils; + + +/** + * A title bar for an InternalShell. + * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Jan 21, 2005 + * @version $Id: TitleBar.java 342 2005-07-09 20:37:13 +0000 (Sat, 09 Jul 2005) szeiger $ + */ + +class TitleBar : Canvas +{ + private static const long UPDATE_DELAY = 25; + private static const int MINIMUM_GRAB_AREA = 2; + private static const String ELLIPSIS = "..."; + private static const int LEFT_PADDING = 2; + private static const int RIGHT_PADDING = 2; + private static const int IMAGE_SIZE = 16; + private static const int TOOL_SIZE = 14; + private static const int TOP_PADDING = 1; + private static const int BOTTOM_PADDING = 1; + + private int mouseDownOffsetX, mouseDownOffsetY, snapBackX, snapBackY; + private bool cancelled; + private /**volatile*/ long lastUpdate; + private Timer timer; + private TimerTask timerTask; + private InternalShell ishell; + private DesktopForm desktop; + private String text; + private Image image; + private bool styleClose, styleMax, styleTool, styleMin; + private Image closeImage, restoreImage, maximizeImage, minimizeImage; + private MenuItem restoreItem, closeItem, maximizeItem; + private Menu defaultPopup; + private Point minGrabSize; + private Shell shell; + private Color gradStartColor, gradEndColor, textColor, inactiveGradStartColor, inactiveGradEndColor, inactiveTextColor; + private Listener activateListener, deactivateListener; + + + this(InternalShell parent, int style) + { + super(parent, checkStyle(style)); + this.timer = new Timer(true); + this.minGrabSize = new Point(MINIMUM_GRAB_AREA, MINIMUM_GRAB_AREA); + this.ishell = parent; + this.desktop = cast(DesktopForm)ishell.getParent(); + this.styleClose = (style & DWT.CLOSE) !is 0; + this.styleMax = (style & DWT.MAX) !is 0; + this.styleMin = (style & DWT.MIN) !is 0; + this.styleTool = (style & DWT.TOOL) !is 0; + + Display display = getDisplay(); + shell = getShell(); + + gradStartColor = display.getSystemColor(DWT.COLOR_TITLE_BACKGROUND); + gradEndColor = display.getSystemColor(DWT.COLOR_TITLE_BACKGROUND_GRADIENT); + textColor = display.getSystemColor(DWT.COLOR_TITLE_FOREGROUND); + inactiveGradStartColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND); + inactiveGradEndColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT); + inactiveTextColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_FOREGROUND); + + GC gc = new GC(this); + int imgHeight = gc.getFontMetrics().getHeight()-1; + if(imgHeight%2 is 0) imgHeight--; + gc.dispose(); + + closeImage = createMenuImage(IMAGE_TYPE_CLOSE, imgHeight); + restoreImage = createMenuImage(IMAGE_TYPE_RESTORE, imgHeight); + maximizeImage = createMenuImage(IMAGE_TYPE_MAXIMIZE, imgHeight); + minimizeImage = createMenuImage(IMAGE_TYPE_MINIMIZE, imgHeight); + + setFont(createTitleFont(getFont(), styleTool)); + + defaultPopup = new Menu(this); + + restoreItem = new MenuItem(defaultPopup, DWT.PUSH); + restoreItem.setText("&Restore"); + restoreItem.setImage(restoreImage); + restoreItem.addListener(DWT.Selection, dgListener(&restoreListener)); + + MenuItem minimizeItem = new MenuItem(defaultPopup, DWT.PUSH); + minimizeItem.setText("Mi&nimize"); + minimizeItem.setEnabled(styleMin); + minimizeItem.setImage(minimizeImage); + minimizeItem.addListener(DWT.Selection, dgListener(&minimizeListener)); + + maximizeItem = new MenuItem(defaultPopup, DWT.PUSH); + maximizeItem.setText("Ma&ximize"); + maximizeItem.setImage(maximizeImage); + maximizeItem.addListener(DWT.Selection, dgListener(&maximizeListener)); + + new MenuItem(defaultPopup, DWT.SEPARATOR); + + closeItem = new MenuItem(defaultPopup, DWT.PUSH); + closeItem.setText("&Close"); + closeItem.setEnabled(styleClose); + closeItem.setImage(closeImage); + closeItem.addListener(DWT.Selection, dgListener(&closeListener)); + + addListener(DWT.Paint, dgListener(&onPaint)); + addListener(DWT.MouseDown, dgListener(&onMouseDown)); + addListener(DWT.MenuDetect, dgListener(&onMenuDetect)); + addListener(DWT.MouseDoubleClick, dgListener(&onMouseDoubleClick)); + addListener(DWT.MouseMove, dgListener(&onMouseMove)); + addListener(DWT.MouseUp, dgListener(&onMouseUp)); + + activateListener = dgListener(&onActivateListener); + deactivateListener = dgListener(&onDeactivateListener); + shell.addListener(DWT.Activate, activateListener); + shell.addListener(DWT.Deactivate, deactivateListener); + + addListener(DWT.Dispose, dgListener(&onDispose)); + } + + + private void restoreListener(Event event) + { + ishell.setMaximized(false); + } + + + private void minimizeListener(Event event) + { + ishell.setMinimized(true); + } + + + private void maximizeListener(Event event) + { + ishell.setMaximized(true); + } + + + private void closeListener(Event event) + { + ishell.close(); + } + + + private void onPaint(Event event) + { + Rectangle r = getClientArea(); + if(r.width is 0 || r.height is 0) return; + + bool active = (shell is display.getActiveShell() && ishell.isActiveShell()); + + GC gc = event.gc; + gc.setForeground(active ? gradStartColor : inactiveGradStartColor); + gc.setBackground(active ? gradEndColor : inactiveGradEndColor); + gc.fillGradientRectangle(r.x, r.y, r.width, r.height, false); + + int textLeftPadding = LEFT_PADDING; + if(image !is null) + { + Rectangle imageBounds = image.getBounds(); + if(imageBounds.width > IMAGE_SIZE || imageBounds.height > IMAGE_SIZE) + gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, LEFT_PADDING, TOP_PADDING, IMAGE_SIZE, IMAGE_SIZE); + else + gc.drawImage(image, LEFT_PADDING + (IMAGE_SIZE-imageBounds.width)/2, (r.height-imageBounds.height)/2); + textLeftPadding += IMAGE_SIZE + LEFT_PADDING; + } + + if(text !is null && text.length() > 0) + { + gc.setForeground(active ? textColor : inactiveTextColor); + String s = text; + int availableWidth = r.width - textLeftPadding - RIGHT_PADDING; + if(gc.textExtent(s, DWT.DRAW_TRANSPARENT).x > availableWidth) + { + int ellipsisWidth = gc.textExtent(ELLIPSIS, DWT.DRAW_TRANSPARENT).x; + while(s.length() > 0) + { + s = s.substring(0, s.length()-1); + if(gc.textExtent(s, DWT.DRAW_TRANSPARENT).x + ellipsisWidth <= availableWidth) + { + s ~= ELLIPSIS; + break; + } + } + setToolTipText(text); + } + else setToolTipText(null); + if(s.length() > 0) gc.drawString(s, textLeftPadding, (r.height-gc.getFontMetrics().getHeight())/2, true); + } + else setToolTipText(null); + } + + + private void onMouseDown(Event event) + { + if(event.button is 1) + { + if(image !is null && event.x < LEFT_PADDING + IMAGE_SIZE) + { + cancelled = true; + // left-clicking on the image always shows the default popup menu + instrumentDefaultPopup(true); + defaultPopup.setLocation(toDisplay(0, getSize().y)); + defaultPopup.setVisible(true); + } + else + { + mouseDownOffsetX = event.x; + mouseDownOffsetY = event.y; + Point p = ishell.getLocation(); + snapBackX = p.x; + snapBackY = p.y; + cancelled = false; + } + } + else if(event.button is 3) + { + if((event.stateMask & DWT.BUTTON1) !is 0 && snapBackX !is Integer.MIN_VALUE && snapBackY !is Integer.MIN_VALUE) + { + ishell.setLocation(snapBackX, snapBackY); + snapBackX = Integer.MIN_VALUE; + snapBackY = Integer.MIN_VALUE; + cancelled = true; + } + else + { + } + } + } + + + private void onMenuDetect(Event event) + { + event.doit = false; + Menu m = getMenu(); + if(m is null || m.isDisposed()) + { + m = defaultPopup; + instrumentDefaultPopup(false); + } + m.setLocation(event.x, event.y); + m.setVisible(true); + } + + + private void onMouseDoubleClick(Event event) + { + if(event.button is 1) + { + if(image !is null && event.x < LEFT_PADDING + IMAGE_SIZE) + { + if(styleClose) ishell.close(); + } + else + { + if(styleMax) ishell.setMaximized(!ishell.getMaximized()); + } + cancelled = true; + } + } + + + private void onMouseMove(Event event) + { + if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0 && !ishell.getMaximized()) + { + if(timerTask !is null) + { + timerTask.cancel(); + timerTask = null; + } + long now = System.currentTimeMillis(); + if(lastUpdate + UPDATE_DELAY < now) + { + performMove(event); + lastUpdate = now; + } + else + { + timerTask = new class() TimerTask + { + public void run() + { + TimerTask executingTask = this; + event.display.asyncExec(new class() Runnable + { + public void run() + { + if(executingTask !is timerTask) return; + performMove(event); + } + }); + } + }; + timer.schedule(timerTask, UPDATE_DELAY); + } + } + } + + + private void onMouseUp(Event event) + { + if(ishell.getMaximized()) return; + if(image is null || event.x >= LEFT_PADDING + IMAGE_SIZE) + { + if(timerTask !is null) + { + timerTask.cancel(); + timerTask = null; + } + if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0) + { + performMove(event); + } + } + } + + + private void onActivateListener(Event event) + { + redraw(); + } + + + private void onDeactivateListener(Event event) + { + redraw(); + } + + + private void onDispose(Event event) + { + timer.cancel(); + shell.removeListener(DWT.Activate, activateListener); + shell.removeListener(DWT.Deactivate, deactivateListener); + closeImage.dispose(); + maximizeImage.dispose(); + restoreImage.dispose(); + minimizeImage.dispose(); + defaultPopup.dispose(); + } + + + private void performMove(Event event) + { + Point p = ishell.getLocation(); + int newX = p.x + event.x - mouseDownOffsetX; + int newY = p.y + event.y - mouseDownOffsetY; + + // Make sure that the minimum grab area stays visible + Rectangle deskCA = desktop.getClientArea(); + Rectangle bounds = getBounds(); + newX = Math.min(Math.max(newX, deskCA.x-bounds.x-bounds.width+MINIMUM_GRAB_AREA), deskCA.x-bounds.x+deskCA.width-minGrabSize.x); + newY = Math.min(Math.max(newY, deskCA.y-bounds.y-bounds.height+MINIMUM_GRAB_AREA), deskCA.y-bounds.y+deskCA.height-MINIMUM_GRAB_AREA); + + if(newX !is p.x || newY !is p.y) ishell.setLocation(newX, newY); + } + + + public Point getMinGrabSize() + { + return minGrabSize; + } + + + public Point computeSize(int wHint, int hHint, bool changed) + { + checkWidget(); + if(wHint is DWT.DEFAULT) wHint = 50; + if(hHint is DWT.DEFAULT) + { + GC gc = new GC(this); + hHint = gc.getFontMetrics().getHeight(); + hHint = Math.max(hHint, styleTool ? TOOL_SIZE : IMAGE_SIZE); + hHint += TOP_PADDING + BOTTOM_PADDING; + gc.dispose(); + } + return new Point(wHint, hHint); + } + + + private static int checkStyle(int style) + { + //int mask = DWT.SHADOW_IN | DWT.FLAT; + //style &= mask; + style = DWT.NO_FOCUS; + return style; + } + + + public bool setFocus() + { + checkWidget(); + return false; + } + + + public bool isReparentable () + { + checkWidget(); + return false; + } + + + public void setText(String text) + { + checkWidget(); + this.text = text; + redraw(); + } + + + public String getText() { return text; } + + + public void setImage(Image image) + { + checkWidget(); + if(styleTool) return; + this.image = image; + minGrabSize.x = MINIMUM_GRAB_AREA; + if(image !is null) minGrabSize.x += LEFT_PADDING + IMAGE_SIZE; + redraw(); + } + + + public Image getImage() { return image; } + + + private Font createTitleFont(Font f, bool tool) + { + FontData[] fds = f.getFontData(); + foreach(fd; fds) + { + fd.setStyle(fd.getStyle() | DWT.BOLD); + if(tool) fd.setHeight(cast(int)(fd.getHeight()*0.9)); + } + return new Font(getDisplay(), fds); + } + + + private void instrumentDefaultPopup(bool onImage) + { + restoreItem.setEnabled(styleMax && ishell.getMaximized()); + maximizeItem.setEnabled(styleMax && !ishell.getMaximized()); + MenuItem def = null; + if(onImage) + { + if(styleClose) def = closeItem; + } + else if(styleMax) + { + def = ishell.getMaximized() ? restoreItem : maximizeItem; + } + defaultPopup.setDefaultItem(def); + } + + + private static const int IMAGE_TYPE_CLOSE = 1; + private static const int IMAGE_TYPE_MAXIMIZE = 2; + private static const int IMAGE_TYPE_RESTORE = 3; + private static const int IMAGE_TYPE_MINIMIZE = 4; + + + private Image createMenuImage(int type, int height) + { + final Point size = new Point(height, height); + final int imgWidth = height + height/2; + final Color fg = getForeground(); + final Color white = getDisplay().getSystemColor(DWT.COLOR_WHITE); + final RGB blackRGB = new RGB(0,0,0); + + ImageData id = new ImageData(imgWidth, size.y, 1, new PaletteData([ blackRGB, fg.getRGB() ])); + ImageData maskid = new ImageData(imgWidth, size.y, 1, new PaletteData([ blackRGB, white.getRGB() ])); + + Image img = new Image(getDisplay(), id); + GC gc = new GC(img); + gc.setForeground(fg); + drawMenuImage(gc, size, type); + gc.dispose(); + + Image maskimg = new Image(getDisplay(), maskid); + gc = new GC(maskimg); + gc.setForeground(white); + drawMenuImage(gc, size, type); + gc.dispose(); + + Image transp = new Image(getDisplay(), img.getImageData(), maskimg.getImageData()); + img.dispose(); + maskimg.dispose(); + return transp; + } + + + private void drawMenuImage(GC gc, Point size, int type) + { + switch(type) + { + case IMAGE_TYPE_CLOSE: + gc.drawLine(1, 1, size.x-2, size.y-2); + gc.drawLine(2, 1, size.x-2, size.y-3); + gc.drawLine(1, 2, size.x-3, size.y-2); + gc.drawLine(1, size.y-2, size.x-2, 1); + gc.drawLine(1, size.y-3, size.x-3, 1); + gc.drawLine(2, size.y-2, size.x-2, 2); + break; + + case IMAGE_TYPE_RESTORE: + gc.drawRectangle(0, 4, size.x-4, size.y-6); + gc.drawLine(1, 5, size.x-5, 5); + gc.drawLine(2, 1, size.x-2, 1); + gc.drawLine(2, 2, size.x-2, 2); + gc.drawPoint(2, 3); + gc.drawLine(size.x-2, 3, size.x-2, size.y-5); + gc.drawPoint(size.x-3, size.y-5); + break; + + case IMAGE_TYPE_MAXIMIZE: + gc.drawRectangle(0, 0, size.x-2, size.y-2); + gc.drawLine(1, 1, size.x-3, 1); + break; + + case IMAGE_TYPE_MINIMIZE: + gc.drawLine(1, size.y-2, size.x-4, size.y-2); + gc.drawLine(1, size.y-3, size.x-4, size.y-3); + break; + } + } +} diff -r 71ca5bcf2307 -r df4e66472aff dwtx/novocode/ishell/internal/TitleBarButton.d --- a/dwtx/novocode/ishell/internal/TitleBarButton.d Sun Oct 26 14:57:25 2008 +0100 +++ b/dwtx/novocode/ishell/internal/TitleBarButton.d Sun Oct 26 15:04:41 2008 +0100 @@ -1,205 +1,205 @@ -/******************************************************************************* - * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html - * - * Contributors: - * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation - *******************************************************************************/ - -module dwtx.novocode.ishell.internal.TitleBarButton; - -import dwt.DWT; -import dwt.graphics.Color; -import dwt.graphics.GC; -import dwt.graphics.Point; -import dwt.widgets.Display; -import dwt.widgets.Event; -import dwt.widgets.Listener; -import dwt.widgets.Shell; - -import dwtx.novocode.ishell.InternalShell; -import dwtx.novocode.ishell.internal.CustomDrawnButton; - - -/** - * A title bar button for an InternalShell. - * - * @author Stefan Zeiger (szeiger@novocode.com) - * @since Jan 30, 2005 - * @version $Id: TitleBarButton.java 322 2005-02-26 20:31:26 +0000 (Sat, 26 Feb 2005) szeiger $ - */ - -class TitleBarButton : CustomDrawnButton -{ - private Color highlightShadowColor, lightShadowColor, normalShadowColor, darkShadowColor; - private Color gradEndColor, inactiveGradEndColor, widgetBackgroundColor, widgetForegroundColor; - private int style; - private Shell shell; - private Display display; - private InternalShell ishell; - private int leftOff, rightOff; - private Listener activateListener, deactivateListener; - - this(InternalShell parent, int style) - { - super(parent, DWT.NO_FOCUS | DWT.NO_BACKGROUND); - this.style = style; - this.shell = getShell(); - this.display = getDisplay(); - this.ishell = parent; - - highlightShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); - lightShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_LIGHT_SHADOW); - normalShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); - darkShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW); - gradEndColor = display.getSystemColor(DWT.COLOR_TITLE_BACKGROUND_GRADIENT); - inactiveGradEndColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT); - widgetBackgroundColor = display.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND); - widgetForegroundColor = display.getSystemColor(DWT.COLOR_WIDGET_FOREGROUND); - - if((style & (DWT.CLOSE | DWT.MAX)) !is 0) rightOff = 2; - else leftOff = 2; - - activateListener = dgListener(&onActivateListener); - deactivateListener = dgListener(&onDeactivateListener); - shell.addListener(DWT.Activate, activateListener); - shell.addListener(DWT.Deactivate, deactivateListener); - - addListener(DWT.Dispose, dgListener(&onDispose)); - } - - - private void onActivateListener(Event event) - { - redraw(); - } - - - private void onDeactivateListener(Event event) - { - redraw(); - } - - - private void onDispose(Event event) - { - shell.removeListener(DWT.Activate, activateListener); - shell.removeListener(DWT.Deactivate, deactivateListener); - } - - - public int getStyle() - { - return style; - } - - - protected void onPaint(Event event, bool pressed) - { - Point size = getSize(); - bool active = (shell is display.getActiveShell() && ishell.isActiveShell()); - GC gc = event.gc; - - gc.setBackground(active ? gradEndColor : inactiveGradEndColor); - gc.fillRectangle(0, 0, size.x, size.y); - gc.setBackground(widgetBackgroundColor); - gc.fillRectangle(2, 4, size.x-4, size.y-6); - - Color tloColor, tliColor, broColor, briColor; - int pOff; - if(pressed) - { - tloColor = darkShadowColor; - tliColor = normalShadowColor; - broColor = highlightShadowColor; - briColor = lightShadowColor; - pOff = 1; - } - else - { - tloColor = highlightShadowColor; - tliColor = lightShadowColor; - broColor = darkShadowColor; - briColor = normalShadowColor; - pOff = 0; - } - - drawBevelRect(gc, leftOff, 2, size.x-1-leftOff-rightOff, size.y-5, tloColor, broColor); - drawBevelRect(gc, 1+leftOff, 3, size.x-3-leftOff-rightOff, size.y-7, tliColor, briColor); - - if(isEnabled()) - { - gc.setForeground(widgetForegroundColor); - drawImage(gc, size, pOff); - } - else - { - gc.setForeground(highlightShadowColor); - drawImage(gc, size, 1); - gc.setForeground(normalShadowColor); - drawImage(gc, size, 0); - } - } - - - private void drawImage(GC gc, Point size, int pOff) - { - if((style & DWT.CLOSE) !is 0) drawCloseImage(gc, size, pOff); - else if((style & DWT.MAX) !is 0) - { - if(ishell.getMaximized()) drawRestoreImage(gc, size, pOff); - else drawMaximizeImage(gc, size, pOff); - } - else if((style & DWT.MIN) !is 0) drawMinimizeImage(gc, size, pOff); - } - - - private static 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); - } - - - private void drawCloseImage(GC gc, Point size, int pOff) - { - gc.drawLine(pOff+leftOff+4, pOff+5, pOff+size.x-leftOff-rightOff-6, pOff+size.y-7); - gc.drawLine(pOff+leftOff+5, pOff+5, pOff+size.x-leftOff-rightOff-5, pOff+size.y-7); - gc.drawLine(pOff+leftOff+4, pOff+size.y-7, pOff+size.x-leftOff-rightOff-6, pOff+5); - gc.drawLine(pOff+leftOff+5, pOff+size.y-7, pOff+size.x-leftOff-rightOff-5, pOff+5); - } - - - private void drawRestoreImage(GC gc, Point size, int pOff) - { - gc.drawRectangle(pOff+leftOff+3, pOff+7, size.x-leftOff-rightOff-11, size.y-13); - gc.drawLine(pOff+leftOff+4, pOff+8, pOff+size.x-leftOff-rightOff-9, pOff+8); - gc.drawLine(pOff+leftOff+6, pOff+5, pOff+size.x-leftOff-rightOff-7, pOff+5); - gc.drawLine(pOff+leftOff+5, pOff+4, pOff+size.x-leftOff-rightOff-6, pOff+4); - gc.drawLine(pOff+size.x-leftOff-rightOff-7, pOff+size.y-9, pOff+size.x-leftOff-rightOff-6, pOff+size.y-9); - gc.drawLine(pOff+size.x-leftOff-rightOff-6, pOff+size.y-10, pOff+size.x-leftOff-rightOff-6, pOff+5); - gc.drawLine(pOff+leftOff+5, pOff+5, pOff+leftOff+5, pOff+6); - } - - - private void drawMaximizeImage(GC gc, Point size, int pOff) - { - gc.drawRectangle(pOff+leftOff+3, pOff+4, size.x-leftOff-rightOff-8, size.y-10); - gc.drawLine(pOff+leftOff+4, pOff+5, pOff+size.x-leftOff-rightOff-6, pOff+5); - } - - - private void drawMinimizeImage(GC gc, Point size, int pOff) - { - gc.drawLine(pOff+leftOff+4, pOff+size.y-6, pOff+size.x-leftOff-rightOff-5, pOff+size.y-6); - gc.drawLine(pOff+leftOff+4, pOff+size.y-7, pOff+size.x-leftOff-rightOff-5, pOff+size.y-7); - } -} +/******************************************************************************* + * Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html + * + * Contributors: + * Stefan Zeiger (szeiger@novocode.com) - initial API and implementation + *******************************************************************************/ + +module dwtx.novocode.ishell.internal.TitleBarButton; + +import dwt.DWT; +import dwt.graphics.Color; +import dwt.graphics.GC; +import dwt.graphics.Point; +import dwt.widgets.Display; +import dwt.widgets.Event; +import dwt.widgets.Listener; +import dwt.widgets.Shell; + +import dwtx.novocode.ishell.InternalShell; +import dwtx.novocode.ishell.internal.CustomDrawnButton; + + +/** + * A title bar button for an InternalShell. + * + * @author Stefan Zeiger (szeiger@novocode.com) + * @since Jan 30, 2005 + * @version $Id: TitleBarButton.java 322 2005-02-26 20:31:26 +0000 (Sat, 26 Feb 2005) szeiger $ + */ + +class TitleBarButton : CustomDrawnButton +{ + private Color highlightShadowColor, lightShadowColor, normalShadowColor, darkShadowColor; + private Color gradEndColor, inactiveGradEndColor, widgetBackgroundColor, widgetForegroundColor; + private int style; + private Shell shell; + private Display display; + private InternalShell ishell; + private int leftOff, rightOff; + private Listener activateListener, deactivateListener; + + this(InternalShell parent, int style) + { + super(parent, DWT.NO_FOCUS | DWT.NO_BACKGROUND); + this.style = style; + this.shell = getShell(); + this.display = getDisplay(); + this.ishell = parent; + + highlightShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); + lightShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_LIGHT_SHADOW); + normalShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW); + darkShadowColor = display.getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW); + gradEndColor = display.getSystemColor(DWT.COLOR_TITLE_BACKGROUND_GRADIENT); + inactiveGradEndColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT); + widgetBackgroundColor = display.getSystemColor(DWT.COLOR_WIDGET_BACKGROUND); + widgetForegroundColor = display.getSystemColor(DWT.COLOR_WIDGET_FOREGROUND); + + if((style & (DWT.CLOSE | DWT.MAX)) !is 0) rightOff = 2; + else leftOff = 2; + + activateListener = dgListener(&onActivateListener); + deactivateListener = dgListener(&onDeactivateListener); + shell.addListener(DWT.Activate, activateListener); + shell.addListener(DWT.Deactivate, deactivateListener); + + addListener(DWT.Dispose, dgListener(&onDispose)); + } + + + private void onActivateListener(Event event) + { + redraw(); + } + + + private void onDeactivateListener(Event event) + { + redraw(); + } + + + private void onDispose(Event event) + { + shell.removeListener(DWT.Activate, activateListener); + shell.removeListener(DWT.Deactivate, deactivateListener); + } + + + public int getStyle() + { + return style; + } + + + protected void onPaint(Event event, bool pressed) + { + Point size = getSize(); + bool active = (shell is display.getActiveShell() && ishell.isActiveShell()); + GC gc = event.gc; + + gc.setBackground(active ? gradEndColor : inactiveGradEndColor); + gc.fillRectangle(0, 0, size.x, size.y); + gc.setBackground(widgetBackgroundColor); + gc.fillRectangle(2, 4, size.x-4, size.y-6); + + Color tloColor, tliColor, broColor, briColor; + int pOff; + if(pressed) + { + tloColor = darkShadowColor; + tliColor = normalShadowColor; + broColor = highlightShadowColor; + briColor = lightShadowColor; + pOff = 1; + } + else + { + tloColor = highlightShadowColor; + tliColor = lightShadowColor; + broColor = darkShadowColor; + briColor = normalShadowColor; + pOff = 0; + } + + drawBevelRect(gc, leftOff, 2, size.x-1-leftOff-rightOff, size.y-5, tloColor, broColor); + drawBevelRect(gc, 1+leftOff, 3, size.x-3-leftOff-rightOff, size.y-7, tliColor, briColor); + + if(isEnabled()) + { + gc.setForeground(widgetForegroundColor); + drawImage(gc, size, pOff); + } + else + { + gc.setForeground(highlightShadowColor); + drawImage(gc, size, 1); + gc.setForeground(normalShadowColor); + drawImage(gc, size, 0); + } + } + + + private void drawImage(GC gc, Point size, int pOff) + { + if((style & DWT.CLOSE) !is 0) drawCloseImage(gc, size, pOff); + else if((style & DWT.MAX) !is 0) + { + if(ishell.getMaximized()) drawRestoreImage(gc, size, pOff); + else drawMaximizeImage(gc, size, pOff); + } + else if((style & DWT.MIN) !is 0) drawMinimizeImage(gc, size, pOff); + } + + + private static 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); + } + + + private void drawCloseImage(GC gc, Point size, int pOff) + { + gc.drawLine(pOff+leftOff+4, pOff+5, pOff+size.x-leftOff-rightOff-6, pOff+size.y-7); + gc.drawLine(pOff+leftOff+5, pOff+5, pOff+size.x-leftOff-rightOff-5, pOff+size.y-7); + gc.drawLine(pOff+leftOff+4, pOff+size.y-7, pOff+size.x-leftOff-rightOff-6, pOff+5); + gc.drawLine(pOff+leftOff+5, pOff+size.y-7, pOff+size.x-leftOff-rightOff-5, pOff+5); + } + + + private void drawRestoreImage(GC gc, Point size, int pOff) + { + gc.drawRectangle(pOff+leftOff+3, pOff+7, size.x-leftOff-rightOff-11, size.y-13); + gc.drawLine(pOff+leftOff+4, pOff+8, pOff+size.x-leftOff-rightOff-9, pOff+8); + gc.drawLine(pOff+leftOff+6, pOff+5, pOff+size.x-leftOff-rightOff-7, pOff+5); + gc.drawLine(pOff+leftOff+5, pOff+4, pOff+size.x-leftOff-rightOff-6, pOff+4); + gc.drawLine(pOff+size.x-leftOff-rightOff-7, pOff+size.y-9, pOff+size.x-leftOff-rightOff-6, pOff+size.y-9); + gc.drawLine(pOff+size.x-leftOff-rightOff-6, pOff+size.y-10, pOff+size.x-leftOff-rightOff-6, pOff+5); + gc.drawLine(pOff+leftOff+5, pOff+5, pOff+leftOff+5, pOff+6); + } + + + private void drawMaximizeImage(GC gc, Point size, int pOff) + { + gc.drawRectangle(pOff+leftOff+3, pOff+4, size.x-leftOff-rightOff-8, size.y-10); + gc.drawLine(pOff+leftOff+4, pOff+5, pOff+size.x-leftOff-rightOff-6, pOff+5); + } + + + private void drawMinimizeImage(GC gc, Point size, int pOff) + { + gc.drawLine(pOff+leftOff+4, pOff+size.y-6, pOff+size.x-leftOff-rightOff-5, pOff+size.y-6); + gc.drawLine(pOff+leftOff+4, pOff+size.y-7, pOff+size.x-leftOff-rightOff-5, pOff+size.y-7); + } +}