com.badlogic.gdx.tools.particleeditor.GradientPanel Maven / Gradle / Ivy
The newest version!
/*******************************************************************************
* Copyright 2011 See AUTHORS file.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.badlogic.gdx.tools.particleeditor;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JColorChooser;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import com.badlogic.gdx.graphics.g2d.ParticleEmitter.GradientColorValue;
class GradientPanel extends EditorPanel {
private final GradientColorValue value;
private GradientEditor gradientEditor;
ColorSlider saturationSlider, lightnessSlider;
JPanel colorPanel;
private ColorSlider hueSlider;
public GradientPanel (GradientColorValue value, String name, String description, boolean hideGradientEditor) {
super(value, name, description);
this.value = value;
initializeComponents();
if (hideGradientEditor) {
gradientEditor.setVisible(false);
}
gradientEditor.percentages.clear();
for (float percent : value.getTimeline())
gradientEditor.percentages.add(percent);
gradientEditor.colors.clear();
float[] colors = value.getColors();
for (int i = 0; i < colors.length;) {
float r = colors[i++];
float g = colors[i++];
float b = colors[i++];
gradientEditor.colors.add(new Color(r, g, b));
}
if (gradientEditor.colors.isEmpty() || gradientEditor.percentages.isEmpty()) {
gradientEditor.percentages.clear();
gradientEditor.percentages.add(0f);
gradientEditor.percentages.add(1f);
gradientEditor.colors.clear();
gradientEditor.colors.add(Color.white);
}
setColor(gradientEditor.colors.get(0));
}
public Dimension getPreferredSize () {
Dimension size = super.getPreferredSize();
size.width = 10;
return size;
}
private void initializeComponents () {
JPanel contentPanel = getContentPanel();
{
gradientEditor = new GradientEditor() {
public void handleSelected (Color color) {
GradientPanel.this.setColor(color);
}
};
contentPanel.add(gradientEditor, new GridBagConstraints(0, 1, 3, 1, 1.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 10));
}
{
hueSlider = new ColorSlider(
new Color[] {Color.red, Color.yellow, Color.green, Color.cyan, Color.blue, Color.magenta, Color.red}) {
protected void colorPicked () {
saturationSlider.setColors(new Color[] {new Color(Color.HSBtoRGB(getPercentage(), 1, 1)), Color.white});
updateColor();
}
};
contentPanel.add(hueSlider, new GridBagConstraints(1, 2, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
}
{
saturationSlider = new ColorSlider(new Color[] {Color.red, Color.white}) {
protected void colorPicked () {
updateColor();
}
};
contentPanel.add(saturationSlider, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 6), 0, 0));
}
{
lightnessSlider = new ColorSlider(new Color[0]) {
protected void colorPicked () {
updateColor();
}
};
contentPanel.add(lightnessSlider, new GridBagConstraints(2, 3, 1, 1, 1, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
}
{
colorPanel = new JPanel() {
public Dimension getPreferredSize () {
Dimension size = super.getPreferredSize();
size.width = 52;
return size;
}
};
contentPanel.add(colorPanel, new GridBagConstraints(0, 2, 1, 2, 0.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.BOTH, new Insets(3, 0, 0, 6), 0, 0));
}
colorPanel.addMouseListener(new MouseAdapter() {
public void mouseClicked (MouseEvent e) {
Color color = JColorChooser.showDialog(colorPanel, "Set Color", colorPanel.getBackground());
if (color != null) setColor(color);
}
});
colorPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));
}
public void setColor (Color color) {
float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
hueSlider.setPercentage(hsb[0]);
saturationSlider.setPercentage(1 - hsb[1]);
lightnessSlider.setPercentage(1 - hsb[2]);
colorPanel.setBackground(color);
}
void updateColor () {
Color color = new Color(Color.HSBtoRGB(hueSlider.getPercentage(), 1 - saturationSlider.getPercentage(), 1));
lightnessSlider.setColors(new Color[] {color, Color.black});
color = new Color(
Color.HSBtoRGB(hueSlider.getPercentage(), 1 - saturationSlider.getPercentage(), 1 - lightnessSlider.getPercentage()));
colorPanel.setBackground(color);
gradientEditor.setColor(color);
float[] colors = new float[gradientEditor.colors.size() * 3];
int i = 0;
for (Color c : gradientEditor.colors) {
colors[i++] = c.getRed() / 255f;
colors[i++] = c.getGreen() / 255f;
colors[i++] = c.getBlue() / 255f;
}
float[] percentages = new float[gradientEditor.percentages.size()];
i = 0;
for (Float percent : gradientEditor.percentages)
percentages[i++] = percent;
value.setColors(colors);
value.setTimeline(percentages);
}
public class GradientEditor extends JPanel {
ArrayList colors = new ArrayList();
ArrayList percentages = new ArrayList();
int handleWidth = 12;
int handleHeight = 12;
int gradientX = handleWidth / 2;
int gradientY = 0;
int gradientWidth;
int gradientHeight;
int dragIndex = -1;
int selectedIndex;
public GradientEditor () {
setPreferredSize(new Dimension(100, 30));
addMouseListener(new MouseAdapter() {
public void mousePressed (MouseEvent event) {
dragIndex = -1;
int mouseX = event.getX();
int mouseY = event.getY();
int y = gradientY + gradientHeight;
for (int i = 0, n = colors.size(); i < n; i++) {
int x = gradientX + (int)(percentages.get(i) * gradientWidth) - handleWidth / 2;
if (mouseX >= x && mouseX <= x + handleWidth && mouseY >= gradientY && mouseY <= y + handleHeight) {
dragIndex = selectedIndex = i;
handleSelected(colors.get(selectedIndex));
repaint();
break;
}
}
}
public void mouseReleased (MouseEvent event) {
if (dragIndex != -1) {
dragIndex = -1;
repaint();
}
}
public void mouseClicked (MouseEvent event) {
int mouseX = event.getX();
int mouseY = event.getY();
if (event.getClickCount() == 2) {
if (percentages.size() <= 1) return;
if (selectedIndex == -1 || selectedIndex == 0) return;
int y = gradientY + gradientHeight;
int x = gradientX + (int)(percentages.get(selectedIndex) * gradientWidth) - handleWidth / 2;
if (mouseX >= x && mouseX <= x + handleWidth && mouseY >= gradientY && mouseY <= y + handleHeight) {
percentages.remove(selectedIndex);
colors.remove(selectedIndex);
selectedIndex--;
dragIndex = selectedIndex;
if (percentages.size() == 2) percentages.set(1, 1f);
handleSelected(colors.get(selectedIndex));
repaint();
}
return;
}
if (mouseX < gradientX || mouseX > gradientX + gradientWidth) return;
if (mouseY < gradientY || mouseY > gradientY + gradientHeight) return;
float percent = (event.getX() - gradientX) / (float)gradientWidth;
if (percentages.size() == 1) percent = 1f;
for (int i = 0, n = percentages.size(); i <= n; i++) {
if (i == n || percent < percentages.get(i)) {
percentages.add(i, percent);
colors.add(i, colors.get(i - 1));
dragIndex = selectedIndex = i;
handleSelected(colors.get(selectedIndex));
updateColor();
repaint();
break;
}
}
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged (MouseEvent event) {
if (dragIndex == -1 || dragIndex == 0 || dragIndex == percentages.size() - 1) return;
float percent = (event.getX() - gradientX) / (float)gradientWidth;
percent = Math.max(percent, percentages.get(dragIndex - 1) + 0.01f);
percent = Math.min(percent, percentages.get(dragIndex + 1) - 0.01f);
percentages.set(dragIndex, percent);
updateColor();
repaint();
}
});
}
public void setColor (Color color) {
if (selectedIndex == -1) return;
colors.set(selectedIndex, color);
repaint();
}
public void handleSelected (Color color) {
}
protected void paintComponent (Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g = (Graphics2D)graphics;
int width = getWidth() - 1;
int height = getHeight();
gradientWidth = width - handleWidth;
gradientHeight = height - 16;
g.translate(gradientX, gradientY);
for (int i = 0, n = colors.size() == 1 ? 1 : colors.size() - 1; i < n; i++) {
Color color1 = colors.get(i);
Color color2 = colors.size() == 1 ? color1 : colors.get(i + 1);
float percent1 = percentages.get(i);
float percent2 = colors.size() == 1 ? 1 : percentages.get(i + 1);
int point1 = (int)(percent1 * gradientWidth);
int point2 = (int)Math.ceil(percent2 * gradientWidth);
g.setPaint(new GradientPaint(point1, 0, color1, point2, 0, color2, false));
g.fillRect(point1, 0, point2 - point1, gradientHeight);
}
g.setPaint(null);
g.setColor(Color.black);
g.drawRect(0, 0, gradientWidth, gradientHeight);
int y = gradientHeight;
int[] yPoints = new int[3];
yPoints[0] = y;
yPoints[1] = y + handleHeight;
yPoints[2] = y + handleHeight;
int[] xPoints = new int[3];
for (int i = 0, n = colors.size(); i < n; i++) {
int x = (int)(percentages.get(i) * gradientWidth);
xPoints[0] = x;
xPoints[1] = x - handleWidth / 2;
xPoints[2] = x + handleWidth / 2;
if (i == selectedIndex) {
g.setColor(colors.get(i));
g.fillPolygon(xPoints, yPoints, 3);
g.fillRect(xPoints[1], yPoints[1] + 2, handleWidth + 1, 2);
g.setColor(Color.black);
}
g.drawPolygon(xPoints, yPoints, 3);
}
g.translate(-gradientX, -gradientY);
}
}
static public class ColorSlider extends JPanel {
Color[] paletteColors;
JSlider slider;
private ColorPicker colorPicker;
public ColorSlider (Color[] paletteColors) {
this.paletteColors = paletteColors;
setLayout(new GridBagLayout());
{
slider = new JSlider(0, 1000, 0);
slider.setPaintTrack(false);
add(slider, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
new Insets(0, 6, 0, 6), 0, 0));
}
{
colorPicker = new ColorPicker();
add(colorPicker, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
GridBagConstraints.HORIZONTAL, new Insets(0, 6, 0, 6), 0, 0));
}
slider.addChangeListener(new ChangeListener() {
public void stateChanged (ChangeEvent event) {
colorPicked();
}
});
}
public Dimension getPreferredSize () {
Dimension size = super.getPreferredSize();
size.width = 10;
return size;
}
public void setPercentage (float percent) {
slider.setValue((int)(1000 * percent));
}
public float getPercentage () {
return slider.getValue() / 1000f;
}
protected void colorPicked () {
}
public void setColors (Color[] colors) {
paletteColors = colors;
repaint();
}
public class ColorPicker extends JPanel {
public ColorPicker () {
addMouseListener(new MouseAdapter() {
public void mouseClicked (MouseEvent event) {
slider.setValue((int)(event.getX() / (float)getWidth() * 1000));
}
});
}
protected void paintComponent (Graphics graphics) {
Graphics2D g = (Graphics2D)graphics;
int width = getWidth() - 1;
int height = getHeight() - 1;
for (int i = 0, n = paletteColors.length - 1; i < n; i++) {
Color color1 = paletteColors[i];
Color color2 = paletteColors[i + 1];
float point1 = i / (float)n * width;
float point2 = (i + 1) / (float)n * width;
g.setPaint(new GradientPaint(point1, 0, color1, point2, 0, color2, false));
g.fillRect((int)point1, 0, (int)Math.ceil(point2 - point1), height);
}
g.setPaint(null);
g.setColor(Color.black);
g.drawRect(0, 0, width, height);
}
}
}
}