/******************************************************************************* * 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 org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.RGB; /** * Color class that can use both RGB and HSV values. * * @author Marko Luukkainen * */ public class Color implements Comparable{ private int r; private int g; private int b; private float h; private float s; private float v; public Color() { r = 255; g = 255; b = 255; updateHSV(); } public Color(int r, int g, int b) { this.r = r; this.g = g; this.b = b; updateHSV(); } public Color(float h, float s, float v) { this.h = h; this.s = s; this.v = v; updateRGB(); } public Color(double h, double s, double v) { this.h = (float)h; this.s = (float)s; this.v = (float)v; updateRGB(); } public Color(RGB rgb) { this.r = rgb.red; this.g = rgb.green; this.b = rgb.blue; updateHSV(); } public Color(Color color) { this.r = color.r; this.g = color.g; this.b = color.b; this.h = color.h; this.s = color.s; this.v = color.v; } /** * Sets color form AWT color. Alpha component is omitted. * @param color */ public Color(java.awt.Color color) { this.r = color.getRed(); this.g = color.getGreen(); this.b = color.getBlue(); updateHSV(); } public Color(org.eclipse.swt.graphics.Color color) { this.r = color.getRed(); this.g = color.getGreen(); this.b = color.getBlue(); updateHSV(); } /** * @return Returns the r component of RGB color. */ public int getR() { return r; } /** * @return Returns the b component of RGB color. */ public int getB() { return b; } /** * @return Returns the g component of RGB color. */ public int getG() { return g; } /** * @return Returns the h component of HSV color . */ public float getH() { return h; } /** * @return Returns the s component of HSV color. */ public float getS() { return s; } /** * @return Returns the v component of HSV color. */ public float getV() { return v; } public Color getWhite() { return new Color(255, 255, 255); } public Color getBlack() { return new Color(0, 0, 0); } public Color getRed() { return new Color(255, 0, 0); } public Color getGreen() { return new Color(0, 255, 0); } public Color getBlue() { return new Color(0, 0, 255); } /** * Returns random color * @return random color */ public static Color getRandom() { return new Color((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255)); } /** * Returns random color * @param minSaturation minimum satuation of random color * @param minValue minimum value of random color * @return random color with specified mimimum allowed saturation and value */ public static Color getRandomHSV(float minSaturation, float minValue) { float randS = (float)Math.random() * (1.f - minSaturation) + minSaturation; float randV = (float)Math.random() * (1.f - minValue) + minValue; return new Color((float)Math.random() * 360.f, randS, randV); } /** * Returns AWT Color * @return */ public java.awt.Color getAWTColor() { return new java.awt.Color(r,g,b); } /** * Returns SWT Color * @param device * @return */ public org.eclipse.swt.graphics.Color getSWTColor(Device device) { return new org.eclipse.swt.graphics.Color(device,r,g,b); } public RGB getRgb() { return new RGB(r,g,b); } /** * Updates HSV values from RGB values * */ private void updateHSV() { float tr = (float) r / 255.f; float tg = (float) g / 255.f; float tb = (float) b / 255.f; v = Math.max(tr, tg); v = Math.max(v, tb); float min = Math.min(tr, tg); min = Math.min(min, tb); float delta = v - min; if (v < 0.01f) { s = 0.f; } else { s = delta / v; } if (s == 0.f) { //h = Float.NaN; // saturation is 0 -> achromatic color h = 0.f; } else { if (tr == v) { h = 60.f * (tg - tb); } else if (tg == v) { h = 120.f + 60.f * (tb - tr); } else { h = 240.f + 60.f * (tr - tg); } if (h < 0.f) h += 360.f; } } private int floatToInt(float v) { return (int) (v * 255.f); } /** * Updates RGB values from HSV values * */ private void updateRGB() { if (s == 0.f) { r = floatToInt(v); g = floatToInt(v); b = floatToInt(v); } else { while (h < 0.f) h+= 360.f; while (h >= 360.f) h-=360.f; int hi = (int) Math.floor(h / 60.f); float f = h / 60.f - hi; float p = v * (1.f - s); float q = v * (1.f - (f * s)); float t = v * (1.f - ((1.f - f) * s)); switch (hi) { case 0: r = floatToInt(v); g = floatToInt(t); b = floatToInt(p); break; case 1: r = floatToInt(q); g = floatToInt(v); b = floatToInt(p); break; case 2: r = floatToInt(p); g = floatToInt(v); b = floatToInt(t); break; case 3: r = floatToInt(p); g = floatToInt(q); b = floatToInt(v); break; case 4: r = floatToInt(t); g = floatToInt(p); b = floatToInt(v); break; case 5: r = floatToInt(v); g = floatToInt(p); b = floatToInt(q); break; } } } @Override public int hashCode() { return r ^ (g << 8) ^ (b << 16); } @Override public boolean equals(Object obj) { if (!(obj instanceof Color)) return false; Color c = (Color) obj; return (c.r==r && c.g==g && c.b==b); } // Uses Hue value for comparisons. @Override public int compareTo(Color arg0) { int d = (int)((h - arg0.h)*10000.f); if (d == 0) { d = r - arg0.r; if (d == 0) { d = g - arg0.g; if (d == 0) { d = b - arg0.b; } } } return d; } void setH(float h) { this.h = h; } }