package com.kartoflane.superluminal2.ui.sidebar.data;
import java.io.File;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Text;
import com.kartoflane.superluminal2.Superluminal;
import com.kartoflane.superluminal2.components.enums.OS;
import com.kartoflane.superluminal2.components.enums.Systems;
import com.kartoflane.superluminal2.core.Cache;
import com.kartoflane.superluminal2.core.Manager;
import com.kartoflane.superluminal2.ftl.GlowSet;
import com.kartoflane.superluminal2.ftl.SystemObject;
import com.kartoflane.superluminal2.mvc.controllers.AbstractController;
import com.kartoflane.superluminal2.mvc.controllers.GlowController;
import com.kartoflane.superluminal2.mvc.controllers.RoomController;
import com.kartoflane.superluminal2.mvc.controllers.SystemController;
import com.kartoflane.superluminal2.ui.BrowseMenu;
import com.kartoflane.superluminal2.ui.DatabaseFileDialog;
import com.kartoflane.superluminal2.ui.EditorWindow;
import com.kartoflane.superluminal2.ui.GlowSelectionDialog;
import com.kartoflane.superluminal2.ui.ImageViewerDialog;
import com.kartoflane.superluminal2.ui.OverviewWindow;
import com.kartoflane.superluminal2.ui.ShipContainer;
import com.kartoflane.superluminal2.ui.SystemsMenu;
import com.kartoflane.superluminal2.undo.UndoablePropertyEdit;
import com.kartoflane.superluminal2.utils.IOUtils;
import com.kartoflane.superluminal2.utils.UIUtils;
import com.kartoflane.superluminal2.utils.Utils;
@SuppressWarnings("serial")
public class RoomDataComposite extends Composite implements DataComposite {
private static String prevInteriorPath = System.getProperty("user.home");
private RoomController roomC = null;
private ShipContainer container = null;
private Button btnSystem;
private Label lblSysLevel;
private Label lblMaxLevel;
private Scale scaleSysLevel;
private Text txtSysLevel;
private Scale scaleMaxLevel;
private Text txtMaxLevel;
private Button btnAvailable;
private Composite imagesComposite;
private Button btnInteriorBrowse;
private Button btnInteriorClear;
private Text txtInterior;
private Label lblNameInfo;
private Label lblName;
private Text txtName;
private Button btnInteriorView;
private Label label;
private Label lblGlow;
private Button btnGlow;
private BrowseMenu mnb;
public RoomDataComposite(Composite parent, RoomController control) {
super(parent, SWT.NONE);
setLayout(new GridLayout(3, false));
Image helpImage = Cache.checkOutImage(this, "cpath:/assets/help.png");
roomC = control;
container = Manager.getCurrentShip();
label = new Label(this, SWT.NONE);
label.setAlignment(SWT.CENTER);
label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
label.setText("Room");
Label lblHelp = new Label(this, SWT.NONE);
lblHelp.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblHelp.setImage(helpImage);
String msg = "- Click on the system button to open system assignment menu\n" +
"- Alternatively, right-click on the room to open the menu\n" +
"- When a system is assigned, it'll be visible in the assignment\n" +
" menu, under 'Assign' - this menu contains more options\n" +
"- Multiple systems can be assigned to a single room (should\n" +
" only be used for Clonebay/Medbay)\n" +
"- The editor only shows one system at a time -- you can bring\n" +
" one of the other assigned systems into focus by clicking on\n" +
" 'Select' in the system's submenu.";
UIUtils.addTooltip(lblHelp, msg);
Label separator = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
separator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1));
Label lblSystem = new Label(this, SWT.NONE);
lblSystem.setText("System: ");
btnSystem = new Button(this, SWT.NONE);
GridData gd_btnSystem = new GridData(SWT.RIGHT, SWT.CENTER, true, false, 2, 1);
gd_btnSystem.widthHint = 100;
btnSystem.setLayoutData(gd_btnSystem);
btnSystem.setText("");
btnAvailable = new Button(this, SWT.CHECK);
btnAvailable.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
btnAvailable.setText("Available At Start");
Label lblStartHelp = new Label(this, SWT.NONE);
lblStartHelp.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblStartHelp.setImage(helpImage);
msg = "This determines whether the ship starts with this system already installed.";
UIUtils.addTooltip(lblStartHelp, Utils.wrapOSNot(msg, Superluminal.WRAP_WIDTH, Superluminal.WRAP_TOLERANCE, OS.MACOSX()));
lblSysLevel = new Label(this, SWT.NONE);
lblSysLevel.setText("Starting Level:");
scaleSysLevel = new Scale(this, SWT.NONE);
scaleSysLevel.setMaximum(2);
scaleSysLevel.setMinimum(1);
scaleSysLevel.setPageIncrement(1);
scaleSysLevel.setIncrement(1);
scaleSysLevel.setSelection(1);
scaleSysLevel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
txtSysLevel = new Text(this, SWT.BORDER | SWT.READ_ONLY);
txtSysLevel.setText("");
txtSysLevel.setTextLimit(3);
GridData gd_txtSysLevel = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
gd_txtSysLevel.widthHint = 20;
txtSysLevel.setLayoutData(gd_txtSysLevel);
scaleSysLevel.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
SystemController system = (SystemController) container.getController(sys);
system.setLevel(scaleSysLevel.getSelection());
txtSysLevel.setText("" + scaleSysLevel.getSelection());
}
});
if (!container.isPlayerShip()) {
lblMaxLevel = new Label(this, SWT.NONE);
lblMaxLevel.setText("Max Level:");
scaleMaxLevel = new Scale(this, SWT.NONE);
scaleMaxLevel.setMaximum(2);
scaleMaxLevel.setMinimum(1);
scaleMaxLevel.setPageIncrement(1);
scaleMaxLevel.setIncrement(1);
scaleMaxLevel.setSelection(1);
scaleMaxLevel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
txtMaxLevel = new Text(this, SWT.BORDER | SWT.READ_ONLY);
txtMaxLevel.setText("");
txtMaxLevel.setTextLimit(3);
GridData gd_txtMaxLevel = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
gd_txtMaxLevel.widthHint = 20;
txtMaxLevel.setLayoutData(gd_txtMaxLevel);
scaleMaxLevel.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
SystemController system = (SystemController) container.getController(sys);
system.setLevelMax(scaleMaxLevel.getSelection());
txtMaxLevel.setText("" + scaleMaxLevel.getSelection());
scaleSysLevel.setMaximum(scaleMaxLevel.getSelection());
scaleSysLevel.notifyListeners(SWT.Selection, null);
scaleSysLevel.setEnabled(scaleMaxLevel.getSelection() > 1);
scaleSysLevel.setSelection(Math.min(scaleSysLevel.getSelection(), scaleSysLevel.getMaximum()));
}
});
} else {
imagesComposite = new Composite(this, SWT.NONE);
GridLayout gl_imagesComposite = new GridLayout(4, false);
gl_imagesComposite.marginHeight = 20;
gl_imagesComposite.marginWidth = 0;
imagesComposite.setLayout(gl_imagesComposite);
imagesComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
// Interior widgets
Label lblInterior = new Label(imagesComposite, SWT.NONE);
lblInterior.setText("Interior image:");
btnInteriorView = new Button(imagesComposite, SWT.NONE);
btnInteriorView.setEnabled(false);
btnInteriorView.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false, 1, 1));
btnInteriorView.setText("View");
btnInteriorBrowse = new Button(imagesComposite, SWT.NONE);
btnInteriorBrowse.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
btnInteriorBrowse.setText("Browse");
btnInteriorClear = new Button(imagesComposite, SWT.NONE);
btnInteriorClear.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
btnInteriorClear.setText("Default");
txtInterior = new Text(imagesComposite, SWT.BORDER | SWT.READ_ONLY);
txtInterior.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1));
Composite cGlow = new Composite(imagesComposite, SWT.NONE);
GridLayout gl_cGlow = new GridLayout(3, false);
gl_cGlow.marginHeight = 0;
gl_cGlow.marginWidth = 0;
cGlow.setLayout(gl_cGlow);
cGlow.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 4, 1));
lblName = new Label(cGlow, SWT.NONE);
lblName.setText("Export Name");
txtName = new Text(cGlow, SWT.BORDER);
txtName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
lblNameInfo = new Label(cGlow, SWT.NONE);
lblNameInfo.setImage(helpImage);
lblNameInfo.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
msg = "This field allows you to specify the name the interior image will be exported as. " +
"This is useful, because glow images are tied to image names, so having a unique name " +
"will allow the glow image to only be used for your ship.";
UIUtils.addTooltip(lblNameInfo, Utils.wrapOSNot(msg, Superluminal.WRAP_WIDTH, Superluminal.WRAP_TOLERANCE, OS.MACOSX()));
// Glow widgets
lblGlow = new Label(imagesComposite, SWT.NONE);
lblGlow.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblGlow.setText("Manning Glow:");
btnGlow = new Button(imagesComposite, SWT.NONE);
GridData gd_btnGlow = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 3, 1);
gd_btnGlow.widthHint = 120;
btnGlow.setLayoutData(gd_btnGlow);
btnGlow.setText("None");
btnInteriorView.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
SystemController system = (SystemController) container.getController(sys);
String path = system.getInteriorPath();
if (path != null) {
ImageViewerDialog dialog = new ImageViewerDialog(EditorWindow.getInstance().getShell());
dialog.open(path);
}
}
});
mnb = new BrowseMenu(this);
mnb.addTo(btnInteriorBrowse);
mnb.addSystemListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
FileDialog dialog = new FileDialog(EditorWindow.getInstance().getShell(), SWT.OPEN);
dialog.setFilterExtensions(new String[] { "*.png" });
dialog.setFilterPath(prevInteriorPath);
dialog.setFileName(prevInteriorPath);
boolean exit = false;
while (!exit) {
String path = dialog.open();
// path == null only when user cancels
if (path == null) {
exit = true;
} else {
prevInteriorPath = path;
exit = setInteriorImage("file:", path);
}
}
}
});
mnb.addDataListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
DatabaseFileDialog dialog = new DatabaseFileDialog(EditorWindow.getInstance().getShell());
dialog.setFilterExtensions(new String[] { "*.png" });
dialog.setText("FTL Archive Browser");
boolean exit = false;
while (!exit) {
String path = dialog.open();
// path == null only when user cancels
if (path == null) {
exit = true;
} else {
exit = setInteriorImage("db:", path);
}
}
}
});
btnInteriorClear.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
SystemController system = (SystemController) container.getController(sys);
UndoablePropertyEdit<String> edit = new UndoablePropertyEdit<String>(system) {
public void callback(String arg) {
SystemController system = (SystemController) data;
boolean vis = system.isVisible();
system.setVisible(false);
system.setInteriorPath(arg);
system.setVisible(vis);
if (!isDisposed())
updateData();
}
@Override
public String getPresentationName() {
SystemController system = (SystemController) data;
return String.format("clear %s image", system.toString());
}
};
edit.setOld(system.getInteriorPath());
system.setInteriorPath(null);
edit.setCurrent(system.getInteriorPath());
EditorWindow.getInstance().canvasRedraw();
updateData();
if (!edit.isValuesEqual())
Manager.postEdit(edit);
}
});
btnGlow.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SystemObject systemObject = container.getActiveSystem(roomC.getGameObject());
GlowSelectionDialog dialog = new GlowSelectionDialog(EditorWindow.getInstance().getShell());
GlowSet glowSet = dialog.open(systemObject);
if (glowSet != null) {
btnGlow.setText(glowSet.getIdentifier());
if (systemObject.getSystemId() == Systems.CLOAKING) {
systemObject.getGlow().setGlowSet(glowSet);
} else {
GlowController gc = (GlowController) container.getController(systemObject.getGlow());
gc.setVisible(false);
gc.setGlowSet(glowSet);
gc.setVisible(true);
}
}
}
});
txtName.addFocusListener(new FocusListener() {
private String prevValue = "";
public void focusGained(FocusEvent e) {
}
public void focusLost(FocusEvent e) {
String newValue = txtName.getText();
if (!newValue.trim().equals("") && !prevValue.equals(newValue)) {
prevValue = newValue;
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
sys.setInteriorNamespace(newValue);
}
}
});
}
btnSystem.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SystemsMenu sysMenu = new SystemsMenu(container.getParent().getShell(), roomC);
sysMenu.setLocation(btnSystem.toDisplay(0, btnSystem.getSize().y));
sysMenu.open();
}
});
btnAvailable.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
SystemController system = (SystemController) container.getController(sys);
system.setAvailableAtStart(btnAvailable.getSelection());
roomC.redraw();
UndoablePropertyEdit<Boolean> edit = new UndoablePropertyEdit<Boolean>(system) {
@Override
public void callback(Boolean arg) {
SystemController system = (SystemController) data;
system.setAvailableAtStart(arg);
system.redraw();
if (!isDisposed())
updateData();
}
@Override
public String getPresentationName() {
SystemController system = (SystemController) data;
return String.format("toggle %s availability", system.toString());
}
};
edit.setOld(!system.isAvailableAtStart());
edit.setCurrent(system.isAvailableAtStart());
Manager.postEdit(edit);
}
});
updateData();
pack();
}
public void updateData() {
if (roomC == null)
return;
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
SystemController system = (SystemController) container.getController(sys);
boolean playerShip = container.isPlayerShip();
String alias = roomC.getAlias();
label.setText("Room " + roomC.getId() + (alias == null || alias.trim().equals("") ? "" : " (" + alias + ")"));
alias = sys.getAlias();
btnSystem.setText(sys.toString() + (alias == null || alias.trim().equals("") ? "" : " (" + alias + ")"));
btnAvailable.setEnabled(system.getSystemId() != Systems.EMPTY);
scaleSysLevel.setEnabled(system.getSystemId() != Systems.EMPTY);
if (!playerShip)
scaleMaxLevel.setEnabled(system.getSystemId() != Systems.EMPTY);
if (system.getSystemId() != Systems.EMPTY) {
// Update widgets with the system's data
btnAvailable.setSelection(system.isAvailableAtStart());
scaleSysLevel.setMaximum(playerShip ? system.getLevelCap() : scaleMaxLevel.getSelection());
scaleSysLevel.setSelection(system.getLevel());
scaleSysLevel.notifyListeners(SWT.Selection, null);
if (playerShip) {
btnInteriorBrowse.setEnabled(system.canContainInterior());
btnInteriorClear.setEnabled(system.canContainInterior());
btnInteriorView.setEnabled(system.getInteriorPath() != null);
String temp = system.getInteriorPath();
txtInterior.setText(temp == null ? "" : IOUtils.trimProtocol(temp));
txtInterior.selectAll();
txtInterior.clearSelection();
if (system.getSystemId() == Systems.CLOAKING) {
lblGlow.setText("Activation glow:");
} else {
lblGlow.setText("Manning glow:");
}
lblGlow.setVisible(system.canContainGlow());
btnGlow.setVisible(system.canContainGlow());
lblName.setVisible(system.canContainGlow());
lblNameInfo.setVisible(system.canContainGlow());
txtName.setVisible(system.canContainGlow());
if (system.canContainGlow()) {
btnGlow.setText(system.getGameObject().getGlow().getGlowSet().getIdentifier());
txtName.setText(system.getGameObject().getInteriorNamespace());
}
} else {
scaleMaxLevel.setMaximum(system.getLevelCap());
scaleMaxLevel.setSelection(system.getLevelMax());
scaleMaxLevel.notifyListeners(SWT.Selection, null);
scaleSysLevel.setEnabled(scaleMaxLevel.getSelection() > 1);
}
} else {
// No system - reset to default
scaleSysLevel.setMaximum(2);
scaleSysLevel.setSelection(1);
txtSysLevel.setText("");
if (playerShip) {
btnInteriorBrowse.setEnabled(false);
btnInteriorClear.setEnabled(false);
btnInteriorView.setEnabled(false);
txtInterior.setText("");
lblGlow.setVisible(false);
btnGlow.setVisible(false);
lblName.setVisible(false);
lblNameInfo.setVisible(false);
txtName.setVisible(false);
} else {
scaleMaxLevel.setMaximum(2);
scaleMaxLevel.setSelection(1);
txtMaxLevel.setText("");
}
}
OverviewWindow.staticUpdate(roomC);
}
@Override
public void setController(AbstractController roomC) {
if (this.roomC != null) {
SystemObject sys = container.getActiveSystem(this.roomC.getGameObject());
if (container.isPlayerShip() && sys.canContainGlow()) {
txtName.notifyListeners(SWT.FocusOut, null);
}
}
this.roomC = (RoomController) roomC;
}
public void reloadController() {
}
@Override
public void dispose() {
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
if (container.isPlayerShip() && sys.canContainGlow()) {
txtName.notifyListeners(SWT.FocusOut, null);
}
super.dispose();
}
private boolean setInteriorImage(String protocol, String path) {
SystemObject sys = container.getActiveSystem(roomC.getGameObject());
SystemController system = (SystemController) container.getController(sys);
if (protocol.equals("file:") && !new File(path).exists()) {
UIUtils.showWarningDialog(EditorWindow.getInstance().getShell(), null, "The file you have selected does not exist.");
return false;
}
UndoablePropertyEdit<String> edit = new UndoablePropertyEdit<String>(system) {
public void callback(String arg) {
SystemController system = (SystemController) data;
boolean vis = system.isVisible();
system.setVisible(false);
system.setInteriorPath(arg);
system.setVisible(vis);
if (!isDisposed())
updateData();
}
@Override
public String getPresentationName() {
SystemController system = (SystemController) data;
return String.format("change %s image", system.toString());
}
};
edit.setOld(system.getInteriorPath());
edit.setCurrent(protocol + path);
system.setInteriorPath(protocol + path);
EditorWindow.getInstance().canvasRedraw();
updateData();
if (!edit.isValuesEqual())
Manager.postEdit(edit);
return true;
}
}