/*
* HSBDiscreteColourDecorator.java
*
* Copyright (C) 2006-2014 Andrew Rambaut
*
* 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 figtree.treeviewer.decorators;
import jebl.util.Attributable;
import java.awt.*;
import java.util.Set;
/**
* @author Andrew Rambaut
* @version $Id$
*
* $HeadURL$
*
* $LastChangedBy$
* $LastChangedDate$
* $LastChangedRevision$
*/
public class HSBDiscreteColourDecorator extends DiscreteColourDecorator {
public enum Axis {
HUE,
SATURATION,
BRIGHTNESS;
@Override
public String toString() {
return super.toString().toLowerCase();
}
}
public HSBDiscreteColourDecorator(String attributeName) {
super(attributeName);
}
public HSBDiscreteColourDecorator(String attributeName, String settings) {
super(attributeName);
setup(settings);
}
public HSBDiscreteColourDecorator(String attributeName, Set<? extends Attributable> items) {
super(attributeName, items);
setupColours();
}
/**
* Set up from a settings string
* @param settings
*/
public void setup(String settings) {
if (!settings.startsWith("{") || !settings.endsWith("}")) {
throw new IllegalArgumentException("HSBDiscreteColourDecorator settings string not in correct format");
}
String[] parts = settings.substring(1, settings.length() - 1).split("[, ]+");
if (parts.length != 8) {
throw new IllegalArgumentException("HSBDiscreteColourDecorator settings string not in correct format");
}
try {
primaryAxis = Axis.valueOf(parts[0].toUpperCase());
secondaryCount = Integer.parseInt(parts[1]);
hueLower = Float.parseFloat(parts[2]);
hueUpper = Float.parseFloat(parts[3]);
saturationLower = Float.parseFloat(parts[4]);
saturationUpper = Float.parseFloat(parts[5]);
brightnessLower = Float.parseFloat(parts[6]);
brightnessUpper = Float.parseFloat(parts[7]);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("HSBDiscreteColourDecorator settings string not in correct format");
} catch (IllegalArgumentException iae) {
throw new IllegalArgumentException("HSBDiscreteColourDecorator settings string not in correct format");
}
}
public void setup(int secondaryCount, float hueLower, float hueUpper, float saturationLower, float saturationUpper, float brightnessLower, float brightnessUpper, Axis primaryAxis) {
this.secondaryCount = secondaryCount;
this.hueUpper = hueUpper;
this.hueLower = hueLower;
this.saturationUpper = saturationUpper;
this.saturationLower = saturationLower;
this.brightnessUpper = brightnessUpper;
this.brightnessLower = brightnessLower;
this.primaryAxis = primaryAxis;
setupColours();
}
protected void setupColours() {
if (getValues() == null) {
return;
}
if (secondaryCount == 0) {
return;
}
int valueCount = getValues().size();
int primaryCount = valueCount / secondaryCount;
if (valueCount % secondaryCount > 0) {
primaryCount += secondaryCount - (valueCount % secondaryCount);
}
Color[] paints = new Color[primaryCount * secondaryCount];
float hDelta = (hueUpper - hueLower) / (primaryAxis == Axis.HUE ? primaryCount : secondaryCount);
float bDelta = (brightnessUpper - brightnessLower) / (primaryAxis == Axis.BRIGHTNESS ? primaryCount : secondaryCount);
float sDelta = (saturationUpper - saturationLower) / (primaryAxis == Axis.SATURATION ? primaryCount : secondaryCount);
float hue = hueLower;
float brightness = brightnessUpper;
float saturation = saturationLower;
int k = 0;
for (int i = 0; i < primaryCount; i++) {
switch (primaryAxis) {
case HUE:
saturation = saturationLower;
brightness = brightnessUpper;
break;
case SATURATION:
hue = hueLower;
brightness = brightnessUpper;
break;
case BRIGHTNESS:
hue = hueLower;
saturation = saturationLower;
break;
}
for (int j = 0; j < secondaryCount; j++) {
paints[k] = Color.getHSBColor(hue, saturation, brightness);
switch (primaryAxis) {
case HUE:
saturation += sDelta;
brightness -= bDelta;
break;
case SATURATION:
hue += hDelta;
brightness -= bDelta;
break;
case BRIGHTNESS:
hue += hDelta;
saturation += sDelta;
break;
}
k++;
}
switch (primaryAxis) {
case HUE:
hue += hDelta;
break;
case SATURATION:
saturation += sDelta;
break;
case BRIGHTNESS:
brightness -= bDelta;
break;
}
}
setColourMap(getValues(), paints);
}
public void setSecondaryCount(int secondaryCount) {
this.secondaryCount = secondaryCount;
setupColours();
}
public void setHueUpper(float hueUpper) {
this.hueUpper = hueUpper;
setupColours();
}
public void setHueLower(float hueLower) {
this.hueLower = hueLower;
setupColours();
}
public void setSaturationUpper(float saturationUpper) {
this.saturationUpper = saturationUpper;
setupColours();
}
public void setSaturationLower(float saturationLower) {
this.saturationLower = saturationLower;
setupColours();
}
public void setBrightnessUpper(float brightnessUpper) {
this.brightnessUpper = brightnessUpper;
setupColours();
}
public void setBrightnessLower(float brightnessLower) {
this.brightnessLower = brightnessLower;
setupColours();
}
public void setPrimaryAxis(Axis primaryAxis) {
this.primaryAxis = primaryAxis;
setupColours();
}
public int getSecondaryCount() {
return secondaryCount;
}
public float getHueUpper() {
return hueUpper;
}
public float getHueLower() {
return hueLower;
}
public float getSaturationUpper() {
return saturationUpper;
}
public float getSaturationLower() {
return saturationLower;
}
public float getBrightnessUpper() {
return brightnessUpper;
}
public float getBrightnessLower() {
return brightnessLower;
}
public Axis getPrimaryAxis() {
return primaryAxis;
}
/**
* Create a string representation suitable for writing to a text file
* @return the string
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{");
sb.append(primaryAxis);
sb.append(",");
sb.append(secondaryCount);
sb.append(",");
sb.append(hueLower);
sb.append(",");
sb.append(hueUpper);
sb.append(",");
sb.append(saturationLower);
sb.append(",");
sb.append(saturationUpper);
sb.append(",");
sb.append(brightnessLower);
sb.append(",");
sb.append(brightnessUpper);
sb.append("}");
return sb.toString();
}
private Axis primaryAxis = Axis.HUE;
private int secondaryCount = 1;
private float hueUpper = 1.0F;
private float hueLower = 0.0F;
private float saturationUpper = 0.6F;
private float saturationLower = 0.6F;
private float brightnessUpper = 0.8F;
private float brightnessLower = 0.4F;
}