gdx-studio
git clone https://git.pyrossh.dev/gdx-studio
An IDE for creating Games using libgdx and Java supported on all platforms Android, iOS, Desktop
src_libs/com/badlogic/gdx/tools/hiero/unicodefont/effects/EffectUtil.java
| a62d533 | 1 | /******************************************************************************* |
| a62d533 | 2 | * Copyright 2011 See AUTHORS file. |
| a62d533 | 3 | * |
| a62d533 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| a62d533 | 5 | * you may not use this file except in compliance with the License. |
| a62d533 | 6 | * You may obtain a copy of the License at |
| a62d533 | 7 | * |
| a62d533 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| a62d533 | 9 | * |
| a62d533 | 10 | * Unless required by applicable law or agreed to in writing, software |
| a62d533 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| a62d533 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| a62d533 | 13 | * See the License for the specific language governing permissions and |
| a62d533 | 14 | * limitations under the License. |
| a62d533 | 15 | ******************************************************************************/ |
| a62d533 | 16 | |
| a62d533 | 17 | package com.badlogic.gdx.tools.hiero.unicodefont.effects; |
| a62d533 | 18 | |
| a62d533 | 19 | import java.awt.AlphaComposite; |
| a62d533 | 20 | import java.awt.Color; |
| a62d533 | 21 | import java.awt.Dimension; |
| a62d533 | 22 | import java.awt.EventQueue; |
| a62d533 | 23 | import java.awt.Graphics2D; |
| a62d533 | 24 | import java.awt.GridBagConstraints; |
| a62d533 | 25 | import java.awt.GridBagLayout; |
| a62d533 | 26 | import java.awt.Insets; |
| a62d533 | 27 | import java.awt.event.ActionEvent; |
| a62d533 | 28 | import java.awt.event.ActionListener; |
| a62d533 | 29 | import java.awt.image.BufferedImage; |
| a62d533 | 30 | |
| a62d533 | 31 | import javax.swing.BorderFactory; |
| a62d533 | 32 | import javax.swing.DefaultComboBoxModel; |
| a62d533 | 33 | import javax.swing.JButton; |
| a62d533 | 34 | import javax.swing.JCheckBox; |
| a62d533 | 35 | import javax.swing.JColorChooser; |
| a62d533 | 36 | import javax.swing.JComboBox; |
| a62d533 | 37 | import javax.swing.JComponent; |
| a62d533 | 38 | import javax.swing.JDialog; |
| a62d533 | 39 | import javax.swing.JLabel; |
| a62d533 | 40 | import javax.swing.JPanel; |
| a62d533 | 41 | import javax.swing.JSpinner; |
| a62d533 | 42 | import javax.swing.JTextArea; |
| a62d533 | 43 | import javax.swing.SpinnerNumberModel; |
| a62d533 | 44 | |
| a62d533 | 45 | import com.badlogic.gdx.tools.hiero.unicodefont.GlyphPage; |
| a62d533 | 46 | import com.badlogic.gdx.tools.hiero.unicodefont.effects.ConfigurableEffect.Value; |
| a62d533 | 47 | |
| a62d533 | 48 | /** Provides utility methods for effects. |
| a62d533 | 49 | * @author Nathan Sweet */ |
| a62d533 | 50 | public class EffectUtil {
|
| a62d533 | 51 | static private BufferedImage scratchImage = new BufferedImage(GlyphPage.MAX_GLYPH_SIZE, GlyphPage.MAX_GLYPH_SIZE, |
| a62d533 | 52 | BufferedImage.TYPE_INT_ARGB); |
| a62d533 | 53 | |
| a62d533 | 54 | /** Returns an image that can be used by effects as a temp image. */ |
| a62d533 | 55 | static public BufferedImage getScratchImage () {
|
| a62d533 | 56 | Graphics2D g = (Graphics2D)scratchImage.getGraphics(); |
| a62d533 | 57 | g.setComposite(AlphaComposite.Clear); |
| a62d533 | 58 | g.fillRect(0, 0, GlyphPage.MAX_GLYPH_SIZE, GlyphPage.MAX_GLYPH_SIZE); |
| a62d533 | 59 | g.setComposite(AlphaComposite.SrcOver); |
| a62d533 | 60 | g.setColor(java.awt.Color.white); |
| a62d533 | 61 | return scratchImage; |
| a62d533 | 62 | } |
| a62d533 | 63 | |
| a62d533 | 64 | /** Returns a value that represents a color. */ |
| a62d533 | 65 | static public Value colorValue (String name, Color currentValue) {
|
| a62d533 | 66 | return new DefaultValue(name, EffectUtil.toString(currentValue)) {
|
| a62d533 | 67 | public void showDialog () {
|
| a62d533 | 68 | Color newColor = JColorChooser.showDialog(null, "Choose a color", EffectUtil.fromString(value)); |
| a62d533 | 69 | if (newColor != null) value = EffectUtil.toString(newColor); |
| a62d533 | 70 | } |
| a62d533 | 71 | |
| a62d533 | 72 | public Object getObject () {
|
| a62d533 | 73 | return EffectUtil.fromString(value); |
| a62d533 | 74 | } |
| a62d533 | 75 | }; |
| a62d533 | 76 | } |
| a62d533 | 77 | |
| a62d533 | 78 | /** Returns a value that represents an int. */ |
| a62d533 | 79 | static public Value intValue (String name, final int currentValue, final String description) {
|
| a62d533 | 80 | return new DefaultValue(name, String.valueOf(currentValue)) {
|
| a62d533 | 81 | public void showDialog () {
|
| a62d533 | 82 | JSpinner spinner = new JSpinner(new SpinnerNumberModel(currentValue, Short.MIN_VALUE, Short.MAX_VALUE, 1)); |
| a62d533 | 83 | if (showValueDialog(spinner, description)) value = String.valueOf(spinner.getValue()); |
| a62d533 | 84 | } |
| a62d533 | 85 | |
| a62d533 | 86 | public Object getObject () {
|
| a62d533 | 87 | return Integer.valueOf(value); |
| a62d533 | 88 | } |
| a62d533 | 89 | }; |
| a62d533 | 90 | } |
| a62d533 | 91 | |
| a62d533 | 92 | /** Returns a value that represents a float, from 0 to 1 (inclusive). */ |
| a62d533 | 93 | static public Value floatValue (String name, final float currentValue, final float min, final float max, |
| a62d533 | 94 | final String description) {
|
| a62d533 | 95 | return new DefaultValue(name, String.valueOf(currentValue)) {
|
| a62d533 | 96 | public void showDialog () {
|
| a62d533 | 97 | JSpinner spinner = new JSpinner(new SpinnerNumberModel(currentValue, min, max, 0.1f)); |
| a62d533 | 98 | if (showValueDialog(spinner, description)) value = String.valueOf(((Double)spinner.getValue()).floatValue()); |
| a62d533 | 99 | } |
| a62d533 | 100 | |
| a62d533 | 101 | public Object getObject () {
|
| a62d533 | 102 | return Float.valueOf(value); |
| a62d533 | 103 | } |
| a62d533 | 104 | }; |
| a62d533 | 105 | } |
| a62d533 | 106 | |
| a62d533 | 107 | /** Returns a value that represents a boolean. */ |
| a62d533 | 108 | static public Value booleanValue (String name, final boolean currentValue, final String description) {
|
| a62d533 | 109 | return new DefaultValue(name, String.valueOf(currentValue)) {
|
| a62d533 | 110 | public void showDialog () {
|
| a62d533 | 111 | JCheckBox checkBox = new JCheckBox(); |
| a62d533 | 112 | checkBox.setSelected(currentValue); |
| a62d533 | 113 | if (showValueDialog(checkBox, description)) value = String.valueOf(checkBox.isSelected()); |
| a62d533 | 114 | } |
| a62d533 | 115 | |
| a62d533 | 116 | public Object getObject () {
|
| a62d533 | 117 | return Boolean.valueOf(value); |
| a62d533 | 118 | } |
| a62d533 | 119 | }; |
| a62d533 | 120 | } |
| a62d533 | 121 | |
| a62d533 | 122 | /** Returns a value that represents a fixed number of options. All options are strings. |
| a62d533 | 123 | * @param options The first array has an entry for each option. Each entry is either a String[1] that is both the display value |
| a62d533 | 124 | * and actual value, or a String[2] whose first element is the display value and second element is the actual value. */ |
| a62d533 | 125 | static public Value optionValue (String name, final String currentValue, final String[][] options, final String description) {
|
| a62d533 | 126 | return new DefaultValue(name, currentValue.toString()) {
|
| a62d533 | 127 | public void showDialog () {
|
| a62d533 | 128 | int selectedIndex = -1; |
| a62d533 | 129 | DefaultComboBoxModel model = new DefaultComboBoxModel(); |
| a62d533 | 130 | for (int i = 0; i < options.length; i++) {
|
| a62d533 | 131 | model.addElement(options[i][0]); |
| a62d533 | 132 | if (getValue(i).equals(currentValue)) selectedIndex = i; |
| a62d533 | 133 | } |
| a62d533 | 134 | JComboBox comboBox = new JComboBox(model); |
| a62d533 | 135 | comboBox.setSelectedIndex(selectedIndex); |
| a62d533 | 136 | if (showValueDialog(comboBox, description)) value = getValue(comboBox.getSelectedIndex()); |
| a62d533 | 137 | } |
| a62d533 | 138 | |
| a62d533 | 139 | private String getValue (int i) {
|
| a62d533 | 140 | if (options[i].length == 1) return options[i][0]; |
| a62d533 | 141 | return options[i][1]; |
| a62d533 | 142 | } |
| a62d533 | 143 | |
| a62d533 | 144 | public String toString () {
|
| a62d533 | 145 | for (int i = 0; i < options.length; i++) |
| a62d533 | 146 | if (getValue(i).equals(value)) return options[i][0].toString(); |
| a62d533 | 147 | return ""; |
| a62d533 | 148 | } |
| a62d533 | 149 | |
| a62d533 | 150 | public Object getObject () {
|
| a62d533 | 151 | return value; |
| a62d533 | 152 | } |
| a62d533 | 153 | }; |
| a62d533 | 154 | } |
| a62d533 | 155 | |
| a62d533 | 156 | /** Convers a color to a string. */ |
| a62d533 | 157 | static public String toString (Color color) {
|
| a62d533 | 158 | if (color == null) throw new IllegalArgumentException("color cannot be null.");
|
| a62d533 | 159 | String r = Integer.toHexString(color.getRed()); |
| a62d533 | 160 | if (r.length() == 1) r = "0" + r; |
| a62d533 | 161 | String g = Integer.toHexString(color.getGreen()); |
| a62d533 | 162 | if (g.length() == 1) g = "0" + g; |
| a62d533 | 163 | String b = Integer.toHexString(color.getBlue()); |
| a62d533 | 164 | if (b.length() == 1) b = "0" + b; |
| a62d533 | 165 | return r + g + b; |
| a62d533 | 166 | } |
| a62d533 | 167 | |
| a62d533 | 168 | /** Converts a string to a color. */ |
| a62d533 | 169 | static public Color fromString (String rgb) {
|
| a62d533 | 170 | if (rgb == null || rgb.length() != 6) return Color.white; |
| a62d533 | 171 | return new Color(Integer.parseInt(rgb.substring(0, 2), 16), Integer.parseInt(rgb.substring(2, 4), 16), Integer.parseInt( |
| a62d533 | 172 | rgb.substring(4, 6), 16)); |
| a62d533 | 173 | } |
| a62d533 | 174 | |
| a62d533 | 175 | /** Provides generic functionality for an effect's configurable value. */ |
| a62d533 | 176 | static private abstract class DefaultValue implements Value {
|
| a62d533 | 177 | String value; |
| a62d533 | 178 | String name; |
| a62d533 | 179 | |
| a62d533 | 180 | public DefaultValue (String name, String value) {
|
| a62d533 | 181 | this.value = value; |
| a62d533 | 182 | this.name = name; |
| a62d533 | 183 | } |
| a62d533 | 184 | |
| a62d533 | 185 | public void setString (String value) {
|
| a62d533 | 186 | this.value = value; |
| a62d533 | 187 | } |
| a62d533 | 188 | |
| a62d533 | 189 | public String getString () {
|
| a62d533 | 190 | return value; |
| a62d533 | 191 | } |
| a62d533 | 192 | |
| a62d533 | 193 | public String getName () {
|
| a62d533 | 194 | return name; |
| a62d533 | 195 | } |
| a62d533 | 196 | |
| a62d533 | 197 | public String toString () {
|
| a62d533 | 198 | if (value == null) return ""; |
| a62d533 | 199 | return value.toString(); |
| a62d533 | 200 | } |
| a62d533 | 201 | |
| a62d533 | 202 | public boolean showValueDialog (final JComponent component, String description) {
|
| a62d533 | 203 | ValueDialog dialog = new ValueDialog(component, name, description); |
| a62d533 | 204 | dialog.setTitle(name); |
| a62d533 | 205 | dialog.setLocationRelativeTo(null); |
| a62d533 | 206 | EventQueue.invokeLater(new Runnable() {
|
| a62d533 | 207 | public void run () {
|
| a62d533 | 208 | JComponent focusComponent = component; |
| a62d533 | 209 | if (focusComponent instanceof JSpinner) |
| a62d533 | 210 | focusComponent = ((JSpinner.DefaultEditor)((JSpinner)component).getEditor()).getTextField(); |
| a62d533 | 211 | focusComponent.requestFocusInWindow(); |
| a62d533 | 212 | } |
| a62d533 | 213 | }); |
| a62d533 | 214 | dialog.setVisible(true); |
| a62d533 | 215 | return dialog.okPressed; |
| a62d533 | 216 | } |
| a62d533 | 217 | }; |
| a62d533 | 218 | |
| a62d533 | 219 | /** Provides generic functionality for a dialog to configure a value. */ |
| a62d533 | 220 | static private class ValueDialog extends JDialog {
|
| a62d533 | 221 | public boolean okPressed = false; |
| a62d533 | 222 | |
| a62d533 | 223 | public ValueDialog (JComponent component, String name, String description) {
|
| a62d533 | 224 | setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); |
| a62d533 | 225 | setLayout(new GridBagLayout()); |
| a62d533 | 226 | setModal(true); |
| a62d533 | 227 | |
| a62d533 | 228 | if (component instanceof JSpinner) |
| a62d533 | 229 | ((JSpinner.DefaultEditor)((JSpinner)component).getEditor()).getTextField().setColumns(4); |
| a62d533 | 230 | |
| a62d533 | 231 | JPanel descriptionPanel = new JPanel(); |
| a62d533 | 232 | descriptionPanel.setLayout(new GridBagLayout()); |
| a62d533 | 233 | getContentPane().add( |
| a62d533 | 234 | descriptionPanel, |
| a62d533 | 235 | new GridBagConstraints(0, 0, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, |
| a62d533 | 236 | 0), 0, 0)); |
| a62d533 | 237 | descriptionPanel.setBackground(Color.white); |
| a62d533 | 238 | descriptionPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.black)); |
| a62d533 | 239 | {
|
| a62d533 | 240 | JTextArea descriptionText = new JTextArea(description); |
| a62d533 | 241 | descriptionPanel.add(descriptionText, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, |
| a62d533 | 242 | GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); |
| a62d533 | 243 | descriptionText.setWrapStyleWord(true); |
| a62d533 | 244 | descriptionText.setLineWrap(true); |
| a62d533 | 245 | descriptionText.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); |
| a62d533 | 246 | descriptionText.setEditable(false); |
| a62d533 | 247 | } |
| a62d533 | 248 | |
| a62d533 | 249 | JPanel panel = new JPanel(); |
| a62d533 | 250 | getContentPane().add( |
| a62d533 | 251 | panel, |
| a62d533 | 252 | new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 5, 0, |
| a62d533 | 253 | 5), 0, 0)); |
| a62d533 | 254 | panel.add(new JLabel(name + ":")); |
| a62d533 | 255 | panel.add(component); |
| a62d533 | 256 | |
| a62d533 | 257 | JPanel buttonPanel = new JPanel(); |
| a62d533 | 258 | getContentPane().add( |
| a62d533 | 259 | buttonPanel, |
| a62d533 | 260 | new GridBagConstraints(0, 2, 2, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, |
| a62d533 | 261 | new Insets(0, 0, 0, 0), 0, 0)); |
| a62d533 | 262 | {
|
| a62d533 | 263 | JButton okButton = new JButton("OK");
|
| a62d533 | 264 | buttonPanel.add(okButton); |
| a62d533 | 265 | okButton.addActionListener(new ActionListener() {
|
| a62d533 | 266 | public void actionPerformed (ActionEvent evt) {
|
| a62d533 | 267 | okPressed = true; |
| a62d533 | 268 | setVisible(false); |
| a62d533 | 269 | } |
| a62d533 | 270 | }); |
| a62d533 | 271 | } |
| a62d533 | 272 | {
|
| a62d533 | 273 | JButton cancelButton = new JButton("Cancel");
|
| a62d533 | 274 | buttonPanel.add(cancelButton); |
| a62d533 | 275 | cancelButton.addActionListener(new ActionListener() {
|
| a62d533 | 276 | public void actionPerformed (ActionEvent evt) {
|
| a62d533 | 277 | setVisible(false); |
| a62d533 | 278 | } |
| a62d533 | 279 | }); |
| a62d533 | 280 | } |
| a62d533 | 281 | |
| a62d533 | 282 | setSize(new Dimension(320, 175)); |
| a62d533 | 283 | } |
| a62d533 | 284 | } |
| a62d533 | 285 | } |