Files
archived-ATCS/src/com/gpl/rpg/atcontentstudio/ui/JSONCreationWizard.java
2025-06-21 18:36:37 +02:00

582 lines
28 KiB
Java

package com.gpl.rpg.atcontentstudio.ui;
import com.gpl.rpg.atcontentstudio.ATContentStudio;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.gamedata.*;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.ui.sprites.SpriteChooser;
import com.jidesoft.swing.JideBoxLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListDataListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class JSONCreationWizard extends JDialog {
private static final long serialVersionUID = -5744628699021314026L;
public static enum DataType {
none,
actorCondition,
dialogue,
droplist,
item,
itemCategory,
npc,
quest
}
private JSONElement creation = null;
final JLabel message;
@SuppressWarnings("rawtypes")
final JComboBox dataTypeCombo;
final JTextField idField;
final JTextField nameField;
final JButton ok;
final Project proj;
public JSONCreationWizard(final Project proj, Class<? extends GameDataElement> dataClass) {
this(proj);
if (dataClass == ActorCondition.class) {
dataTypeCombo.setSelectedItem(DataType.actorCondition);
} else if (dataClass == Dialogue.class) {
dataTypeCombo.setSelectedItem(DataType.dialogue);
} else if (dataClass == Droplist.class) {
dataTypeCombo.setSelectedItem(DataType.droplist);
} else if (dataClass == Item.class) {
dataTypeCombo.setSelectedItem(DataType.item);
} else if (dataClass == ItemCategory.class) {
dataTypeCombo.setSelectedItem(DataType.itemCategory);
} else if (dataClass == NPC.class) {
dataTypeCombo.setSelectedItem(DataType.npc);
} else if (dataClass == Quest.class) {
dataTypeCombo.setSelectedItem(DataType.quest);
}
dataTypeCombo.setEnabled(false);
}
@SuppressWarnings({"unchecked", "rawtypes"})
public JSONCreationWizard(final Project proj) {
super(ATContentStudio.frame);
this.proj = proj;
setTitle("Create Game Data Element (JSON)");
JPanel pane = new JPanel();
pane.setLayout(new JideBoxLayout(pane, JideBoxLayout.PAGE_AXIS, 6));
pane.add(new JLabel("Create a new game data element."), JideBoxLayout.FIX);
message = new JLabel("Select a data type below:");
pane.add(message, JideBoxLayout.FIX);
dataTypeCombo = new JComboBox(new DataTypeComboModel());
dataTypeCombo.setRenderer(new DataTypeComboCellRenderer());
pane.add(dataTypeCombo);
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);
final JPanel namePane = new JPanel();
namePane.setLayout(new BorderLayout());
JLabel nameLabel = new JLabel("Display name: ");
namePane.add(nameLabel, BorderLayout.WEST);
nameField = new JTextField("");
nameField.setEditable(true);
namePane.add(nameField, BorderLayout.CENTER);
pane.add(namePane, JideBoxLayout.FIX);
final JPanel iconPane = new JPanel();
iconPane.setLayout(new BorderLayout());
final JLabel iconLabel = new JLabel("Icon: ");
iconPane.add(iconLabel, BorderLayout.WEST);
final JButton iconButton = new JButton(new ImageIcon(DefaultIcons.getActorConditionImage()));
iconPane.add(iconButton, BorderLayout.CENTER);
pane.add(iconPane, JideBoxLayout.FIX);
iconPane.setVisible(true);
dataTypeCombo.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
idPane.setVisible(true);
switch ((DataType) e.getItem()) {
case actorCondition:
iconPane.setVisible(true);
namePane.setVisible(true);
iconButton.setIcon(new ImageIcon(DefaultIcons.getActorConditionImage()));
creation = new ActorCondition();
break;
case dialogue:
iconPane.setVisible(false);
namePane.setVisible(false);
creation = new Dialogue();
break;
case droplist:
iconPane.setVisible(false);
namePane.setVisible(false);
creation = new Droplist();
break;
case item:
iconPane.setVisible(true);
namePane.setVisible(true);
creation = new Item();
iconButton.setIcon(new ImageIcon(DefaultIcons.getItemImage()));
break;
case itemCategory:
iconPane.setVisible(false);
namePane.setVisible(true);
creation = new ItemCategory();
break;
case npc:
iconPane.setVisible(true);
namePane.setVisible(true);
creation = new NPC();
iconButton.setIcon(new ImageIcon(DefaultIcons.getNPCImage()));
break;
case quest:
iconPane.setVisible(false);
namePane.setVisible(true);
creation = new Quest();
break;
default:
idPane.setVisible(false);
iconPane.setVisible(false);
namePane.setVisible(false);
creation = null;
break;
}
updateStatus();
idPane.revalidate();
namePane.revalidate();
iconPane.revalidate();
idPane.repaint();
namePane.repaint();
iconPane.repaint();
}
}
});
iconButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Spritesheet.Category cat = null;
switch ((DataType) dataTypeCombo.getSelectedItem()) {
case actorCondition:
cat = Spritesheet.Category.actorcondition;
break;
case dialogue:
break;
case droplist:
break;
case item:
cat = Spritesheet.Category.item;
break;
case itemCategory:
break;
case npc:
cat = Spritesheet.Category.monster;
break;
case quest:
break;
default:
break;
}
if (cat == null) return;
SpriteChooser chooser = SpriteChooser.getChooser(proj, cat);
chooser.setSelectionListener(new SpriteChooser.SelectionListener() {
@Override
public void iconSelected(String selected) {
if (selected != null) {
switch ((DataType) dataTypeCombo.getSelectedItem()) {
case actorCondition:
((ActorCondition) creation).icon_id = selected;
break;
case item:
((Item) creation).icon_id = selected;
break;
case npc:
((NPC) creation).icon_id = selected;
break;
case dialogue:
case droplist:
case itemCategory:
case quest:
default:
break;
}
iconButton.setIcon(new ImageIcon(proj.getImage(selected)));
iconButton.revalidate();
iconButton.repaint();
updateStatus();
}
}
});
chooser.setVisible(true);
}
});
pane.add(new JPanel(), JideBoxLayout.VARY);
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) {
switch ((DataType) dataTypeCombo.getSelectedItem()) {
case actorCondition:
((ActorCondition) creation).display_name = nameField.getText();
break;
case item:
((Item) creation).name = nameField.getText();
break;
case npc:
((NPC) creation).name = nameField.getText();
break;
case dialogue:
case droplist:
break;
case itemCategory:
((ItemCategory) creation).name = nameField.getText();
break;
case quest:
((Quest) creation).name = nameField.getText();
break;
default:
return;
}
creation.id = idField.getText();
JSONCreationWizard.this.setVisible(false);
JSONCreationWizard.this.dispose();
creation.state = State.created;
proj.createElement(creation);
notifyCreated();
ATContentStudio.frame.selectInTree(creation);
ATContentStudio.frame.openEditor(creation);
}
});
cancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
creation = null;
JSONCreationWizard.this.setVisible(false);
JSONCreationWizard.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);
nameField.getDocument().addDocumentListener(statusUpdater);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(pane, BorderLayout.CENTER);
setMinimumSize(new Dimension(350, 250));
idPane.setVisible(false);
iconPane.setVisible(false);
namePane.setVisible(false);
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 (creation == null) {
message.setText("<html><font color=\"#FF0000\">Select a data type below:</font></html>");
trouble = true;
} else 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 {
switch ((DataType) dataTypeCombo.getSelectedItem()) {
case actorCondition:
if (nameField.getText() == null || nameField.getText().length() <= 0) {
message.setText("<html><font color=\"#FF0000\">An actor condition must have a name.</font></html>");
trouble = true;
} else if (((ActorCondition) creation).icon_id == null) {
message.setText("<html><font color=\"#FF0000\">An actor condition must have an icon.</font></html>");
trouble = true;
} else if (proj.getActorCondition(idField.getText()) != null) {
if (proj.getActorCondition(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">An actor condition with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getActorCondition(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">An actor condition with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getActorCondition(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">An actor condition with the same ID exists in the game. It will be added under \"altered\".</font></html>");
}
}
break;
case item:
if (nameField.getText() == null || nameField.getText().length() <= 0) {
message.setText("<html><font color=\"#FF0000\">An item must have a name.</font></html>");
trouble = true;
} else if (((Item) creation).icon_id == null) {
message.setText("<html><font color=\"#FF0000\">An item must have an icon.</font></html>");
trouble = true;
} else if (proj.getItem(idField.getText()) != null) {
if (proj.getItem(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">An item with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getItem(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">An item with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getItem(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">An item with the same ID exists in the game. It will be added under \"altered\".</font></html>");
}
}
break;
case npc:
if (nameField.getText() == null || nameField.getText().length() <= 0) {
message.setText("<html><font color=\"#FF0000\">A NPC must have a name.</font></html>");
trouble = true;
} else if (((NPC) creation).icon_id == null) {
message.setText("<html><font color=\"#FF0000\">A NPC must have an icon.</font></html>");
trouble = true;
} else if (proj.getNPC(idField.getText()) != null) {
if (proj.getNPC(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">A NPC with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getNPC(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">A NPC with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getNPC(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">A NPC with the same ID exists in the game. It will be added under \"altered\".</font></html>");
}
}
break;
case dialogue:
if (proj.getDialogue(idField.getText()) != null) {
if (proj.getDialogue(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">A dialogue with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getDialogue(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">A dialogue with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getDialogue(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">A dialogue with the same ID exists in the game. It will be added under \"altered\".</font></html>");
}
}
break;
case droplist:
if (proj.getDroplist(idField.getText()) != null) {
if (proj.getDroplist(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">A droplist with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getDroplist(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">A droplist with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getDroplist(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">A droplist with the same ID exists in the game. It will be added under \"altered\".</font></html>");
}
}
break;
case itemCategory:
if (nameField.getText() == null || nameField.getText().length() <= 0) {
message.setText("<html><font color=\"#FF0000\">An item category must have a name.</font></html>");
trouble = true;
} else if (proj.getItemCategory(idField.getText()) != null) {
if (proj.getItemCategory(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">An item category with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getItemCategory(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">An item category with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getItemCategory(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">An item category with the same ID exists in the game. It will be added under \"altered\".</font></html>");
}
}
break;
case quest:
if (nameField.getText() == null || nameField.getText().length() <= 0) {
message.setText("<html><font color=\"#FF0000\">A quest must have a name.</font></html>");
trouble = true;
} else if (proj.getQuest(idField.getText()) != null) {
if (proj.getQuest(idField.getText()).getDataType() == GameSource.Type.created) {
message.setText("<html><font color=\"#FF0000\">A quest with the same ID was already created in this project.</font></html>");
trouble = true;
} else if (proj.getQuest(idField.getText()).getDataType() == GameSource.Type.altered) {
message.setText("<html><font color=\"#FF0000\">A quest with the same ID exists in the game and is already altered in this project.</font></html>");
trouble = true;
} else if (proj.getQuest(idField.getText()).getDataType() == GameSource.Type.source) {
message.setText("<html><font color=\"#FF9000\">A quest with the same ID exists in the game. It will be added under \"altered\".</font></html>");
}
}
break;
default:
break;
}
}
ok.setEnabled(!trouble);
message.revalidate();
message.repaint();
}
public static String dataTypeDesc(DataType type) {
switch (type) {
case actorCondition:
return "Actor Condition";
case dialogue:
return "Dialogue";
case droplist:
return "Droplist";
case item:
return "Item";
case itemCategory:
return "Item Category";
case npc:
return "NPC";
case quest:
return "Quest";
default:
return "Select below";
}
}
@SuppressWarnings("rawtypes")
public static class DataTypeComboModel implements ComboBoxModel {
DataType selected = DataType.none;
@Override
public int getSize() {
return DataType.values().length;
}
@Override
public Object getElementAt(int index) {
return DataType.values()[index];
}
List<ListDataListener> listeners = new CopyOnWriteArrayList<ListDataListener>();
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
}
@Override
public void removeListDataListener(ListDataListener l) {
listeners.remove(l);
}
@Override
public void setSelectedItem(Object anItem) {
selected = (DataType) anItem;
}
@Override
public Object getSelectedItem() {
return selected;
}
}
public static class DataTypeComboCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = 5621373849299980998L;
@Override
public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (c instanceof JLabel) {
((JLabel) c).setText(JSONCreationWizard.dataTypeDesc((DataType) value));
switch ((DataType) value) {
case actorCondition:
((JLabel) c).setIcon(new ImageIcon(DefaultIcons.getActorConditionIcon()));
break;
case dialogue:
((JLabel) c).setIcon(new ImageIcon(DefaultIcons.getDialogueIcon()));
break;
case droplist:
((JLabel) c).setIcon(new ImageIcon(DefaultIcons.getDroplistIcon()));
break;
case item:
((JLabel) c).setIcon(new ImageIcon(DefaultIcons.getItemIcon()));
break;
case itemCategory:
((JLabel) c).setIcon(new ImageIcon(DefaultIcons.getDroplistIcon()));
break;
case npc:
((JLabel) c).setIcon(new ImageIcon(DefaultIcons.getNPCIcon()));
break;
case quest:
((JLabel) c).setIcon(new ImageIcon(DefaultIcons.getQuestIcon()));
break;
default:
break;
}
}
return c;
}
}
public static interface CreationCompletedListener {
public void elementCreated(JSONElement created);
}
private List<CreationCompletedListener> listeners = new CopyOnWriteArrayList<JSONCreationWizard.CreationCompletedListener>();
public void addCreationListener(CreationCompletedListener l) {
listeners.add(l);
}
public void notifyCreated() {
for (CreationCompletedListener l : listeners) {
l.elementCreated(creation);
}
}
}