/*
* MegaMek - Copyright (C) 2000-2003 Ben Mazur (bmazur@sev.org)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
package megamek.client.ui.AWT;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Checkbox;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dialog;
import java.awt.FileDialog;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Panel;
import java.awt.SystemColor;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Iterator;
import keypoint.PngEncoder;
import megamek.client.event.BoardViewEvent;
import megamek.client.event.BoardViewListenerAdapter;
import megamek.client.ui.Messages;
import megamek.common.Coords;
import megamek.common.Game;
import megamek.common.Hex;
import megamek.common.IBoard;
import megamek.common.IHex;
import megamek.common.ITerrain;
import megamek.common.MapSettings;
import megamek.common.Terrains;
import megamek.common.util.BoardUtilities;
/**
* The BoardEditor class is a
*/
public class BoardEditor extends Container implements ItemListener,
ActionListener, TextListener, IMapSettingsObserver {
/**
* Serialization ID.
*/
private static final long serialVersionUID = -8281854232284355981L;
private final Frame frame = new Frame();
private final Game game = new Game();
private IBoard board = game.getBoard();
private BoardView1 bv;
private final CommonMenuBar menuBar = new CommonMenuBar();
private CommonAboutDialog about = null;
private CommonHelpDialog help = null;
private CommonSettingsDialog setdlg = null;
/**
* The current working hex.
*/
private IHex curHex = new Hex();
private String curpath, curfile, curfileImage;
// buttons and labels and such:
private HexCanvas canHex;
private Label labElev;
private TextField texElev;
private Button butElevUp;
private Button butElevDown;
private Label labTerrain;
private java.awt.List lisTerrain;
private Button butDelTerrain;
private Panel panTerrainType;
private Choice choTerrainType;
private TextField texTerrainLevel;
private Panel panTerrExits;
private Checkbox cheTerrExitSpecified;
private TextField texTerrExits;
private Button butTerrExits;
private Panel panRoads;
private Checkbox cheRoadsAutoExit;
private Label labTheme;
private TextField texTheme;
private Button butAddTerrain;
private Label blankL;
private Label labBoard;
private Panel panButtons;
private Button butBoardNew, butBoardLoad;
private Button butBoardSave, butBoardSaveAs;
private Button butBoardSaveAsImage;
private Button butMiniMap;
private Dialog minimapW;
private MiniMap minimap;
private Coords lastClicked;
private MapSettings mapSettings = new MapSettings();
/**
* Creates and lays out a new Board Editor frame.
*/
public BoardEditor() {
try {
bv = new BoardView1(game);
} catch (final IOException e) {
new AlertDialog(
frame,
Messages.getString("BoardEditor.FatalError"), Messages.getString("BoardEditor.CouldntInitialize") + e); //$NON-NLS-1$ //$NON-NLS-2$
frame.dispose();
}
bv.addBoardViewListener(new BoardViewListenerAdapter() {
public void hexMoused(final BoardViewEvent b) {
final Coords c = b.getCoords();
if (c.equals(lastClicked))
return;
lastClicked = c;
bv.cursor(c);
if ((b.getModifiers() & InputEvent.ALT_MASK) != 0) {
setCurrentHex(board.getHex(b.getCoords()));
} else if ((b.getModifiers() & InputEvent.CTRL_MASK) != 0) {
if (!board.getHex(b.getCoords()).equals(curHex)) {
paintHex(b.getCoords());
}
} else if ((b.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
addToHex(b.getCoords());
} else if ((b.getModifiers() & InputEvent.BUTTON1_MASK) != 0) {
resurfaceHex(b.getCoords());
}
}
});
bv.setUseLOSTool(false);
setupEditorPanel();
setupFrame();
frame.setVisible(true);
if (true == GUIPreferences.getInstance().getNagForMapEdReadme()) {
final String title = Messages.getString("BoardEditor.readme.title"); //$NON-NLS-1$
final String body = Messages
.getString("BoardEditor.readme.message"); //$NON-NLS-1$
final ConfirmDialog confirm = new ConfirmDialog(frame, title, body,
true);
confirm.setVisible(true);
if (!confirm.getShowAgain()) {
GUIPreferences.getInstance().setNagForMapEdReadme(false);
}
if (confirm.getAnswer()) {
showHelp();
}
}
}
/**
* Sets up the frame that will display the editor.
*/
private void setupFrame() {
frame.setTitle(Messages.getString("BoardEditor.title")); //$NON-NLS-1$
frame.setLayout(new BorderLayout());
frame.add(bv.getComponent(), BorderLayout.CENTER);
frame.add(this, BorderLayout.EAST);
menuBar.addActionListener(this);
frame.setMenuBar(menuBar);
frame.setBackground(SystemColor.menu);
frame.setForeground(SystemColor.menuText);
if (GUIPreferences.getInstance().getWindowSizeHeight() != 0) {
frame.setLocation(GUIPreferences.getInstance().getWindowPosX(),
GUIPreferences.getInstance().getWindowPosY());
frame.setSize(GUIPreferences.getInstance().getWindowSizeWidth(),
GUIPreferences.getInstance().getWindowSizeHeight());
} else {
frame.setSize(800, 600);
}
// when frame is closing, just hide it
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(final WindowEvent e) {
frame.setVisible(false);
setMapVisible(false);
}
});
}
/**
* Sets up the editor panel, which goes on the right of the map and has
* controls for editing the current square.
*/
private void setupEditorPanel() {
canHex = new HexCanvas();
labElev = new Label(
Messages.getString("BoardEditor.labElev"), Label.RIGHT); //$NON-NLS-1$
texElev = new TextField("0", 1); //$NON-NLS-1$
texElev.addActionListener(this);
texElev.addTextListener(this);
butElevUp = new Button(Messages.getString("BoardEditor.butElevUp")); //$NON-NLS-1$
butElevUp.addActionListener(this);
butElevDown = new Button(Messages.getString("BoardEditor.butElevDown")); //$NON-NLS-1$
butElevDown.addActionListener(this);
labTerrain = new Label(
Messages.getString("BoardEditor.labTerrain"), Label.LEFT); //$NON-NLS-1$
lisTerrain = new java.awt.List(6);
lisTerrain.addItemListener(this);
refreshTerrainList();
butDelTerrain = new Button(Messages
.getString("BoardEditor.butDelTerrain")); //$NON-NLS-1$
butDelTerrain.addActionListener(this);
choTerrainType = new Choice();
for (int i = 1; i < Terrains.SIZE; i++) {
choTerrainType.add(Terrains.getName(i));
}
texTerrainLevel = new TextField("1", 1); //$NON-NLS-1$
butAddTerrain = new Button(Messages
.getString("BoardEditor.butAddTerrain")); //$NON-NLS-1$
butAddTerrain.addActionListener(this);
butMiniMap = new Button(Messages.getString("BoardEditor.butMiniMap")); //$NON-NLS-1$
butMiniMap.setActionCommand("viewMiniMap"); //$NON-NLS-1$
butMiniMap.addActionListener(this);
panTerrainType = new Panel(new BorderLayout());
panTerrainType.add(choTerrainType, BorderLayout.WEST);
panTerrainType.add(texTerrainLevel, BorderLayout.CENTER);
cheTerrExitSpecified = new Checkbox(Messages
.getString("BoardEditor.cheTerrExitSpecified")); //$NON-NLS-1$
butTerrExits = new Button(Messages
.getString("BoardEditor.butTerrExits")); //$NON-NLS-1$
texTerrExits = new TextField("0", 1); //$NON-NLS-1$
butTerrExits.addActionListener(this);
panTerrExits = new Panel(new FlowLayout());
panTerrExits.add(cheTerrExitSpecified);
panTerrExits.add(butTerrExits);
panTerrExits.add(texTerrExits);
panRoads = new Panel(new FlowLayout());
cheRoadsAutoExit = new Checkbox(Messages
.getString("BoardEditor.cheRoadsAutoExit")); //$NON-NLS-1$
cheRoadsAutoExit.addItemListener(this);
panRoads.add(cheRoadsAutoExit);
labTheme = new Label(
Messages.getString("BoardEditor.labTheme"), Label.LEFT); //$NON-NLS-1$
texTheme = new TextField("", 15); //$NON-NLS-1$
texTheme.addTextListener(this);
labBoard = new Label(
Messages.getString("BoardEditor.labBoard"), Label.LEFT); //$NON-NLS-1$
butBoardNew = new Button(Messages.getString("BoardEditor.butBoardNew")); //$NON-NLS-1$
butBoardNew.setActionCommand("fileBoardNew"); //$NON-NLS-1$
butBoardNew.addActionListener(this);
butBoardLoad = new Button(Messages
.getString("BoardEditor.butBoardLoad")); //$NON-NLS-1$
butBoardLoad.setActionCommand("fileBoardOpen"); //$NON-NLS-1$
butBoardLoad.addActionListener(this);
butBoardSave = new Button(Messages
.getString("BoardEditor.butBoardSave")); //$NON-NLS-1$
butBoardSave.setActionCommand("fileBoardSave"); //$NON-NLS-1$
butBoardSave.addActionListener(this);
butBoardSaveAs = new Button(Messages
.getString("BoardEditor.butBoardSaveAs")); //$NON-NLS-1$
butBoardSaveAs.setActionCommand("fileBoardSaveAs"); //$NON-NLS-1$
butBoardSaveAs.addActionListener(this);
butBoardSaveAsImage = new Button(Messages
.getString("BoardEditor.butBoardSaveAsImage")); //$NON-NLS-1$
butBoardSaveAsImage.setActionCommand("fileBoardSaveAsImage"); //$NON-NLS-1$
butBoardSaveAsImage.addActionListener(this);
panButtons = new Panel(new GridLayout(3, 2, 2, 2));
panButtons.add(labBoard);
panButtons.add(butBoardNew);
panButtons.add(butBoardLoad);
panButtons.add(butBoardSave);
panButtons.add(butBoardSaveAs);
panButtons.add(butBoardSaveAsImage);
blankL = new Label("", Label.CENTER); //$NON-NLS-1$
final GridBagLayout gridbag = new GridBagLayout();
final GridBagConstraints c = new GridBagConstraints();
setLayout(gridbag);
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0.0;
c.weighty = 0.0;
c.insets = new Insets(4, 4, 1, 1);
c.gridwidth = GridBagConstraints.REMAINDER;
addBag(canHex, gridbag, c);
c.gridwidth = 1;
addBag(labElev, gridbag, c);
addBag(butElevUp, gridbag, c);
addBag(butElevDown, gridbag, c);
c.gridwidth = GridBagConstraints.REMAINDER;
addBag(texElev, gridbag, c);
addBag(labTerrain, gridbag, c);
addBag(lisTerrain, gridbag, c);
addBag(butDelTerrain, gridbag, c);
addBag(panTerrainType, gridbag, c);
addBag(panTerrExits, gridbag, c);
addBag(panRoads, gridbag, c);
addBag(labTheme, gridbag, c);
addBag(texTheme, gridbag, c);
addBag(butAddTerrain, gridbag, c);
addBag(butMiniMap, gridbag, c);
c.weightx = 1.0;
c.weighty = 1.0;
addBag(blankL, gridbag, c);
c.weightx = 1.0;
c.weighty = 0.0;
// addBag(labBoard, gridbag, c);
addBag(panButtons, gridbag, c);
minimapW = new Dialog(frame,
Messages.getString("BoardEditor.minimapW"), false); //$NON-NLS-1$
minimapW.setLocation(GUIPreferences.getInstance().getMinimapPosX(),
GUIPreferences.getInstance().getMinimapPosY());
try {
minimap = new MiniMap(minimapW, game, bv);
} catch (final IOException e) {
new AlertDialog(
frame,
Messages.getString("BoardEditor.FatalError"), Messages.getString("BoardEditor.CouldNotInitialiseMinimap") + e); //$NON-NLS-1$ //$NON-NLS-2$
frame.dispose();
}
minimapW.add(minimap);
setMapVisible(true);
}
private void addBag(final Component comp, final GridBagLayout gridbag,
final GridBagConstraints c) {
gridbag.setConstraints(comp, c);
add(comp);
}
/**
* Apply the current Hex to the Board at the specified location.
*
* @param c the location.
*/
public void paintHex(final Coords c) {
board.setHex(c, curHex.duplicate());
}
/**
* Apply the current Hex to the Board at the specified location.
*
* @param c the location in {@link megamek.common.Coords , Coords }.
*/
public void resurfaceHex(final Coords c) {
if (board.contains(c)) {
final IHex newHex = curHex.duplicate();
newHex.setElevation(board.getHex(c).getElevation());
board.setHex(c, newHex);
}
}
/**
* Apply the current Hex to the Board at the specified location.
*
* @param c the location in {@link megamek.common.Coords , Coords }.
*/
public void addToHex(final Coords c) {
if (board.contains(c)) {
final IHex newHex = curHex.duplicate();
final IHex oldHex = board.getHex(c);
newHex.setElevation(oldHex.getElevation());
for (int i = 0; i < Terrains.SIZE; i++) {
if (!newHex.containsTerrain(i) && oldHex.containsTerrain(i)) {
newHex.addTerrain(oldHex.getTerrain(i));
}
}
board.setHex(c, newHex);
}
}
/**
* Sets the current hex
*
* @param hex hex to set.
*/
public void setCurrentHex(final IHex hex) {
curHex = hex.duplicate();
texElev.setText(Integer.toString(curHex.getElevation()));
refreshTerrainList();
if (lisTerrain.getItemCount() > 0) {
lisTerrain.select(0);
refreshTerrainFromList();
}
texTheme.setText(curHex.getTheme());
repaint();
repaintWorkingHex();
}
/**
* Repaints the current working hex.
*/
private void repaintWorkingHex() {
if (curHex != null) {
final TilesetManager tm = bv.getTilesetManager();
tm.clearHex(curHex);
}
canHex.repaint();
lastClicked = null;
}
/**
* Refreshes the terrain list to match the current hex
*/
public void refreshTerrainList() {
lisTerrain.removeAll();
for (int i = 0; i < Terrains.SIZE; i++) {
final ITerrain terrain = curHex.getTerrain(i);
if (terrain != null) {
lisTerrain.add(terrain.toString());
}
}
}
/**
* Returns a new instance of the terrain that is currently entered in the
* terrain input fields
*/
private ITerrain enteredTerrain() {
final int type = Terrains.getType(choTerrainType.getSelectedItem());
final int level = Integer.parseInt(texTerrainLevel.getText());
final boolean exitsSpecified = cheTerrExitSpecified.getState();
final int exits = Integer.parseInt(texTerrExits.getText());
return Terrains.getTerrainFactory().createTerrain(type, level,
exitsSpecified, exits);
}
/**
* Add or set the terrain to the list based on the fields.
*/
private void addSetTerrain() {
final ITerrain toAdd = enteredTerrain();
curHex.addTerrain(toAdd);
refreshTerrainList();
repaintWorkingHex();
}
/**
* Set all the appropriate terrain field to match the currently selected
* terrain in the list.
*/
private void refreshTerrainFromList() {
ITerrain terrain = Terrains.getTerrainFactory().createTerrain(
lisTerrain.getSelectedItem());
terrain = curHex.getTerrain(terrain.getType());
choTerrainType.select(Terrains.getName(terrain.getType()));
texTerrainLevel.setText(Integer.toString(terrain.getLevel()));
cheTerrExitSpecified.setState(terrain.hasExitsSpecified());
texTerrExits.setText(Integer.toString(terrain.getExits()));
}
/**
* Initialize a new data set in the current board. If hexes are loaded,
* brings up a dialog box requesting width and height and default hex. If
* height and width are valid, creates new board data and fills it with the
* selected hex.
*/
public void boardNewXX() {
// display new board dialog
final BoardNewDialog bnd = new BoardNewDialog(frame, lisTerrain
.getItems(), lisTerrain.getSelectedIndex());
bnd.setLocation(frame.getLocation().x + 150,
frame.getLocation().y + 100);
bnd.setVisible(true);
if (bnd.getX() > 0 || bnd.getY() > 0) {
final IHex[] newHexes = new IHex[bnd.getX() * bnd.getY()];
for (int i = 0; i < newHexes.length; i++) {
newHexes[i] = new Hex();
}
board.newData(bnd.getX(), bnd.getY(), newHexes);
curpath = null;
curfile = null;
frame.setTitle(Messages.getString("BoardEditor.title")); //$NON-NLS-1$
menuBar.setBoard(true);
}
}
public void boardNew() {
final RandomMapDialog rmd = new RandomMapDialog(frame, this,
mapSettings);
rmd.setVisible(true);
board = BoardUtilities.generateRandom(mapSettings);
game.setBoard(board);
curpath = null;
curfile = null;
frame.setTitle(Messages.getString("BoardEditor.title")); //$NON-NLS-1$
menuBar.setBoard(true);
}
/**
* Updates the map settings.
*
* @param newSettings the new settings.
*/
public void updateMapSettings(final MapSettings newSettings) {
mapSettings = newSettings;
}
/**
* Selects and loads a file into the BoardEditor. Called when the user
* selects load file.
*/
public void boardLoad() {
final FileDialog fd = new FileDialog(frame, Messages
.getString("BoardEditor.loadBoard"), FileDialog.LOAD); //$NON-NLS-1$
fd.setDirectory("data" + File.separator + "boards"); //$NON-NLS-1$ //$NON-NLS-2$
fd
.setLocation(frame.getLocation().x + 150,
frame.getLocation().y + 100);
fd.setVisible(true);
if (fd.getFile() == null) {
// I want a file, y'know!
return;
}
curpath = fd.getDirectory();
curfile = fd.getFile();
// load!
try {
final InputStream is = new FileInputStream(new File(curpath,
curfile));
// tell the board to load!
board.load(is);
// okay, done!
is.close();
menuBar.setBoard(true);
} catch (final IOException ex) {
System.err.println("error opening file to load!"); //$NON-NLS-1$
System.err.println(ex);
}
frame.setTitle(Messages.getString("BoardEditor.title0") + curfile); //$NON-NLS-1$
cheRoadsAutoExit.setState(board.getRoadsAutoExit());
refreshTerrainList();
}
/**
* Checks to see if there is already a path and name stored; if not, calls
* "save as"; otherwise, saves the board to the specified file.
*/
public void boardSave() {
if (curfile == null) {
boardSaveAs();
return;
}
// save!
try {
final OutputStream os = new FileOutputStream(new File(curpath,
curfile));
// tell the board to save!
board.save(os);
// okay, done!
os.close();
} catch (final IOException ex) {
System.err.println("error opening file to save!"); //$NON-NLS-1$
System.err.println(ex);
}
}
/**
* Saves the board in PNG image format.
*/
public void boardSaveImage() {
if (curfileImage == null) {
boardSaveAsImage();
return;
}
final Dialog waitD = new Dialog(this.frame, Messages
.getString("BoardEditor.waitDialog.title")); //$NON-NLS-1$
waitD.add(new Label(Messages
.getString("BoardEditor.waitDialog.message"))); //$NON-NLS-1$
waitD.setSize(250, 130);
// move to middle of screen
waitD.setLocation(
frame.getSize().width / 2 - waitD.getSize().width / 2, frame
.getSize().height
/ 2 - waitD.getSize().height / 2);
waitD.setVisible(true);
frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
waitD.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
// save!
final int filter = 0; // 0 - no filter; 1 - sub; 2 - up
final int compressionLevel = 9; // 0 to 9 with 0 being no compression
final PngEncoder png = new PngEncoder(bv.getEntireBoardImage(),
PngEncoder.NO_ALPHA, filter, compressionLevel);
try {
final FileOutputStream outfile = new FileOutputStream(curfileImage);
byte[] pngbytes;
pngbytes = png.pngEncode();
if (pngbytes == null) {
System.out.println("Failed to save board as image:Null image"); //$NON-NLS-1$
} else {
outfile.write(pngbytes);
}
outfile.flush();
outfile.close();
} catch (final IOException e) {
e.printStackTrace();
}
waitD.setVisible(false);
frame.setCursor(Cursor.getDefaultCursor());
}
/**
* Opens a file dialog box to select a file to save as; saves the board to
* the file.
*/
public void boardSaveAs() {
final FileDialog fd = new FileDialog(frame, Messages
.getString("BoardEditor.saveBoardAs"), FileDialog.SAVE); //$NON-NLS-1$
fd.setDirectory("data" + File.separator + "boards"); //$NON-NLS-1$ //$NON-NLS-2$
fd
.setLocation(frame.getLocation().x + 150,
frame.getLocation().y + 100);
fd.setVisible(true);
if (fd.getFile() == null) {
// I want a file, y'know!
return;
}
curpath = fd.getDirectory();
curfile = fd.getFile();
// make sure the file ends in board
if (!curfile.toLowerCase().endsWith(".board")) { //$NON-NLS-1$
curfile += ".board"; //$NON-NLS-1$
}
frame.setTitle(Messages.getString("BoardEditor.title0") + curfile); //$NON-NLS-1$
boardSave();
}
/**
* Opens a file dialog box to select a file to save as; saves the board to
* the file as an image. Useful for printing boards.
*/
public void boardSaveAsImage() {
final FileDialog fd = new FileDialog(frame, Messages
.getString("BoardEditor.saveAsImage"), FileDialog.SAVE); //$NON-NLS-1$
// fd.setDirectory("data" + File.separator + "boards");
fd
.setLocation(frame.getLocation().x + 150,
frame.getLocation().y + 100);
// Add a filter for PNG files
fd.setFilenameFilter(new FilenameFilter() {
public boolean accept(final File dir, final String name) {
return (null != name && name.endsWith(".png")); //$NON-NLS-1$
}
});
// use base directory by default
fd.setDirectory("."); //$NON-NLS-1$
// Default to the board's name (if it has one).
String fileName = null;
if (null != curfile && curfile.length() > 0) {
fileName = curfile.toUpperCase();
if (fileName.endsWith(".BOARD")) { //$NON-NLS-1$
final int length = fileName.length();
fileName = fileName.substring(0, length - 6);
}
fileName = fileName.toLowerCase() + ".png"; //$NON-NLS-1$
fd.setFile(fileName);
}
// Open the dialog and wait for it's return.
fd.setVisible(true);
if (fd.getFile() == null) {
// I want a file, y'know!
return;
}
curpath = fd.getDirectory();
curfileImage = fd.getFile();
// make sure the file ends in board
if (!curfileImage.toLowerCase().endsWith(".png")) { //$NON-NLS-1$
curfileImage += ".png"; //$NON-NLS-1$
}
frame.setTitle(Messages.getString("BoardEditor.title0") + curfileImage); //$NON-NLS-1$
boardSaveImage();
}
//
// ItemListener
//
/**
* @see java.awt.event.ItemListener
* @param ie the ItemEvent
*/
public void itemStateChanged(final ItemEvent ie) {
if (ie.getSource() == lisTerrain) {
refreshTerrainFromList();
} else if (ie.getSource() == cheRoadsAutoExit) {
// Set the new value for the option, and refresh the board.
board.setRoadsAutoExit(cheRoadsAutoExit.getState());
bv.updateBoard();
repaintWorkingHex();
}
}
//
// TextListener
//
/**
* @see java.awt.event.TextListener
* @param te the TextEvent
*/
public void textValueChanged(final TextEvent te) {
if (te.getSource() == texElev) {
int value;
try {
value = Integer.parseInt(texElev.getText());
} catch (final NumberFormatException ex) {
return;
}
if (value != curHex.getElevation()) {
curHex.setElevation(value);
repaintWorkingHex();
}
} else if (te.getSource() == texTheme) {
curHex.setTheme(texTheme.getText());
repaintWorkingHex();
}
}
/**
* Called when the user selects the "Help->About" menu item.
*/
private void showAbout() {
// Do we need to create the "about" dialog?
if (this.about == null) {
this.about = new CommonAboutDialog(this.frame);
}
// Show the about dialog.
this.about.setVisible(true);
}
/**
* Called when the user selects the "Help->Contents" menu item.
*/
private void showHelp() {
// Do we need to create the "help" dialog?
if (this.help == null) {
final File helpfile = new File("docs", "editor-readme.txt"); //$NON-NLS-1$
this.help = new CommonHelpDialog(this.frame, helpfile);
}
// Show the help dialog.
this.help.setVisible(true);
}
/**
* Called when the user selects the "View->Client Settings" menu item.
*/
private void showSettings() {
// Do we need to create the "settings" dialog?
if (this.setdlg == null) {
this.setdlg = new CommonSettingsDialog(this.frame);
}
// Show the settings dialog.
this.setdlg.setVisible(true);
}
//
// ActionListener
//
public void actionPerformed(final ActionEvent ae) {
if (ae.getActionCommand().equalsIgnoreCase("fileBoardNew")) { //$NON-NLS-1$
boardNew();
} else if (ae.getActionCommand().equalsIgnoreCase("fileBoardOpen")) { //$NON-NLS-1$
boardLoad();
} else if (ae.getActionCommand().equalsIgnoreCase("fileBoardSave")) { //$NON-NLS-1$
boardSave();
} else if (ae.getActionCommand().equalsIgnoreCase("fileBoardSaveAs")) { //$NON-NLS-1$
boardSaveAs();
} else if (ae.getActionCommand().equalsIgnoreCase(
"fileBoardSaveAsImage")) { //$NON-NLS-1$
boardSaveAsImage();
} else if (ae.getSource() == butDelTerrain
&& lisTerrain.getSelectedItem() != null) {
final ITerrain toRemove = Terrains.getTerrainFactory()
.createTerrain(lisTerrain.getSelectedItem());
curHex.removeTerrain(toRemove.getType());
refreshTerrainList();
repaintWorkingHex();
} else if (ae.getSource() == butAddTerrain) {
addSetTerrain();
} else if (ae.getSource() == butElevUp && curHex.getElevation() < 9) {
curHex.setElevation(curHex.getElevation() + 1);
texElev.setText(Integer.toString(curHex.getElevation()));
repaintWorkingHex();
} else if (ae.getSource() == butElevDown && curHex.getElevation() > -5) {
curHex.setElevation(curHex.getElevation() - 1);
texElev.setText(Integer.toString(curHex.getElevation()));
repaintWorkingHex();
} else if (ae.getSource() == butTerrExits) {
final ExitsDialog ed = new ExitsDialog(frame);
cheTerrExitSpecified.setState(true);
ed.setExits(Integer.parseInt(texTerrExits.getText()));
ed.setVisible(true);
texTerrExits.setText(Integer.toString(ed.getExits()));
addSetTerrain();
} else if (ae.getActionCommand().equalsIgnoreCase("viewMiniMap")) { //$NON-NLS-1$
toggleMap();
} else if (ae.getActionCommand().equals(ClientGUI.VIEW_ZOOM_IN)) {
bv.zoomIn();
} else if (ae.getActionCommand().equals(ClientGUI.VIEW_ZOOM_OUT)) {
bv.zoomOut();
} else if (ae.getActionCommand().equalsIgnoreCase("helpAbout")) { //$NON-NLS-1$
showAbout();
} else if (ae.getActionCommand().equalsIgnoreCase("helpContents")) { //$NON-NLS-1$
showHelp();
} else if (ae.getActionCommand().equalsIgnoreCase("viewClientSettings")) { //$NON-NLS-1$
showSettings();
}
}
/**
* Displays the currently selected hex picture, in component form
*/
private class HexCanvas extends Canvas {
private static final long serialVersionUID = 537547390238897105L;
public HexCanvas() {
super();
setSize(72, 72);
}
public void paint(final Graphics g) {
update(g);
}
public void update(final Graphics g) {
if (curHex != null) {
final TilesetManager tm = bv.getTilesetManager();
g.drawImage(tm.baseFor(curHex), 0, 0, this);
if (tm.supersFor(curHex) != null) {
for (final Iterator<Image> i = tm.supersFor(curHex)
.iterator(); i.hasNext();) {
g.drawImage(i.next(), 0, 0, this);
g.drawString(
Messages.getString("BoardEditor.SUPER"), 0, 10); //$NON-NLS-1$
}
}
g.setFont(new Font("SansSerif", Font.PLAIN, 9)); //$NON-NLS-1$
g
.drawString(
Messages.getString("BoardEditor.LEVEL") + curHex.getElevation(), 24, 70); //$NON-NLS-1$
} else {
g.clearRect(0, 0, 72, 72);
}
}
}
/**
* @return the frame this is displayed in
*/
public Frame getFrame() {
return frame;
}
/**
* Toggles the minimap window Also, toggles the minimap enabled setting
*/
public void toggleMap() {
setMapVisible(!minimapW.isVisible());
}
/**
* Sets if the map is visible or not.
*
* @param visible true if the map should be visible, false if not.
*/
public void setMapVisible(final boolean visible) {
minimapW.setVisible(visible);
}
}