package com.kartoflane.superluminal2.ui; import java.util.ArrayList; import java.util.HashMap; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Widget; import com.kartoflane.superluminal2.components.enums.Systems; import com.kartoflane.superluminal2.core.Cache; import com.kartoflane.superluminal2.core.Manager; import com.kartoflane.superluminal2.ftl.ShipObject; import com.kartoflane.superluminal2.ftl.SystemObject; import com.kartoflane.superluminal2.mvc.controllers.RoomController; import com.kartoflane.superluminal2.mvc.controllers.SystemController; import com.kartoflane.superluminal2.tools.Tool.Tools; import com.kartoflane.superluminal2.undo.UndoablePropertyEdit; import com.kartoflane.superluminal2.undo.UndoableSystemAssignmentEdit; import com.kartoflane.superluminal2.undo.UndoableSystemEmptyEdit; import com.kartoflane.superluminal2.undo.UndoableSystemEmptyEdit.NoSystemsException; import com.kartoflane.superluminal2.utils.UIUtils; @SuppressWarnings("serial") public class SystemsMenu { private static SystemsMenu instance; private ShipContainer container = null; private RoomController controller = null; private HashMap<SystemObject, MenuItem> systemItemMap = new HashMap<SystemObject, MenuItem>(); private Menu systemMenu; private Menu menuAssign; private MenuItem mntmAssign; private MenuItem mntmEmpty; private ArrayList<MenuItem> mntmArtilleries = new ArrayList<MenuItem>(); public SystemsMenu(Control parent, RoomController controller) { if (instance != null) throw new IllegalStateException("Previous instance has not been disposed!"); instance = this; container = Manager.getCurrentShip(); this.controller = controller; createContent(parent); } public static SystemsMenu getInstance() { return instance; } public void open() { if (Manager.getSelectedToolId() != Tools.POINTER) throw new IllegalStateException("Manipulation tool is not selected."); if (Manager.getSelected() == null) throw new IllegalStateException("The selected controller is null."); if (Manager.getSelected() instanceof RoomController == false) throw new IllegalStateException("The selected controller is not a RoomController."); container = Manager.getCurrentShip(); SystemObject sys = container.getActiveSystem(controller.getGameObject()); SystemController roomSystem = (SystemController) container.getController(sys); mntmEmpty.setSelection(roomSystem.getSystemId() == Systems.EMPTY); for (Systems systemId : Systems.getSystems()) { for (SystemObject system : container.getShipController().getGameObject().getSystems(systemId)) { MenuItem item = getItem(system); item.setSelection(roomSystem.getSystemId() == systemId); if (system.isAssigned()) { Cache.checkInImage(item, systemId.getSmallIcon()); item.setImage(Cache.checkOutImage(item, "cpath:/assets/tick.png")); } else { Cache.checkInImage(item, "cpath:/assets/tick.png"); item.setImage(Cache.checkOutImage(item, systemId.getSmallIcon())); } } } systemMenu.setVisible(true); Display display = UIUtils.getDisplay(); while (systemMenu.isVisible()) { if (!display.readAndDispatch()) display.sleep(); } dispose(); } public void setLocation(int x, int y) { systemMenu.setLocation(x, y); } public void setLocation(Point p) { systemMenu.setLocation(p.x, p.y); } public void dispose() { systemItemMap.clear(); systemMenu.dispose(); instance = null; } public boolean isDisposed() { return systemMenu == null || systemMenu.isDisposed(); } private void createContent(Control parent) { ShipObject ship = container.getShipController().getGameObject(); Systems[] systems = null; systemMenu = new Menu(parent); mntmAssign = new MenuItem(systemMenu, SWT.CASCADE); mntmAssign.setText("Assign"); menuAssign = new Menu(mntmAssign); mntmAssign.setMenu(menuAssign); mntmEmpty = new MenuItem(menuAssign, SWT.NONE); mntmEmpty.setText("Empty"); mntmEmpty.setData(ship.getSystem(Systems.EMPTY)); final MenuItem mntmSystem = new MenuItem(menuAssign, SWT.CASCADE); mntmSystem.setText("Systems"); final Menu menuSystems = new Menu(mntmSystem); mntmSystem.setMenu(menuSystems); systems = new Systems[] { Systems.ENGINES, Systems.MEDBAY, Systems.CLONEBAY, Systems.OXYGEN, Systems.SHIELDS, Systems.WEAPONS }; for (Systems sys : systems) { for (SystemObject system : ship.getSystems(sys)) { SystemController sysC = (SystemController) container.getController(system); String alias = sysC.getAlias(); MenuItem mntm = new MenuItem(menuSystems, SWT.NONE); mntm.setText(sys.toString() + (alias == null || alias.trim().equals("") ? "" : " (" + alias + ")")); mntm.setData(system); systemItemMap.put(system, mntm); } } final MenuItem mntmSubsystem = new MenuItem(menuAssign, SWT.CASCADE); mntmSubsystem.setText("Subsystems"); final Menu menuSubsystems = new Menu(mntmSubsystem); mntmSubsystem.setMenu(menuSubsystems); systems = new Systems[] { Systems.BATTERY, Systems.DOORS, Systems.PILOT, Systems.SENSORS }; for (Systems sys : systems) { for (SystemObject system : ship.getSystems(sys)) { SystemController sysC = (SystemController) container.getController(system); String alias = sysC.getAlias(); MenuItem mntm = new MenuItem(menuSubsystems, SWT.NONE); mntm.setText(sys.toString() + (alias == null || alias.trim().equals("") ? "" : " (" + alias + ")")); mntm.setData(system); systemItemMap.put(system, mntm); } } final MenuItem mntmSpecial = new MenuItem(menuAssign, SWT.CASCADE); mntmSpecial.setText("Special"); final Menu menuSpecial = new Menu(mntmSpecial); mntmSpecial.setMenu(menuSpecial); systems = new Systems[] { Systems.CLOAKING, Systems.DRONES, Systems.HACKING, Systems.MIND, Systems.TELEPORTER }; for (Systems sys : systems) { for (SystemObject system : ship.getSystems(sys)) { SystemController sysC = (SystemController) container.getController(system); String alias = sysC.getAlias(); MenuItem mntm = new MenuItem(menuSpecial, SWT.NONE); mntm.setText(sys.toString() + (alias == null || alias.trim().equals("") ? "" : " (" + alias + ")")); mntm.setData(system); systemItemMap.put(system, mntm); } } final MenuItem mntmArtillery = new MenuItem(menuAssign, SWT.CASCADE); mntmArtillery.setText("Artillery"); final Menu menuArtillery = new Menu(mntmArtillery); mntmArtillery.setMenu(menuArtillery); for (SystemObject sys : ship.getSystems(Systems.ARTILLERY)) { SystemController sysC = (SystemController) container.getController(sys); String alias = sysC.getAlias(); MenuItem mntm = new MenuItem(menuArtillery, SWT.NONE); mntm.setText(sys.toString() + (alias == null || alias.trim().equals("") ? "" : " (" + alias + ")")); mntm.setData(sys); systemItemMap.put(sys, mntm); mntmArtilleries.add(mntm); } SelectionAdapter systemListener = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Widget w = (Widget) e.getSource(); if (w == mntmEmpty) { try { container.postEdit(new UndoableSystemEmptyEdit(controller)); } catch (NoSystemsException ex) { // Ignore, only serves to prevent the edit from being posted } for (SystemObject system : container.getAllAssignedSystems(controller.getGameObject())) { container.unassign(system); } } else { SystemObject so = (SystemObject) w.getData(); SystemController sys = (SystemController) container.getController(so); RoomController rc = (RoomController) container.getController(so.getRoom()); container.assign((SystemObject) w.getData(), controller); UndoableSystemAssignmentEdit edit = new UndoableSystemAssignmentEdit(sys); edit.setOld(rc); edit.setCurrent(controller); container.postEdit(edit); } EditorWindow.getInstance().updateSidebarContent(); controller.redraw(); OverviewWindow.staticUpdate(controller); } }; mntmEmpty.addSelectionListener(systemListener); for (MenuItem mntm : systemItemMap.values()) { mntm.addSelectionListener(systemListener); } ArrayList<SystemObject> assignedSystems = container.getAllAssignedSystems(controller.getGameObject()); if (assignedSystems.size() > 0) { new MenuItem(systemMenu, SWT.SEPARATOR); for (SystemObject sys : assignedSystems) createSystemSubmenu(sys); } } private MenuItem createSystemSubmenu(final SystemObject sys) { MenuItem mntmSystem = new MenuItem(systemMenu, SWT.CASCADE); String alias = sys.getAlias(); mntmSystem.setText(sys.toString() + (alias == null || alias.trim().equals("") ? "" : " (" + alias + ")")); final Menu menuOptions = new Menu(mntmSystem); mntmSystem.setMenu(menuOptions); final MenuItem mntmSelect = new MenuItem(menuOptions, SWT.NONE); mntmSelect.setText("Select"); final MenuItem mntmUnassign = new MenuItem(menuOptions, SWT.NONE); mntmUnassign.setText("Unassign"); mntmSelect.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { UndoablePropertyEdit<SystemObject> edit = new UndoablePropertyEdit<SystemObject>(controller) { @Override public void callback(SystemObject arg) { RoomController controller = (RoomController) data; container.setActiveSystem(controller.getGameObject(), arg); EditorWindow.getInstance().updateSidebarContent(); } @Override public String getPresentationName() { return "change active system"; } }; edit.setOld(container.getActiveSystem(controller.getGameObject())); edit.setCurrent(sys); container.setActiveSystem(controller.getGameObject(), sys); EditorWindow.getInstance().updateSidebarContent(); if (!edit.isValuesEqual()) Manager.postEdit(edit); } }); mntmUnassign.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { SystemController sc = (SystemController) container.getController(sys); RoomController rc = (RoomController) container.getController(sys.getRoom()); container.unassign(sys); EditorWindow.getInstance().updateSidebarContent(); UndoableSystemAssignmentEdit edit = new UndoableSystemAssignmentEdit(sc); edit.setOld(rc); edit.setCurrent(null); container.postEdit(edit); } }); return mntmSystem; } private MenuItem getItem(SystemObject sys) { return systemItemMap.get(sys); } }