gdx-studio

#libgdx#java#desktop

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/Hiero.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;
a62d533 18
a62d533 19
import java.awt.BorderLayout;
a62d533 20
import java.awt.Component;
a62d533 21
import java.awt.Container;
a62d533 22
import java.awt.Dimension;
a62d533 23
import java.awt.EventQueue;
a62d533 24
import java.awt.FileDialog;
a62d533 25
import java.awt.FlowLayout;
a62d533 26
import java.awt.Font;
a62d533 27
import java.awt.Frame;
a62d533 28
import java.awt.GraphicsEnvironment;
a62d533 29
import java.awt.GridBagConstraints;
a62d533 30
import java.awt.GridBagLayout;
a62d533 31
import java.awt.Insets;
a62d533 32
import java.awt.LayoutManager;
a62d533 33
import java.awt.event.ActionEvent;
a62d533 34
import java.awt.event.ActionListener;
a62d533 35
import java.awt.event.KeyAdapter;
a62d533 36
import java.awt.event.KeyEvent;
a62d533 37
import java.awt.event.MouseAdapter;
a62d533 38
import java.awt.event.MouseEvent;
a62d533 39
import java.awt.event.WindowAdapter;
a62d533 40
import java.awt.event.WindowEvent;
a62d533 41
import java.awt.image.BufferedImage;
a62d533 42
import java.io.File;
a62d533 43
import java.io.IOException;
a62d533 44
import java.util.ArrayList;
a62d533 45
import java.util.Iterator;
a62d533 46
import java.util.List;
a62d533 47
import java.util.prefs.Preferences;
a62d533 48
a62d533 49
import javax.swing.BorderFactory;
a62d533 50
import javax.swing.ButtonGroup;
a62d533 51
import javax.swing.DefaultComboBoxModel;
a62d533 52
import javax.swing.Icon;
a62d533 53
import javax.swing.ImageIcon;
a62d533 54
import javax.swing.JButton;
a62d533 55
import javax.swing.JCheckBox;
a62d533 56
import javax.swing.JColorChooser;
a62d533 57
import javax.swing.JComboBox;
a62d533 58
import javax.swing.JFormattedTextField;
a62d533 59
import javax.swing.JFrame;
a62d533 60
import javax.swing.JLabel;
a62d533 61
import javax.swing.JList;
a62d533 62
import javax.swing.JMenu;
a62d533 63
import javax.swing.JMenuBar;
a62d533 64
import javax.swing.JMenuItem;
a62d533 65
import javax.swing.JPanel;
a62d533 66
import javax.swing.JRadioButton;
a62d533 67
import javax.swing.JScrollPane;
a62d533 68
import javax.swing.JSpinner;
a62d533 69
import javax.swing.JTextField;
a62d533 70
import javax.swing.JTextPane;
a62d533 71
import javax.swing.JWindow;
a62d533 72
import javax.swing.KeyStroke;
a62d533 73
import javax.swing.ScrollPaneConstants;
a62d533 74
import javax.swing.SpinnerNumberModel;
a62d533 75
import javax.swing.SwingUtilities;
a62d533 76
import javax.swing.border.EmptyBorder;
a62d533 77
import javax.swing.event.ChangeEvent;
a62d533 78
import javax.swing.event.ChangeListener;
a62d533 79
import javax.swing.event.DocumentEvent;
a62d533 80
import javax.swing.event.DocumentListener;
a62d533 81
import javax.swing.event.ListSelectionEvent;
a62d533 82
import javax.swing.event.ListSelectionListener;
a62d533 83
a62d533 84
import org.lwjgl.opengl.GL11;
a62d533 85
a62d533 86
import com.badlogic.gdx.ApplicationListener;
a62d533 87
import com.badlogic.gdx.Gdx;
a62d533 88
import com.badlogic.gdx.backends.lwjgl.LwjglCanvas;
a62d533 89
import com.badlogic.gdx.graphics.Color;
a62d533 90
import com.badlogic.gdx.graphics.Texture;
a62d533 91
import com.badlogic.gdx.graphics.g2d.BitmapFont;
a62d533 92
import com.badlogic.gdx.tools.hiero.unicodefont.GlyphPage;
a62d533 93
import com.badlogic.gdx.tools.hiero.unicodefont.HieroSettings;
a62d533 94
import com.badlogic.gdx.tools.hiero.unicodefont.UnicodeFont;
a62d533 95
import com.badlogic.gdx.tools.hiero.unicodefont.effects.ColorEffect;
a62d533 96
import com.badlogic.gdx.tools.hiero.unicodefont.effects.ConfigurableEffect;
a62d533 97
import com.badlogic.gdx.tools.hiero.unicodefont.effects.ConfigurableEffect.Value;
a62d533 98
import com.badlogic.gdx.tools.hiero.unicodefont.effects.DistanceFieldEffect;
a62d533 99
import com.badlogic.gdx.tools.hiero.unicodefont.effects.EffectUtil;
a62d533 100
import com.badlogic.gdx.tools.hiero.unicodefont.effects.GradientEffect;
a62d533 101
import com.badlogic.gdx.tools.hiero.unicodefont.effects.OutlineEffect;
a62d533 102
import com.badlogic.gdx.tools.hiero.unicodefont.effects.OutlineWobbleEffect;
a62d533 103
import com.badlogic.gdx.tools.hiero.unicodefont.effects.OutlineZigzagEffect;
a62d533 104
import com.badlogic.gdx.tools.hiero.unicodefont.effects.ShadowEffect;
a62d533 105
a62d533 106
import static org.lwjgl.opengl.GL11.*;
a62d533 107
a62d533 108
/** A tool to visualize settings for {@link UnicodeFont} and to export BMFont files for use with {@link BitmapFont}.
a62d533 109
 * @author Nathan Sweet */
