mirror of
https://github.com/OMGeeky/ATCS.git
synced 2025-12-30 00:03:29 +01:00
v0.4.0
Worldmap Segment's label edition capability. First version of the BeanShell console. Bug fixes...
This commit is contained in:
@@ -18,7 +18,7 @@ import com.gpl.rpg.atcontentstudio.ui.WorkspaceSelector;
|
||||
public class ATContentStudio {
|
||||
|
||||
public static final String APP_NAME = "Andor's Trail Content Studio";
|
||||
public static final String APP_VERSION = "v0.3.4.dev";
|
||||
public static final String APP_VERSION = "v0.4.0";
|
||||
|
||||
public static boolean STARTED = false;
|
||||
public static StudioFrame frame = null;
|
||||
|
||||
@@ -773,6 +773,26 @@ public class Project implements ProjectTreeNode, Serializable {
|
||||
((JSONElement) target).jsonFile = new File(baseContent.gameData.getGameDataElement(((JSONElement)target).getClass(), target.id).jsonFile.getAbsolutePath());
|
||||
alteredContent.gameData.addElement((JSONElement) target);
|
||||
}
|
||||
|
||||
public void createWorldmapSegment(WorldmapSegment node) {
|
||||
node.writable = true;
|
||||
if (getWorldmapSegment(node.id) != null) {
|
||||
WorldmapSegment existingNode = getWorldmapSegment(node.id);
|
||||
for (GameDataElement backlink : existingNode.getBacklinks()) {
|
||||
backlink.elementChanged(existingNode, node);
|
||||
}
|
||||
existingNode.getBacklinks().clear();
|
||||
node.writable = true;
|
||||
node.state = GameDataElement.State.created;
|
||||
alteredContent.worldmap.addSegment(node);
|
||||
node.link();
|
||||
} else {
|
||||
createdContent.worldmap.addSegment(node);
|
||||
node.state = GameDataElement.State.created;
|
||||
node.link();
|
||||
}
|
||||
fireElementAdded(node, getNodeIndex(node));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.awt.Image;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
|
||||
@@ -48,6 +49,12 @@ public class TMXMapSet implements ProjectTreeNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(tmxMaps, new Comparator<TMXMap>() {
|
||||
@Override
|
||||
public int compare(TMXMap o1, TMXMap o2) {
|
||||
return o1.id.compareTo(o2.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.gpl.rpg.atcontentstudio.model.maps;
|
||||
import java.awt.Image;
|
||||
import java.awt.Point;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -21,8 +23,9 @@ public class WorldmapSegment extends GameDataElement {
|
||||
|
||||
public int segmentX;
|
||||
public int segmentY;
|
||||
public Map<String, Point> mapLocations = new HashMap<String, Point>();
|
||||
public Map<String, NamedArea> labelLocations = new HashMap<String, NamedArea>();
|
||||
public Map<String, Point> mapLocations = new LinkedHashMap<String, Point>();
|
||||
public Map<String, List<String>> labelledMaps = new LinkedHashMap<String, List<String>>();
|
||||
public Map<String, NamedArea> labels = new LinkedHashMap<String, NamedArea>();
|
||||
public Element xmlNode;
|
||||
|
||||
public WorldmapSegment(Worldmap parent, String name, Element xmlNode) {
|
||||
@@ -49,11 +52,18 @@ public class WorldmapSegment extends GameDataElement {
|
||||
for (int j = 0; j < mapsList.getLength(); j++) {
|
||||
Element mapNode = (Element) mapsList.item(j);
|
||||
mapLocations.put(mapNode.getAttribute("id"), new Point(Integer.parseInt(mapNode.getAttribute("x")) - segmentX, Integer.parseInt(mapNode.getAttribute("y")) - segmentY));
|
||||
String area;
|
||||
if ((area = mapNode.getAttribute("area")) != null && !"".equals(area)) {
|
||||
if (labelledMaps.get(area) == null) {
|
||||
labelledMaps.put(area, new LinkedList<String>());
|
||||
}
|
||||
labelledMaps.get(area).add(mapNode.getAttribute("id"));
|
||||
}
|
||||
}
|
||||
NodeList namedAreasNodeList = xmlNode.getElementsByTagName("namedarea");
|
||||
for (int j = 0; j < namedAreasNodeList.getLength(); j++) {
|
||||
Element namedAreaNode = (Element) namedAreasNodeList.item(j);
|
||||
labelLocations.put(namedAreaNode.getAttribute("id"), new NamedArea(namedAreaNode.getAttribute("id"), namedAreaNode.getAttribute("name"), namedAreaNode.getAttribute("type")));
|
||||
labels.put(namedAreaNode.getAttribute("id"), new NamedArea(namedAreaNode.getAttribute("id"), namedAreaNode.getAttribute("name"), namedAreaNode.getAttribute("type")));
|
||||
}
|
||||
this.state = State.parsed;
|
||||
}
|
||||
@@ -104,10 +114,15 @@ public class WorldmapSegment extends GameDataElement {
|
||||
map.setAttribute("id", s);
|
||||
map.setAttribute("x", Integer.toString(mapLocations.get(s).x + segmentX));
|
||||
map.setAttribute("y", Integer.toString(mapLocations.get(s).y + segmentY));
|
||||
for (String label : labelledMaps.keySet()) {
|
||||
if (labelledMaps.get(label).contains(s)) {
|
||||
map.setAttribute("area", label);
|
||||
}
|
||||
}
|
||||
element.appendChild(map);
|
||||
}
|
||||
|
||||
for (NamedArea area : labelLocations.values()) {
|
||||
for (NamedArea area : labels.values()) {
|
||||
Element namedArea = doc.createElement("namedarea");
|
||||
namedArea.setAttribute("id", area.id);
|
||||
namedArea.setAttribute("name", area.name);
|
||||
@@ -117,6 +132,7 @@ public class WorldmapSegment extends GameDataElement {
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<SaveEvent> attemptSave() {
|
||||
@@ -126,9 +142,9 @@ public class WorldmapSegment extends GameDataElement {
|
||||
}
|
||||
|
||||
public static class NamedArea {
|
||||
String id;
|
||||
String name;
|
||||
String type;
|
||||
public String id;
|
||||
public String name;
|
||||
public String type;
|
||||
|
||||
public NamedArea(String id, String name, String type) {
|
||||
this.id = id;
|
||||
|
||||
@@ -69,6 +69,9 @@ public class AboutEditor extends Editor {
|
||||
"<a href=\"http://prefuse.org/\">Prefuse</a> by the Berkeley Institue of Design.<br/>" +
|
||||
"License: <a href=\"http://prefuse.org/license-prefuse.txt\">Modified BSD License (a.k.a 3-Clause BSD)</a><br/>" +
|
||||
"<br/>" +
|
||||
"<a href=\"http://www.beanshell.org/\">BeanShell</a> by Pat Niemeyer.<br/>" +
|
||||
"License: <a href=\"http://www.beanshell.org/license.html\">LGPL v3</a><br/>" +
|
||||
"<br/>" +
|
||||
"See the tabs below to find the full license text for each of these.<br/>" +
|
||||
"<br/>" +
|
||||
"The Windows installer was created with:<br/>" +
|
||||
@@ -116,6 +119,7 @@ public class AboutEditor extends Editor {
|
||||
editorTabsHolder.add("JIDE Common Layer License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.JIDE.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||
editorTabsHolder.add("libtiled-java License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.libtiled.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||
editorTabsHolder.add("prefuse License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/license-prefuse.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||
editorTabsHolder.add("BeanShell License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.LGPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||
editorTabsHolder.add("ATCS License", getInfoPane(new Scanner(ATContentStudio.class.getResourceAsStream("/LICENSE.GPLv3.txt"), "UTF-8").useDelimiter("\\A").next(), "text/text"));
|
||||
|
||||
}
|
||||
|
||||
@@ -262,6 +262,7 @@ public class JSONCreationWizard extends JDialog {
|
||||
buttonPane.add(cancel, JideBoxLayout.FIX);
|
||||
ok = new JButton("Ok");
|
||||
buttonPane.add(ok, JideBoxLayout.FIX);
|
||||
pane.add(new JPanel(), JideBoxLayout.VARY);
|
||||
pane.add(buttonPane, JideBoxLayout.FIX);
|
||||
|
||||
ok.addActionListener(new ActionListener() {
|
||||
|
||||
@@ -201,6 +201,10 @@ public class ProjectsTree extends JPanel {
|
||||
addNextSeparator = true;
|
||||
popupMenu.add(new JMenuItem(actions.importJSON));
|
||||
}
|
||||
if (actions.createWorldmap.isEnabled()) {
|
||||
addNextSeparator = true;
|
||||
popupMenu.add(new JMenuItem(actions.createWorldmap));
|
||||
}
|
||||
if (actions.loadSave.isEnabled()) {
|
||||
addNextSeparator = true;
|
||||
popupMenu.add(new JMenuItem(actions.loadSave));
|
||||
@@ -219,6 +223,10 @@ public class ProjectsTree extends JPanel {
|
||||
addNextSeparator = true;
|
||||
popupMenu.add(new JMenuItem(actions.compareNPCs));
|
||||
}
|
||||
if (actions.runBeanShell.isEnabled()) {
|
||||
addNextSeparator = true;
|
||||
popupMenu.add(new JMenuItem(actions.runBeanShell));
|
||||
}
|
||||
if (actions.exportProject.isEnabled()) {
|
||||
addNextSeparator = true;
|
||||
popupMenu.add(new JMenuItem(actions.exportProject));
|
||||
|
||||
@@ -136,6 +136,7 @@ public class StudioFrame extends JFrame {
|
||||
projectMenu.add(new JSeparator());
|
||||
projectMenu.add(new JMenuItem(actions.createGDE));
|
||||
projectMenu.add(new JMenuItem(actions.importJSON));
|
||||
projectMenu.add(new JMenuItem(actions.createWorldmap));
|
||||
projectMenu.add(new JMenuItem(actions.loadSave));
|
||||
getJMenuBar().add(projectMenu);
|
||||
|
||||
@@ -143,6 +144,8 @@ public class StudioFrame extends JFrame {
|
||||
toolsMenu.add(new JMenuItem(actions.compareItems));
|
||||
toolsMenu.add(new JMenuItem(actions.compareNPCs));
|
||||
toolsMenu.add(new JSeparator());
|
||||
toolsMenu.add(new JMenuItem(actions.runBeanShell));
|
||||
toolsMenu.add(new JSeparator());
|
||||
toolsMenu.add(new JMenuItem(actions.exportProject));
|
||||
getJMenuBar().add(toolsMenu);
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ import javax.swing.JOptionPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import bsh.util.JConsole;
|
||||
|
||||
import com.gpl.rpg.atcontentstudio.ATContentStudio;
|
||||
import com.gpl.rpg.atcontentstudio.model.ClosedProject;
|
||||
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
|
||||
@@ -32,6 +34,7 @@ import com.gpl.rpg.atcontentstudio.model.gamedata.JSONElement;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet;
|
||||
import com.gpl.rpg.atcontentstudio.model.saves.SavedGamesSet;
|
||||
import com.gpl.rpg.atcontentstudio.ui.tools.BeanShellView;
|
||||
import com.gpl.rpg.atcontentstudio.ui.tools.ItemsTableView;
|
||||
import com.gpl.rpg.atcontentstudio.ui.tools.NPCsTableView;
|
||||
|
||||
@@ -213,6 +216,17 @@ public class WorkspaceActions {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public ATCSAction createWorldmap = new ATCSAction("Create Worldmap segment", "Opens the worldmap segment creation wizard") {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (selectedNode == null || selectedNode.getProject() == null) return;
|
||||
new WorldmapCreationWizard(selectedNode.getProject()).setVisible(true);
|
||||
}
|
||||
public void selectionChanged(ProjectTreeNode selectedNode, TreePath[] selectedPaths) {
|
||||
setEnabled(selectedNode != null && selectedNode.getProject() != null);
|
||||
}
|
||||
};
|
||||
|
||||
public ATCSAction importJSON = new ATCSAction("Import JSON data", "Opens the JSON import wizard") {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (selectedNode == null || selectedNode.getProject() == null) return;
|
||||
@@ -281,6 +295,12 @@ public class WorkspaceActions {
|
||||
};
|
||||
};
|
||||
|
||||
public ATCSAction runBeanShell = new ATCSAction("Run Beanshell console", "Opens a beanshell scripting pad."){
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new BeanShellView();
|
||||
};
|
||||
};
|
||||
|
||||
public ATCSAction showAbout = new ATCSAction("About...", "Displays credits and other informations about ATCS"){
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ATContentStudio.frame.showAbout();
|
||||
|
||||
158
src/com/gpl/rpg/atcontentstudio/ui/WorldmapCreationWizard.java
Normal file
158
src/com/gpl/rpg/atcontentstudio/ui/WorldmapCreationWizard.java
Normal file
@@ -0,0 +1,158 @@
|
||||
package com.gpl.rpg.atcontentstudio.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import com.gpl.rpg.atcontentstudio.ATContentStudio;
|
||||
import com.gpl.rpg.atcontentstudio.model.GameSource;
|
||||
import com.gpl.rpg.atcontentstudio.model.Project;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
|
||||
import com.jidesoft.swing.JideBoxLayout;
|
||||
|
||||
public class WorldmapCreationWizard extends JDialog {
|
||||
|
||||
private static final long serialVersionUID = 6491044105090917567L;
|
||||
|
||||
private WorldmapSegment creation = new WorldmapSegment(null, null, null);
|
||||
|
||||
final JLabel message;
|
||||
final JTextField idField;
|
||||
final JButton ok;
|
||||
final Project proj;
|
||||
|
||||
|
||||
public WorldmapCreationWizard(final Project proj) {
|
||||
super(ATContentStudio.frame);
|
||||
this.proj = proj;
|
||||
setTitle("Create Worldmap segment");
|
||||
|
||||
JPanel pane = new JPanel();
|
||||
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
|
||||
|
||||
pane.add(new JLabel("Create a new worldmap segment."), JideBoxLayout.FIX);
|
||||
|
||||
message = new JLabel("Enter a map segment ID below: ");
|
||||
pane.add(message, JideBoxLayout.FIX);
|
||||
|
||||
final JPanel idPane = new JPanel();
|
||||
idPane.setLayout(new BorderLayout());
|
||||
JLabel idLabel = new JLabel("Internal ID: ");
|
||||
idPane.add(idLabel, BorderLayout.WEST);
|
||||
idField = new JTextField("");
|
||||
idField.setEditable(true);
|
||||
idPane.add(idField, BorderLayout.CENTER);
|
||||
pane.add(idPane, JideBoxLayout.FIX);
|
||||
|
||||
JPanel buttonPane = new JPanel();
|
||||
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
|
||||
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
|
||||
JButton cancel = new JButton("Cancel");
|
||||
buttonPane.add(cancel, JideBoxLayout.FIX);
|
||||
ok = new JButton("Ok");
|
||||
buttonPane.add(ok, JideBoxLayout.FIX);
|
||||
pane.add(new JPanel(), JideBoxLayout.VARY);
|
||||
pane.add(buttonPane, JideBoxLayout.FIX);
|
||||
|
||||
ok.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
creation.id = idField.getText();
|
||||
WorldmapCreationWizard.this.setVisible(false);
|
||||
WorldmapCreationWizard.this.dispose();
|
||||
proj.createWorldmapSegment(creation);
|
||||
notifyCreated();
|
||||
ATContentStudio.frame.selectInTree(creation);
|
||||
ATContentStudio.frame.openEditor(creation);
|
||||
}
|
||||
});
|
||||
|
||||
cancel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
creation = null;
|
||||
WorldmapCreationWizard.this.setVisible(false);
|
||||
WorldmapCreationWizard.this.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
DocumentListener statusUpdater = new DocumentListener() {
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
updateStatus();
|
||||
}
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
updateStatus();
|
||||
}
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
updateStatus();
|
||||
}
|
||||
};
|
||||
idField.getDocument().addDocumentListener(statusUpdater);
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
getContentPane().add(pane, BorderLayout.CENTER);
|
||||
|
||||
setMinimumSize(new Dimension(350,120));
|
||||
updateStatus();
|
||||
pack();
|
||||
|
||||
Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
Dimension wdim = getSize();
|
||||
setLocation((sdim.width - wdim.width)/2, (sdim.height - wdim.height)/2);
|
||||
}
|
||||
|
||||
public void updateStatus() {
|
||||
boolean trouble = false;
|
||||
message.setText("<html><font color=\"#00AA00\">Looks OK to me.</font></html>");
|
||||
if (idField.getText() == null || idField.getText().length() <= 0) {
|
||||
message.setText("<html><font color=\"#FF0000\">Internal ID must not be empty.</font></html>");
|
||||
trouble = true;
|
||||
} else if (proj.getWorldmapSegment(idField.getText()) != null) {
|
||||
if (proj.getWorldmapSegment(idField.getText()).getDataType() == GameSource.Type.created) {
|
||||
message.setText("<html><font color=\"#FF0000\">A worldmap segment with the same ID was already created in this project.</font></html>");
|
||||
trouble = true;
|
||||
} else if (proj.getWorldmapSegment(idField.getText()).getDataType() == GameSource.Type.altered) {
|
||||
message.setText("<html><font color=\"#FF0000\">A worldmap segment with the same ID exists in the game and is already altered in this project.</font></html>");
|
||||
trouble = true;
|
||||
} else if (proj.getWorldmapSegment(idField.getText()).getDataType() == GameSource.Type.source) {
|
||||
message.setText("<html><font color=\"#FF9000\">A worldmap segment with the same ID exists in the game. It will be added under \"altered\".</font></html>");
|
||||
}
|
||||
}
|
||||
|
||||
ok.setEnabled(!trouble);
|
||||
|
||||
message.revalidate();
|
||||
message.repaint();
|
||||
}
|
||||
|
||||
public static interface CreationCompletedListener {
|
||||
public void segmentCreated(WorldmapSegment created);
|
||||
}
|
||||
|
||||
private List<CreationCompletedListener> listeners = new ArrayList<WorldmapCreationWizard.CreationCompletedListener>();
|
||||
|
||||
public void addCreationListener(CreationCompletedListener l) {
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void notifyCreated() {
|
||||
for (CreationCompletedListener l : listeners) {
|
||||
l.segmentCreated(creation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.gpl.rpg.atcontentstudio.ui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import com.gpl.rpg.atcontentstudio.ATContentStudio;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
|
||||
import com.jidesoft.swing.JideBoxLayout;
|
||||
|
||||
public class WorldmapLabelEditionWizard extends JDialog {
|
||||
|
||||
private static final long serialVersionUID = 4911946705579386332L;
|
||||
|
||||
final JLabel message;
|
||||
final JTextField idField;
|
||||
final JTextField labelField;
|
||||
final JTextField typeField;
|
||||
final JButton ok;
|
||||
final WorldmapSegment segment;
|
||||
final WorldmapSegment.NamedArea label;
|
||||
|
||||
boolean createMode = false;
|
||||
|
||||
public WorldmapLabelEditionWizard(WorldmapSegment segment) {
|
||||
this(segment, new WorldmapSegment.NamedArea(null, null, null), true);
|
||||
}
|
||||
|
||||
public WorldmapLabelEditionWizard(WorldmapSegment segment, WorldmapSegment.NamedArea label) {
|
||||
this(segment, label, false);
|
||||
}
|
||||
|
||||
public WorldmapLabelEditionWizard(WorldmapSegment segment, WorldmapSegment.NamedArea namedArea, boolean createMode) {
|
||||
super(ATContentStudio.frame);
|
||||
this.createMode = createMode;
|
||||
this.segment = segment;
|
||||
this.label = namedArea;
|
||||
|
||||
setTitle(createMode ? "Create Worldmap Label" : "Edit Worldmap Label");
|
||||
|
||||
JPanel pane = new JPanel();
|
||||
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
|
||||
|
||||
pane.add(new JLabel(createMode ? "Create a worldmap label." : "Edit a worldmap label."), JideBoxLayout.FIX);
|
||||
|
||||
message = new JLabel("Enter a label ID below: ");
|
||||
pane.add(message, JideBoxLayout.FIX);
|
||||
|
||||
final JPanel idPane = new JPanel();
|
||||
idPane.setLayout(new BorderLayout());
|
||||
JLabel idLabel = new JLabel("Internal ID: ");
|
||||
idPane.add(idLabel, BorderLayout.WEST);
|
||||
idField = new JTextField(label.id);
|
||||
idField.setEditable(true);
|
||||
idPane.add(idField, BorderLayout.CENTER);
|
||||
pane.add(idPane, JideBoxLayout.FIX);
|
||||
|
||||
final JPanel labelPane = new JPanel();
|
||||
labelPane.setLayout(new BorderLayout());
|
||||
JLabel labelLabel = new JLabel("Label: ");
|
||||
labelPane.add(labelLabel, BorderLayout.WEST);
|
||||
labelField = new JTextField(label.name);
|
||||
labelField.setEditable(true);
|
||||
labelPane.add(labelField, BorderLayout.CENTER);
|
||||
pane.add(labelPane, JideBoxLayout.FIX);
|
||||
|
||||
final JPanel typePane = new JPanel();
|
||||
typePane.setLayout(new BorderLayout());
|
||||
JLabel typeLabel = new JLabel("Type: ");
|
||||
typePane.add(typeLabel, BorderLayout.WEST);
|
||||
typeField = new JTextField(label.type);
|
||||
if (typeField.getText().equals("")) {
|
||||
typeField.setText("settlement");
|
||||
}
|
||||
typeField.setEditable(true);
|
||||
typePane.add(typeField, BorderLayout.CENTER);
|
||||
pane.add(typePane, JideBoxLayout.FIX);
|
||||
|
||||
JPanel buttonPane = new JPanel();
|
||||
buttonPane.setLayout(new JideBoxLayout(buttonPane, JideBoxLayout.LINE_AXIS, 6));
|
||||
buttonPane.add(new JPanel(), JideBoxLayout.VARY);
|
||||
JButton cancel = new JButton("Cancel");
|
||||
buttonPane.add(cancel, JideBoxLayout.FIX);
|
||||
ok = new JButton("Ok");
|
||||
buttonPane.add(ok, JideBoxLayout.FIX);
|
||||
pane.add(new JPanel(), JideBoxLayout.VARY);
|
||||
pane.add(buttonPane, JideBoxLayout.FIX);
|
||||
|
||||
ok.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
label.id = idField.getText();
|
||||
label.name = labelField.getText();
|
||||
label.type = labelField.getText();
|
||||
WorldmapLabelEditionWizard.this.setVisible(false);
|
||||
WorldmapLabelEditionWizard.this.dispose();
|
||||
if (WorldmapLabelEditionWizard.this.createMode) {
|
||||
WorldmapLabelEditionWizard.this.segment.labels.put(label.id, label);
|
||||
}
|
||||
notifyCreated();
|
||||
}
|
||||
});
|
||||
|
||||
cancel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
WorldmapLabelEditionWizard.this.setVisible(false);
|
||||
WorldmapLabelEditionWizard.this.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
DocumentListener statusUpdater = new DocumentListener() {
|
||||
@Override
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
updateStatus();
|
||||
}
|
||||
@Override
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
updateStatus();
|
||||
}
|
||||
@Override
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
updateStatus();
|
||||
}
|
||||
};
|
||||
idField.getDocument().addDocumentListener(statusUpdater);
|
||||
labelField.getDocument().addDocumentListener(statusUpdater);
|
||||
typeField.getDocument().addDocumentListener(statusUpdater);
|
||||
|
||||
getContentPane().setLayout(new BorderLayout());
|
||||
getContentPane().add(pane, BorderLayout.CENTER);
|
||||
|
||||
setMinimumSize(new Dimension(350,170));
|
||||
updateStatus();
|
||||
pack();
|
||||
|
||||
Dimension sdim = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
Dimension wdim = getSize();
|
||||
setLocation((sdim.width - wdim.width)/2, (sdim.height - wdim.height)/2);
|
||||
}
|
||||
|
||||
public void updateStatus() {
|
||||
boolean trouble = false;
|
||||
message.setText("<html><font color=\"#00AA00\">Looks OK to me.</font></html>");
|
||||
if (idField.getText() == null || idField.getText().length() <= 0) {
|
||||
message.setText("<html><font color=\"#FF0000\">Internal ID must not be empty.</font></html>");
|
||||
trouble = true;
|
||||
} else if (segment.labels.get(idField.getText()) != null && segment.labels.get(idField.getText()) != label) {
|
||||
message.setText("<html><font color=\"#FF0000\">A worldmap label with the same ID already exists in this worldmap.</font></html>");
|
||||
trouble = true;
|
||||
} else if (labelField.getText() == null || labelField.getText().length() <= 0) {
|
||||
message.setText("<html><font color=\"#FF0000\">Label must not be empty.</font></html>");
|
||||
trouble = true;
|
||||
}
|
||||
// message.setText("<html><font color=\"#FF9000\">This is a Warning example</font></html>");
|
||||
|
||||
ok.setEnabled(!trouble);
|
||||
|
||||
message.revalidate();
|
||||
message.repaint();
|
||||
}
|
||||
|
||||
public static interface CreationCompletedListener {
|
||||
public void labelCreated(WorldmapSegment.NamedArea created);
|
||||
}
|
||||
|
||||
private List<CreationCompletedListener> listeners = new ArrayList<WorldmapLabelEditionWizard.CreationCompletedListener>();
|
||||
|
||||
public void addCreationListener(CreationCompletedListener l) {
|
||||
listeners.add(l);
|
||||
}
|
||||
|
||||
public void notifyCreated() {
|
||||
for (CreationCompletedListener l : listeners) {
|
||||
l.labelCreated(label);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,12 @@ import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ButtonGroup;
|
||||
@@ -30,9 +33,11 @@ import com.gpl.rpg.atcontentstudio.model.SaveEvent;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.TMXMap;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.Worldmap;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
|
||||
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment.NamedArea;
|
||||
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
|
||||
import com.gpl.rpg.atcontentstudio.ui.Editor;
|
||||
import com.gpl.rpg.atcontentstudio.ui.SaveItemsWizard;
|
||||
import com.gpl.rpg.atcontentstudio.ui.WorldmapLabelEditionWizard;
|
||||
import com.jidesoft.swing.ComboBoxSearchable;
|
||||
import com.jidesoft.swing.JideBoxLayout;
|
||||
import com.jidesoft.swing.JideTabbedPane;
|
||||
@@ -47,10 +52,12 @@ public class WorldMapEditor extends Editor {
|
||||
moveViewSelect,
|
||||
moveMaps,
|
||||
deleteMaps,
|
||||
addMap
|
||||
addMap,
|
||||
editLabelCoverage
|
||||
}
|
||||
|
||||
public String mapBeingAddedID = null;
|
||||
public String selectedLabel = null;
|
||||
|
||||
public WorldMapEditor(WorldmapSegment worldmap) {
|
||||
target = worldmap;
|
||||
@@ -94,6 +101,11 @@ public class WorldMapEditor extends Editor {
|
||||
zoomSliderPane.add(zoomSlider, JideBoxLayout.VARY);
|
||||
zoomSliderPane.add(new JLabel(new ImageIcon(DefaultIcons.getZoomIcon())), JideBoxLayout.FIX);
|
||||
|
||||
final JRadioButton editLabelCoverage = new JRadioButton("Edit label coverage");
|
||||
final JButton editLabel = new JButton("Edit map label");
|
||||
final JButton createLabel = new JButton("Create map label");
|
||||
final JButton deleteLabel = new JButton("Delete map label");
|
||||
|
||||
if (target.writable) {
|
||||
JPanel mapToolsPane = new JPanel();
|
||||
mapToolsPane.setLayout(new JideBoxLayout(mapToolsPane, JideBoxLayout.LINE_AXIS));
|
||||
@@ -136,7 +148,23 @@ public class WorldMapEditor extends Editor {
|
||||
mapToolsPane.add(new JPanel(), JideBoxLayout.VARY);
|
||||
moveView.setSelected(true);
|
||||
pane.add(mapToolsPane, JideBoxLayout.FIX);
|
||||
|
||||
|
||||
JPanel labelToolsPane = new JPanel();
|
||||
labelToolsPane.setLayout(new JideBoxLayout(labelToolsPane, JideBoxLayout.LINE_AXIS));
|
||||
mapToolsGroup.add(editLabelCoverage);
|
||||
editLabelCoverage.setEnabled(false);
|
||||
labelToolsPane.add(editLabelCoverage, JideBoxLayout.FIX);
|
||||
editLabel.setEnabled(false);
|
||||
labelToolsPane.add(editLabel, JideBoxLayout.FIX);
|
||||
deleteLabel.setEnabled(false);
|
||||
labelToolsPane.add(deleteLabel, JideBoxLayout.FIX);
|
||||
createLabel.setEnabled(false);
|
||||
labelToolsPane.add(createLabel, JideBoxLayout.FIX);
|
||||
|
||||
labelToolsPane.add(new JPanel(), JideBoxLayout.VARY);
|
||||
pane.add(labelToolsPane, JideBoxLayout.FIX);
|
||||
|
||||
|
||||
moveView.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
@@ -196,10 +224,114 @@ public class WorldMapEditor extends Editor {
|
||||
if (mapBox.getSelectedItem() == null) {
|
||||
mapBeingAddedID = null;
|
||||
} else {
|
||||
if (mapBeingAddedID != null) {
|
||||
mapView.updateFromModel();
|
||||
}
|
||||
mapBeingAddedID = ((TMXMap)mapBox.getSelectedItem()).id;
|
||||
if (mapView.mapLocations.isEmpty()) {
|
||||
TMXMap map = target.getProject().getMap(mapBeingAddedID);
|
||||
int w = map.tmxMap.getWidth() * WorldMapView.TILE_SIZE;
|
||||
int h = map.tmxMap.getHeight() * WorldMapView.TILE_SIZE;
|
||||
mapView.mapLocations.put(mapBeingAddedID, new Rectangle(0, 0, w, h));
|
||||
mapView.recomputeSize();
|
||||
mapView.revalidate();
|
||||
mapView.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
editLabelCoverage.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
editMode = EditMode.editLabelCoverage;
|
||||
mapBox.setEnabled(false);
|
||||
mapView.selected.clear();
|
||||
mapView.selected.addAll(((WorldmapSegment)target).labelledMaps.get(selectedLabel));
|
||||
if (mapBeingAddedID != null) {
|
||||
mapView.mapLocations.remove(mapBeingAddedID);
|
||||
mapBeingAddedID = null;
|
||||
}
|
||||
mapView.revalidate();
|
||||
mapView.repaint();
|
||||
}
|
||||
});
|
||||
|
||||
editLabelCoverage.addItemListener(new ItemListener() {
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.DESELECTED) {
|
||||
WorldmapSegment map = (WorldmapSegment)target;
|
||||
if (map.labelledMaps.get(selectedLabel) != null) {
|
||||
map.labelledMaps.get(selectedLabel).clear();
|
||||
} else {
|
||||
map.labelledMaps.put(selectedLabel, new LinkedList<String>());
|
||||
}
|
||||
for (String s : mapView.selected) {
|
||||
map.labelledMaps.get(selectedLabel).add(s);
|
||||
}
|
||||
mapView.revalidate();
|
||||
mapView.repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
editLabel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mapView.selected.clear();
|
||||
mapView.selected.addAll(((WorldmapSegment)target).labelledMaps.get(selectedLabel));
|
||||
mapView.revalidate();
|
||||
mapView.repaint();
|
||||
WorldmapLabelEditionWizard wiz = new WorldmapLabelEditionWizard(worldmap, worldmap.labels.get(selectedLabel));
|
||||
wiz.addCreationListener(new WorldmapLabelEditionWizard.CreationCompletedListener() {
|
||||
@Override
|
||||
public void labelCreated(NamedArea created) {
|
||||
if (!created.id.equals(selectedLabel)) {
|
||||
worldmap.labelledMaps.put(created.id, worldmap.labelledMaps.get(selectedLabel));
|
||||
worldmap.labelledMaps.remove(selectedLabel);
|
||||
worldmap.labels.put(created.id, created);
|
||||
worldmap.labels.remove(selectedLabel);
|
||||
selectedLabel = created.id;
|
||||
mapView.revalidate();
|
||||
mapView.repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
wiz.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
deleteLabel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
worldmap.labelledMaps.remove(selectedLabel);
|
||||
worldmap.labels.remove(selectedLabel);
|
||||
selectedLabel = null;
|
||||
mapView.revalidate();
|
||||
mapView.repaint();
|
||||
}
|
||||
});
|
||||
|
||||
createLabel.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
WorldmapLabelEditionWizard wiz = new WorldmapLabelEditionWizard(worldmap);
|
||||
wiz.addCreationListener(new WorldmapLabelEditionWizard.CreationCompletedListener() {
|
||||
@Override
|
||||
public void labelCreated(NamedArea created) {
|
||||
worldmap.labelledMaps.put(created.id, new LinkedList<String>());
|
||||
worldmap.labelledMaps.get(created.id).addAll(mapView.selected);
|
||||
mapView.revalidate();
|
||||
mapView.repaint();
|
||||
}
|
||||
});
|
||||
wiz.setVisible(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -247,20 +379,25 @@ public class WorldMapEditor extends Editor {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (editMode == EditMode.moveViewSelect) {
|
||||
if (editMode == EditMode.moveViewSelect || editMode == EditMode.editLabelCoverage) {
|
||||
if (selectedMap == null) return;
|
||||
if (e.getButton() == MouseEvent.BUTTON1) {
|
||||
if (e.isControlDown() || e.isShiftDown()) {
|
||||
if (mapView.selected.contains(selectedMap)) {
|
||||
mapView.selected.remove(selectedMap);
|
||||
update = true;
|
||||
if (editMode != EditMode.editLabelCoverage || mapView.selected.size() > 1) {
|
||||
mapView.selected.remove(selectedMap);
|
||||
mapSelectionChanged();
|
||||
update = true;
|
||||
}
|
||||
} else {
|
||||
mapView.selected.add(selectedMap);
|
||||
mapSelectionChanged();
|
||||
update = true;
|
||||
}
|
||||
} else {
|
||||
mapView.selected.clear();
|
||||
mapView.selected.add(selectedMap);
|
||||
mapSelectionChanged();
|
||||
update = true;
|
||||
}
|
||||
if (e.getClickCount() == 2) {
|
||||
@@ -269,8 +406,9 @@ public class WorldMapEditor extends Editor {
|
||||
}
|
||||
} else if (editMode == EditMode.deleteMaps) {
|
||||
worldmap.mapLocations.remove(selectedMap);
|
||||
worldmap.labelLocations.remove(selectedMap);
|
||||
worldmap.labels.remove(selectedMap);
|
||||
mapView.selected.remove(selectedMap);
|
||||
mapSelectionChanged();
|
||||
mapView.updateFromModel();
|
||||
update = true;
|
||||
} else if (editMode == EditMode.addMap && mapBeingAddedID != null) {
|
||||
@@ -360,6 +498,47 @@ public class WorldMapEditor extends Editor {
|
||||
mapView.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
public void mapSelectionChanged() {
|
||||
if (mapView.selected.isEmpty()) {
|
||||
editLabelCoverage.setEnabled(false);
|
||||
editLabel.setEnabled(false);
|
||||
createLabel.setEnabled(false);
|
||||
selectedLabel = null;
|
||||
} else {
|
||||
String label = null;
|
||||
boolean multiLabel = false;
|
||||
for (String map : mapView.selected) {
|
||||
for (String existingLabel : ((WorldmapSegment)target).labelledMaps.keySet()) {
|
||||
if (((WorldmapSegment)target).labelledMaps.get(existingLabel).contains(map)) {
|
||||
if (label != null && !label.equals(existingLabel)) {
|
||||
multiLabel = true;
|
||||
}
|
||||
label = existingLabel;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (multiLabel) {
|
||||
editLabelCoverage.setEnabled(false);
|
||||
editLabel.setEnabled(false);
|
||||
createLabel.setEnabled(false);
|
||||
deleteLabel.setEnabled(false);
|
||||
selectedLabel = null;
|
||||
} else if (label != null) {
|
||||
editLabelCoverage.setEnabled(true);
|
||||
editLabel.setEnabled(true);
|
||||
deleteLabel.setEnabled(true);
|
||||
createLabel.setEnabled(false);
|
||||
selectedLabel = label;
|
||||
} else {
|
||||
editLabelCoverage.setEnabled(false);
|
||||
editLabel.setEnabled(false);
|
||||
deleteLabel.setEnabled(false);
|
||||
createLabel.setEnabled(true);
|
||||
selectedLabel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mapView.addMouseListener(mouseListener);
|
||||
|
||||
@@ -3,10 +3,16 @@ package com.gpl.rpg.atcontentstudio.ui.map;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@@ -87,6 +93,30 @@ public class WorldMapView extends JComponent implements Scrollable {
|
||||
g2.translate(-x, -y);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Font f = g2.getFont();
|
||||
f = f.deriveFont(70f).deriveFont(Font.BOLD);
|
||||
g2.setFont(f);
|
||||
g2.setStroke(new BasicStroke(3));
|
||||
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
FontMetrics fm = g2.getFontMetrics();
|
||||
FontRenderContext frc = g2.getFontRenderContext();
|
||||
|
||||
for (String s : worldmap.labels.keySet()) {
|
||||
String label = worldmap.labels.get(s).name;
|
||||
Rectangle areaCovered = new Rectangle(0, 0, -1, -1);
|
||||
for (String map : worldmap.labelledMaps.get(s)) {
|
||||
areaCovered.add(mapLocations.get(map));
|
||||
}
|
||||
|
||||
Rectangle2D stringBounds = fm.getStringBounds(label, g2);
|
||||
GlyphVector gv = f.createGlyphVector(frc, label);
|
||||
g2.setColor(Color.WHITE);
|
||||
g2.fill(gv.getOutline((int)(areaCovered.getCenterX() - stringBounds.getCenterX()), (int)(areaCovered.getCenterY() - stringBounds.getCenterY())));
|
||||
g2.setColor(Color.BLACK);
|
||||
g2.draw(gv.getOutline((int)(areaCovered.getCenterX() - stringBounds.getCenterX()), (int)(areaCovered.getCenterY() - stringBounds.getCenterY())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -202,6 +232,8 @@ public class WorldMapView extends JComponent implements Scrollable {
|
||||
return originMoved;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void updateFromModel() {
|
||||
mapLocations.clear();
|
||||
sizeX = sizeY = 0;
|
||||
@@ -232,13 +264,13 @@ public class WorldMapView extends JComponent implements Scrollable {
|
||||
}
|
||||
|
||||
List<String> toRemove = new ArrayList<String>();
|
||||
for (String s : worldmap.labelLocations.keySet()) {
|
||||
for (String s : worldmap.labels.keySet()) {
|
||||
if (!mapLocations.containsKey(s)) {
|
||||
toRemove.add(s);
|
||||
}
|
||||
}
|
||||
for (String s : toRemove) {
|
||||
worldmap.labelLocations.remove(s);
|
||||
worldmap.labels.remove(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user