package holeg.ui.controller; import java.awt.*; import java.util.List; import java.util.Collection; import java.util.LinkedList; import holeg.model.AbstractCanvasObject; import holeg.model.Edge; import holeg.model.GroupNode; import holeg.model.Node; import holeg.ui.model.GuiSettings; import holeg.ui.model.Model; import holeg.utility.math.vector.Vec2i; class NodeController { private Model model; private CanvasController cvs; private Point point; NodeController(Model model, CanvasController cvs) { this.model = model; this.cvs = cvs; } /** * Add a CpsUpperNode into Canvas */ void addGroupNode(String nodeName, GroupNode groupNode, List toGroup) { GroupNode node = new GroupNode(nodeName); node.setPosition(calculatePos(toGroup)); makeGroupNode(node, groupNode, toGroup); if (groupNode == null) { cvs.addNewObject(node); } else { addObjectInGroupNode(node, groupNode, false); } } /** * Delete a CpsUpperNode from the Canvas */ void undoGroupNode(GroupNode node, GroupNode groupNode) { if(node.getObjectsInThisLayer().findAny().isPresent()) { cvs.deleteObjectOnCanvas(node); return; } Vec2i old = calculatePos(node.getObjectsInThisLayer().toList()); Vec2i p = node.getPosition(); point = new Point(old.getX() - p.getX(), old.getY() - p.getY()); unmakeNodesOfNodes(node, groupNode); if (groupNode == null) cvs.deleteObjectOnCanvas(node); else deleteObjectInGroupNode(node, groupNode); } /** * Put selected Nodes inside the Upper Node */ private void makeGroupNode(GroupNode node, GroupNode groupNode, List toGroup) { // Put all selected Nodes into the Upper Node for (AbstractCanvasObject obj : toGroup) { addObjectInGroupNode(obj, node, false); } for (AbstractCanvasObject abs : toGroup) { if (groupNode == null) removeForNodeOfNode(abs); else removeForNodeOfNode(abs, groupNode); } } /** * Transfer all relevant data from Node into the next higher layer of Node * (upperNode) */ private void unmakeNodesOfNodes(GroupNode node, GroupNode upperNode) { // add all nodes into upperNode node.getObjectsInThisLayer().forEach(obj -> { updatePosition(obj, upperNode); }); if (upperNode == null) { model.getCanvas().addAll(node.getObjectsInThisLayer()); } else { node.getObjectsInThisLayer().forEach(obj -> upperNode.add(obj)); } } /** * Calculate new Position of the Upper Node */ Vec2i calculatePos(Collection toGroup) { Vec2i pos = new Vec2i(0, 0); for (AbstractCanvasObject abs : toGroup) { pos = pos.add(abs.getPosition()); } return pos.divide(toGroup.size()); } /** * Removes the Given Obj from current Layer and adjusts the idx */ private void removeForNodeOfNode(AbstractCanvasObject obj, GroupNode upperNode) { upperNode.remove(obj); } /** * Removes the Given Obj from current Layer and adjusts the idx */ private void removeForNodeOfNode(AbstractCanvasObject obj) { model.getCanvas().remove(obj); } /** * Adds object to the upperNode, might replace objects if replace==true * @param object * @param upperNode * @param replace */ void addObjectInGroupNode(AbstractCanvasObject object, GroupNode upperNode, boolean replace) { if(object == null){ new Error("object == null while adding to "+upperNode.toString()).printStackTrace(); return; } if(upperNode == null){ new Error("upperNode == null while adding "+object.toString()).printStackTrace(); return; } upperNode.add(object); /** * check if we should drag & drop replace */ if(replace && !(object instanceof Node) ){ /** x of the dragged Object */ int x = object.getPosition().getX(); /** y of the dragged Object */ int y = object.getPosition().getY(); /** distance threshold for replacement */ int treshhold = GuiSettings.getPictureScaleDiv2(); /** 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 : upperNode.getObjectsInThisLayer().toList()){ /** 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) edgesToDelete = new LinkedList(); for (Edge p : model.getEdgesOnCanvas()) { if(p.isConnectedTo(object)) { edgesToDelete.add(p); } } model.getEdgesOnCanvas().removeAll(edgesToDelete); groupNode.remove(object); } /** * Replaces {@code toBePlaced} by {@code by} in {@code upperNode} * @param toBeReplaced * @param by * @param upperNode */ public void replaceObjectInUpperNode(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by, GroupNode upperNode) { /** let all edges of 'toBeReplaced' connect to 'by' */ /** * set Position of by to exactly toBeReplaced */ by.setPosition(toBeReplaced.getPosition()); deleteObjectInGroupNode(toBeReplaced, upperNode); } private void updatePosition(AbstractCanvasObject temp, GroupNode upperNode) { int x = temp.getPosition().getX() - point.x; int y = temp.getPosition().getY() - point.y; if (y < 0) y = 0 + GuiSettings.getPictureScaleDiv2() + 1; if (upperNode != null) { if (x < GuiSettings.getPictureScaleDiv2() + 1) x = GuiSettings.getPictureScaleDiv2() + 1; } else if (x < 0) x = 0 + GuiSettings.getPictureScaleDiv2() + 1; if (x > GuiSettings.canvasSize.getX()) x = GuiSettings.canvasSize.getX() - GuiSettings.getPictureScaleDiv2() - 1; if (y > GuiSettings.canvasSize.getY()) y = GuiSettings.canvasSize.getY() - GuiSettings.getPictureScaleDiv2() - 1; temp.setPosition(new Vec2i(x, y)); } }