a62d533 110
public class Hiero extends JFrame {
a62d533 111
	static final String NEHE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" //
a62d533 112
		+ "abcdefghijklmnopqrstuvwxyz\n1234567890\n" //
a62d533 113
		+ "\"!`?'.,;:()[]{}<>|/@\\^$-%+=#_&~*\u007F";
a62d533 114
a62d533 115
	volatile UnicodeFont newUnicodeFont;
a62d533 116
	UnicodeFont unicodeFont;
a62d533 117
	Color renderingBackgroundColor = Color.BLACK;
a62d533 118
	List effectPanels = new ArrayList();
a62d533 119
	Preferences prefs;
a62d533 120
	ColorEffect colorEffect;
a62d533 121
a62d533 122
	JScrollPane appliedEffectsScroll;
a62d533 123
	JPanel appliedEffectsPanel;
a62d533 124
	JButton addEffectButton;
a62d533 125
	JTextPane sampleTextPane;
a62d533 126
	JSpinner padAdvanceXSpinner;
a62d533 127
	JList effectsList;
a62d533 128
	JPanel gamePanel;
a62d533 129
	JTextField fontFileText;
a62d533 130
	JRadioButton fontFileRadio;
a62d533 131
	JRadioButton systemFontRadio;
a62d533 132
	JSpinner padBottomSpinner;
a62d533 133
	JSpinner padLeftSpinner;
a62d533 134
	JSpinner padRightSpinner;
a62d533 135
	JSpinner padTopSpinner;
a62d533 136
	JList fontList;
a62d533 137
	JSpinner fontSizeSpinner;
a62d533 138
	DefaultComboBoxModel fontListModel;
a62d533 139
	JLabel backgroundColorLabel;
a62d533 140
	JButton browseButton;
a62d533 141
	JSpinner padAdvanceYSpinner;
a62d533 142
	JCheckBox italicCheckBox;
a62d533 143
	JCheckBox boldCheckBox;
a62d533 144
	JRadioButton javaRadio;
a62d533 145
	JRadioButton nativeRadio;
a62d533 146
	JLabel glyphsTotalLabel;
a62d533 147
	JLabel glyphPagesTotalLabel;
a62d533 148
	JComboBox glyphPageHeightCombo;
a62d533 149
	JComboBox glyphPageWidthCombo;
a62d533 150
	JComboBox glyphPageCombo;
a62d533 151
	JPanel glyphCachePanel;
a62d533 152
	JRadioButton glyphCacheRadio;
a62d533 153
	JRadioButton sampleTextRadio;
a62d533 154
	DefaultComboBoxModel glyphPageComboModel;
a62d533 155
	JButton resetCacheButton;
a62d533 156
	JButton sampleAsciiButton;
a62d533 157
	JButton sampleNeheButton;
a62d533 158
	DefaultComboBoxModel effectsListModel;
a62d533 159
	JMenuItem openMenuItem;
a62d533 160
	JMenuItem saveMenuItem;
a62d533 161
	JMenuItem exitMenuItem;
a62d533 162
	JMenuItem saveBMFontMenuItem;
a62d533 163
	File saveBmFontFile;
a62d533 164
	String lastSaveFilename = "", lastSaveBMFilename = "", lastOpenFilename = "";
a62d533 165
a62d533 166
	public Hiero () {
a62d533 167
		super("Hiero v3.0 - Bitmap Font Tool");
a62d533 168
		Splash splash = new Splash(this, "/splash.jpg", 2000);
a62d533 169
		initialize();
a62d533 170
		splash.close();
a62d533 171
a62d533 172
		gamePanel.add(new LwjglCanvas(new Renderer(), false).getCanvas());
a62d533 173
a62d533 174
		prefs = Preferences.userNodeForPackage(Hiero.class);
a62d533 175
		java.awt.Color backgroundColor = EffectUtil.fromString(prefs.get("background", "000000"));
a62d533 176
		backgroundColorLabel.setIcon(getColorIcon(backgroundColor));
a62d533 177
		renderingBackgroundColor = new Color(backgroundColor.getRed() / 255f, backgroundColor.getGreen() / 255f,
a62d533 178
			backgroundColor.getBlue() / 255f, 1);
a62d533 179
		fontList.setSelectedValue(prefs.get("system.font", "Arial"), true);
a62d533 180
		fontFileText.setText(prefs.get("font.file", ""));
a62d533 181
a62d533 182
		java.awt.Color foregroundColor = EffectUtil.fromString(prefs.get("foreground", "ffffff"));
a62d533 183
		colorEffect = new ColorEffect();
a62d533 184
		colorEffect.setColor(foregroundColor);
a62d533 185
		effectsListModel.addElement(colorEffect);
a62d533 186
		effectsListModel.addElement(new GradientEffect());
a62d533 187
		effectsListModel.addElement(new OutlineEffect());
a62d533 188
		effectsListModel.addElement(new OutlineWobbleEffect());
a62d533 189
		effectsListModel.addElement(new OutlineZigzagEffect());
a62d533 190
		effectsListModel.addElement(new ShadowEffect());
a62d533 191
		effectsListModel.addElement(new DistanceFieldEffect());
a62d533 192
		new EffectPanel(colorEffect);
a62d533 193
		setVisible(true);
a62d533 194
	}
a62d533 195
a62d533 196
	void initialize () {
a62d533 197
		initializeComponents();
a62d533 198
		initializeMenus();
a62d533 199
		initializeEvents();
a62d533 200
a62d533 201
		setSize(800, 600);
a62d533 202
		setLocationRelativeTo(null);
a62d533 203
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
a62d533 204
a62d533 205
		sampleNeheButton.doClick();
a62d533 206
	}
a62d533 207
a62d533 208
	void updateFont () {
a62d533 209
		updateFont(false);
a62d533 210
	}
a62d533 211
a62d533 212
	private void updateFont (boolean ignoreFileText) {
a62d533 213
		UnicodeFont unicodeFont;
a62d533 214
a62d533 215
		int fontSize = ((Integer)fontSizeSpinner.getValue()).intValue();
a62d533 216
a62d533 217
		File file = new File(fontFileText.getText());
a62d533 218
		if (!ignoreFileText && file.exists() && file.isFile()) {
a62d533 219
			// Load from file.
a62d533 220
			fontFileRadio.setSelected(true);
a62d533 221
			fontList.setEnabled(false);
a62d533 222
			systemFontRadio.setEnabled(false);
a62d533 223
			try {
a62d533 224
				unicodeFont = new UnicodeFont(fontFileText.getText(), fontSize, boldCheckBox.isSelected(),
a62d533 225
					italicCheckBox.isSelected());
a62d533 226
			} catch (Throwable ex) {
a62d533 227
				ex.printStackTrace();
a62d533 228
				updateFont(true);
a62d533 229
				return;
a62d533 230
			}
a62d533 231
		} else {
a62d533 232
			// Load from java.awt.Font (kerning not available!).
a62d533 233
			fontList.setEnabled(true);
a62d533 234
			systemFontRadio.setEnabled(true);
a62d533 235
			systemFontRadio.setSelected(true);
a62d533 236
			unicodeFont = new UnicodeFont(Font.decode((String)fontList.getSelectedValue()), fontSize, boldCheckBox.isSelected(),
a62d533 237
				italicCheckBox.isSelected());
a62d533 238
		}
a62d533 239
		unicodeFont.setPaddingTop(((Integer)padTopSpinner.getValue()).intValue());
a62d533 240
		unicodeFont.setPaddingRight(((Integer)padRightSpinner.getValue()).intValue());
a62d533 241
		unicodeFont.setPaddingBottom(((Integer)padBottomSpinner.getValue()).intValue());
a62d533 242
		unicodeFont.setPaddingLeft(((Integer)padLeftSpinner.getValue()).intValue());
a62d533 243
		unicodeFont.setPaddingAdvanceX(((Integer)padAdvanceXSpinner.getValue()).intValue());
a62d533 244
		unicodeFont.setPaddingAdvanceY(((Integer)padAdvanceYSpinner.getValue()).intValue());
a62d533 245
		unicodeFont.setGlyphPageWidth(((Integer)glyphPageWidthCombo.getSelectedItem()).intValue());
a62d533 246
		unicodeFont.setGlyphPageHeight(((Integer)glyphPageHeightCombo.getSelectedItem()).intValue());
a62d533 247
		unicodeFont.setNativeRendering(nativeRadio.isSelected());
a62d533 248
a62d533 249
		for (Iterator iter = effectPanels.iterator(); iter.hasNext();) {
a62d533 250
			EffectPanel panel = (EffectPanel)iter.next();
a62d533 251
			unicodeFont.getEffects().add(panel.getEffect());
a62d533 252
		}
a62d533 253
a62d533 254
		int size = sampleTextPane.getFont().getSize();
a62d533 255
		if (size < 14) size = 14;
a62d533 256
		sampleTextPane.setFont(unicodeFont.getFont().deriveFont((float)size));
a62d533 257
a62d533 258
		this.newUnicodeFont = unicodeFont;
a62d533 259
	}
a62d533 260
a62d533 261
	void save (File file) throws IOException {
a62d533 262
		HieroSettings settings = new HieroSettings();
a62d533 263
		settings.setFontName((String)fontList.getSelectedValue());
a62d533 264
		settings.setFontSize(((Integer)fontSizeSpinner.getValue()).intValue());
a62d533 265
		settings.setBold(boldCheckBox.isSelected());
a62d533 266
		settings.setItalic(italicCheckBox.isSelected());
a62d533 267
		settings.setPaddingTop(((Integer)padTopSpinner.getValue()).intValue());
a62d533 268
		settings.setPaddingRight(((Integer)padRightSpinner.getValue()).intValue());
a62d533 269
		settings.setPaddingBottom(((Integer)padBottomSpinner.getValue()).intValue());
a62d533 270
		settings.setPaddingLeft(((Integer)padLeftSpinner.getValue()).intValue());
a62d533 271
		settings.setPaddingAdvanceX(((Integer)padAdvanceXSpinner.getValue()).intValue());
a62d533 272
		settings.setPaddingAdvanceY(((Integer)padAdvanceYSpinner.getValue()).intValue());
a62d533 273
		settings.setGlyphPageWidth(((Integer)glyphPageWidthCombo.getSelectedItem()).intValue());
a62d533 274
		settings.setGlyphPageHeight(((Integer)glyphPageHeightCombo.getSelectedItem()).intValue());
a62d533 275
		settings.setGlyphText(sampleTextPane.getText());
a62d533 276
		for (Iterator iter = effectPanels.iterator(); iter.hasNext();) {
a62d533 277
			EffectPanel panel = (EffectPanel)iter.next();
a62d533 278
			settings.getEffects().add(panel.getEffect());
a62d533 279
		}
a62d533 280
		settings.save(file);
a62d533 281
	}
a62d533 282
a62d533 283
	void open (File file) {
a62d533 284
		EffectPanel[] panels = (EffectPanel[])effectPanels.toArray(new EffectPanel[effectPanels.size()]);
a62d533 285
		for (int i = 0; i < panels.length; i++)
a62d533 286
			panels[i].remove();
a62d533 287
a62d533 288
		HieroSettings settings = new HieroSettings(file.getAbsolutePath());
a62d533 289
		fontList.setSelectedValue(settings.getFontName(), true);
a62d533 290
		fontSizeSpinner.setValue(new Integer(settings.getFontSize()));
a62d533 291
		boldCheckBox.setSelected(settings.isBold());
a62d533 292
		italicCheckBox.setSelected(settings.isItalic());
a62d533 293
		padTopSpinner.setValue(new Integer(settings.getPaddingTop()));
a62d533 294
		padRightSpinner.setValue(new Integer(settings.getPaddingRight()));
a62d533 295
		padBottomSpinner.setValue(new Integer(settings.getPaddingBottom()));
a62d533 296
		padLeftSpinner.setValue(new Integer(settings.getPaddingLeft()));
a62d533 297
		padAdvanceXSpinner.setValue(new Integer(settings.getPaddingAdvanceX()));
a62d533 298
		padAdvanceYSpinner.setValue(new Integer(settings.getPaddingAdvanceY()));
a62d533 299
		glyphPageWidthCombo.setSelectedItem(new Integer(settings.getGlyphPageWidth()));
a62d533 300
		glyphPageHeightCombo.setSelectedItem(new Integer(settings.getGlyphPageHeight()));
a62d533 301
		String gt = settings.getGlyphText();
a62d533 302
		if (gt.length() > 0) {
a62d533 303
			sampleTextPane.setText(settings.getGlyphText());
a62d533 304
		}
a62d533 305
a62d533 306
		for (Iterator iter = settings.getEffects().iterator(); iter.hasNext();) {
a62d533 307
			ConfigurableEffect settingsEffect = (ConfigurableEffect)iter.next();
a62d533 308
			for (int i = 0, n = effectsListModel.getSize(); i < n; i++) {
a62d533 309
				ConfigurableEffect effect = (ConfigurableEffect)effectsListModel.getElementAt(i);
a62d533 310
				if (effect.getClass() == settingsEffect.getClass()) {
a62d533 311
					effect.setValues(settingsEffect.getValues());
a62d533 312
					new EffectPanel(effect);
a62d533 313
					break;
a62d533 314
				}
a62d533 315
			}
a62d533 316
		}
a62d533 317
a62d533 318
		updateFont();
a62d533 319
	}
a62d533 320
a62d533 321
	private void initializeEvents () {
a62d533 322
		fontList.addListSelectionListener(new ListSelectionListener() {
a62d533 323
			public void valueChanged (ListSelectionEvent evt) {
a62d533 324
				if (evt.getValueIsAdjusting()) return;
a62d533 325
				prefs.put("system.font", (String)fontList.getSelectedValue());
a62d533 326
				updateFont();
a62d533 327
			}
a62d533 328
		});
a62d533 329
a62d533 330
		class FontUpdateListener implements ChangeListener, ActionListener {
a62d533 331
			public void stateChanged (ChangeEvent evt) {
a62d533 332
				updateFont();
a62d533 333
			}
a62d533 334
a62d533 335
			public void actionPerformed (ActionEvent evt) {
a62d533 336
				updateFont();
a62d533 337
			}
a62d533 338
a62d533 339
			public void addSpinners (JSpinner[] spinners) {
a62d533 340
				for (int i = 0; i < spinners.length; i++) {
a62d533 341
					final JSpinner spinner = spinners[i];
a62d533 342
					spinner.addChangeListener(this);
a62d533 343
					((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
a62d533 344
						String lastText;
a62d533 345
a62d533 346
						public void keyReleased (KeyEvent evt) {
a62d533 347
							JFormattedTextField textField = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
a62d533 348
							String text = textField.getText();
a62d533 349
							if (text.length() == 0) return;
a62d533 350
							if (text.equals(lastText)) return;
a62d533 351
							lastText = text;
a62d533 352
							int caretPosition = textField.getCaretPosition();
a62d533 353
							try {
a62d533 354
								spinner.setValue(Integer.valueOf(text));
a62d533 355
								textField.setCaretPosition(caretPosition);
a62d533 356
							} catch (Throwable ignored) {
a62d533 357
							}
a62d533 358
						}
a62d533 359
					});
a62d533 360
				}
a62d533 361
			}
a62d533 362
		}
a62d533 363
		FontUpdateListener listener = new FontUpdateListener();
a62d533 364
a62d533 365
		listener.addSpinners(new JSpinner[] {padTopSpinner, padRightSpinner, padBottomSpinner, padLeftSpinner, padAdvanceXSpinner,
a62d533 366
			padAdvanceYSpinner});
a62d533 367
		fontSizeSpinner.addChangeListener(listener);
a62d533 368
a62d533 369
		glyphPageWidthCombo.addActionListener(listener);
a62d533 370
		glyphPageHeightCombo.addActionListener(listener);
a62d533 371
		boldCheckBox.addActionListener(listener);
a62d533 372
		italicCheckBox.addActionListener(listener);
a62d533 373
		resetCacheButton.addActionListener(listener);
a62d533 374
		javaRadio.addActionListener(listener);
a62d533 375
		nativeRadio.addActionListener(listener);
a62d533 376
a62d533 377
		sampleTextRadio.addActionListener(new ActionListener() {
a62d533 378
			public void actionPerformed (ActionEvent evt) {
a62d533 379
				glyphCachePanel.setVisible(false);
a62d533 380
			}
a62d533 381
		});
a62d533 382
		glyphCacheRadio.addActionListener(new ActionListener() {
a62d533 383
			public void actionPerformed (ActionEvent evt) {
a62d533 384
				glyphCachePanel.setVisible(true);
a62d533 385
			}
a62d533 386
		});
a62d533 387
a62d533 388
		fontFileText.getDocument().addDocumentListener(new DocumentListener() {
a62d533 389
			public void removeUpdate (DocumentEvent evt) {
a62d533 390
				changed();
a62d533 391
			}
a62d533 392
a62d533 393
			public void insertUpdate (DocumentEvent evt) {
a62d533 394
				changed();
a62d533 395
			}
a62d533 396
a62d533 397
			public void changedUpdate (DocumentEvent evt) {
a62d533 398
				changed();
a62d533 399
			}
a62d533 400
a62d533 401
			private void changed () {
a62d533 402
				File file = new File(fontFileText.getText());
a62d533 403
				if (fontList.isEnabled() && (!file.exists() || !file.isFile())) return;
a62d533 404
				prefs.put("font.file", fontFileText.getText());
a62d533 405
				updateFont();
a62d533 406
			}
a62d533 407
		});
a62d533 408
a62d533 409
		fontFileRadio.addActionListener(new ActionListener() {
a62d533 410
			public void actionPerformed (ActionEvent evt) {
a62d533 411
				if (fontList.isEnabled()) systemFontRadio.setSelected(true);
a62d533 412
			}
a62d533 413
		});
a62d533 414
a62d533 415
		browseButton.addActionListener(new ActionListener() {
a62d533 416
			public void actionPerformed (ActionEvent evt) {
a62d533 417
				FileDialog dialog = new FileDialog(Hiero.this, "Choose TrueType font file", FileDialog.LOAD);
a62d533 418
				dialog.setLocationRelativeTo(null);
a62d533 419
				dialog.setFile("*.ttf");
a62d533 420
				dialog.setDirectory(prefs.get("dir.font", ""));
a62d533 421
				dialog.setVisible(true);
a62d533 422
				if (dialog.getDirectory() != null) {
a62d533 423
					prefs.put("dir.font", dialog.getDirectory());
a62d533 424
				}
a62d533 425
a62d533 426
				String fileName = dialog.getFile();
a62d533 427
				if (fileName == null) return;
a62d533 428
				fontFileText.setText(new File(dialog.getDirectory(), fileName).getAbsolutePath());
a62d533 429
			}
a62d533 430
		});
a62d533 431
a62d533 432
		backgroundColorLabel.addMouseListener(new MouseAdapter() {
a62d533 433
			public void mouseClicked (MouseEvent evt) {
a62d533 434
				java.awt.Color color = JColorChooser.showDialog(null, "Choose a background color",
a62d533 435
					EffectUtil.fromString(prefs.get("background", "000000")));
a62d533 436
				if (color == null) return;
a62d533 437
				renderingBackgroundColor = new Color(color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, 1);
a62d533 438
				backgroundColorLabel.setIcon(getColorIcon(color));
a62d533 439
				prefs.put("background", EffectUtil.toString(color));
a62d533 440
			}
a62d533 441
		});
a62d533 442
a62d533 443
		effectsList.addListSelectionListener(new ListSelectionListener() {
a62d533 444
			public void valueChanged (ListSelectionEvent evt) {
a62d533 445
				ConfigurableEffect selectedEffect = (ConfigurableEffect)effectsList.getSelectedValue();
a62d533 446
				boolean enabled = selectedEffect != null;
a62d533 447
				for (Iterator iter = effectPanels.iterator(); iter.hasNext();) {
a62d533 448
					ConfigurableEffect effect = ((EffectPanel)iter.next()).getEffect();
a62d533 449
					if (effect == selectedEffect) {
a62d533 450
						enabled = false;
a62d533 451
						break;
a62d533 452
					}
a62d533 453
				}
a62d533 454
				addEffectButton.setEnabled(enabled);
a62d533 455
			}
a62d533 456
		});
a62d533 457
a62d533 458
		effectsList.addMouseListener(new MouseAdapter() {
a62d533 459
			public void mouseClicked (MouseEvent evt) {
a62d533 460
				if (evt.getClickCount() == 2 && addEffectButton.isEnabled()) addEffectButton.doClick();
a62d533 461
			}
a62d533 462
		});
a62d533 463
a62d533 464
		addEffectButton.addActionListener(new ActionListener() {
a62d533 465
			public void actionPerformed (ActionEvent evt) {
a62d533 466
				new EffectPanel((ConfigurableEffect)effectsList.getSelectedValue());
a62d533 467
			}
a62d533 468
		});
a62d533 469
a62d533 470
		openMenuItem.addActionListener(new ActionListener() {
a62d533 471
			public void actionPerformed (ActionEvent evt) {
a62d533 472
				FileDialog dialog = new FileDialog(Hiero.this, "Open Hiero settings file", FileDialog.LOAD);
a62d533 473
				dialog.setLocationRelativeTo(null);
a62d533 474
				dialog.setFile("*.hiero");
a62d533 475
				dialog.setDirectory(prefs.get("dir.open", ""));
a62d533 476
				dialog.setVisible(true);
a62d533 477
				if (dialog.getDirectory() != null) {
a62d533 478
					prefs.put("dir.open", dialog.getDirectory());
a62d533 479
				}
a62d533 480
a62d533 481
				String fileName = dialog.getFile();
a62d533 482
				if (fileName == null) return;
a62d533 483
				lastOpenFilename = fileName;
a62d533 484
				open(new File(dialog.getDirectory(), fileName));
a62d533 485
			}
a62d533 486
		});
a62d533 487
a62d533 488
		saveMenuItem.addActionListener(new ActionListener() {
a62d533 489
			public void actionPerformed (ActionEvent evt) {
a62d533 490
				FileDialog dialog = new FileDialog(Hiero.this, "Save Hiero settings file", FileDialog.SAVE);
a62d533 491
				dialog.setLocationRelativeTo(null);
a62d533 492
				dialog.setFile("*.hiero");
a62d533 493
				dialog.setDirectory(prefs.get("dir.save", ""));
a62d533 494
a62d533 495
				if (lastSaveFilename.length() > 0) {
a62d533 496
					dialog.setFile(lastSaveFilename);
a62d533 497
				} else if (lastOpenFilename.length() > 0) {
a62d533 498
					dialog.setFile(lastOpenFilename);
a62d533 499
				}
a62d533 500
a62d533 501
				dialog.setVisible(true);
a62d533 502
a62d533 503
				if (dialog.getDirectory() != null) {
a62d533 504
					prefs.put("dir.save", dialog.getDirectory());
a62d533 505
				}
a62d533 506
a62d533 507
				String fileName = dialog.getFile();
a62d533 508
				if (fileName == null) return;
a62d533 509
				if (!fileName.endsWith(".hiero")) fileName += ".hiero";
a62d533 510
				lastSaveFilename = fileName;
a62d533 511
				File file = new File(dialog.getDirectory(), fileName);
a62d533 512
				try {
a62d533 513
					save(file);
a62d533 514
				} catch (IOException ex) {
a62d533 515
					throw new RuntimeException("Error saving Hiero settings file: " + file.getAbsolutePath(), ex);
a62d533 516
				}
a62d533 517
			}
a62d533 518
		});
a62d533 519
a62d533 520
		saveBMFontMenuItem.addActionListener(new ActionListener() {
a62d533 521
			public void actionPerformed (ActionEvent evt) {
a62d533 522
				FileDialog dialog = new FileDialog(Hiero.this, "Save BMFont files", FileDialog.SAVE);
a62d533 523
				dialog.setLocationRelativeTo(null);
a62d533 524
				dialog.setFile("*.fnt");
a62d533 525
				dialog.setDirectory(prefs.get("dir.savebm", ""));
a62d533 526
a62d533 527
				if (lastSaveBMFilename.length() > 0) {
a62d533 528
					dialog.setFile(lastSaveBMFilename);
a62d533 529
				} else if (lastOpenFilename.length() > 0) {
a62d533 530
					dialog.setFile(lastOpenFilename.replace(".hiero", ".fnt"));
a62d533 531
				}
a62d533 532
a62d533 533
				dialog.setVisible(true);
a62d533 534
				if (dialog.getDirectory() != null) {
a62d533 535
					prefs.put("dir.savebm", dialog.getDirectory());
a62d533 536
				}
a62d533 537
a62d533 538
				String fileName = dialog.getFile();
a62d533 539
				if (fileName == null) return;
a62d533 540
				lastSaveBMFilename = fileName;
a62d533 541
				saveBmFontFile = new File(dialog.getDirectory(), fileName);
a62d533 542
			}
a62d533 543
		});
a62d533 544
a62d533 545
		exitMenuItem.addActionListener(new ActionListener() {
a62d533 546
			public void actionPerformed (ActionEvent evt) {
a62d533 547
				dispose();
a62d533 548
			}
a62d533 549
		});
a62d533 550
a62d533 551
		sampleNeheButton.addActionListener(new ActionListener() {
a62d533 552
			public void actionPerformed (ActionEvent evt) {
a62d533 553
				sampleTextPane.setText(NEHE);
a62d533 554
			}
a62d533 555
		});
a62d533 556
a62d533 557
		sampleAsciiButton.addActionListener(new ActionListener() {
a62d533 558
			public void actionPerformed (ActionEvent evt) {
a62d533 559
				StringBuilder buffer = new StringBuilder();
a62d533 560
				buffer.append(NEHE);
a62d533 561
				buffer.append('\n');
a62d533 562
				int count = 0;
a62d533 563
				for (int i = 33; i <= 255; i++) {
a62d533 564
					if (buffer.indexOf(Character.toString((char)i)) != -1) continue;
a62d533 565
					buffer.append((char)i);
a62d533 566
					if (++count % 30 == 0) buffer.append('\n');
a62d533 567
				}
a62d533 568
				sampleTextPane.setText(buffer.toString());
a62d533 569
			}
a62d533 570
		});
a62d533 571
	}
a62d533 572
a62d533 573
	private void initializeComponents () {
a62d533 574
		getContentPane().setLayout(new GridBagLayout());
a62d533 575
		JPanel leftSidePanel = new JPanel();
a62d533 576
		leftSidePanel.setLayout(new GridBagLayout());
a62d533 577
		getContentPane().add(
a62d533 578
			leftSidePanel,
a62d533 579
			new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0),
a62d533 580
				0, 0));
