package com.vitco.layout.content.colorchooser;
import com.vitco.layout.content.colorchooser.basic.ColorChooserPrototype;
import com.vitco.util.misc.ColorTools;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
/**
* A panel that displays hue and saturation for a given color.
*/
public final class SatBrightPanelChooser extends ColorChooserPrototype {
// the current position of the selected color
private Point crossPosition = new Point(0,0);
// to check if the currentColor has changed
private float[] prevCurrentColor = new float[] {-1, -1, -1};
// current color that is used to draw the panel
private float[] currentColor = new float[] {-1, -1, -1};
// buffer image used for redraw without hue change
private BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
// set the internal color
public final void setColor(float[] newCurrentColor) {
currentColor = newCurrentColor.clone();
}
// constructor
public SatBrightPanelChooser() {
// register mouse down events
MouseAdapter ma = new MouseAdapter() {
private void internalColorUpdate(Point point, boolean notify) {
point = new Point(
(int)Math.max(0, Math.min(getWidth(), point.getX())),
(int)Math.max(0, Math.min(getHeight(), point.getY()))
);
currentColor = new float[] {
Math.max(0, Math.min(1, currentColor[0])),
Math.max(0, Math.min(1, (float)((point.getX() / (double) getWidth())))),
Math.max(0, Math.min(1, 1-(float)((point.getY() / (double) getHeight()))))
};
if (notify) {
// set the main color
notifyListeners(currentColor);
}
repaint();
}
@Override
public void mousePressed(MouseEvent e) {
internalColorUpdate(e.getPoint(), false);
}
@Override
public void mouseDragged(MouseEvent e) {
internalColorUpdate(e.getPoint(), false);
}
@Override
public void mouseReleased(MouseEvent e) {
internalColorUpdate(e.getPoint(), true);
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
@Override
protected final void paintComponent(Graphics g1) {
boolean[] same = new boolean[] {
currentColor[0] == prevCurrentColor[0],
currentColor[1] == prevCurrentColor[1],
currentColor[2] == prevCurrentColor[2],
this.getWidth() == image.getWidth() && this.getHeight() == image.getHeight()
};
if (!same[3] || !same[0] || !same[1] || !same[2]) {
// calculate the position of the current color
if (!same[3] || !same[1] || !same[2]) {
crossPosition = new Point(
Math.round(currentColor[1]*getWidth()),
Math.round((1-currentColor[2])*getHeight())
);
}
if (!same[3]) {
// resize the image
image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
}
if (!same[3] || !same[0]) {
// repaint the image
Graphics2D g = (Graphics2D)image.getGraphics();
g.setPaint(new GradientPaint(
0, 0, Color.WHITE,
getWidth() - 1, 0, ColorTools.hsbToColor(new float[] {currentColor[0],1,1}),
false)
);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g.setPaint(new GradientPaint(
0, 0, new Color(0,0,0,0),
0, getHeight() - 1, new Color(0,0,0,255),
false)
);
g.fillRect(0,0,image.getWidth(),image.getHeight());
g.dispose();
}
// update the previous color
prevCurrentColor = currentColor.clone();
}
Graphics2D ig = (Graphics2D) g1;
// draw image
ig.drawImage(image, 0, 0, null);
// Anti-alias
ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// draw circle (selected color)
ig.setStroke(new BasicStroke(1.5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL)); // line size
ig.setColor(ColorTools.perceivedBrightness(currentColor) > 127 ? Color.BLACK : Color.WHITE);
ig.drawOval(crossPosition.x - 5, crossPosition.y - 5, 10, 10);
}
}