Mercurial > projects > dwt-addons
view dwtx/ui/internal/forms/widgets/FormImages.d @ 77:26c6c9dfd13c
ui.forms compile, just FormTextModel with xml reimpl left todo
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 24 May 2008 06:59:31 +0200 |
parents | e193036d82c9 |
children | 7ffeace6c47f |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Port to the D programming language: * Frank Benoit <benoit@tionex.de> *******************************************************************************/ module dwtx.ui.internal.forms.widgets.FormImages; //import dwtx.ui.internal.forms.widgets.FormImages; import dwt.graphics.Color; import dwt.graphics.GC; import dwt.graphics.Image; import dwt.widgets.Display; import dwt.dwthelper.utils; import tango.util.collection.HashMap; public class FormImages { private static FormImages instance; public static FormImages getInstance() { if (instance is null) instance = new FormImages(); return instance; } private HashMap!(Object,Object) images; private HashMap!(Object,Object) ids; private this() { } private abstract class ImageIdentifier { Display fDisplay; Color[] fColors; int fLength; this(Display display, Color[] colors, int length) { fDisplay = display; fColors = colors; fLength = length; } public bool equals(Object obj) { if (null !is cast(ImageIdentifier)obj ) { ImageIdentifier id = cast(ImageIdentifier)obj; if (id.fColors.length is fColors.length) { bool result = id.fDisplay.opEquals(fDisplay) && id.fLength is fLength; for (int i = 0; i < fColors.length && result; i++) { result = result && id.fColors[i].opEquals(fColors[i]); } return result; } } return false; } public override hash_t toHash() { int hash = fDisplay.toHash(); for (int i = 0; i < fColors.length; i++) hash = hash * 7 + fColors[i].toHash(); hash = hash * 7 + fLength; return hash; } } private class SimpleImageIdentifier : ImageIdentifier{ private int fTheight; private int fMarginHeight; this (Display display, Color color1, Color color2, int realtheight, int theight, int marginHeight) { super(display, [color1, color2], realtheight); fTheight = theight; fMarginHeight = marginHeight; } public bool equals(Object obj) { if (null !is cast(SimpleImageIdentifier)obj ) { SimpleImageIdentifier id = cast(SimpleImageIdentifier) obj; if (super.equals(obj) && id.fTheight is fTheight && id.fMarginHeight is fMarginHeight) return true; } return false; } public override hash_t toHash() { int hash = super.toHash(); hash = hash * 7 + (new Integer(fTheight)).toHash(); hash = hash * 7 + (new Integer(fMarginHeight)).toHash(); return hash; } } private class ComplexImageIdentifier : ImageIdentifier { Color fBg; bool fVertical; int[] fPercents; public this(Display display, Color[] colors, int length, int[] percents, bool vertical, Color bg) { super(display, colors, length); fBg = bg; fVertical = vertical; fPercents = percents; } public bool equals(Object obj) { if (null !is cast(ComplexImageIdentifier)obj ) { ComplexImageIdentifier id = cast(ComplexImageIdentifier) obj; if (super.equals(obj) && id.fVertical is fVertical && ArrayEquals(id.fPercents, fPercents)) { if ((id.fBg is null && fBg is null) || (id.fBg !is null && id.fBg.opEquals(fBg))) return true; // if the only thing that isn't the same is the background color // still return true if it does not matter (percents add up to 100) int sum = 0; for (int i = 0; i < fPercents.length; i++) sum += fPercents[i]; if (sum >= 100) return true; } } return false; } public override hash_t toHash() { int hash = super.toHash(); hash = hash * 7 + (new Boolean(fVertical)).toHash(); for (int i = 0; i < fPercents.length; i++) hash = hash * 7 + (new Integer(fPercents[i])).toHash(); return hash; } } private class ImageReference { private Image fImage; private int fCount; public this(Image image) { fImage = image; fCount = 1; } public Image getImage() { return fImage; } // returns a bool indicating if all clients of this image are finished // a true result indicates the underlying image should be disposed public bool decCount() { return --fCount is 0; } public void incCount() { fCount++; } } public Image getGradient(Display display, Color color1, Color color2, int realtheight, int theight, int marginHeight) { checkHashMaps(); ImageIdentifier id = new SimpleImageIdentifier(display, color1, color2, realtheight, theight, marginHeight); ImageReference result = cast(ImageReference) images.get(id); if (result !is null && !result.getImage().isDisposed()) { result.incCount(); return result.getImage(); } Image image = createGradient(display, color1, color2, realtheight, theight, marginHeight); images.add(id, new ImageReference(image)); ids.add(image, id); return image; } public Image getGradient(Display display, Color[] colors, int[] percents, int length, bool vertical, Color bg) { checkHashMaps(); ImageIdentifier id = new ComplexImageIdentifier(display, colors, length, percents, vertical, bg); ImageReference result = cast(ImageReference) images.get(id); if (result !is null && !result.getImage().isDisposed()) { result.incCount(); return result.getImage(); } Image image = createGradient(display, colors, percents, length, vertical, bg); images.add(id, new ImageReference(image)); ids.add(image, id); return image; } public bool markFinished(Image image) { checkHashMaps(); ImageIdentifier id = cast(ImageIdentifier)ids.get(image); if (id !is null) { ImageReference ref_ = cast(ImageReference) images.get(id); if (ref_ !is null) { if (ref_.decCount()) { images.remove(id); ids.remove(ref_.getImage()); ref_.getImage().dispose(); validateHashMaps(); } return true; } } // if the image was not found, dispose of it for the caller image.dispose(); return false; } private void checkHashMaps() { if (images is null) images = new HashMap!(Object,Object); if (ids is null) ids = new HashMap!(Object,Object); } private void validateHashMaps() { if (images.size() is 0) images = null; if (ids.size() is 0) ids = null; } private Image createGradient(Display display, Color color1, Color color2, int realtheight, int theight, int marginHeight) { Image image = new Image(display, 1, realtheight); image.setBackground(color1); GC gc = new GC(image); gc.setBackground(color1); gc.fillRectangle(0, 0, 1, realtheight); gc.setForeground(color2); gc.setBackground(color1); gc.fillGradientRectangle(0, marginHeight + 2, 1, theight - 2, true); gc.dispose(); return image; } private Image createGradient(Display display, Color[] colors, int[] percents, int length, bool vertical, Color bg) { int width = vertical ? 1 : length; int height = vertical ? length : 1; Image gradient = new Image(display, Math.max(width, 1), Math .max(height, 1)); GC gc = new GC(gradient); drawTextGradient(gc, width, height, colors, percents, vertical, bg); gc.dispose(); return gradient; } private void drawTextGradient(GC gc, int width, int height, Color[] colors, int[] percents, bool vertical, Color bg) { final Color oldBackground = gc.getBackground(); if (colors.length is 1) { if (colors[0] !is null) gc.setBackground(colors[0]); gc.fillRectangle(0, 0, width, height); } else { final Color oldForeground = gc.getForeground(); Color lastColor = colors[0]; if (lastColor is null) lastColor = oldBackground; int pos = 0; for (int i = 0; i < percents.length; ++i) { gc.setForeground(lastColor); lastColor = colors[i + 1]; if (lastColor is null) lastColor = oldBackground; gc.setBackground(lastColor); if (vertical) { int gradientHeight = percents[i] * height / 100; gc.fillGradientRectangle(0, pos, width, gradientHeight, true); pos += gradientHeight; } else { int gradientWidth = percents[i] * height / 100; gc.fillGradientRectangle(pos, 0, gradientWidth, height, false); pos += gradientWidth; } } if (vertical && pos < height) { if (bg !is null) gc.setBackground(bg); gc.fillRectangle(0, pos, width, height - pos); } if (!vertical && pos < width) { if (bg !is null) gc.setBackground(bg); gc.fillRectangle(pos, 0, width - pos, height); } gc.setForeground(oldForeground); } } }