a62d533 581
		{
a62d533 582
			JPanel fontPanel = new JPanel();
a62d533 583
			leftSidePanel.add(fontPanel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 584
				GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
a62d533 585
			fontPanel.setLayout(new GridBagLayout());
a62d533 586
			fontPanel.setBorder(BorderFactory.createTitledBorder("Font"));
a62d533 587
			{
a62d533 588
				fontSizeSpinner = new JSpinner(new SpinnerNumberModel(32, 0, 256, 1));
a62d533 589
				fontPanel.add(fontSizeSpinner, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
a62d533 590
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 591
				((JSpinner.DefaultEditor)fontSizeSpinner.getEditor()).getTextField().setColumns(2);
a62d533 592
			}
a62d533 593
			{
a62d533 594
				JScrollPane fontScroll = new JScrollPane();
a62d533 595
				fontPanel.add(fontScroll, new GridBagConstraints(1, 1, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER,
a62d533 596
					GridBagConstraints.BOTH, new Insets(0, 0, 5, 5), 0, 0));
a62d533 597
				{
a62d533 598
					fontListModel = new DefaultComboBoxModel(GraphicsEnvironment.getLocalGraphicsEnvironment()
a62d533 599
						.getAvailableFontFamilyNames());
a62d533 600
					fontList = new JList();
a62d533 601
					fontScroll.setViewportView(fontList);
a62d533 602
					fontList.setModel(fontListModel);
a62d533 603
					fontList.setVisibleRowCount(6);
a62d533 604
					fontList.setSelectedIndex(0);
a62d533 605
					fontScroll.setMinimumSize(new Dimension(220, fontList.getPreferredScrollableViewportSize().height));
a62d533 606
				}
a62d533 607
			}
a62d533 608
			{
a62d533 609
				systemFontRadio = new JRadioButton("System:", true);
a62d533 610
				fontPanel.add(systemFontRadio, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST,
a62d533 611
					GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0));
a62d533 612
				systemFontRadio.setMargin(new Insets(0, 0, 0, 0));
a62d533 613
			}
a62d533 614
			{
a62d533 615
				fontFileRadio = new JRadioButton("File:");
a62d533 616
				fontPanel.add(fontFileRadio, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
a62d533 617
					GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
a62d533 618
				fontFileRadio.setMargin(new Insets(0, 0, 0, 0));
a62d533 619
			}
a62d533 620
			{
a62d533 621
				fontFileText = new JTextField();
a62d533 622
				fontPanel.add(fontFileText, new GridBagConstraints(1, 2, 3, 1, 1.0, 0.0, GridBagConstraints.CENTER,
a62d533 623
					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
a62d533 624
			}
a62d533 625
			{
a62d533 626
				fontPanel.add(new JLabel("Size:"), new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
a62d533 627
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 628
			}
a62d533 629
			{
a62d533 630
				boldCheckBox = new JCheckBox("Bold");
a62d533 631
				fontPanel.add(boldCheckBox, new GridBagConstraints(2, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 632
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 633
			}
a62d533 634
			{
a62d533 635
				italicCheckBox = new JCheckBox("Italic");
a62d533 636
				fontPanel.add(italicCheckBox, new GridBagConstraints(3, 3, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
a62d533 637
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 638
			}
a62d533 639
			{
a62d533 640
				browseButton = new JButton("...");
a62d533 641
				fontPanel.add(browseButton, new GridBagConstraints(4, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 642
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 643
				browseButton.setMargin(new Insets(0, 0, 0, 0));
a62d533 644
			}
a62d533 645
			{
a62d533 646
				fontPanel.add(new JLabel("Rendering:"), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
a62d533 647
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 648
			}
a62d533 649
			{
a62d533 650
				javaRadio = new JRadioButton("Java");
a62d533 651
				fontPanel.add(javaRadio, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 652
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 653
				javaRadio.setSelected(true);
a62d533 654
			}
a62d533 655
			{
a62d533 656
				nativeRadio = new JRadioButton("Native");
a62d533 657
				fontPanel.add(nativeRadio, new GridBagConstraints(2, 4, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
a62d533 658
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 659
			}
a62d533 660
			ButtonGroup buttonGroup = new ButtonGroup();
a62d533 661
			buttonGroup.add(systemFontRadio);
a62d533 662
			buttonGroup.add(fontFileRadio);
a62d533 663
			buttonGroup = new ButtonGroup();
a62d533 664
			buttonGroup.add(javaRadio);
a62d533 665
			buttonGroup.add(nativeRadio);
a62d533 666
		}
a62d533 667
		{
a62d533 668
			JPanel samplePanel = new JPanel();
a62d533 669
			leftSidePanel.add(samplePanel, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
a62d533 670
				GridBagConstraints.BOTH, new Insets(5, 0, 5, 5), 0, 0));
a62d533 671
			samplePanel.setLayout(new GridBagLayout());
a62d533 672
			samplePanel.setBorder(BorderFactory.createTitledBorder("Sample Text"));
a62d533 673
			{
a62d533 674
				JScrollPane textScroll = new JScrollPane();
a62d533 675
				samplePanel.add(textScroll, new GridBagConstraints(0, 0, 3, 1, 1.0, 1.0, GridBagConstraints.CENTER,
a62d533 676
					GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0));
a62d533 677
				{
a62d533 678
					sampleTextPane = new JTextPane();
a62d533 679
					textScroll.setViewportView(sampleTextPane);
a62d533 680
				}
a62d533 681
			}
a62d533 682
			{
a62d533 683
				sampleNeheButton = new JButton();
a62d533 684
				sampleNeheButton.setText("NEHE");
a62d533 685
				samplePanel.add(sampleNeheButton, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 686
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 687
			}
a62d533 688
			{
a62d533 689
				sampleAsciiButton = new JButton();
a62d533 690
				sampleAsciiButton.setText("ASCII");
a62d533 691
				samplePanel.add(sampleAsciiButton, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.EAST,
a62d533 692
					GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 693
			}
a62d533 694
		}
a62d533 695
		{
a62d533 696
			JPanel renderingPanel = new JPanel();
a62d533 697
			leftSidePanel.add(renderingPanel, new GridBagConstraints(0, 1, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER,
a62d533 698
				GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0));
a62d533 699
			renderingPanel.setBorder(BorderFactory.createTitledBorder("Rendering"));
a62d533 700
			renderingPanel.setLayout(new GridBagLayout());
a62d533 701
			{
a62d533 702
				JPanel wrapperPanel = new JPanel();
a62d533 703
				renderingPanel.add(wrapperPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
a62d533 704
					GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0));
a62d533 705
				wrapperPanel.setLayout(new BorderLayout());
a62d533 706
				wrapperPanel.setBackground(java.awt.Color.white);
a62d533 707
				{
a62d533 708
					gamePanel = new JPanel();
a62d533 709
					wrapperPanel.add(gamePanel);
a62d533 710
					gamePanel.setLayout(new BorderLayout());
a62d533 711
					gamePanel.setBackground(java.awt.Color.white);
a62d533 712
				}
a62d533 713
			}
a62d533 714
			{
a62d533 715
				glyphCachePanel = new JPanel() {
a62d533 716
					private int maxWidth;
a62d533 717
a62d533 718
					public Dimension getPreferredSize () {
a62d533 719
						// Keep glyphCachePanel width from ever going down so the CanvasGameContainer doesn't change sizes and flicker.
a62d533 720
						Dimension size = super.getPreferredSize();
a62d533 721
						maxWidth = Math.max(maxWidth, size.width);
a62d533 722
						size.width = maxWidth;
a62d533 723
						return size;
a62d533 724
					}
a62d533 725
				};
a62d533 726
				glyphCachePanel.setVisible(false);
a62d533 727
				renderingPanel.add(glyphCachePanel, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH,
a62d533 728
					GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
a62d533 729
				glyphCachePanel.setLayout(new GridBagLayout());
a62d533 730
				{
a62d533 731
					glyphCachePanel.add(new JLabel("Glyphs:"), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
a62d533 732
						GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
a62d533 733
				}
a62d533 734
				{
a62d533 735
					glyphCachePanel.add(new JLabel("Pages:"), new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
a62d533 736
						GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
a62d533 737
				}
a62d533 738
				{
a62d533 739
					glyphCachePanel.add(new JLabel("Page width:"), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
a62d533 740
						GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
a62d533 741
				}
a62d533 742
				{
a62d533 743
					glyphCachePanel.add(new JLabel("Page height:"), new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
a62d533 744
						GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
a62d533 745
				}
a62d533 746
				{
a62d533 747
					glyphPageWidthCombo = new JComboBox(new DefaultComboBoxModel(new Integer[] {new Integer(32), new Integer(64),
a62d533 748
						new Integer(128), new Integer(256), new Integer(512), new Integer(1024), new Integer(2048)}));
a62d533 749
					glyphCachePanel.add(glyphPageWidthCombo, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
a62d533 750
						GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 751
					glyphPageWidthCombo.setSelectedIndex(4);
a62d533 752
				}
a62d533 753
				{
a62d533 754
					glyphPageHeightCombo = new JComboBox(new DefaultComboBoxModel(new Integer[] {new Integer(32), new Integer(64),
a62d533 755
						new Integer(128), new Integer(256), new Integer(512), new Integer(1024), new Integer(2048)}));
a62d533 756
					glyphCachePanel.add(glyphPageHeightCombo, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
a62d533 757
						GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 758
					glyphPageHeightCombo.setSelectedIndex(4);
a62d533 759
				}
a62d533 760
				{
a62d533 761
					resetCacheButton = new JButton("Reset Cache");
a62d533 762
					glyphCachePanel.add(resetCacheButton, new GridBagConstraints(0, 6, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER,
a62d533 763
						GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
a62d533 764
				}
a62d533 765
				{
a62d533 766
					glyphPagesTotalLabel = new JLabel("1");
a62d533 767
					glyphCachePanel.add(glyphPagesTotalLabel, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
a62d533 768
						GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 769
				}
a62d533 770
				{
a62d533 771
					glyphsTotalLabel = new JLabel("0");
a62d533 772
					glyphCachePanel.add(glyphsTotalLabel, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
a62d533 773
						GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 774
				}
a62d533 775
				{
a62d533 776
					glyphPageComboModel = new DefaultComboBoxModel();
a62d533 777
					glyphPageCombo = new JComboBox();
a62d533 778
					glyphCachePanel.add(glyphPageCombo, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST,
a62d533 779
						GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 780
					glyphPageCombo.setModel(glyphPageComboModel);
a62d533 781
				}
a62d533 782
				{
a62d533 783
					glyphCachePanel.add(new JLabel("View:"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
a62d533 784
						GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
a62d533 785
				}
a62d533 786
			}
a62d533 787
			{
a62d533 788
				JPanel radioButtonsPanel = new JPanel();
a62d533 789
				renderingPanel.add(radioButtonsPanel, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 790
					GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
a62d533 791
				radioButtonsPanel.setLayout(new GridBagLayout());
a62d533 792
				{
a62d533 793
					sampleTextRadio = new JRadioButton("Sample text");
a62d533 794
					radioButtonsPanel.add(sampleTextRadio, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 795
						GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 796
					sampleTextRadio.setSelected(true);
a62d533 797
				}
a62d533 798
				{
a62d533 799
					glyphCacheRadio = new JRadioButton("Glyph cache");
a62d533 800
					radioButtonsPanel.add(glyphCacheRadio, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 801
						GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 802
				}
a62d533 803
				{
a62d533 804
					radioButtonsPanel.add(new JLabel("Background:"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
a62d533 805
						GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0));
a62d533 806
				}
a62d533 807
				{
a62d533 808
					backgroundColorLabel = new JLabel();
a62d533 809
					radioButtonsPanel.add(backgroundColorLabel, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
a62d533 810
						GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
a62d533 811
				}
a62d533 812
				ButtonGroup buttonGroup = new ButtonGroup();
a62d533 813
				buttonGroup.add(glyphCacheRadio);
a62d533 814
				buttonGroup.add(sampleTextRadio);
a62d533 815
			}
a62d533 816
		}
a62d533 817
		JPanel rightSidePanel = new JPanel();
a62d533 818
		rightSidePanel.setLayout(new GridBagLayout());
a62d533 819
		getContentPane().add(
a62d533 820
			rightSidePanel,
a62d533 821
			new GridBagConstraints(1, 0, 1, 2, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0),
a62d533 822
				0, 0));
a62d533 823
		{
a62d533 824
			JPanel paddingPanel = new JPanel();
a62d533 825
			paddingPanel.setLayout(new GridBagLayout());
a62d533 826
			rightSidePanel.add(paddingPanel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 827
				GridBagConstraints.BOTH, new Insets(0, 0, 5, 5), 0, 0));
a62d533 828
			paddingPanel.setBorder(BorderFactory.createTitledBorder("Padding"));
a62d533 829
			{
a62d533 830
				padTopSpinner = new JSpinner();
a62d533 831
				paddingPanel.add(padTopSpinner, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 832
					GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
a62d533 833
				((JSpinner.DefaultEditor)padTopSpinner.getEditor()).getTextField().setColumns(2);
a62d533 834
			}
a62d533 835
			{
a62d533 836
				padRightSpinner = new JSpinner();
a62d533 837
				paddingPanel.add(padRightSpinner, new GridBagConstraints(2, 2, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
a62d533 838
					GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
a62d533 839
				((JSpinner.DefaultEditor)padRightSpinner.getEditor()).getTextField().setColumns(2);
a62d533 840
			}
a62d533 841
			{
a62d533 842
				padLeftSpinner = new JSpinner();
a62d533 843
				paddingPanel.add(padLeftSpinner, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.EAST,
a62d533 844
					GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0));
a62d533 845
				((JSpinner.DefaultEditor)padLeftSpinner.getEditor()).getTextField().setColumns(2);
a62d533 846
			}
a62d533 847
			{
a62d533 848
				padBottomSpinner = new JSpinner();
a62d533 849
				paddingPanel.add(padBottomSpinner, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER,
a62d533 850
					GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
a62d533 851
				((JSpinner.DefaultEditor)padBottomSpinner.getEditor()).getTextField().setColumns(2);
a62d533 852
			}
a62d533 853
			{
a62d533 854
				JPanel advancePanel = new JPanel();
a62d533 855
				FlowLayout advancePanelLayout = new FlowLayout();
a62d533 856
				advancePanel.setLayout(advancePanelLayout);
a62d533 857
				paddingPanel.add(advancePanel, new GridBagConstraints(0, 4, 3, 1, 1.0, 0.0, GridBagConstraints.CENTER,
a62d533 858
					GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
a62d533 859
				{
a62d533 860
					advancePanel.add(new JLabel("X:"));
a62d533 861
				}
a62d533 862
				{
a62d533 863
					padAdvanceXSpinner = new JSpinner();
a62d533 864
					advancePanel.add(padAdvanceXSpinner);
a62d533 865
					((JSpinner.DefaultEditor)padAdvanceXSpinner.getEditor()).getTextField().setColumns(2);
a62d533 866
				}
a62d533 867
				{
a62d533 868
					advancePanel.add(new JLabel("Y:"));
a62d533 869
				}
a62d533 870
				{
a62d533 871
					padAdvanceYSpinner = new JSpinner();
a62d533 872
					advancePanel.add(padAdvanceYSpinner);
a62d533 873
					((JSpinner.DefaultEditor)padAdvanceYSpinner.getEditor()).getTextField().setColumns(2);
a62d533 874
				}
a62d533 875
			}
a62d533 876
		}
a62d533 877
		{
a62d533 878
			JPanel effectsPanel = new JPanel();
a62d533 879
			effectsPanel.setLayout(new GridBagLayout());
a62d533 880
			rightSidePanel.add(effectsPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER,
a62d533 881
				GridBagConstraints.BOTH, new Insets(5, 0, 5, 5), 0, 0));
a62d533 882
			effectsPanel.setBorder(BorderFactory.createTitledBorder("Effects"));
a62d533 883
			effectsPanel.setMinimumSize(new Dimension(210, 1));
a62d533 884
			{
a62d533 885
				JScrollPane effectsScroll = new JScrollPane();
a62d533 886
				effectsPanel.add(effectsScroll, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH,
a62d533 887
					GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5), 0, 0));
a62d533 888
				{
a62d533 889
					effectsListModel = new DefaultComboBoxModel();
a62d533 890
					effectsList = new JList();
a62d533 891
					effectsScroll.setViewportView(effectsList);
a62d533 892
					effectsList.setModel(effectsListModel);
a62d533 893
					effectsList.setVisibleRowCount(7);
a62d533 894
					effectsScroll.setMinimumSize(effectsList.getPreferredScrollableViewportSize());
a62d533 895
				}
a62d533 896
			}
a62d533 897
			{
a62d533 898
				addEffectButton = new JButton("Add");
a62d533 899
				effectsPanel.add(addEffectButton, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
a62d533 900
					GridBagConstraints.NONE, new Insets(0, 5, 6, 5), 0, 0));
a62d533 901
				addEffectButton.setEnabled(false);
a62d533 902
			}
a62d533 903
			{
a62d533 904
				appliedEffectsScroll = new JScrollPane();
a62d533 905
				effectsPanel.add(appliedEffectsScroll, new GridBagConstraints(1, 3, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
a62d533 906
					GridBagConstraints.BOTH, new Insets(0, 0, 5, 0), 0, 0));
a62d533 907
				appliedEffectsScroll.setBorder(new EmptyBorder(0, 0, 0, 0));
a62d533 908
				appliedEffectsScroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
a62d533 909
				{
a62d533 910
					JPanel panel = new JPanel();
a62d533 911
					panel.setLayout(new GridBagLayout());
a62d533 912
					appliedEffectsScroll.setViewportView(panel);
a62d533 913
					{
a62d533 914
						appliedEffectsPanel = new JPanel();
a62d533 915
						appliedEffectsPanel.setLayout(new GridBagLayout());
a62d533 916
						panel.add(appliedEffectsPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH,
a62d533 917
							GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
a62d533 918
						appliedEffectsPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, java.awt.Color.black));
a62d533 919
					}
a62d533 920
				}
a62d533 921
			}
a62d533 922
		}
a62d533 923
	}
a62d533 924
a62d533 925
	private void initializeMenus () {
a62d533 926
		{
a62d533 927
			JMenuBar menuBar = new JMenuBar();
a62d533 928
			setJMenuBar(menuBar);
a62d533 929
			{
a62d533 930
				JMenu fileMenu = new JMenu();
a62d533 931
				menuBar.add(fileMenu);
a62d533 932
				fileMenu.setText("File");
a62d533 933
				fileMenu.setMnemonic(KeyEvent.VK_F);
a62d533 934
				{
a62d533 935
					openMenuItem = new JMenuItem("Open Hiero settings file...");
a62d533 936
					openMenuItem.setMnemonic(KeyEvent.VK_O);
a62d533 937
					openMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK));
a62d533 938
					fileMenu.add(openMenuItem);
a62d533 939
				}
a62d533 940
				{
a62d533 941
					saveMenuItem = new JMenuItem("Save Hiero settings file...");
a62d533 942
					saveMenuItem.setMnemonic(KeyEvent.VK_S);
a62d533 943
					saveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK));
a62d533 944
					fileMenu.add(saveMenuItem);
a62d533 945
				}
a62d533 946
				fileMenu.addSeparator();
a62d533 947
				{
a62d533 948
					saveBMFontMenuItem = new JMenuItem("Save BMFont files (text)...");
a62d533 949
					saveBMFontMenuItem.setMnemonic(KeyEvent.VK_B);
a62d533 950
					saveBMFontMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, KeyEvent.CTRL_MASK));
a62d533 951
					fileMenu.add(saveBMFontMenuItem);
a62d533 952
				}
a62d533 953
				fileMenu.addSeparator();
a62d533 954
				{
a62d533 955
					exitMenuItem = new JMenuItem("Exit");
a62d533 956
					exitMenuItem.setMnemonic(KeyEvent.VK_X);
a62d533 957
					fileMenu.add(exitMenuItem);
a62d533 958
				}
a62d533 959
			}
a62d533 960
		}
a62d533 961
	}
a62d533 962
a62d533 963
	static Icon getColorIcon (java.awt.Color color) {
a62d533 964
		BufferedImage image = new BufferedImage(32, 16, BufferedImage.TYPE_INT_RGB);
a62d533 965
		java.awt.Graphics g = image.getGraphics();
a62d533 966
		g.setColor(color);
a62d533 967
		g.fillRect(1, 1, 30, 14);
a62d533 968
		g.setColor(java.awt.Color.black);
a62d533 969
		g.drawRect(0, 0, 31, 15);
a62d533 970
		return new ImageIcon(image);
a62d533 971
	}
a62d533 972
a62d533 973
	private class EffectPanel extends JPanel {
a62d533 974
		final java.awt.Color selectedColor = new java.awt.Color(0xb1d2e9);
a62d533 975
a62d533 976
		final ConfigurableEffect effect;
a62d533 977
		List values;
a62d533 978
a62d533 979
		JButton deleteButton;
a62d533 980
		private JPanel valuesPanel;
a62d533 981
		JLabel nameLabel;
a62d533 982
a62d533 983
		EffectPanel (final ConfigurableEffect effect) {
a62d533 984
			this.effect = effect;
a62d533 985
			effectPanels.add(this);
a62d533 986
			effectsList.getListSelectionListeners()[0].valueChanged(null);
a62d533 987
a62d533 988
			setLayout(new GridBagLayout());
a62d533 989
			setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, java.awt.Color.black));
a62d533 990
			appliedEffectsPanel.add(this, new GridBagConstraints(0, -1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
a62d533 991
				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
a62d533 992
			{
a62d533 993
				JPanel titlePanel = new JPanel();
a62d533 994
				titlePanel.setLayout(new LayoutManager() {
a62d533 995
					public void removeLayoutComponent (Component comp) {
a62d533 996
					}
a62d533 997
a62d533 998
					public Dimension preferredLayoutSize (Container parent) {
a62d533 999
						return null;
a62d533 1000
					}
a62d533 1001
a62d533 1002
					public Dimension minimumLayoutSize (Container parent) {
a62d533 1003
						return null;
a62d533 1004
					}
a62d533 1005
a62d533 1006
					public void layoutContainer (Container parent) {
a62d533 1007
						Dimension buttonSize = deleteButton.getPreferredSize();
a62d533 1008
						deleteButton.setBounds(getWidth() - buttonSize.width - 5, 0, buttonSize.width, buttonSize.height);
a62d533 1009
a62d533 1010
						Dimension labelSize = nameLabel.getPreferredSize();
a62d533 1011
						nameLabel.setBounds(5, buttonSize.height / 2 - labelSize.height / 2, getWidth() - buttonSize.width - 5 - 5,
a62d533 1012
							labelSize.height);
a62d533 1013
					}
a62d533 1014
a62d533 1015
					public void addLayoutComponent (String name, Component comp) {
a62d533 1016
					}
a62d533 1017
				});
a62d533 1018
				{
a62d533 1019
					deleteButton = new JButton();
a62d533 1020
					titlePanel.add(deleteButton);
a62d533 1021
					deleteButton.setText("X");
a62d533 1022
					deleteButton.setMargin(new Insets(0, 0, 0, 0));
a62d533 1023
					Font font = deleteButton.getFont();
a62d533 1024
					deleteButton.setFont(new Font(font.getName(), font.getStyle(), font.getSize() - 2));
a62d533 1025
				}
a62d533 1026
				{
a62d533 1027
					nameLabel = new JLabel(effect.toString());
a62d533 1028
					titlePanel.add(nameLabel);
a62d533 1029
					Font font = nameLabel.getFont();
a62d533 1030
					nameLabel.setFont(new Font(font.getName(), Font.BOLD, font.getSize()));
a62d533 1031
				}
a62d533 1032
				titlePanel.setPreferredSize(new Dimension(0, Math.max(nameLabel.getPreferredSize().height,
a62d533 1033
					deleteButton.getPreferredSize().height)));
a62d533 1034
				add(titlePanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
a62d533 1035
					new Insets(5, 0, 0, 5), 0, 0));
a62d533 1036
				titlePanel.setOpaque(false);
a62d533 1037
			}
a62d533 1038
			{
a62d533 1039
				valuesPanel = new JPanel();
a62d533 1040
				valuesPanel.setOpaque(false);
a62d533 1041
				valuesPanel.setLayout(new GridBagLayout());
a62d533 1042
				add(valuesPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER,
a62d533 1043
					GridBagConstraints.HORIZONTAL, new Insets(0, 10, 5, 0), 0, 0));
a62d533 1044
			}
a62d533 1045
a62d533 1046
			deleteButton.addActionListener(new ActionListener() {
a62d533 1047
				public void actionPerformed (ActionEvent evt) {
a62d533 1048
					remove();
a62d533 1049
					updateFont();
a62d533 1050
				}
a62d533 1051
			});
a62d533 1052
a62d533 1053
			updateValues();
a62d533 1054
			updateFont();
a62d533 1055
		}
a62d533 1056
a62d533 1057
		public void remove () {
a62d533 1058
			effectPanels.remove(this);
a62d533 1059
			appliedEffectsPanel.remove(EffectPanel.this);
a62d533 1060
			getContentPane().validate();
a62d533 1061
			effectsList.getListSelectionListeners()[0].valueChanged(null);
a62d533 1062
		}
a62d533 1063
a62d533 1064
		public void updateValues () {
a62d533 1065
			prefs.put("foreground", EffectUtil.toString(colorEffect.getColor()));
a62d533 1066
			valuesPanel.removeAll();
a62d533 1067
			values = effect.getValues();
a62d533 1068
			for (Iterator iter = values.iterator(); iter.hasNext();)
a62d533 1069
				addValue((Value)iter.next());
a62d533 1070
		}
a62d533 1071
a62d533 1072
		public void addValue (final Value value) {
a62d533 1073
			JLabel valueNameLabel = new JLabel(value.getName() + ":");
a62d533 1074
			valuesPanel.add(valueNameLabel, new GridBagConstraints(0, -1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST,
a62d533 1075
				GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
a62d533 1076
a62d533 1077
			final JLabel valueValueLabel = new JLabel();
a62d533 1078
			valuesPanel.add(valueValueLabel, new GridBagConstraints(1, -1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST,
a62d533 1079
				GridBagConstraints.BOTH, new Insets(0, 0, 0, 5), 0, 0));
a62d533 1080
			valueValueLabel.setOpaque(true);
a62d533 1081
			if (value.getObject() instanceof java.awt.Color)
a62d533 1082
				valueValueLabel.setIcon(getColorIcon((java.awt.Color)value.getObject()));
a62d533 1083
			else
a62d533 1084
				valueValueLabel.setText(value.toString());
a62d533 1085
a62d533 1086
			valueValueLabel.addMouseListener(new MouseAdapter() {
a62d533 1087
				public void mouseEntered (MouseEvent evt) {
a62d533 1088
					valueValueLabel.setBackground(selectedColor);
a62d533 1089
				}
a62d533 1090
a62d533 1091
				public void mouseExited (MouseEvent evt) {
a62d533 1092
					valueValueLabel.setBackground(null);
a62d533 1093
				}
a62d533 1094
a62d533 1095
				public void mouseClicked (MouseEvent evt) {
a62d533 1096
					Object oldObject = value.getObject();
a62d533 1097
					value.showDialog();
a62d533 1098
					if (!value.getObject().equals(oldObject)) {
a62d533 1099
						effect.setValues(values);
a62d533 1100
						updateValues();
a62d533 1101
						updateFont();
a62d533 1102
					}
a62d533 1103
				}
a62d533 1104
			});
a62d533 1105
		}
a62d533 1106
a62d533 1107
		public ConfigurableEffect getEffect () {
a62d533 1108
			return effect;
a62d533 1109
		}
a62d533 1110
a62d533 1111
		public boolean equals (Object obj) {
a62d533 1112
			if (this == obj) return true;
a62d533 1113
			if (obj == null) return false;
a62d533 1114
			if (getClass() != obj.getClass()) return false;
a62d533 1115
			final EffectPanel other = (EffectPanel)obj;
a62d533 1116
			if (effect == null) {
a62d533 1117
				if (other.effect != null) return false;
a62d533 1118
			} else if (!effect.equals(other.effect)) return false;
a62d533 1119
			return true;
a62d533 1120
		}
a62d533 1121
	}
a62d533 1122
a62d533 1123
	static private class Splash extends JWindow {
a62d533 1124
		final int minMillis;
a62d533 1125
		final long startTime;
a62d533 1126
a62d533 1127
		public Splash (Frame frame, String imageFile, int minMillis) {
a62d533 1128
			super(frame);
a62d533 1129
			this.minMillis = minMillis;
a62d533 1130
			getContentPane().add(new JLabel(new ImageIcon(Splash.class.getResource(imageFile))), BorderLayout.CENTER);
a62d533 1131
			pack();
a62d533 1132
			setLocationRelativeTo(null);
a62d533 1133
			setVisible(true);
a62d533 1134
			startTime = System.currentTimeMillis();
a62d533 1135
		}
a62d533 1136
a62d533 1137
		public void close () {
a62d533 1138
			final long endTime = System.currentTimeMillis();
a62d533 1139
			new Thread(new Runnable() {
a62d533 1140
				public void run () {
a62d533 1141
					if (endTime - startTime < minMillis) {
a62d533 1142
						addMouseListener(new MouseAdapter() {
a62d533 1143
							public void mousePressed (MouseEvent evt) {
a62d533 1144
								dispose();
a62d533 1145
							}
a62d533 1146
						});
a62d533 1147
						try {
a62d533 1148
							Thread.sleep(minMillis - (endTime - startTime));
a62d533 1149
						} catch (InterruptedException ignored) {
a62d533 1150
						}
a62d533 1151
					}
a62d533 1152
					EventQueue.invokeLater(new Runnable() {
a62d533 1153
						public void run () {
a62d533 1154
							dispose();
a62d533 1155
						}
a62d533 1156
					});
a62d533 1157
				}
a62d533 1158
			}, "Splash").start();
a62d533 1159
		}
a62d533 1160
	}
a62d533 1161
a62d533 1162
	class Renderer implements ApplicationListener {
a62d533 1163
		private String sampleText;
a62d533 1164
a62d533 1165
		@Override
a62d533 1166
		public void create () {
a62d533 1167
			glEnable(GL_SCISSOR_TEST);
a62d533 1168
a62d533 1169
			glEnable(GL_TEXTURE_2D);
a62d533 1170
			glEnableClientState(GL_TEXTURE_COORD_ARRAY);
a62d533 1171
			glEnableClientState(GL_VERTEX_ARRAY);
a62d533 1172
a62d533 1173
			glClearColor(0, 0, 0, 0);
a62d533 1174
			glClearDepth(1);
a62d533 1175
a62d533 1176
			glDisable(GL_LIGHTING);
a62d533 1177
a62d533 1178
			glEnable(GL_BLEND);
a62d533 1179
			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
a62d533 1180
		}
a62d533 1181
a62d533 1182
		@Override
a62d533 1183
		public void resize (int width, int height) {
a62d533 1184
			glViewport(0, 0, width, height);
a62d533 1185
			glScissor(0, 0, width, height);
a62d533 1186
a62d533 1187
			glMatrixMode(GL_PROJECTION);
a62d533 1188
			glLoadIdentity();
a62d533 1189
			glOrtho(0, width, height, 0, 1, -1);
a62d533 1190
			glMatrixMode(GL_MODELVIEW);
a62d533 1191
			glLoadIdentity();
a62d533 1192
		}
a62d533 1193
a62d533 1194
		public void render () {
a62d533 1195
			int viewWidth = Gdx.graphics.getWidth();
a62d533 1196
			int viewHeight = Gdx.graphics.getHeight();
a62d533 1197
a62d533 1198
			if (newUnicodeFont != null) {
a62d533 1199
				if (unicodeFont != null) unicodeFont.destroy();
a62d533 1200
				unicodeFont = newUnicodeFont;
a62d533 1201
				newUnicodeFont = null;
a62d533 1202
			}
a62d533 1203
a62d533 1204
			if (!unicodeFont.getEffects().isEmpty() && unicodeFont.loadGlyphs(25)) {
a62d533 1205
				glyphPageComboModel.removeAllElements();
a62d533 1206
				int pageCount = unicodeFont.getGlyphPages().size();
a62d533 1207
				int glyphCount = 0;
a62d533 1208
				for (int i = 0; i < pageCount; i++) {
a62d533 1209
					glyphPageComboModel.addElement("Page " + (i + 1));
a62d533 1210
					glyphCount += ((GlyphPage)unicodeFont.getGlyphPages().get(i)).getGlyphs().size();
a62d533 1211
				}
a62d533 1212
				glyphPagesTotalLabel.setText(String.valueOf(pageCount));
a62d533 1213
				glyphsTotalLabel.setText(String.valueOf(glyphCount));
a62d533 1214
			}
a62d533 1215
a62d533 1216
			if (saveBmFontFile != null) {
a62d533 1217
				try {
a62d533 1218
					BMFontUtil bmFont = new BMFontUtil(unicodeFont);
a62d533 1219
					bmFont.save(saveBmFontFile);
a62d533 1220
				} catch (Throwable ex) {
a62d533 1221
					System.out.println("Error saving BMFont files: " + saveBmFontFile.getAbsolutePath());
a62d533 1222
					ex.printStackTrace();
a62d533 1223
				} finally {
a62d533 1224
					saveBmFontFile = null;
a62d533 1225
				}
a62d533 1226
			}
a62d533 1227
a62d533 1228
			if (unicodeFont == null) return;
a62d533 1229
a62d533 1230
			try {
a62d533 1231
				sampleText = sampleTextPane.getText();
a62d533 1232
			} catch (Exception ex) {
a62d533 1233
			}
a62d533 1234
a62d533 1235
			if (sampleTextRadio.isSelected()) {
a62d533 1236
				GL11.glClearColor(renderingBackgroundColor.r, renderingBackgroundColor.g, renderingBackgroundColor.b,
a62d533 1237
					renderingBackgroundColor.a);
a62d533 1238
				GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
a62d533 1239
				int offset = unicodeFont.getYOffset(sampleText);
a62d533 1240
				if (offset > 0) offset = 0;
a62d533 1241
				unicodeFont.drawString(0, -offset, sampleText, Color.WHITE, 0, sampleText.length());
a62d533 1242
			} else {
a62d533 1243
				GL11.glClearColor(1, 1, 1, 1);
a62d533 1244
				GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
a62d533 1245
				unicodeFont.addGlyphs(sampleText);
a62d533 1246
				// GL11.glColor4f(renderingBackgroundColor.r, renderingBackgroundColor.g, renderingBackgroundColor.b,
a62d533 1247
				// renderingBackgroundColor.a);
a62d533 1248
				// fillRect(0, 0, unicodeFont.getGlyphPageWidth() + 2, unicodeFont.getGlyphPageHeight() + 2);
a62d533 1249
				int index = glyphPageCombo.getSelectedIndex();
a62d533 1250
				List pages = unicodeFont.getGlyphPages();
a62d533 1251
				if (index >= 0 && index < pages.size()) {
a62d533 1252
					Texture texture = ((GlyphPage)pages.get(glyphPageCombo.getSelectedIndex())).getTexture();
a62d533 1253
a62d533 1254
					glDisable(GL_TEXTURE_2D);
a62d533 1255
					glColor4f(renderingBackgroundColor.r, renderingBackgroundColor.g, renderingBackgroundColor.b,
a62d533 1256
						renderingBackgroundColor.a);
a62d533 1257
					glBegin(GL_QUADS);
a62d533 1258
					glVertex3f(0, 0, 0);
a62d533 1259
					glVertex3f(0, texture.getHeight(), 0);
a62d533 1260
					glVertex3f(texture.getWidth(), texture.getHeight(), 0);
a62d533 1261
					glVertex3f(texture.getWidth(), 0, 0);
a62d533 1262
					glEnd();
a62d533 1263
					glEnable(GL_TEXTURE_2D);
a62d533 1264
a62d533 1265
					texture.bind();
a62d533 1266
					glColor4f(1, 1, 1, 1);
a62d533 1267
					glBegin(GL_QUADS);
a62d533 1268
					glTexCoord2f(0, 0);
a62d533 1269
					glVertex3f(0, 0, 0);
a62d533 1270
a62d533 1271
					glTexCoord2f(0, 1);
a62d533 1272
					glVertex3f(0, texture.getHeight(), 0);
a62d533 1273
a62d533 1274
					glTexCoord2f(1, 1);
a62d533 1275
					glVertex3f(texture.getWidth(), texture.getHeight(), 0);
a62d533 1276
a62d533 1277
					glTexCoord2f(1, 0);
a62d533 1278
					glVertex3f(texture.getWidth(), 0, 0);
a62d533 1279
					glEnd();
a62d533 1280
				}
a62d533 1281
			}
a62d533 1282
		}
a62d533 1283
a62d533 1284
		@Override
a62d533 1285
		public void pause () {
a62d533 1286
		}
a62d533 1287
a62d533 1288
		@Override
a62d533 1289
		public void resume () {
a62d533 1290
		}
a62d533 1291
a62d533 1292
		@Override
a62d533 1293
		public void dispose () {
a62d533 1294
		}
a62d533 1295
	}
a62d533 1296
}