• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 package com.badlogic.gdx.tools.flame;
18 import java.awt.Color;
19 import java.awt.Dimension;
20 import java.awt.GradientPaint;
21 import java.awt.Graphics;
22 import java.awt.Graphics2D;
23 import java.awt.GridBagConstraints;
24 import java.awt.GridBagLayout;
25 import java.awt.Insets;
26 import java.awt.event.MouseAdapter;
27 import java.awt.event.MouseEvent;
28 import java.awt.event.MouseMotionAdapter;
29 import java.util.ArrayList;
30 
31 import javax.swing.BorderFactory;
32 import javax.swing.JColorChooser;
33 import javax.swing.JPanel;
34 import javax.swing.JSlider;
35 import javax.swing.event.ChangeEvent;
36 import javax.swing.event.ChangeListener;
37 
38 import com.badlogic.gdx.graphics.g3d.particles.values.GradientColorValue;
39 
40 /** @author Inferno */
41 class GradientPanel extends ParticleValuePanel<GradientColorValue> {
42 	private GradientEditor gradientEditor;
43 	ColorSlider saturationSlider, lightnessSlider;
44 	JPanel colorPanel;
45 	private ColorSlider hueSlider;
46 
GradientPanel(FlameMain editor, GradientColorValue value, String name, String description, boolean hideGradientEditor)47 	public GradientPanel (FlameMain editor, GradientColorValue value, String name, String description,
48 																boolean hideGradientEditor) {
49 		super(editor, name, description);
50 		setValue(value);
51 
52 		if (hideGradientEditor) {
53 			gradientEditor.setVisible(false);
54 		}
55 		gradientEditor.percentages.clear();
56 		for (float percent : value.getTimeline())
57 			gradientEditor.percentages.add(percent);
58 
59 		gradientEditor.colors.clear();
60 		float[] colors = value.getColors();
61 		for (int i = 0; i < colors.length;) {
62 			float r = colors[i++];
63 			float g = colors[i++];
64 			float b = colors[i++];
65 			gradientEditor.colors.add(new Color(r, g, b));
66 		}
67 		if (gradientEditor.colors.isEmpty() || gradientEditor.percentages.isEmpty()) {
68 			gradientEditor.percentages.clear();
69 			gradientEditor.percentages.add(0f);
70 			gradientEditor.percentages.add(1f);
71 			gradientEditor.colors.clear();
72 			gradientEditor.colors.add(Color.white);
73 		}
74 		setColor(gradientEditor.colors.get(0));
75 	}
76 
getPreferredSize()77 	public Dimension getPreferredSize () {
78 		Dimension size = super.getPreferredSize();
79 		size.width = 10;
80 		return size;
81 	}
82 
initializeComponents()83 	protected void initializeComponents () {
84 		super.initializeComponents();
85 		JPanel contentPanel = getContentPanel();
86 		{
87 			gradientEditor = new GradientEditor() {
88 				public void handleSelected (Color color) {
89 					GradientPanel.this.setColor(color);
90 				}
91 			};
92 			contentPanel.add(gradientEditor, new GridBagConstraints(0, 1, 3, 1, 1.0, 0.0, GridBagConstraints.CENTER,
93 				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 10));
94 		}
95 		{
96 			hueSlider = new ColorSlider(new Color[] {Color.red, Color.yellow, Color.green, Color.cyan, Color.blue, Color.magenta,
97 				Color.red}) {
98 				protected void colorPicked () {
99 					saturationSlider.setColors(new Color[] {new Color(Color.HSBtoRGB(getPercentage(), 1, 1)), Color.white});
100 					updateColor();
101 				}
102 			};
103 			contentPanel.add(hueSlider, new GridBagConstraints(1, 2, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER,
104 				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 6, 0), 0, 0));
105 		}
106 		{
107 			saturationSlider = new ColorSlider(new Color[] {Color.red, Color.white}) {
108 				protected void colorPicked () {
109 					updateColor();
110 				}
111 			};
112 			contentPanel.add(saturationSlider, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
113 				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 6), 0, 0));
114 		}
115 		{
116 			lightnessSlider = new ColorSlider(new Color[0]) {
117 				protected void colorPicked () {
118 					updateColor();
119 				}
120 			};
121 			contentPanel.add(lightnessSlider, new GridBagConstraints(2, 3, 1, 1, 1, 0.0, GridBagConstraints.CENTER,
122 				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
123 		}
124 		{
125 			colorPanel = new JPanel() {
126 				public Dimension getPreferredSize () {
127 					Dimension size = super.getPreferredSize();
128 					size.width = 52;
129 					return size;
130 				}
131 			};
132 			contentPanel.add(colorPanel, new GridBagConstraints(0, 2, 1, 2, 0.0, 0.0, GridBagConstraints.CENTER,
133 				GridBagConstraints.BOTH, new Insets(3, 0, 0, 6), 0, 0));
134 		}
135 
136 		colorPanel.addMouseListener(new MouseAdapter() {
137 			public void mouseClicked (MouseEvent e) {
138 				Color color = JColorChooser.showDialog(colorPanel, "Set Color", colorPanel.getBackground());
139 				if (color != null) setColor(color);
140 			}
141 		});
142 		colorPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.black));
143 	}
144 
setColor(Color color)145 	public void setColor (Color color) {
146 		float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
147 		hueSlider.setPercentage(hsb[0]);
148 		saturationSlider.setPercentage(1 - hsb[1]);
149 		lightnessSlider.setPercentage(1 - hsb[2]);
150 		colorPanel.setBackground(color);
151 	}
152 
updateColor()153 	void updateColor () {
154 		Color color = new Color(Color.HSBtoRGB(hueSlider.getPercentage(), 1 - saturationSlider.getPercentage(), 1));
155 		lightnessSlider.setColors(new Color[] {color, Color.black});
156 		color = new Color(Color.HSBtoRGB(hueSlider.getPercentage(), 1 - saturationSlider.getPercentage(),
157 			1 - lightnessSlider.getPercentage()));
158 		colorPanel.setBackground(color);
159 		gradientEditor.setColor(color);
160 
161 		float[] colors = new float[gradientEditor.colors.size() * 3];
162 		int i = 0;
163 		for (Color c : gradientEditor.colors) {
164 			colors[i++] = c.getRed() / 255f;
165 			colors[i++] = c.getGreen() / 255f;
166 			colors[i++] = c.getBlue() / 255f;
167 		}
168 		float[] percentages = new float[gradientEditor.percentages.size()];
169 		i = 0;
170 		for (Float percent : gradientEditor.percentages)
171 			percentages[i++] = percent;
172 		value.setColors(colors);
173 		value.setTimeline(percentages);
174 	}
175 
176 	public class GradientEditor extends JPanel {
177 		ArrayList<Color> colors = new ArrayList();
178 		ArrayList<Float> percentages = new ArrayList();
179 
180 		int handleWidth = 12;
181 		int handleHeight = 12;
182 		int gradientX = handleWidth / 2;
183 		int gradientY = 0;
184 		int gradientWidth;
185 		int gradientHeight;
186 		int dragIndex = -1;
187 		int selectedIndex;
188 
GradientEditor()189 		public GradientEditor () {
190 			setPreferredSize(new Dimension(100, 30));
191 
192 			addMouseListener(new MouseAdapter() {
193 				public void mousePressed (MouseEvent event) {
194 					dragIndex = -1;
195 					int mouseX = event.getX();
196 					int mouseY = event.getY();
197 					int y = gradientY + gradientHeight;
198 					for (int i = 0, n = colors.size(); i < n; i++) {
199 						int x = gradientX + (int)(percentages.get(i) * gradientWidth) - handleWidth / 2;
200 						if (mouseX >= x && mouseX <= x + handleWidth && mouseY >= gradientY && mouseY <= y + handleHeight) {
201 							dragIndex = selectedIndex = i;
202 							handleSelected(colors.get(selectedIndex));
203 							repaint();
204 							break;
205 						}
206 					}
207 				}
208 
209 				public void mouseReleased (MouseEvent event) {
210 					if (dragIndex != -1) {
211 						dragIndex = -1;
212 						repaint();
213 					}
214 				}
215 
216 				public void mouseClicked (MouseEvent event) {
217 					int mouseX = event.getX();
218 					int mouseY = event.getY();
219 					if (event.getClickCount() == 2) {
220 						if (percentages.size() <= 1) return;
221 						if (selectedIndex == -1 || selectedIndex == 0) return;
222 						int y = gradientY + gradientHeight;
223 						int x = gradientX + (int)(percentages.get(selectedIndex) * gradientWidth) - handleWidth / 2;
224 						if (mouseX >= x && mouseX <= x + handleWidth && mouseY >= gradientY && mouseY <= y + handleHeight) {
225 							percentages.remove(selectedIndex);
226 							colors.remove(selectedIndex);
227 							selectedIndex--;
228 							dragIndex = selectedIndex;
229 							if (percentages.size() == 2) percentages.set(1, 1f);
230 							handleSelected(colors.get(selectedIndex));
231 							repaint();
232 						}
233 						return;
234 					}
235 					if (mouseX < gradientX || mouseX > gradientX + gradientWidth) return;
236 					if (mouseY < gradientY || mouseY > gradientY + gradientHeight) return;
237 					float percent = (event.getX() - gradientX) / (float)gradientWidth;
238 					if (percentages.size() == 1) percent = 1f;
239 					for (int i = 0, n = percentages.size(); i <= n; i++) {
240 						if (i == n || percent < percentages.get(i)) {
241 							percentages.add(i, percent);
242 							colors.add(i, colors.get(i - 1));
243 							dragIndex = selectedIndex = i;
244 							handleSelected(colors.get(selectedIndex));
245 							repaint();
246 							break;
247 						}
248 					}
249 				}
250 			});
251 			addMouseMotionListener(new MouseMotionAdapter() {
252 				public void mouseDragged (MouseEvent event) {
253 					if (dragIndex == -1 || dragIndex == 0 || dragIndex == percentages.size() - 1) return;
254 					float percent = (event.getX() - gradientX) / (float)gradientWidth;
255 					percent = Math.max(percent, percentages.get(dragIndex - 1) + 0.01f);
256 					percent = Math.min(percent, percentages.get(dragIndex + 1) - 0.01f);
257 					percentages.set(dragIndex, percent);
258 					repaint();
259 				}
260 			});
261 		}
262 
setColor(Color color)263 		public void setColor (Color color) {
264 			if (selectedIndex == -1) return;
265 			colors.set(selectedIndex, color);
266 			repaint();
267 		}
268 
handleSelected(Color color)269 		public void handleSelected (Color color) {
270 		}
271 
paintComponent(Graphics graphics)272 		protected void paintComponent (Graphics graphics) {
273 			super.paintComponent(graphics);
274 			Graphics2D g = (Graphics2D)graphics;
275 			int width = getWidth() - 1;
276 			int height = getHeight();
277 
278 			gradientWidth = width - handleWidth;
279 			gradientHeight = height - 16;
280 
281 			g.translate(gradientX, gradientY);
282 			for (int i = 0, n = colors.size() == 1 ? 1 : colors.size() - 1; i < n; i++) {
283 				Color color1 = colors.get(i);
284 				Color color2 = colors.size() == 1 ? color1 : colors.get(i + 1);
285 				float percent1 = percentages.get(i);
286 				float percent2 = colors.size() == 1 ? 1 : percentages.get(i + 1);
287 				int point1 = (int)(percent1 * gradientWidth);
288 				int point2 = (int)Math.ceil(percent2 * gradientWidth);
289 				g.setPaint(new GradientPaint(point1, 0, color1, point2, 0, color2, false));
290 				g.fillRect(point1, 0, point2 - point1, gradientHeight);
291 			}
292 			g.setPaint(null);
293 			g.setColor(Color.black);
294 			g.drawRect(0, 0, gradientWidth, gradientHeight);
295 
296 			int y = gradientHeight;
297 			int[] yPoints = new int[3];
298 			yPoints[0] = y;
299 			yPoints[1] = y + handleHeight;
300 			yPoints[2] = y + handleHeight;
301 			int[] xPoints = new int[3];
302 			for (int i = 0, n = colors.size(); i < n; i++) {
303 				int x = (int)(percentages.get(i) * gradientWidth);
304 				xPoints[0] = x;
305 				xPoints[1] = x - handleWidth / 2;
306 				xPoints[2] = x + handleWidth / 2;
307 				if (i == selectedIndex) {
308 					g.setColor(colors.get(i));
309 					g.fillPolygon(xPoints, yPoints, 3);
310 					g.fillRect(xPoints[1], yPoints[1] + 2, handleWidth + 1, 2);
311 					g.setColor(Color.black);
312 				}
313 				g.drawPolygon(xPoints, yPoints, 3);
314 			}
315 			g.translate(-gradientX, -gradientY);
316 		}
317 	}
318 
319 	static public class ColorSlider extends JPanel {
320 		Color[] paletteColors;
321 		JSlider slider;
322 		private ColorPicker colorPicker;
323 
ColorSlider(Color[] paletteColors)324 		public ColorSlider (Color[] paletteColors) {
325 			this.paletteColors = paletteColors;
326 			setLayout(new GridBagLayout());
327 			{
328 				slider = new JSlider(0, 1000, 0);
329 				slider.setPaintTrack(false);
330 				add(slider, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
331 					new Insets(0, 6, 0, 6), 0, 0));
332 			}
333 			{
334 				colorPicker = new ColorPicker();
335 				add(colorPicker, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
336 					GridBagConstraints.HORIZONTAL, new Insets(0, 6, 0, 6), 0, 0));
337 			}
338 
339 			slider.addChangeListener(new ChangeListener() {
340 				public void stateChanged (ChangeEvent event) {
341 					colorPicked();
342 				}
343 			});
344 		}
345 
getPreferredSize()346 		public Dimension getPreferredSize () {
347 			Dimension size = super.getPreferredSize();
348 			size.width = 10;
349 			return size;
350 		}
351 
setPercentage(float percent)352 		public void setPercentage (float percent) {
353 			slider.setValue((int)(1000 * percent));
354 		}
355 
getPercentage()356 		public float getPercentage () {
357 			return slider.getValue() / 1000f;
358 		}
359 
colorPicked()360 		protected void colorPicked () {
361 		}
362 
setColors(Color[] colors)363 		public void setColors (Color[] colors) {
364 			paletteColors = colors;
365 			repaint();
366 		}
367 
368 		public class ColorPicker extends JPanel {
ColorPicker()369 			public ColorPicker () {
370 				addMouseListener(new MouseAdapter() {
371 					public void mouseClicked (MouseEvent event) {
372 						slider.setValue((int)(event.getX() / (float)getWidth() * 1000));
373 					}
374 				});
375 			}
376 
paintComponent(Graphics graphics)377 			protected void paintComponent (Graphics graphics) {
378 				Graphics2D g = (Graphics2D)graphics;
379 				int width = getWidth() - 1;
380 				int height = getHeight() - 1;
381 				for (int i = 0, n = paletteColors.length - 1; i < n; i++) {
382 					Color color1 = paletteColors[i];
383 					Color color2 = paletteColors[i + 1];
384 					float point1 = i / (float)n * width;
385 					float point2 = (i + 1) / (float)n * width;
386 					g.setPaint(new GradientPaint(point1, 0, color1, point2, 0, color2, false));
387 					g.fillRect((int)point1, 0, (int)Math.ceil(point2 - point1), height);
388 				}
389 				g.setPaint(null);
390 				g.setColor(Color.black);
391 				g.drawRect(0, 0, width, height);
392 			}
393 		}
394 	}
395 }
396