package ui.controller; import java.awt.Point; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.ListIterator; import java.util.stream.Collectors; import classes.AbstractCanvasObject; import classes.Edge; import classes.GroupNode; import classes.HolonObject; import classes.HolonSwitch; import classes.Node; import interfaces.ObjectListener; import ui.model.Model; import ui.view.GUI; import utility.Vector2Int; /** * Controller for the Canvas. * * @author Gruppe14 */ public class CanvasController { private Model model; private MultiPurposeController mpC; private GUI gui; /** * Constructor. * * @param model * the Model * @param mp * the MultipurposeController */ public CanvasController(Model model, MultiPurposeController mp) { this.model = model; this.mpC = mp; } /** * Add an CpsObject to the model and notify the ObjectListener for update. * * @param object * CpsObject to be added. * @param replace when true objects could be replaced */ public void addObject(AbstractCanvasObject object, boolean replace) { model.getCvsObjIdx().put(object.getId(), model.getObjectsOnCanvas().size()); model.getObjectsOnCanvas().add(object); /** * check if we should drag & drop replace */ if(!(object instanceof Node) && replace){ /** x of the dragged Object */ int x = object.getPosition().getX(); /** y of the dragged Object */ int y = object.getPosition().getY(); /** distance treshold for replacement */ int treshhold = model.getScale()/2; /** number of Objects that might be replaced (should be 1) */ int replaceCounter = 0; /** last object that could be replaced */ AbstractCanvasObject toBeReplaced = null; /** for each cps on Canvas */ for (AbstractCanvasObject cps : model.getObjectsOnCanvas()){ /** same object -> ignore */ if(cps == object)continue; /** x of object that might get replaced */ int c_x = cps.getPosition().getX(); /** y of object that might get replaced */ int c_y = cps.getPosition().getY(); /** if near enough */ if(Math.abs(x-c_x)()); addObject(object, true); } /** * adds the ObjectListener. * * @param objLis * ObjectListener */ public void addObjectListener(ObjectListener objLis) { model.getObjectListeners().add(objLis); } /** * Deletes an CpsObject on the Canvas and its connections. * * @param obj * AbstractCpsObject */ public void deleteObjectOnCanvas(AbstractCanvasObject obj) { removeAllConnectionsFromObject(obj); mpC.decIdx(obj.getId(), model.getCvsObjIdx()); model.getCvsObjIdx().remove(obj.getId()); model.getObjectsOnCanvas().remove(obj); } public void deleteObjectsOnCanvas(Collection objects) { for(AbstractCanvasObject obj: objects) { removeAllConnectionsFromObject(obj); mpC.decIdx(obj.getId(), model.getCvsObjIdx()); model.getCvsObjIdx().remove(obj.getId()); model.getObjectsOnCanvas().remove(obj); } } /** * Replaces {@code toBeReplaced} by {@code by} on the canvas * @param toBeReplaced the object that will be replaced * @param by the object that will replace it */ public void replaceObjectOnCanvas(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) { //Replace edges ListIterator iter = model.getEdgesOnCanvas().listIterator(); while(iter.hasNext() ) { Edge edge = iter.next(); if(edge.getA() == toBeReplaced && edge.getB() != by) { edge.setA(by); } else if( edge.getB() == toBeReplaced && edge.getA() != by) { edge.setB(by); } } /** delete 'toBeReplaced' new empty connections, to prevent Nullpointer*/ toBeReplaced.setConnections(new ArrayList(1)); /** * set Position of by to exactly toBeReplaced */ by.setPosition(toBeReplaced.getPosition()); deleteObjectOnCanvas(toBeReplaced); } /** * Add an edge to the Canvas. * * @param edge * the edge */ public void addEdgeOnCanvas(Edge edge) { model.getEdgesOnCanvas().add(edge); } /** * Removes an Edge from the Canvas. * * @param edge * the edge to remove */ public void removeEdgesOnCanvas(Edge edge) { edge.getA().getConnections().remove(edge); edge.getB().getConnections().remove(edge); model.getEdgesOnCanvas().remove(edge); } /** * Paste all Selected Objects. * * @param p * the mouse Position */ public void pasteObjects(Point p) { model.getSelectedObjects().clear(); AbstractCanvasObject tCps = null; int x = Integer.MAX_VALUE, y = Integer.MAX_VALUE; // Location whre to copy the Elements for (AbstractCanvasObject cps : model.getClipboradObjects()) { if (cps.getPosition().getX() < x) { x = cps.getPosition().getX(); } if (cps.getPosition().getY() < y) { y = cps.getPosition().getY(); } } // Objects for (AbstractCanvasObject cps : model.getClipboradObjects()) { if (cps instanceof HolonObject) { tCps = new HolonObject((HolonObject) cps); } else if (cps instanceof HolonSwitch) { tCps = new HolonSwitch((HolonSwitch) cps); } else { tCps = new Node("Node"); } tCps.setPosition(new Vector2Int(p.x + (cps.getPosition().getX() - x), p.y + (cps.getPosition().getY() - y))); tCps.setSav(cps.getSav()); addObject(tCps, false); } // Edges for (AbstractCanvasObject cps : model.getClipboradObjects()) { for (Edge e : cps.getConnectedTo()) { // A and B of e in the copied Elements? if (model.getClipboradObjects().contains(e.getA()) && model.getClipboradObjects().contains(e.getB())) { AbstractCanvasObject a = e.getA(); AbstractCanvasObject b = e.getB(); boolean newEdge = true; // was this Edge created or not? for (Edge et : cps.getConnectedTo()) { for (Edge etA : et.getA().getConnectedTo()) { if (etA.getA() == a && etA.getB() == b) { newEdge = false; } } for (Edge etB : et.getB().getConnectedTo()) { if (etB.getA() == a && etB.getB() == b) { newEdge = false; } } } if (newEdge) { Edge tempE = new Edge(a, b, e.getCapacity()); addEdgeOnCanvas(tempE); } } } } } /** * Cut all Selected Objects. */ public void cutObjects() { model.setClipboradObjects(model.getSelectedObjects().stream().collect(Collectors.toSet())); for (AbstractCanvasObject cps : model.getClipboradObjects()) { deleteObjectOnCanvas(cps); } model.getSelectedObjects().clear(); } /** * Some cleaning Algorithm which traverses the UpperNode through BFS Can be * extended with other cleaning stuff No need for coloring since there tree * is only directed in one direction * * @param node */ public void bfsNodeCleaner(GroupNode node) { List objectsInGroupNode = node.getNodesAndGroupnodeNodes(); ListIterator iter = model.getEdgesOnCanvas().listIterator(); while(iter.hasNext() ) { Edge edge = iter.next(); if(objectsInGroupNode.contains(edge.getA()) || objectsInGroupNode.contains(edge.getB())) { iter.remove(); } } } public void removeAllConnectionsFromObject(AbstractCanvasObject obj) { ListIterator iter = model.getEdgesOnCanvas().listIterator(); while(iter.hasNext() ) { Edge edge = iter.next(); if(edge.getA() == obj || edge.getB() == obj) { iter.remove(); } } } public void updateOutliner(SimulationManager manager ) { gui.updateOutliners(manager.getActualDecorState()); } public void updateFlexWindow() { gui.updateFlexWindows(); } public void updateCanvas() { gui.repaintCanvas(); gui.triggerUpdateController(null); } public GUI getGui() { return gui; } public void guiDisable(boolean state) { gui.guiDisable(state); } public void setGui(GUI gui) { this.gui = gui; } /** * Set the Background Image; * * @param imagePath * Image Path * @param mode * Image Mode * @param width * Image custom width * @param height * Image custom height */ public void setBackgroundImage(String imagePath, int mode, int width, int height) { model.setCanvasImagePath(imagePath); model.setCanvasImageMode(mode); model.setCanvasImageWidth(width); model.setCanvasImageHeight(height); } }