/*
* Copyright (C) 2007 TGMG <thegamemakerguru@gmail.com>
* Copyright (C) 2007, 2008, 2010, 2011 IsmAvatar <IsmAvatar@gmail.com>
* Copyright (C) 2007, 2008 Clam <clamisgood@gmail.com>
* Copyright (C) 2007, 2008 Quadduc <quadduc@gmail.com>
* Copyright (C) 2014, Robert B. Colton
*
* This file is part of LateralGM.
* LateralGM is free software and comes with ABSOLUTELY NO WARRANTY.
* See LICENSE for details.
*/
package org.lateralgm.subframes;
import static java.lang.Integer.MAX_VALUE;
import static javax.swing.GroupLayout.DEFAULT_SIZE;
import static javax.swing.GroupLayout.PREFERRED_SIZE;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.SwingConstants;
import org.lateralgm.components.ColorSelect;
import org.lateralgm.components.CustomFileChooser;
import org.lateralgm.components.NumberField;
import org.lateralgm.components.impl.CustomFileFilter;
import org.lateralgm.components.impl.IndexButtonGroup;
import org.lateralgm.components.impl.ResNode;
import org.lateralgm.components.visual.FileChooserImagePreview;
import org.lateralgm.file.ProjectFile;
import org.lateralgm.file.iconio.ICOFile;
import org.lateralgm.main.LGM;
import org.lateralgm.main.Util;
import org.lateralgm.messages.Messages;
import org.lateralgm.resources.GameSettings;
import org.lateralgm.resources.GameSettings.ColorDepth;
import org.lateralgm.resources.GameSettings.Frequency;
import org.lateralgm.resources.GameSettings.IncludeFolder;
import org.lateralgm.resources.GameSettings.PGameSettings;
import org.lateralgm.resources.GameSettings.Priority;
import org.lateralgm.resources.GameSettings.ProgressBar;
import org.lateralgm.resources.GameSettings.Resolution;
import org.lateralgm.resources.Include;
public class GameSettingFrame extends ResourceFrame<GameSettings,PGameSettings>
{
private static final long serialVersionUID = 1L;
private static final int MAX_VIEWABLE_ICON_SIZE = 64; //Icons bigger than this are scaled down (for viewing only).
boolean imagesChanged = false;
public JPanel cardPane;
public JCheckBox startFullscreen;
public IndexButtonGroup scaling;
public NumberField scale;
public JCheckBox interpolatecolors;
public JCheckBox softwareVertexProcessing;
public ColorSelect colorbutton;
public JCheckBox resizeWindow;
public JCheckBox stayOnTop;
public JCheckBox noWindowBorder;
public JCheckBox noWindowButtons;
public JCheckBox displayMouse;
public JCheckBox freezeGame;
private JPanel makeGraphicsPane()
{
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
panel.setLayout(layout);
startFullscreen = new JCheckBox(Messages.getString("GameSettingFrame.FULLSCREEN")); //$NON-NLS-1$
plf.make(startFullscreen,PGameSettings.START_FULLSCREEN);
JPanel scalegroup = new JPanel();
GroupLayout sLayout = new GroupLayout(scalegroup);
scalegroup.setLayout(sLayout);
String t = Messages.getString("GameSettingFrame.SCALING_TITLE"); //$NON-NLS-1$
scalegroup.setBorder(BorderFactory.createTitledBorder(t));
scaling = new IndexButtonGroup(3,true,false,this);
JRadioButton osFixed = new JRadioButton(Messages.getString("GameSettingFrame.SCALING_FIXED")); //$NON-NLS-1$
scaling.add(osFixed,1);
scale = new NumberField(1,999,100);
JRadioButton osRatio = new JRadioButton(Messages.getString("GameSettingFrame.SCALING_RATIO")); //$NON-NLS-1$
scaling.add(osRatio,-1);
JRadioButton osFull = new JRadioButton(Messages.getString("GameSettingFrame.SCALING_FULL")); //$NON-NLS-1$
scaling.add(osFull,0);
//due to the complexity of this setup resolving to 1 property, we handle this in commitChanges.
sLayout.setHorizontalGroup(sLayout.createParallelGroup()
/**/.addGroup(sLayout.createSequentialGroup()
/* */.addComponent(osFixed).addPreferredGap(ComponentPlacement.RELATED)
/* */.addComponent(scale,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE).addContainerGap())
/**/.addComponent(osRatio)
/**/.addComponent(osFull));
sLayout.setVerticalGroup(sLayout.createSequentialGroup()
/**/.addGroup(sLayout.createParallelGroup(Alignment.BASELINE)
/* */.addComponent(osFixed)
/* */.addComponent(scale))
/**/.addComponent(osRatio)
/**/.addComponent(osFull));
int s = res.properties.get(PGameSettings.SCALING);
scaling.setValue(s > 1 ? 1 : s);
if (s > 1) scale.setValue(s);
scale.setEnabled(s > 0);
t = Messages.getString("GameSettingFrame.INTERPOLATE"); //$NON-NLS-1$
plf.make(interpolatecolors = new JCheckBox(t),PGameSettings.INTERPOLATE);
softwareVertexProcessing = new JCheckBox(
Messages.getString("GameSettingFrame.FORCE_SOFTWARE_VERTEX_PROCESSING")); //$NON-NLS-1$
plf.make(softwareVertexProcessing,PGameSettings.FORCE_SOFTWARE_VERTEX_PROCESSING);
JLabel backcolor = new JLabel(Messages.getString("GameSettingFrame.BACKCOLOR")); //$NON-NLS-1$
plf.make(colorbutton = new ColorSelect(),PGameSettings.COLOR_OUTSIDE_ROOM);
resizeWindow = new JCheckBox(Messages.getString("GameSettingFrame.RESIZE")); //$NON-NLS-1$
stayOnTop = new JCheckBox(Messages.getString("GameSettingFrame.STAYONTOP")); //$NON-NLS-1$
noWindowBorder = new JCheckBox(Messages.getString("GameSettingFrame.NOBORDER")); //$NON-NLS-1$
noWindowButtons = new JCheckBox(Messages.getString("GameSettingFrame.NOBUTTONS")); //$NON-NLS-1$
displayMouse = new JCheckBox(Messages.getString("GameSettingFrame.DISPLAYCURSOR")); //$NON-NLS-1$
freezeGame = new JCheckBox(Messages.getString("GameSettingFrame.FREEZE")); //$NON-NLS-1$
plf.make(resizeWindow,PGameSettings.ALLOW_WINDOW_RESIZE);
plf.make(stayOnTop,PGameSettings.ALWAYS_ON_TOP);
plf.make(noWindowBorder,PGameSettings.DONT_DRAW_BORDER);
plf.make(noWindowButtons,PGameSettings.DONT_SHOW_BUTTONS);
plf.make(displayMouse,PGameSettings.DISPLAY_CURSOR);
plf.make(freezeGame,PGameSettings.FREEZE_ON_LOSE_FOCUS);
layout.setHorizontalGroup(layout.createParallelGroup()
/**/.addComponent(startFullscreen)
/**/.addComponent(scalegroup)
/**/.addComponent(interpolatecolors)
/**/.addComponent(softwareVertexProcessing)
/**/.addGroup(layout.createSequentialGroup()
/* */.addComponent(backcolor)
/* */.addComponent(colorbutton))
/**/.addComponent(resizeWindow)
/**/.addComponent(stayOnTop)
/**/.addComponent(noWindowBorder)
/**/.addComponent(noWindowButtons)
/**/.addComponent(displayMouse)
/**/.addComponent(freezeGame));
layout.setVerticalGroup(layout.createSequentialGroup()
/**/.addComponent(startFullscreen)
/**/.addComponent(scalegroup)
/**/.addComponent(interpolatecolors)
/**/.addComponent(softwareVertexProcessing)
/**/.addGroup(layout.createParallelGroup(Alignment.BASELINE,false)
/* */.addComponent(backcolor)
/* */.addComponent(colorbutton))
/**/.addComponent(resizeWindow)
/**/.addComponent(stayOnTop)
/**/.addComponent(noWindowBorder)
/**/.addComponent(noWindowButtons)
/**/.addComponent(displayMouse)
/**/.addComponent(freezeGame)
/**/.addGap(4,4,MAX_VALUE));
return panel;
}
public JCheckBox synchronised;
public JCheckBox setResolution;
public ButtonGroup colorDepth;
public ButtonGroup resolution;
public ButtonGroup frequency;
public JPanel resolutionPane;
private <V extends Enum<V>>JPanel makeRadioPane(String title, ButtonGroup bg, PGameSettings prop,
Class<V> optsClass, String[] vals)
{
JPanel p = new JPanel();
p.setBorder(BorderFactory.createTitledBorder(title));
p.setLayout(new BoxLayout(p,BoxLayout.PAGE_AXIS));
for (String s : vals)
{
JRadioButton but = new JRadioButton(Messages.getString(s));
bg.add(but);
p.add(but);
}
plf.make(bg,prop,optsClass);
return p;
}
private JPanel makeResolutionPane()
{
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
layout.setHonorsVisibility(false);
panel.setLayout(layout);
synchronised = new JCheckBox(Messages.getString("GameSettingFrame.USE_SYNC")); //$NON-NLS-1$
plf.make(synchronised,PGameSettings.USE_SYNCHRONIZATION);
setResolution = new JCheckBox(Messages.getString("GameSettingFrame.SET_RESOLUTION")); //$NON-NLS-1$
plf.make(setResolution,PGameSettings.SET_RESOLUTION);
setResolution.addActionListener(this);
resolutionPane = new JPanel();
GroupLayout rpLayout = new GroupLayout(resolutionPane);
rpLayout.setAutoCreateGaps(true);
resolutionPane.setLayout(rpLayout);
String colDepths[] = { "GameSettingFrame.NO_CHANGE", //$NON-NLS-1$
"GameSettingFrame.16_BIT","GameSettingFrame.32_BIT" }; //$NON-NLS-1$ //$NON-NLS-2$
String resolutions[] = { "GameSettingFrame.NO_CHANGE","GameSettingFrame.320X240", //$NON-NLS-1$ //$NON-NLS-2$
"GameSettingFrame.640X480","GameSettingFrame.800X600","GameSettingFrame.1024X768", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
"GameSettingFrame.1280X1024","GameSettingFrame.1600X1200" }; //$NON-NLS-1$ //$NON-NLS-2$
String freqs[] = { "GameSettingFrame.NO_CHANGE","GameSettingFrame.60HZ", //$NON-NLS-1$ //$NON-NLS-2$
"GameSettingFrame.70HZ","GameSettingFrame.85HZ", //$NON-NLS-1$ //$NON-NLS-2$
"GameSettingFrame.100HZ","GameSettingFrame.120HZ", }; //$NON-NLS-1$ //$NON-NLS-2$
JPanel depth = makeRadioPane(Messages.getString("GameSettingFrame.TITLE_COLOR_DEPTH"), //$NON-NLS-1$
colorDepth = new ButtonGroup(),PGameSettings.COLOR_DEPTH,ColorDepth.class,colDepths);
JPanel resol = makeRadioPane(Messages.getString("GameSettingFrame.TITLE_RESOLUTION"), //$NON-NLS-1$
resolution = new ButtonGroup(),PGameSettings.RESOLUTION,Resolution.class,resolutions);
JPanel freq = makeRadioPane(Messages.getString("GameSettingFrame.TITLE_FREQUENCY"), //$NON-NLS-1$
frequency = new ButtonGroup(),PGameSettings.FREQUENCY,Frequency.class,freqs);
rpLayout.setHorizontalGroup(rpLayout.createSequentialGroup()
/**/.addComponent(depth,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/**/.addComponent(resol,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/**/.addComponent(freq,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE));
rpLayout.setVerticalGroup(rpLayout.createParallelGroup(Alignment.LEADING,false)
/**/.addComponent(depth,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/**/.addComponent(resol,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/**/.addComponent(freq,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE));
resolutionPane.setVisible(setResolution.isSelected());
layout.setHorizontalGroup(layout.createParallelGroup()
/**/.addComponent(synchronised).addComponent(setResolution).addComponent(resolutionPane));
layout.setVerticalGroup(layout.createSequentialGroup()
/**/.addComponent(synchronised).addComponent(setResolution).addComponent(resolutionPane));
return panel;
}
public JCheckBox esc, close, f1, f4, f5, f9;
public ButtonGroup gamePriority;
private JPanel makeOtherPane()
{
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
panel.setLayout(layout);
String t = Messages.getString("GameSettingFrame.TITLE_KEYS"); //$NON-NLS-1$
JPanel dKeys = new JPanel();
dKeys.setBorder(BorderFactory.createTitledBorder(t));
dKeys.setLayout(new BoxLayout(dKeys,BoxLayout.PAGE_AXIS));
esc = new JCheckBox(Messages.getString("GameSettingFrame.KEY_ENDGAME")); //$NON-NLS-1$
close = new JCheckBox(Messages.getString("GameSettingFrame.KEY_CLOSEGAME")); //$NON-NLS-1$
f1 = new JCheckBox(Messages.getString("GameSettingFrame.KEY_INFO")); //$NON-NLS-1$
f4 = new JCheckBox(Messages.getString("GameSettingFrame.KEY_SWITCHFULLSCREEN")); //$NON-NLS-1$
f5 = new JCheckBox(Messages.getString("GameSettingFrame.SAVELOAD")); //$NON-NLS-1$
f9 = new JCheckBox(Messages.getString("GameSettingFrame.KEY_SCREENSHOT")); //$NON-NLS-1$
dKeys.add(esc);
dKeys.add(close);
dKeys.add(f1);
dKeys.add(f4);
dKeys.add(f5);
dKeys.add(f9);
plf.make(esc,PGameSettings.LET_ESC_END_GAME);
plf.make(close,PGameSettings.TREAT_CLOSE_AS_ESCAPE);
plf.make(f1,PGameSettings.LET_F1_SHOW_GAME_INFO);
plf.make(f4,PGameSettings.LET_F4_SWITCH_FULLSCREEN);
plf.make(f5,PGameSettings.LET_F5_SAVE_F6_LOAD);
plf.make(f9,PGameSettings.LET_F9_SCREENSHOT);
String priorities[] = { "GameSettingFrame.PRIORITY_NORMAL", //$NON-NLS-1$
"GameSettingFrame.PRIORITY_HIGH","GameSettingFrame.PRIORITY_HIHGEST" }; //$NON-NLS-1$ //$NON-NLS-2$
JPanel priority = makeRadioPane(Messages.getString("GameSettingFrame.TITLE_PRIORITY"), //$NON-NLS-1$
gamePriority = new ButtonGroup(),PGameSettings.GAME_PRIORITY,Priority.class,priorities);
layout.setHorizontalGroup(layout.createParallelGroup()
/**/.addComponent(dKeys,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/**/.addComponent(priority,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE));
layout.setVerticalGroup(layout.createSequentialGroup()
/**/.addComponent(dKeys)
/**/.addComponent(priority));
return panel;
}
private JPanel makeTextureAtlasesPane()
{
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
panel.setLayout(layout);
return panel;
}
public JCheckBox showCustomLoadImage;
public BufferedImage customLoadingImage;
public JButton changeCustomLoad;
public JCheckBox imagePartiallyTransparent;
public NumberField loadImageAlpha;
public ButtonGroup loadBarMode;
public JRadioButton pbCustom;
public JButton backLoad;
public JButton frontLoad;
public BufferedImage backLoadImage;
public BufferedImage frontLoadImage;
public JCheckBox scaleProgressBar;
public NumberField gameId;
public JButton randomise;
private JPanel makeLoadingPane()
{
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
panel.setLayout(layout);
JPanel loadImage = new JPanel();
String t = Messages.getString("GameSettingFrame.TITLE_LOADING_IMAGE"); //$NON-NLS-1$
loadImage.setBorder(BorderFactory.createTitledBorder(t));
GroupLayout liLayout = new GroupLayout(loadImage);
loadImage.setLayout(liLayout);
showCustomLoadImage = new JCheckBox(Messages.getString("GameSettingFrame.CUSTOM_LOAD_IMAGE")); //$NON-NLS-1$
plf.make(showCustomLoadImage,PGameSettings.SHOW_CUSTOM_LOAD_IMAGE);
showCustomLoadImage.addActionListener(this);
customLoadingImage = res.properties.get(PGameSettings.LOADING_IMAGE);
changeCustomLoad = new JButton(Messages.getString("GameSettingFrame.CHANGE_IMAGE")); //$NON-NLS-1$
changeCustomLoad.setEnabled(showCustomLoadImage.isSelected());
changeCustomLoad.addActionListener(this);
imagePartiallyTransparent = new JCheckBox(
Messages.getString("GameSettingFrame.MAKE_TRANSPARENT")); //$NON-NLS-1$
plf.make(imagePartiallyTransparent,PGameSettings.IMAGE_PARTIALLY_TRANSPARENTY);
JLabel lAlpha = new JLabel(Messages.getString("GameSettingFrame.ALPHA_TRANSPARENCY")); //$NON-NLS-1$
loadImageAlpha = new NumberField(0,255);
plf.make(loadImageAlpha,PGameSettings.LOAD_IMAGE_ALPHA);
liLayout.setHorizontalGroup(liLayout.createParallelGroup()
/**/.addGroup(liLayout.createSequentialGroup()
/* */.addComponent(showCustomLoadImage).addPreferredGap(ComponentPlacement.RELATED)
/* */.addComponent(changeCustomLoad))
/**/.addComponent(imagePartiallyTransparent)
/**/.addGroup(liLayout.createSequentialGroup().addContainerGap()
/* */.addComponent(lAlpha).addPreferredGap(ComponentPlacement.RELATED)
/* */.addComponent(loadImageAlpha,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE)
/* */.addContainerGap()));
liLayout.setVerticalGroup(liLayout.createSequentialGroup()
/**/.addGroup(liLayout.createParallelGroup(Alignment.BASELINE)
/* */.addComponent(showCustomLoadImage)
/* */.addComponent(changeCustomLoad))
/**/.addComponent(imagePartiallyTransparent)
/**/.addPreferredGap(ComponentPlacement.UNRELATED)
/**/.addGroup(liLayout.createParallelGroup(Alignment.BASELINE)
/* */.addComponent(lAlpha)
/* */.addComponent(loadImageAlpha))
/**/.addContainerGap());
JRadioButton pbNo, pbDef;
JPanel progBar = new JPanel();
GroupLayout pbLayout = new GroupLayout(progBar);
t = Messages.getString("GameSettingFrame.TITLE_LOADING_PROGRESS_BAR"); //$NON-NLS-1$
progBar.setBorder(BorderFactory.createTitledBorder(t));
progBar.setLayout(pbLayout);
loadBarMode = new ButtonGroup();
loadBarMode.add(pbNo = new JRadioButton(Messages.getString("GameSettingFrame.NO_PROGRESS_BAR"))); //$NON-NLS-1$
loadBarMode.add(pbDef = new JRadioButton(
Messages.getString("GameSettingFrame.DEF_PROGRESS_BAR"))); //$NON-NLS-1$
loadBarMode.add(pbCustom = new JRadioButton(
Messages.getString("GameSettingFrame.CUSTOM_PROGRESS_BAR"))); //$NON-NLS-1$
plf.make(loadBarMode,PGameSettings.LOAD_BAR_MODE,ProgressBar.class);
backLoad = new JButton(Messages.getString("GameSettingFrame.BACK_IMAGE")); //$NON-NLS-1$
backLoad.addActionListener(this);
backLoadImage = res.properties.get(PGameSettings.BACK_LOAD_BAR);
frontLoad = new JButton(Messages.getString("GameSettingFrame.FRONT_IMAGE")); //$NON-NLS-1$
frontLoad.addActionListener(this);
frontLoadImage = res.properties.get(PGameSettings.FRONT_LOAD_BAR);
backLoad.setEnabled(pbCustom.isSelected());
frontLoad.setEnabled(backLoad.isEnabled());
scaleProgressBar = new JCheckBox(Messages.getString("GameSettingFrame.SCALE_IMAGE")); //$NON-NLS-1$
plf.make(scaleProgressBar,PGameSettings.SCALE_PROGRESS_BAR);
pbLayout.setHorizontalGroup(pbLayout.createParallelGroup()
/**/.addComponent(pbNo).addComponent(pbDef).addComponent(pbCustom)
/**/.addGroup(pbLayout.createSequentialGroup().addContainerGap()
/* */.addComponent(backLoad).addPreferredGap(ComponentPlacement.RELATED)
/* */.addComponent(frontLoad).addContainerGap())
/**/.addComponent(scaleProgressBar));
pbLayout.setVerticalGroup(pbLayout.createSequentialGroup()
/**/.addComponent(pbNo).addComponent(pbDef).addComponent(pbCustom)
/**/.addGroup(pbLayout.createParallelGroup()
/* */.addComponent(backLoad)
/* */.addComponent(frontLoad))
/**/.addComponent(scaleProgressBar));
JFileChooser fc = new JFileChooser();
fc.setFileFilter(new CustomFileFilter(Messages.getString("GameSettingFrame.ICO_FILES"),".ico")); //$NON-NLS-1$ //$NON-NLS-2$
JLabel lId = new JLabel(Messages.getString("GameSettingFrame.GAME_ID")); //$NON-NLS-1$
gameId = new NumberField(0,100000000);
plf.make(gameId,PGameSettings.GAME_ID);
randomise = new JButton(Messages.getString("GameSettingFrame.RANDOMIZE")); //$NON-NLS-1$
randomise.addActionListener(this);
layout.setHorizontalGroup(layout.createParallelGroup()
/**/.addComponent(loadImage,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/**/.addComponent(progBar,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/**/.addGroup(layout.createSequentialGroup()
/* */.addGroup(layout.createParallelGroup()
/* */.addGroup(layout.createSequentialGroup()
/* */.addComponent(lId)
/* */.addComponent(gameId,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE)))
/* */.addGroup(layout.createParallelGroup()
/* */.addComponent(randomise,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE))));
layout.setVerticalGroup(layout.createSequentialGroup()
/**/.addComponent(loadImage)
/**/.addComponent(progBar)
/**/.addGroup(layout.createParallelGroup(Alignment.BASELINE)
/* */.addComponent(lId)
/* */.addComponent(gameId)
/* */.addComponent(randomise)));
return panel;
}
public JList<Include> includes;
public ButtonGroup exportFolder;
public JCheckBox overwriteExisting;
public JCheckBox removeAtGameEnd;
private CustomFileChooser includesFc;
private JPanel makeIncludePane()
{
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
panel.setLayout(layout);
String incFolders[] = { "GameSettingFrame.SAME_FOLDER","GameSettingFrame.TEMP_DIRECTORY" }; //$NON-NLS-1$ //$NON-NLS-2$
JPanel folderPanel = makeRadioPane(
Messages.getString("GameSettingFrame.EXPORT_TO"), //$NON-NLS-1$
exportFolder = new ButtonGroup(),PGameSettings.INCLUDE_FOLDER,IncludeFolder.class,
incFolders);
overwriteExisting = new JCheckBox(Messages.getString("GameSettingFrame.OVERWRITE_EXISTING")); //$NON-NLS-1$
removeAtGameEnd = new JCheckBox(Messages.getString("GameSettingFrame.REMOVE_FILES_AT_END")); //$NON-NLS-1$
plf.make(overwriteExisting,PGameSettings.OVERWRITE_EXISTING);
plf.make(removeAtGameEnd,PGameSettings.REMOVE_AT_GAME_END);
includesFc = new CustomFileChooser("/org/lateralgm","LAST_INCLUDES_DIR"); //$NON-NLS-1$ //$NON-NLS-2$
includesFc.setMultiSelectionEnabled(true);
layout.setHorizontalGroup(layout.createParallelGroup()
/**/.addGroup(layout.createSequentialGroup()
/* */.addComponent(folderPanel).addGap(4,8,MAX_VALUE)
/* */.addGroup(layout.createParallelGroup()
/* */.addComponent(overwriteExisting)
/* */.addComponent(removeAtGameEnd))));
layout.setVerticalGroup(layout.createSequentialGroup()
/**/.addGroup(layout.createParallelGroup()
/* */.addComponent(folderPanel)
/* */.addGroup(layout.createSequentialGroup()
/* */.addComponent(overwriteExisting)
/* */.addComponent(removeAtGameEnd))));
return panel;
}
JCheckBox displayErrors;
JCheckBox writeToLog;
JCheckBox abortOnError;
JCheckBox treatUninitialisedAs0;
JCheckBox errorOnArgs;
private JPanel makeErrorPane()
{
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
panel.setLayout(layout);
displayErrors = new JCheckBox(Messages.getString("GameSettingFrame.ERRORS_DISPLAY")); //$NON-NLS-1$
writeToLog = new JCheckBox(Messages.getString("GameSettingFrame.ERRORS_LOG")); //$NON-NLS-1$
abortOnError = new JCheckBox(Messages.getString("GameSettingFrame.ERRORS_ABORT")); //$NON-NLS-1$
treatUninitialisedAs0 = new JCheckBox(Messages.getString("GameSettingFrame.UNINITZERO")); //$NON-NLS-1$
errorOnArgs = new JCheckBox(Messages.getString("GameSettingFrame.ERRORS_ARGS")); //$NON-NLS-1$
plf.make(displayErrors,PGameSettings.DISPLAY_ERRORS);
plf.make(writeToLog,PGameSettings.WRITE_TO_LOG);
plf.make(abortOnError,PGameSettings.ABORT_ON_ERROR);
plf.make(treatUninitialisedAs0,PGameSettings.TREAT_UNINIT_AS_0);
plf.make(errorOnArgs,PGameSettings.ERROR_ON_ARGS);
layout.setHorizontalGroup(layout.createParallelGroup().
/**/addComponent(displayErrors).addComponent(writeToLog).addComponent(abortOnError).
/**/addComponent(treatUninitialisedAs0).addComponent(errorOnArgs));
layout.setVerticalGroup(layout.createSequentialGroup()
/**/.addComponent(displayErrors).addComponent(writeToLog).addComponent(abortOnError).
/**/addComponent(treatUninitialisedAs0).addComponent(errorOnArgs));
return panel;
}
JTextField author;
JTextField version;
JTextField lastChanged;
JTextArea information;
private JPanel makeInfoPane()
{
JPanel panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
JLabel lAuthor = new JLabel(Messages.getString("GameSettingFrame.AUTHOR")); //$NON-NLS-1$
author = new JTextField();
JLabel lVersion = new JLabel(Messages.getString("GameSettingFrame.VERSION")); //$NON-NLS-1$
version = new JTextField();
JLabel lChanged = new JLabel(Messages.getString("GameSettingFrame.LASTCHANGED")); //$NON-NLS-1$
lastChanged = new JTextField(ProjectFile.gmTimeToString(res.getLastChanged()));
lastChanged.setEditable(false);
JLabel lInfo = new JLabel(Messages.getString("GameSettingFrame.INFORMATION")); //$NON-NLS-1$
information = new JTextArea();
information.setLineWrap(true);
JScrollPane infoScroll = new JScrollPane(information);
plf.make(author.getDocument(),PGameSettings.AUTHOR);
plf.make(version.getDocument(),PGameSettings.VERSION);
plf.make(information.getDocument(),PGameSettings.INFORMATION);
layout.setHorizontalGroup(layout.createParallelGroup()
/**/.addGroup(layout.createSequentialGroup()
/* */.addGroup(layout.createParallelGroup(Alignment.TRAILING)
/* */.addComponent(lAuthor)
/* */.addComponent(lVersion)
/* */.addComponent(lChanged))
/* */.addGroup(layout.createParallelGroup()
/* */.addComponent(author,DEFAULT_SIZE,240,MAX_VALUE)
/* */.addComponent(version,DEFAULT_SIZE,240,MAX_VALUE)
/* */.addComponent(lastChanged,DEFAULT_SIZE,240,MAX_VALUE)))
/**/.addComponent(lInfo,DEFAULT_SIZE,320,MAX_VALUE)
/**/.addComponent(infoScroll));
layout.setVerticalGroup(layout.createSequentialGroup()
/**/.addGroup(layout.createParallelGroup(Alignment.BASELINE)
/* */.addComponent(lAuthor)
/* */.addComponent(author))
/**/.addGroup(layout.createParallelGroup(Alignment.BASELINE)
/* */.addComponent(lVersion)
/* */.addComponent(version))
/**/.addGroup(layout.createParallelGroup(Alignment.BASELINE)
/* */.addComponent(lChanged)
/* */.addComponent(lastChanged))
/**/.addComponent(lInfo)
/**/.addComponent(infoScroll));
panel.setLayout(layout);
return panel;
}
public JLabel iconPreview;
public ICOFile gameIcon;
public JButton changeIcon;
private CustomFileChooser iconFc;
private static BufferedImage scale_image(BufferedImage src, int imgType, int destSize) {
if(src == null) { return null; }
BufferedImage dest = new BufferedImage(destSize, destSize, imgType);
Graphics2D g = dest.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
AffineTransform at = AffineTransform.getScaleInstance(destSize/((float)src.getWidth()), destSize/((float)src.getHeight()));
g.drawRenderedImage(src, at);
return dest;
}
private void setIconPreviewToGameIcon() {
BufferedImage src = null;
if (gameIcon != null) {
src = (BufferedImage)gameIcon.getDisplayImage();
if (src!=null) {
if (src.getWidth()>32 || src.getHeight()>32) {
src = scale_image((BufferedImage)src, BufferedImage.TYPE_INT_ARGB, MAX_VIEWABLE_ICON_SIZE);
}
}
}
iconPreview.setIcon(new ImageIcon(src));
}
NumberField versionMajorField;
NumberField versionMinorField;
NumberField versionReleaseField;
NumberField versionBuildField;
JTextField companyField;
JTextField productField;
JTextField copyrightField;
JTextField descriptionField;
private JPanel makeWindowsPane() {
JPanel panel = new JPanel();
gameIcon = res.properties.get(PGameSettings.GAME_ICON);
iconPreview = new JLabel(Messages.getString("GameSettingFrame.GAME_ICON")); //$NON-NLS-1$
setIconPreviewToGameIcon();
iconPreview.setHorizontalTextPosition(SwingConstants.LEFT);
changeIcon = new JButton(Messages.getString("GameSettingFrame.CHANGE_ICON")); //$NON-NLS-1$
changeIcon.addActionListener(this);
iconFc = new CustomFileChooser("/org/lateralgm","LAST_ICON_DIR"); //$NON-NLS-1$ //$NON-NLS-2$
iconFc.setAccessory(new FileChooserImagePreview(iconFc));
iconFc.setFileFilter(new CustomFileFilter(
Messages.getString("GameSettingFrame.ICO_FILES"),".ico")); //$NON-NLS-1$ //$NON-NLS-2$
JPanel versionPanel = new JPanel();
versionPanel.setBorder(BorderFactory.createTitledBorder(Messages.getString("GameSettingFrame.VERSION_INFORMATION")));
JLabel versionLabel = new JLabel(Messages.getString("GameSettingFrame.VERSION"));
versionMajorField = new NumberField(0);
plf.make(versionMajorField,PGameSettings.VERSION_MAJOR);
versionMinorField = new NumberField(0);
plf.make(versionMinorField,PGameSettings.VERSION_MINOR);
versionReleaseField = new NumberField(0);
plf.make(versionReleaseField,PGameSettings.VERSION_RELEASE);
versionBuildField = new NumberField(0);
plf.make(versionBuildField,PGameSettings.VERSION_BUILD);
JLabel companyLabel = new JLabel(Messages.getString("GameSettingFrame.COMPANY"));
companyField = new JTextField("");
plf.make(companyField.getDocument(),PGameSettings.COMPANY);
JLabel productLabel = new JLabel(Messages.getString("GameSettingFrame.PRODUCT"));
productField = new JTextField("");
plf.make(productField.getDocument(),PGameSettings.PRODUCT);
JLabel copyrightLabel = new JLabel(Messages.getString("GameSettingFrame.COPYRIGHT"));
copyrightField = new JTextField("");
plf.make(copyrightField.getDocument(),PGameSettings.COPYRIGHT);
JLabel descriptionLabel = new JLabel(Messages.getString("GameSettingFrame.DESCRIPTION"));
descriptionField = new JTextField("");
plf.make(descriptionField.getDocument(),PGameSettings.DESCRIPTION);
GroupLayout vl = new GroupLayout(versionPanel);
vl.setAutoCreateGaps(true);
vl.setAutoCreateContainerGaps(true);
vl.setHorizontalGroup(vl.createSequentialGroup()
/**/.addGroup(vl.createParallelGroup(Alignment.TRAILING)
/* */.addComponent(versionLabel)
/* */.addComponent(companyLabel)
/* */.addComponent(productLabel)
/* */.addComponent(copyrightLabel)
/* */.addComponent(descriptionLabel))
/**/.addGroup(vl.createParallelGroup()
/* */.addGroup(vl.createSequentialGroup()
/* */.addComponent(versionMajorField)
/* */.addComponent(versionMinorField)
/* */.addComponent(versionReleaseField)
/* */.addComponent(versionBuildField))
/* */.addComponent(companyField)
/* */.addComponent(productField)
/* */.addComponent(copyrightField)
/* */.addComponent(descriptionField)));
vl.setVerticalGroup(vl.createSequentialGroup()
/**/.addGroup(vl.createParallelGroup(Alignment.CENTER)
/* */.addComponent(versionLabel)
/* */.addComponent(versionMajorField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE)
/* */.addComponent(versionMinorField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE)
/* */.addComponent(versionReleaseField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE)
/* */.addComponent(versionBuildField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE))
/**/.addGroup(vl.createParallelGroup(Alignment.CENTER)
/* */.addComponent(companyLabel)
/* */.addComponent(companyField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE))
/**/.addGroup(vl.createParallelGroup(Alignment.CENTER)
/* */.addComponent(productLabel)
/* */.addComponent(productField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE))
/**/.addGroup(vl.createParallelGroup(Alignment.CENTER)
/* */.addComponent(copyrightLabel)
/* */.addComponent(copyrightField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE))
/**/.addGroup(vl.createParallelGroup(Alignment.CENTER)
/* */.addComponent(descriptionLabel)
/* */.addComponent(descriptionField, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE)));
versionPanel.setLayout(vl);
GroupLayout gl = new GroupLayout(panel);
gl.setAutoCreateGaps(true);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createParallelGroup()
/**/.addGroup(gl.createSequentialGroup()
/* */.addComponent(iconPreview)
/* */.addComponent(changeIcon))
/**/.addComponent(versionPanel));
gl.setVerticalGroup(gl.createSequentialGroup()
/**/.addGroup(gl.createParallelGroup()
/* */.addComponent(iconPreview)
/* */.addComponent(changeIcon))
/**/.addComponent(versionPanel));
panel.setLayout(gl);
return panel;
}
public JButton discardButton;
public JTree tree;
public GameSettingFrame(GameSettings res)
{
this(res,null);
}
public void updateTitle() {
this.setTitle(Messages.getString("GameSettingFrame.TITLE") + " : " + resOriginal.getName());
}
public GameSettingFrame(GameSettings res, ResNode node)
{
super(res,node,Messages.getString("GameSettingFrame.TITLE"),true,true,true,true); //$NON-NLS-1$
setDefaultCloseOperation(HIDE_ON_CLOSE);
GroupLayout layout = new GroupLayout(getContentPane());
layout.setAutoCreateGaps(true);
setLayout(layout);
String t = Messages.getString("GameSettingFrame.BUTTON_SAVE"); //$NON-NLS-1$
save.setText(t);
t = Messages.getString("GameSettingFrame.BUTTON_DISCARD"); //$NON-NLS-1$
discardButton = new JButton(t);
discardButton.addActionListener(this);
discardButton.setIcon(LGM.getIconForKey("GameSettingFrame.BUTTON_DISCARD"));
// make discard button the height as save, Win32 look and feel makes
// buttons with icons 2x as tall
discardButton.setMinimumSize(save.getMaximumSize());
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Preferences");
tree = new JTree(new DefaultTreeModel(root));
tree.setEditable(false);
//tree.expandRow(0);
tree.setRootVisible(false);
tree.setShowsRootHandles(true);
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
// Simplest way to stop updateUI/setUI calls for changing the look and feel from reverting the
// tree icons.
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
renderer.setLeafIcon(null);
renderer.setClosedIcon(null);
renderer.setOpenIcon(null);
tree.setCellRenderer(renderer);
buildTabs(root);
// reload after adding all root children to make sure its children are visible
((DefaultTreeModel)tree.getModel()).reload();
tree.addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
tree.getLastSelectedPathComponent();
// if nothing is selected
if (node == null) return;
// retrieve the node that was selected
String nodeInfo = node.getUserObject().toString();
CardLayout cl = (CardLayout)(cardPane.getLayout());
cl.show(cardPane, nodeInfo);
}
});
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,
new JScrollPane(tree),cardPane);
split.setDividerLocation(200);
layout.setHorizontalGroup(layout.createParallelGroup()
/**/.addComponent(split)
/**/.addGroup(layout.createSequentialGroup()
/* */.addContainerGap()
/* */.addComponent(save,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/* */.addComponent(discardButton,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)
/* */.addContainerGap()));
layout.setVerticalGroup(layout.createSequentialGroup()
/**/.addComponent(split)
/**/.addPreferredGap(ComponentPlacement.UNRELATED)
/**/.addGroup(layout.createParallelGroup()
/* */.addComponent(save)
/* */.addComponent(discardButton))
/**/.addContainerGap());
pack();
this.setSize(600,500);
}
private DefaultMutableTreeNode buildTab(DefaultMutableTreeNode root, String key, JComponent pane) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(Messages.getString(key));
root.add(node);
if (pane != null) {
pane.setName(key);
cardPane.add(Messages.getString(key),pane);
}
return node;
}
private void buildTabs(DefaultMutableTreeNode root)
{
cardPane = new JPanel(new CardLayout());
buildTab(root, "GameSettingFrame.TAB_GRAPHICS", makeGraphicsPane());
buildTab(root, "GameSettingFrame.TAB_RESOLUTION", makeResolutionPane());
buildTab(root, "GameSettingFrame.TAB_OTHER", makeOtherPane());
buildTab(root, "GameSettingFrame.TAB_LOADING", makeLoadingPane());
buildTab(root, "GameSettingFrame.TAB_INCLUDE", makeIncludePane());
buildTab(root, "GameSettingFrame.TAB_ERRORS", makeErrorPane());
buildTab(root, "GameSettingFrame.TAB_INFO", makeInfoPane());
buildTab(root, "GameSettingFrame.TAB_TEXTUREATLASES", makeTextureAtlasesPane());
DefaultMutableTreeNode pnode = buildTab(root, "GameSettingFrame.TAB_PLATFORMS", null);
buildTab(pnode, "GameSettingFrame.TAB_WINDOWS", makeWindowsPane());
buildTab(pnode, "GameSettingFrame.TAB_MAC", null);
buildTab(pnode, "GameSettingFrame.TAB_UBUNTU", null);
}
public void actionPerformed(ActionEvent e)
{
super.actionPerformed(e);
if (e.getSource() == discardButton)
{
revertResource();
close();
return;
}
//TODO: icky way of getting the selected index
String name = null;
for (Component comp : cardPane.getComponents()) {
name = comp.getName();
if (comp.isVisible() == true && name != null) {
break;
}
}
if (name == null) return;
if (name.endsWith(".TAB_GRAPHICS")) {
if (e.getSource() instanceof JRadioButton) scale.setEnabled(scaling.getValue() > 0);
} else if (name.endsWith(".TAB_RESOLUTION")) {
resolutionPane.setVisible(setResolution.isSelected());
} else if (name.endsWith(".TAB_LOADING")) {
loadActionPerformed(e);
} else if (name.endsWith(".TAB_WINDOWS")) {
windowsActionPerformed(e);
}
}
private void windowsActionPerformed(ActionEvent e)
{
if (e.getSource() == changeIcon)
{
if (iconFc.showOpenDialog(LGM.frame) == JFileChooser.APPROVE_OPTION)
{
File f = iconFc.getSelectedFile();
if (f.exists()) try
{
FileInputStream fis = new FileInputStream(f);
gameIcon = new ICOFile(fis);
fis.close();
setIconPreviewToGameIcon();
imagesChanged = true;
}
catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
}
private void loadActionPerformed(ActionEvent e)
{
if (e.getSource() == showCustomLoadImage)
{
changeCustomLoad.setEnabled(showCustomLoadImage.isSelected());
}
else if (e.getSource() == changeCustomLoad)
{
try
{
customLoadingImage = Util.getValidImage();
imagesChanged = true;
}
catch (Throwable ex)
{
JOptionPane.showMessageDialog(LGM.frame,
Messages.getString("GameSettingFrame.ERROR_LOADING_IMAGE")); //$NON-NLS-1$
}
}
else if (e.getSource() instanceof JRadioButton)
{
backLoad.setEnabled(pbCustom.isSelected());
frontLoad.setEnabled(backLoad.isEnabled());
}
else if (e.getSource() == backLoad)
{
BufferedImage img = Util.getValidImage();
if (img != null)
{
backLoadImage = img;
imagesChanged = true;
}
}
else if (e.getSource() == frontLoad)
{
BufferedImage img = Util.getValidImage();
if (img != null)
{
frontLoadImage = img;
imagesChanged = true;
}
}
else if (e.getSource() == randomise)
{
gameId.setValue(new Random().nextInt(100000001));
}
}
public void commitChanges()
{
// in GMX this is two options binded together into one value
//res.put(PGameSettings.FORCE_SOFTWARE_VERTEX_PROCESSING,softwareVertexProcessing.is);
res.put(PGameSettings.SCALING,scaling.getValue() > 0 ? scale.getIntValue() : scaling.getValue());
res.put(PGameSettings.LOADING_IMAGE,customLoadingImage);
res.put(PGameSettings.BACK_LOAD_BAR,backLoadImage);
res.put(PGameSettings.FRONT_LOAD_BAR,frontLoadImage);
res.put(PGameSettings.GAME_ICON,gameIcon);
// we don't update the lastChanged time - that's only altered on file save/load
}
public void setComponents(GameSettings g)
{
int s = g.get(PGameSettings.SCALING);
scaling.setValue(s > 1 ? 1 : s);
if (s > 1) scale.setValue(s);
scale.setEnabled(s > 0);
lastChanged.setText(ProjectFile.gmTimeToString(g.getLastChanged()));
customLoadingImage = g.get(PGameSettings.LOADING_IMAGE);
backLoadImage = g.get(PGameSettings.BACK_LOAD_BAR);
frontLoadImage = g.get(PGameSettings.FRONT_LOAD_BAR);
gameIcon = g.get(PGameSettings.GAME_ICON);
setIconPreviewToGameIcon();
imagesChanged = true;
}
@Override
public String getConfirmationName()
{
return getTitle();
}
@Override
public boolean resourceChanged()
{
// NOTE: commit changes must be the first line because if we don't
// the method will be flagged that we handled committing ourselves,
// and the changes wont actually get committed.
commitChanges();
if (frameListener != null && frameListener.resourceChanged()) return true;
if (imagesChanged) return true;
return !res.properties.equals(resOriginal.properties);
}
@Override
public void revertResource()
{
if (frameListener != null) frameListener.revertResource();
res.properties.putAll(resOriginal.properties);
setComponents(res);
plf.setMap(res.properties);
imagesChanged = false;
}
@Override
public void updateResource(boolean commit)
{
super.updateResource(commit);
imagesChanged = false;
}
}