/*
* org.openmicroscopy.shoola.util.ui.colourpicker.RGBModel
*
*------------------------------------------------------------------------------
* Copyright (C) 2006 University of Dundee. All rights reserved.
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*------------------------------------------------------------------------------
*/
package org.openmicroscopy.shoola.util.ui.colourpicker;
//Java imports
import java.awt.Color;
import org.openmicroscopy.shoola.util.ui.UIUtilities;
//Third-party libraries
//Application-internal dependencies
/**
* The model of the RGB slider.
*
* @author Jean-Marie Burel
* <a href="mailto:j.burel@dundee.ac.uk">j.burel@dundee.ac.uk</a>
* @author Donald MacDonald
* <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
* @version 3.0
* <small>
* (<b>Internal version:</b> $Revision: $ $Date: $)
* </small>
* @since OME2.2
*/
class RGBModel
{
/** Original red Component of the model. */
private float originalRed;
/** Original green Component of the model. */
private float originalGreen;
/** Original blue Component of the model. */
private float originalBlue;
/** Original alpha Component of the model. */
private float originalAlpha;
/** Red component of the model, as float between [0..1]. */
private float red;
/** Green component of the model, as float between [0..1]. */
private float green;
/** Blue component of the model, as float between [0..1]. */
private float blue;
/** Alpha component of the model, as float between [0..1]. */
private float alpha;
/**
* Sets the value of the model to v without firing an event.
*
* @param v value.
*/
private void setV(float v)
{
float []vals = RGBtoHSV();
vals[2] = v;
float[] rgb = HSVtoRGB(vals[0], vals[1], vals[2]);
red = rgb[0];
green = rgb[1];
blue = rgb[2];
}
/**
* Sets the hue of the model to h without firing an event.
*
* @param h hue.
*/
private void setH(float h)
{
float []vals = RGBtoHSV();
vals[0] = h;
float[] rgb = HSVtoRGB(vals[0], vals[1], vals[2]);
red = rgb[0];
green = rgb[1];
blue = rgb[2];
}
/**
* Sets the saturation of the model to S without firing an event.
*
* @param s saturation.
*/
private void setS(float s)
{
float[] vals = RGBtoHSV();
vals[1] = s;
float[] rgb = HSVtoRGB(vals[0], vals[1], vals[2]);
red = rgb[0];
green = rgb[1];
blue = rgb[2];
}
/**
* Sets the models initial conditions to the params (r,g,b,a).
*
* @param r red channel.
* @param g green channel.
* @param b blue channel.
* @param a alpha channel.
*/
RGBModel(float r, float g, float b, float a)
{
originalRed = r;
originalGreen = g;
originalBlue = b;
originalAlpha = a;
red = r;
green = g;
blue = b;
alpha = a;
}
/**
* Gets the red channel of the model.
*
* @return See above.
*/
float getRed() { return red; }
/**
* Gets the green channel of the model.
*
* @return See above.
*/
float getGreen() { return green; }
/**
* Gets the blue channel of the model.
*
* @return See above.
*/
float getBlue() { return blue; }
/**
* Gets the alpha channel of the model.
*
* @return See above.
*/
float getAlpha() { return alpha; }
/**
* Gets the hue of the model.
*
* @return See above.
*/
float getHue()
{
float[] vals = RGBtoHSV();
return vals[0];
}
/**
* Gets the saturation of the model.
*
* @return See above.
*/
float getSaturation()
{
float[] vals = RGBtoHSV();
return vals[1];
}
/**
* Gets the vbalue of the model (HSV).
*
* @return See above.
*/
float getValue()
{
float[] vals = RGBtoHSV();
return vals[2];
}
/**
* Sets the value of the model (HSV) to v.
*
* @param v value.
*/
void setValue(float v) { setV(v); }
/**
* Sets the hue of the model to h.
*
* @param h hue.
*/
void setHue(float h) { setH(h); }
/**
* Sets the saturation of the model to s.
*
* @param s saturation.
*/
void setSaturation(float s) { setS(s); }
/**
* Sets the red channel of the model to r.
*
* @param r red.
*/
void setRed(float r) { red = r; }
/**
* Sets the green channel of the model to g.
*
* @param g green.
*/
void setGreen(float g) { green = g; }
/**
* Sets the blue channel of the model to b.
*
* @param b blue.
*/
void setBlue(float b) { blue = b; }
/**
* Sets the alpha of the model to a.
*
* @param a alpha.
*/
void setAlpha(float a) { alpha = a; }
/**
* Sets the colour to the new Color c.
*
* @param c new Colour.
*/
void setColour(Color c)
{
red = (c.getRed()/255.0f);
green = (c.getGreen()/255.0f);
blue = (c.getBlue()/255.0f);
}
/**
* Sets the colour of the model based on the rgb values r, b, g and alpha
* (a).
*
* @param r red.
* @param g green.
* @param b blue.
* @param a alpha.
*/
void setRGBColour(float r, float g, float b, float a)
{
red = r;
green = g;
blue = b;
alpha = a;
}
/**
* Sets the colour of the model based on the hsv values h, s, v and alpha a.
*
* @param h hue.
* @param s saturation.
* @param v value.
* @param a alpha.
*/
void setHSVColour(float h, float s, float v, float a)
{
float[] rgb = HSVtoRGB(h,s,v);
red = rgb[0];
green = rgb[1];
blue = rgb[2];
alpha = a;
}
/**
* Returns the Colour representing by the model.
*
* @return Color from model.
*/
Color getColour() { return new Color(red, green, blue, alpha); }
/**
* Converts current RGB model components to HSV and returns it as an array.
*
* @return hsv conversion of the red, green and blue components to hsv.
*/
float [] RGBtoHSV()
{
float hsv[] = new float[3];
float min, max, delta;
float h, s, v;
min = findMin(red, green, blue);
max = findMax(red, green, blue);
v = max;
delta = max-min;
if (max != 0.0f) s = delta/max;
else
{
v = 0.0f;
s = 0.0f;
h = 0.0f;
}
h = 0;
if (Math.abs(red-max) < UIUtilities.EPSILON)
h = (green-blue)/delta;
else if (Math.abs(green-max) < UIUtilities.EPSILON)
h = 2.0f + (blue-red)/delta;
else if (Math.abs(blue-max) < UIUtilities.EPSILON)
h = 4.0f+(red-green)/delta;
h = h * 60.0f;
if (h < 0) h += 360.0f;
h = h/360.0f;
hsv[0] = h;
hsv[1] = s;
hsv[2] = v;
return hsv;
}
/**
* Finds the minimum value of a, b or c. Used to calculate Value and
* Saturation.
*
* @param a One of the values to analyze.
* @param b One of the values to analyze.
* @param c One of the values to analyze.
* @return greatest of(a,b,c)
*/
float findMin(float a, float b, float c)
{
if (a <= b && a <= c) return a;
else if (b <= a && b <= c) return b;
else if (c <= a && c <= b) return c;
return c;
}
/**
* Finds the maximum value of a,b or c. Used to calculate Value and
* Saturation.
*
* @param a One of the values to analyze.
* @param b One of the values to analyze.
* @param c One of the values to analyze.
* @return smallest of(a,b,c)
*/
float findMax(float a, float b, float c)
{
if (a >= b && a >= c) return a;
if (b > a && b > c) return b;
return c;
}
/**
* Converts 3 float parameters (h, s, v) to 3 float
* RGB values which it returns.
*
* @param h hue, value in [0..1]..
* @param s saturation, value in [0..1].
* @param v value, value in [0..1].
* @return array of floats representing RGB.
*/
float [] HSVtoRGB(float h, float s, float v)
{
int i;
float f, p, q, t;
float rgb [] = new float[3];
float r,g,b;
if (s == 0)
{
r = g = b = v;
rgb[0] = r;
rgb[1] = g;
rgb[2] = b;
return rgb;
}
h *= 6;
i = (int) Math.floor(h);
f = h-i;
p = v*(1-s);
q = v*(1-s*f);
t = v*(1-s*(1-f));
switch (i) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default:
r = v;
g = p;
b = q;
break;
}
rgb[0] = r;
rgb[1] = g;
rgb[2] = b;
return rgb;
}
/**
* Returns the original color.
*
* @return See above.
*/
Color getOriginalColor()
{
return new Color(originalRed, originalGreen, originalBlue,
originalAlpha);
}
/** Allows the user to revert to their original colour selection. */
void revert()
{
red = originalRed;
green = originalGreen;
blue = originalBlue;
alpha = originalAlpha;
}
/**
* Returns <code>true</code> if the passed color is the orginal color,
* <code>false</code>.
*
* @param color The color to test.
* @return See above.
*/
boolean isOriginalColor(Color color)
{
if (color == null) return false;
Color c = getOriginalColor();
return (c.getRed() == color.getRed() && c.getGreen() == color.getGreen()
&& c.getBlue() == color.getBlue() &&
c.getAlpha() == color.getAlpha());
}
}