package rocks.inspectit.ui.rcp.formatter;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
/**
* The class provide different methods for color manipulation.
*
* @author Ivan Senic
*
*/
public final class ColorFormatter {
/**
* Private constructor.
*/
private ColorFormatter() {
}
/**
* Creates the color that is between two supplied color descriptors in linear gradient.
*
* @param rgb1
* {@link RGB} descriptor for first (starting) color.
* @param rgb2
* {@link RGB} descriptor for second (ending) color.
* @param ratio
* Ratio should be number from 0 to 1 (including). The numbers closer to 0 will
* favorite the first (starting) color, while the numbers closer to 1 will favorite
* the second (ending) color.
* @param resourceManager
* {@link ResourceManager} that color will be created with. Note that is
* responsibility of caller to handle the disposal of the resource manager.
* @return {@link Color}
*/
public static Color getLinearGradientColor(RGB rgb1, RGB rgb2, double ratio, ResourceManager resourceManager) {
Assert.isTrue((ratio >= 0) && (ratio <= 1), "Ratio for linear gradient must me between 0 and 1 (including).");
int red = (int) ((rgb2.red * ratio) + (rgb1.red * (1 - ratio)));
int green = (int) ((rgb2.green * ratio) + (rgb1.green * (1 - ratio)));
int blue = (int) ((rgb2.blue * ratio) + (rgb1.blue * (1 - ratio)));
RGB newRgb = new RGB(red, green, blue);
return resourceManager.createColor(newRgb);
}
/**
* Returns the so-called performance color. This color is actually a color between good -
* average - bad color descriptors based on the values supplied. For example, if the actual
* value is close to the good value, good color will be returned. Color is created based on a
* linear gradient between two colors. It is possible that actual value is "better" than good
* value, and in this case always the good color is returned. It is irrelevant if the good value
* is higher or smaller that bad value, but it is important that they are not the same
* (exception will be thrown in that case).
*
* @param goodRgb
* {@link RGB} that defines a color that should be returned if performance is good.
* @param avgRgb
* {@link RGB} that defines a color that should be returned if performance is
* average.
* @param badRgb
* {@link RGB} that defines a color that should be returned if performance is bad.
* @param actualValue
* Actual value.
* @param goodValue
* Good value.
* @param badValue
* Bad value.
* @param resourceManager
* {@link ResourceManager} that color will be created with. Note that is
* responsibility of caller to handle the disposal of the resource manager.
* @return {@link Color}.
*/
public static Color getPerformanceColor(RGB goodRgb, RGB avgRgb, RGB badRgb, double actualValue, double goodValue, double badValue, ResourceManager resourceManager) {
Assert.isTrue(goodValue != badValue);
double avg = (goodValue + badValue) / 2;
if (goodValue > badValue) {
if (actualValue > goodValue) {
return resourceManager.createColor(goodRgb);
} else if (actualValue < badValue) {
return resourceManager.createColor(badRgb);
} else if (actualValue > avg) {
// return combination of green and yellow
double factor = Math.abs((actualValue - avg) / (goodValue - avg));
return getLinearGradientColor(avgRgb, goodRgb, factor, resourceManager);
} else {
// return combination of red and yellow
double factor = Math.abs((actualValue - badValue) / (avg - badValue));
return getLinearGradientColor(badRgb, avgRgb, factor, resourceManager);
}
} else if (goodValue < badValue) {
if (actualValue < goodValue) {
return resourceManager.createColor(goodRgb);
} else if (actualValue > badValue) {
return resourceManager.createColor(badRgb);
} else if (actualValue < avg) {
// return combination of green and yellow
double factor = 1 - Math.abs((actualValue - goodValue) / (avg - goodValue));
return ColorFormatter.getLinearGradientColor(avgRgb, goodRgb, factor, resourceManager);
} else {
// return combination of red and yellow
double factor = 1 - Math.abs((actualValue - avg) / (badValue - avg));
return ColorFormatter.getLinearGradientColor(badRgb, avgRgb, factor, resourceManager);
}
} else {
throw new RuntimeException("Performance color can not be created due to the bad input values.");
}
}
}