--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.utils.ui.color;\r
+\r
+import org.eclipse.swt.graphics.Device;\r
+import org.eclipse.swt.graphics.RGB;\r
+\r
+/**\r
+ * Color class that can use both RGB and HSV values.\r
+ * \r
+ * @author Marko Luukkainen\r
+ *\r
+ */\r
+public class Color implements Comparable<Color>{\r
+\r
+ private int r;\r
+\r
+ private int g;\r
+\r
+ private int b;\r
+\r
+ private float h;\r
+\r
+ private float s;\r
+\r
+ private float v;\r
+\r
+ public Color() {\r
+ r = 255;\r
+ g = 255;\r
+ b = 255;\r
+ updateHSV();\r
+ }\r
+\r
+ public Color(int r, int g, int b) {\r
+ this.r = r;\r
+ this.g = g;\r
+ this.b = b;\r
+ updateHSV();\r
+ }\r
+ \r
+ public Color(float h, float s, float v) {\r
+ this.h = h;\r
+ this.s = s;\r
+ this.v = v;\r
+ updateRGB(); \r
+ }\r
+ \r
+ public Color(double h, double s, double v) {\r
+ this.h = (float)h;\r
+ this.s = (float)s;\r
+ this.v = (float)v;\r
+ updateRGB(); \r
+ }\r
+ \r
+ public Color(RGB rgb) {\r
+ this.r = rgb.red;\r
+ this.g = rgb.green;\r
+ this.b = rgb.blue;\r
+ updateHSV();\r
+ }\r
+ \r
+ public Color(Color color) {\r
+ this.r = color.r;\r
+ this.g = color.g;\r
+ this.b = color.b;\r
+ this.h = color.h;\r
+ this.s = color.s;\r
+ this.v = color.v;\r
+ }\r
+ \r
+ /**\r
+ * Sets color form AWT color. Alpha component is omitted.\r
+ * @param color\r
+ */\r
+ public Color(java.awt.Color color) {\r
+ this.r = color.getRed();\r
+ this.g = color.getGreen();\r
+ this.b = color.getBlue();\r
+ updateHSV();\r
+ }\r
+ \r
+ public Color(org.eclipse.swt.graphics.Color color) {\r
+ this.r = color.getRed();\r
+ this.g = color.getGreen();\r
+ this.b = color.getBlue();\r
+ updateHSV();\r
+ }\r
+\r
+ /**\r
+ * @return Returns the r component of RGB color.\r
+ */\r
+ public int getR() {\r
+ return r;\r
+ }\r
+ \r
+ /**\r
+ * @return Returns the b component of RGB color.\r
+ */\r
+ public int getB() {\r
+ return b;\r
+ }\r
+\r
+ /**\r
+ * @return Returns the g component of RGB color.\r
+ */\r
+ public int getG() {\r
+ return g;\r
+ }\r
+\r
+ /**\r
+ * @return Returns the h component of HSV color .\r
+ */\r
+ public float getH() {\r
+ return h;\r
+ }\r
+\r
+ /**\r
+ * @return Returns the s component of HSV color.\r
+ */\r
+ public float getS() {\r
+ return s;\r
+ }\r
+\r
+ /**\r
+ * @return Returns the v component of HSV color.\r
+ */\r
+ public float getV() {\r
+ return v;\r
+ }\r
+\r
+\r
+ public Color getWhite() {\r
+ return new Color(255, 255, 255);\r
+ }\r
+\r
+ public Color getBlack() {\r
+ return new Color(0, 0, 0);\r
+ }\r
+\r
+ public Color getRed() {\r
+ return new Color(255, 0, 0);\r
+ }\r
+\r
+ public Color getGreen() {\r
+ return new Color(0, 255, 0);\r
+ }\r
+\r
+ public Color getBlue() {\r
+ return new Color(0, 0, 255);\r
+ }\r
+\r
+ /**\r
+ * Returns random color\r
+ * @return random color\r
+ */\r
+ public static Color getRandom() {\r
+ return new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255));\r
+ }\r
+ \r
+ /**\r
+ * Returns random color\r
+ * @param minSaturation minimum satuation of random color\r
+ * @param minValue minimum value of random color\r
+ * @return random color with specified mimimum allowed saturation and value\r
+ */\r
+ public static Color getRandomHSV(float minSaturation, float minValue) {\r
+ float randS = (float)Math.random() * (1.f - minSaturation) + minSaturation;\r
+ float randV = (float)Math.random() * (1.f - minValue) + minValue;\r
+ return new Color((float)Math.random() * 360.f, randS, randV);\r
+ }\r
+ \r
+ /**\r
+ * Returns AWT Color\r
+ * @return\r
+ */\r
+ public java.awt.Color getAWTColor() {\r
+ return new java.awt.Color(r,g,b);\r
+ }\r
+ \r
+ /**\r
+ * Returns SWT Color\r
+ * @param device\r
+ * @return\r
+ */\r
+ public org.eclipse.swt.graphics.Color getSWTColor(Device device) {\r
+ return new org.eclipse.swt.graphics.Color(device,r,g,b);\r
+ }\r
+ \r
+ public RGB getRgb() {\r
+ return new RGB(r,g,b);\r
+ }\r
+\r
+ /**\r
+ * Updates HSV values from RGB values\r
+ * \r
+ */\r
+ private void updateHSV() {\r
+ float tr = (float) r / 255.f;\r
+ float tg = (float) g / 255.f;\r
+ float tb = (float) b / 255.f;\r
+\r
+ v = Math.max(tr, tg);\r
+ v = Math.max(v, tb);\r
+ float min = Math.min(tr, tg);\r
+ min = Math.min(min, tb);\r
+\r
+ float delta = v - min;\r
+\r
+ if (v < 0.01f) {\r
+ s = 0.f;\r
+ } else {\r
+ s = delta / v;\r
+ }\r
+\r
+ if (s == 0.f) {\r
+ h = Float.NaN; // saturation is 0 -> achromatic color\r
+ } else {\r
+ if (tr == v) {\r
+ h = 60.f * (tg - tb);\r
+ } else if (tg == v) {\r
+ h = 120.f + 60.f * (tb - tr);\r
+ } else {\r
+ h = 240.f + 60.f * (tr - tg);\r
+ }\r
+ if (h < 0.f)\r
+ h += 360.f;\r
+ }\r
+\r
+ }\r
+\r
+ private int floatToInt(float v) {\r
+ return (int) (v * 255.f);\r
+ }\r
+\r
+ /**\r
+ * Updates RGB values from HSV values\r
+ * \r
+ */\r
+ private void updateRGB() {\r
+ if (s == 0.f) {\r
+ //if (Float.isNaN(h)) {\r
+ h = Float.NaN;\r
+ r = floatToInt(v);\r
+ g = floatToInt(v);\r
+ b = floatToInt(v);\r
+ //} else {\r
+ // throw new RuntimeException("Saturation is 0 -> Hue must be undefined");\r
+ //}\r
+ } else {\r
+ while (h < 0.f)\r
+ h+= 360.f;\r
+ while (h >= 360.f)\r
+ h-=360.f;\r
+ int hi = (int) Math.floor(h / 60.f);\r
+ float f = h / 60.f - hi;\r
+ float p = v * (1.f - s);\r
+ float q = v * (1.f - (f * s));\r
+ float t = v * (1.f - ((1.f - f) * s));\r
+ switch (hi) {\r
+ case 0:\r
+ r = floatToInt(v);\r
+ g = floatToInt(t);\r
+ b = floatToInt(p);\r
+ break;\r
+ case 1:\r
+ r = floatToInt(q);\r
+ g = floatToInt(v);\r
+ b = floatToInt(p);\r
+ break;\r
+ case 2:\r
+ r = floatToInt(p);\r
+ g = floatToInt(v);\r
+ b = floatToInt(t);\r
+ break;\r
+ case 3:\r
+ r = floatToInt(p);\r
+ g = floatToInt(q);\r
+ b = floatToInt(v);\r
+ break;\r
+ case 4:\r
+ r = floatToInt(t);\r
+ g = floatToInt(p);\r
+ b = floatToInt(v);\r
+ break;\r
+ case 5:\r
+ r = floatToInt(v);\r
+ g = floatToInt(p);\r
+ b = floatToInt(q);\r
+ break;\r
+ }\r
+ }\r
+\r
+ }\r
+ \r
+ @Override\r
+ public int hashCode() {\r
+ return r ^ (g << 8) ^ (b << 16);\r
+ }\r
+ \r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (!(obj instanceof Color))\r
+ return false;\r
+ Color c = (Color) obj;\r
+ return (c.r==r && c.g==g && c.b==b); \r
+ }\r
+ \r
+ // Uses Hue value for comparisons.\r
+ @Override\r
+ public int compareTo(Color arg0) {\r
+ int d = (int)((h - arg0.h)*10000.f);\r
+ if (d == 0) {\r
+ d = r - arg0.r;\r
+ if (d == 0) {\r
+ d = g - arg0.g;\r
+ if (d == 0) {\r
+ d = b - arg0.b;\r
+ }\r
+ }\r
+ }\r
+ return d;\r
+ \r
+ }\r
+ \r
+ void setH(float h) {\r
+ this.h = h;\r
+ }\r
+\r
+}\r