package com.kartoflane.superluminal2.mvc.controllers; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import com.kartoflane.superluminal2.core.Grid; import com.kartoflane.superluminal2.core.Grid.Snapmodes; import com.kartoflane.superluminal2.core.LayeredPainter.Layers; import com.kartoflane.superluminal2.core.Manager; import com.kartoflane.superluminal2.events.SLDeleteEvent; import com.kartoflane.superluminal2.events.SLEvent; import com.kartoflane.superluminal2.ftl.DoorObject; import com.kartoflane.superluminal2.ftl.RoomObject; import com.kartoflane.superluminal2.mvc.View; import com.kartoflane.superluminal2.mvc.models.ObjectModel; import com.kartoflane.superluminal2.mvc.views.BaseView; import com.kartoflane.superluminal2.mvc.views.DoorView; import com.kartoflane.superluminal2.ui.OverviewWindow; import com.kartoflane.superluminal2.ui.ShipContainer; import com.kartoflane.superluminal2.ui.sidebar.data.DataComposite; import com.kartoflane.superluminal2.ui.sidebar.data.DoorDataComposite; public class DoorController extends ObjectController { public static final int COLLISION_TOLERANCE = 3; protected ShipContainer container = null; private DoorController(ShipContainer container, ObjectModel model, DoorView view) { super(); setModel(model); setView(view); this.container = container; setSelectable(true); setLocModifiable(true); setBounded(true); setCollidable(!Manager.allowDoorOverlap); setTolerance(COLLISION_TOLERANCE); setParent(container.getShipController()); setPresentedFactor(ShipContainer.CELL_SIZE); setSize(DoorObject.DOOR_WIDTH, DoorObject.DOOR_HEIGHT); } public static DoorController newInstance(ShipContainer container, DoorObject object) { ObjectModel model = new ObjectModel(object); DoorView view = new DoorView(); DoorController controller = new DoorController(container, model, view); controller.setHorizontal(controller.getGameObject().isHorizontal()); controller.setLeftRoom(object.getLeftRoom()); controller.setRightRoom(object.getRightRoom()); OverviewWindow ow = OverviewWindow.getInstance(); controller.addListener(SLEvent.DELETE, ow); controller.addListener(SLEvent.DISPOSE, ow); return controller; } public DoorObject getGameObject() { return (DoorObject) getModel().getGameObject(); } public void setHorizontal(boolean horizontal) { setVisible(false); Point p = getPresentedLocation(); getGameObject().setHorizontal(horizontal); updateBoundingArea(); setSnapMode(horizontal ? Snapmodes.EDGE_H : Snapmodes.EDGE_V); setLocation(Grid.getInstance().snapToGrid(p.x * getPresentedFactor(), p.y * getPresentedFactor(), getSnapMode())); updateFollowOffset(); updateView(); setVisible(true); } public boolean isHorizontal() { return getGameObject().isHorizontal(); } @Override public void setView(View view) { super.setView(view); this.view.addToPainter(Layers.DOOR); } /** * Links this door to the specified room. May be null for automatic linking. */ public void setLeftRoom(RoomObject room) { AbstractController roomC = container.getController(getLeftRoom()); if (roomC != null) roomC.removeListener(SLEvent.DELETE, this); getGameObject().setLeftRoom(room); roomC = container.getController(getLeftRoom()); if (roomC != null) roomC.addListener(SLEvent.DELETE, this); } /** * Links this door to the specified room. May be null for automatic linking. */ public void setRightRoom(RoomObject room) { AbstractController roomC = container.getController(getRightRoom()); if (roomC != null) roomC.removeListener(SLEvent.DELETE, this); getGameObject().setRightRoom(room); roomC = container.getController(getRightRoom()); if (roomC != null) roomC.addListener(SLEvent.DELETE, this); } public RoomObject getLeftRoom() { return getGameObject().getLeftRoom(); } public RoomObject getRightRoom() { return getGameObject().getRightRoom(); } @Override public int getW() { return isHorizontal() ? DoorObject.DOOR_WIDTH : DoorObject.DOOR_HEIGHT; } @Override public int getH() { return isHorizontal() ? DoorObject.DOOR_HEIGHT : DoorObject.DOOR_WIDTH; } @Override public Rectangle getBounds() { Rectangle b = model.getBounds(); if (!isHorizontal()) { int cX = b.x + b.width / 2; int cY = b.y + b.height / 2; b.x = cX - b.height / 2; b.y = cY - b.width / 2; cX = b.width; b.width = b.height; b.height = cX; } return b; } @Override public Point getPresentedLocation() { return new Point((getX() + getH()) / getPresentedFactor(), (getY() + getW()) / getPresentedFactor()); } @Override public Point getPresentedSize() { throw new UnsupportedOperationException(); } @Override public void setPresentedLocation(int x, int y) { setLocation(Grid.getInstance().snapToGrid(x * getPresentedFactor(), y * getPresentedFactor(), getSnapMode())); } @Override public void setPresentedSize(int w, int h) { throw new UnsupportedOperationException(); } @Override public DataComposite getDataComposite(Composite parent) { DataComposite dc = new DoorDataComposite(parent, this); dc.updateData(); return dc; } protected void updateSelectionAppearance() { if (selected) { view.setBorderColor(BaseView.SELECT_RGB); view.setBorderThickness(2); } else { view.setBorderColor(null); } redraw(); } @Override public void select() { super.select(); updateSelectionAppearance(); } @Override public void deselect() { super.deselect(); setMoving(false); updateSelectionAppearance(); } @Override public void mouseMove(MouseEvent e) { int oldX = getX(), oldY = getY(); super.mouseMove(e); if (Manager.resetDoorLinksOnMove && (oldX != getX() || oldY != getY())) { setLeftRoom(null); setRightRoom(null); container.getParent().updateSidebarContent(); } } @Override public void updateBoundingArea() { Point gridSize = Grid.getInstance().getSize(); gridSize.x -= (gridSize.x % ShipContainer.CELL_SIZE) + ShipContainer.CELL_SIZE; gridSize.y -= (gridSize.y % ShipContainer.CELL_SIZE) + ShipContainer.CELL_SIZE; setBoundingPoints(getParent().getX() + (isHorizontal() ? getW() / 2 + 4 : 0), getParent().getY() + (isHorizontal() ? 0 : getH() / 2 + 4), gridSize.x, gridSize.y); } @Override public String toString() { DoorObject door = getGameObject(); String result = "Door " + (door.isHorizontal() ? "H" : "V"); if (getAlias() != null && !getAlias().equals("")) result += " (" + door.getAlias() + ")"; return result; } @Override public void handleEvent(SLEvent e) { if (e instanceof SLDeleteEvent) { if (e.data instanceof RoomController) { if (container.getController(getLeftRoom()) == e.data) setLeftRoom(null); else if (container.getController(getRightRoom()) == e.data) setRightRoom(null); } } else { super.handleEvent(e); } } }