X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Fcolor%2FColorGradient.java;fp=bundles%2Forg.simantics.utils.ui%2Fsrc%2Forg%2Fsimantics%2Futils%2Fui%2Fcolor%2FColorGradient.java;h=619cb17e89e330a5cde9b483650d4e5036a0f7fb;hp=5fc3d747c26790cbd3795676312eeb39c4126322;hb=0ae2b770234dfc3cbb18bd38f324125cf0faca07;hpb=24e2b34260f219f0d1644ca7a138894980e25b14 diff --git a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradient.java b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradient.java index 5fc3d747c..619cb17e8 100644 --- a/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradient.java +++ b/bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/color/ColorGradient.java @@ -1,310 +1,310 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management - * in Industry THTH ry. - * 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: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.utils.ui.color; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.GC; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.widgets.Display; - -/** - * - *

- * Color gradient between multiple colors - *

- *

- * Supports RGB and HSV linear interpolation between colors - *

- * - * @author Marko Luukkainen - * - */ -public class ColorGradient { - public static final int RGB = 0; - - public static final int HSV = 1; - - protected ArrayList values; - - protected int type; - - public ColorGradient() { - this.values = new ArrayList(); - this.type = RGB; - } - - public ColorGradient(ColorGradient copyFrom) { - this.values = new ArrayList(copyFrom.values); - this.type = copyFrom.type; - } - - public ColorGradient(Collection values) { - this.values = new ArrayList(values); - Collections.sort(this.values, new ColorValueComparator()); - this.type = RGB; - } - - public ColorGradient(ColorValue array[]) { - this.values = new ArrayList(array.length); - for (ColorValue c : array) { - values.add(c); - } - Collections.sort(this.values, new ColorValueComparator()); - this.type = RGB; - } - - public ColorGradient(Collection values, int type) { - this.values = new ArrayList(values); - Collections.sort(this.values, new ColorValueComparator()); - this.type = type; - } - - public ColorGradient(ColorValue array[], int type) { - this.values = new ArrayList(); - for (ColorValue c : array) { - values.add(c); - } - Collections.sort(this.values, new ColorValueComparator()); - this.type = type; - } - - /** - * Interpolates color in RGB space - * - * @param value - * @return - */ - private byte[] getRGBColor(double value) { - int index = 1; - while (values.get(index).getValue() <= value && index < values.size()-1) - index++; - - value -= values.get(index - 1).getValue(); - value /= (values.get(index).getValue() - values.get(index - 1).getValue()); - double valuei = 1.0 - value; - byte color[] = new byte[] { - (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getR() + valuei * values.get(index - 1).getColor().getR())), - (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getG() + valuei * values.get(index - 1).getColor().getG())), - (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getB() + valuei * values.get(index - 1).getColor().getB())) }; - return color; - - } - - /** - * Interpolates color in HSV space - * - * @param value - * @return - */ - private byte[] getHSVColor(double value) { - int index = 1; - while (values.get(index).getValue() <= value && index < values.size()-1) - index++; - - value -= values.get(index - 1).getValue(); - value /= (values.get(index).getValue() - values.get(index - 1).getValue()); - double valuei = 1.0 - value; - double h; - if (Float.isNaN(values.get(index).getColor().getH())) { - h = values.get(index-1).getColor().getH(); - } else if (Float.isNaN(values.get(index-1).getColor().getH())) { - h = values.get(index).getColor().getH(); - } else { - // selecting shortest direction between hues - float angle = values.get(index).getColor().getH() - values.get(index - 1).getColor().getH(); - if (angle > 180.f) - angle -= 360.f; - else if (angle < -180.f) - angle += 360.f; - h = values.get(index - 1).getColor().getH() + value * angle; - if (h > 360.f) - h -= 360.f; - else if (h < 0.f) - h+= 360.f; - } - org.simantics.utils.ui.color.Color interpolated = new org.simantics.utils.ui.color.Color(h, value * values.get(index).getColor().getS() + valuei * values.get(index - 1).getColor().getS(), - value * values.get(index).getColor().getV() + valuei * values.get(index - 1).getColor().getV()); - byte color[] = new byte[] { (byte) interpolated.getR(), (byte) interpolated.getG(), (byte) interpolated.getB() }; - - return color; - - } - - /** - *

- * Returns gradient in array of bytes. Array is RGB order and int contains 3 * requested size of bytes. - *

- *

- * If gradient contains only one color array is filled with that color - *

- *

- * if gradient has no colors array is filled with white - *

- * @param size number of pixels - * @return gradient in array of bytes - */ - public byte[] getGradientArray(int size) { - byte array[] = new byte[size * 3]; - if (values.size() > 1) { - for (int i = 0; i < size; i++) { - int index = i * 3; - double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) i / (double) size; - byte color[]; - if (type == RGB) - color = getRGBColor(value); - else - color = getHSVColor(value); - array[index] = color[0]; - array[index + 1] = color[1]; - array[index + 2] = color[2]; - } - } else if (values.size() == 1) { - byte color[] = new byte[3]; - color[0] = (byte)values.get(0).getColor().getR(); - color[1] = (byte)values.get(0).getColor().getG(); - color[2] = (byte)values.get(0).getColor().getB(); - for (int i = 0; i < size; i++) { - int index = i * 3; - array[index] = color[0]; - array[index + 1] = color[1]; - array[index + 2] = color[2]; - } - } else { - for (int i = 0; i < size; i++) { - int index = i * 3; - array[index] = (byte)255; - array[index + 1] = (byte)255; - array[index + 2] = (byte)255; - } - } - return array; - } - - /** - *

- * Returns gradient in image. - *

- *

- * If gradient contains only one color image is filled with that color - *

- *

- * if gradient has no colors image is filled with white - *

- *

- * Style must be set to SWT.HORIZONTAL or SWT.VERTICAL - *

- * @param size number of pixels - * @return gradient in array of bytes - */ - - public Image getGradientImage(int width, int height, int style) { - Image image = new Image(Display.getCurrent(), width, height); - GC gc = new GC(image); - gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); - gc.fillRectangle(0, 0, width, height); - if (values.size() > 1) { - if (SWT.HORIZONTAL == (style | SWT.HORIZONTAL)) { - for (int x = 0; x < width; x++) { - double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) x - / (double) (width - 1); - byte byteColor[]; - if (type == RGB) - byteColor = getRGBColor(value); - else - byteColor = getHSVColor(value); - Color color = new Color(Display.getCurrent(), byteColor[0] & 0xff, byteColor[1] & 0xff, byteColor[2] & 0xff); - gc.setForeground(color); - gc.drawLine(x, 0, x, height); - color.dispose(); - } - } else if (SWT.VERTICAL == (style | SWT.VERTICAL)){ - for (int y = 0; y < height; y++) { - double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) y - / (double) (height - 1); - byte byteColor[]; - if (type == RGB) - byteColor = getRGBColor(value); - else - byteColor = getHSVColor(value); - Color color = new Color(Display.getCurrent(), byteColor[0] & 0xff, byteColor[1] & 0xff, byteColor[2] & 0xff); - gc.setForeground(color); - gc.drawLine(0, y, width, y); - color.dispose(); - } - } else { - gc.dispose(); - image.dispose(); - SWT.error(SWT.ERROR_INVALID_ARGUMENT); - } - } else if (values.size() == 1) { - Color color = new Color(Display.getCurrent(), values.get(0).getColor().getR(), values.get(0).getColor().getG(), values.get(0).getColor().getB()); - gc.setBackground(color); - gc.fillRectangle(0, 0, width, height); - color.dispose(); - } else { - gc.fillRectangle(0, 0, width, height); - } - gc.dispose(); - return image; - } - - public int getType() { - return type; - } - - public List getColorValues() { - return values; - } - - public ColorValue[] getColorValueArray() { - return values.toArray(new ColorValue[values.size()]); - } - - @Deprecated - public void addCastorColorValue(ColorValue value) { - values.add(value); - Collections.sort(this.values, new ColorValueComparator()); - } - - @Deprecated - public void setCastorType(int type) { - this.type = type; - } - - @Override - public int hashCode() { - int hash = 0x58fb3; - for (ColorValue cv : values) - hash ^= cv.hashCode(); - return hash; - } - - @Override - public boolean equals(Object obj) { - if (obj == null) - return false; - if (obj.getClass() != getClass()) - return false; - ColorGradient cg = (ColorGradient) obj; - if (cg.type != type) return false; - if (values.size()!=cg.values.size()) return false; - if (!values.containsAll(cg.values)) return false; - return true; - } - -} +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * 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: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.utils.ui.color; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Display; + +/** + * + *

+ * Color gradient between multiple colors + *

+ *

+ * Supports RGB and HSV linear interpolation between colors + *

+ * + * @author Marko Luukkainen + * + */ +public class ColorGradient { + public static final int RGB = 0; + + public static final int HSV = 1; + + protected ArrayList values; + + protected int type; + + public ColorGradient() { + this.values = new ArrayList(); + this.type = RGB; + } + + public ColorGradient(ColorGradient copyFrom) { + this.values = new ArrayList(copyFrom.values); + this.type = copyFrom.type; + } + + public ColorGradient(Collection values) { + this.values = new ArrayList(values); + Collections.sort(this.values, new ColorValueComparator()); + this.type = RGB; + } + + public ColorGradient(ColorValue array[]) { + this.values = new ArrayList(array.length); + for (ColorValue c : array) { + values.add(c); + } + Collections.sort(this.values, new ColorValueComparator()); + this.type = RGB; + } + + public ColorGradient(Collection values, int type) { + this.values = new ArrayList(values); + Collections.sort(this.values, new ColorValueComparator()); + this.type = type; + } + + public ColorGradient(ColorValue array[], int type) { + this.values = new ArrayList(); + for (ColorValue c : array) { + values.add(c); + } + Collections.sort(this.values, new ColorValueComparator()); + this.type = type; + } + + /** + * Interpolates color in RGB space + * + * @param value + * @return + */ + private byte[] getRGBColor(double value) { + int index = 1; + while (values.get(index).getValue() <= value && index < values.size()-1) + index++; + + value -= values.get(index - 1).getValue(); + value /= (values.get(index).getValue() - values.get(index - 1).getValue()); + double valuei = 1.0 - value; + byte color[] = new byte[] { + (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getR() + valuei * values.get(index - 1).getColor().getR())), + (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getG() + valuei * values.get(index - 1).getColor().getG())), + (byte) Math.min(255.0, Math.floor(value * values.get(index).getColor().getB() + valuei * values.get(index - 1).getColor().getB())) }; + return color; + + } + + /** + * Interpolates color in HSV space + * + * @param value + * @return + */ + private byte[] getHSVColor(double value) { + int index = 1; + while (values.get(index).getValue() <= value && index < values.size()-1) + index++; + + value -= values.get(index - 1).getValue(); + value /= (values.get(index).getValue() - values.get(index - 1).getValue()); + double valuei = 1.0 - value; + double h; + if (Float.isNaN(values.get(index).getColor().getH())) { + h = values.get(index-1).getColor().getH(); + } else if (Float.isNaN(values.get(index-1).getColor().getH())) { + h = values.get(index).getColor().getH(); + } else { + // selecting shortest direction between hues + float angle = values.get(index).getColor().getH() - values.get(index - 1).getColor().getH(); + if (angle > 180.f) + angle -= 360.f; + else if (angle < -180.f) + angle += 360.f; + h = values.get(index - 1).getColor().getH() + value * angle; + if (h > 360.f) + h -= 360.f; + else if (h < 0.f) + h+= 360.f; + } + org.simantics.utils.ui.color.Color interpolated = new org.simantics.utils.ui.color.Color(h, value * values.get(index).getColor().getS() + valuei * values.get(index - 1).getColor().getS(), + value * values.get(index).getColor().getV() + valuei * values.get(index - 1).getColor().getV()); + byte color[] = new byte[] { (byte) interpolated.getR(), (byte) interpolated.getG(), (byte) interpolated.getB() }; + + return color; + + } + + /** + *

+ * Returns gradient in array of bytes. Array is RGB order and int contains 3 * requested size of bytes. + *

+ *

+ * If gradient contains only one color array is filled with that color + *

+ *

+ * if gradient has no colors array is filled with white + *

+ * @param size number of pixels + * @return gradient in array of bytes + */ + public byte[] getGradientArray(int size) { + byte array[] = new byte[size * 3]; + if (values.size() > 1) { + for (int i = 0; i < size; i++) { + int index = i * 3; + double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) i / (double) size; + byte color[]; + if (type == RGB) + color = getRGBColor(value); + else + color = getHSVColor(value); + array[index] = color[0]; + array[index + 1] = color[1]; + array[index + 2] = color[2]; + } + } else if (values.size() == 1) { + byte color[] = new byte[3]; + color[0] = (byte)values.get(0).getColor().getR(); + color[1] = (byte)values.get(0).getColor().getG(); + color[2] = (byte)values.get(0).getColor().getB(); + for (int i = 0; i < size; i++) { + int index = i * 3; + array[index] = color[0]; + array[index + 1] = color[1]; + array[index + 2] = color[2]; + } + } else { + for (int i = 0; i < size; i++) { + int index = i * 3; + array[index] = (byte)255; + array[index + 1] = (byte)255; + array[index + 2] = (byte)255; + } + } + return array; + } + + /** + *

+ * Returns gradient in image. + *

+ *

+ * If gradient contains only one color image is filled with that color + *

+ *

+ * if gradient has no colors image is filled with white + *

+ *

+ * Style must be set to SWT.HORIZONTAL or SWT.VERTICAL + *

+ * @param size number of pixels + * @return gradient in array of bytes + */ + + public Image getGradientImage(int width, int height, int style) { + Image image = new Image(Display.getCurrent(), width, height); + GC gc = new GC(image); + gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE)); + gc.fillRectangle(0, 0, width, height); + if (values.size() > 1) { + if (SWT.HORIZONTAL == (style | SWT.HORIZONTAL)) { + for (int x = 0; x < width; x++) { + double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) x + / (double) (width - 1); + byte byteColor[]; + if (type == RGB) + byteColor = getRGBColor(value); + else + byteColor = getHSVColor(value); + Color color = new Color(Display.getCurrent(), byteColor[0] & 0xff, byteColor[1] & 0xff, byteColor[2] & 0xff); + gc.setForeground(color); + gc.drawLine(x, 0, x, height); + color.dispose(); + } + } else if (SWT.VERTICAL == (style | SWT.VERTICAL)){ + for (int y = 0; y < height; y++) { + double value = values.get(0).getValue() + (values.get(values.size() - 1).getValue() - values.get(0).getValue()) * (double) y + / (double) (height - 1); + byte byteColor[]; + if (type == RGB) + byteColor = getRGBColor(value); + else + byteColor = getHSVColor(value); + Color color = new Color(Display.getCurrent(), byteColor[0] & 0xff, byteColor[1] & 0xff, byteColor[2] & 0xff); + gc.setForeground(color); + gc.drawLine(0, y, width, y); + color.dispose(); + } + } else { + gc.dispose(); + image.dispose(); + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + } + } else if (values.size() == 1) { + Color color = new Color(Display.getCurrent(), values.get(0).getColor().getR(), values.get(0).getColor().getG(), values.get(0).getColor().getB()); + gc.setBackground(color); + gc.fillRectangle(0, 0, width, height); + color.dispose(); + } else { + gc.fillRectangle(0, 0, width, height); + } + gc.dispose(); + return image; + } + + public int getType() { + return type; + } + + public List getColorValues() { + return values; + } + + public ColorValue[] getColorValueArray() { + return values.toArray(new ColorValue[values.size()]); + } + + @Deprecated + public void addCastorColorValue(ColorValue value) { + values.add(value); + Collections.sort(this.values, new ColorValueComparator()); + } + + @Deprecated + public void setCastorType(int type) { + this.type = type; + } + + @Override + public int hashCode() { + int hash = 0x58fb3; + for (ColorValue cv : values) + hash ^= cv.hashCode(); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) + return false; + if (obj.getClass() != getClass()) + return false; + ColorGradient cg = (ColorGradient) obj; + if (cg.type != type) return false; + if (values.size()!=cg.values.size()) return false; + if (!values.containsAll(cg.values)) return false; + return true; + } + +}