NodeController.java 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. package holeg.ui.controller;
  2. import java.awt.*;
  3. import java.util.List;
  4. import java.util.Collection;
  5. import java.util.LinkedList;
  6. import holeg.model.AbstractCanvasObject;
  7. import holeg.model.Edge;
  8. import holeg.model.GroupNode;
  9. import holeg.model.Node;
  10. import holeg.ui.model.GuiSettings;
  11. import holeg.ui.model.Model;
  12. import holeg.utility.Vector2Int;
  13. class NodeController {
  14. private Model model;
  15. private CanvasController cvs;
  16. private Point point;
  17. NodeController(Model model, CanvasController cvs) {
  18. this.model = model;
  19. this.cvs = cvs;
  20. }
  21. /**
  22. * Add a CpsUpperNode into Canvas
  23. */
  24. void addGroupNode(String nodeName, GroupNode groupNode, List<AbstractCanvasObject> toGroup) {
  25. GroupNode node = new GroupNode(nodeName);
  26. node.setPosition(calculatePos(toGroup));
  27. makeGroupNode(node, groupNode, toGroup);
  28. if (groupNode == null) {
  29. cvs.addNewObject(node);
  30. }
  31. else {
  32. addObjectInGroupNode(node, groupNode, false);
  33. }
  34. }
  35. /**
  36. * Delete a CpsUpperNode from the Canvas
  37. */
  38. void undoGroupNode(GroupNode node, GroupNode groupNode) {
  39. if(node.getObjectsInThisLayer().findAny().isPresent()) {
  40. cvs.deleteObjectOnCanvas(node);
  41. return;
  42. }
  43. Vector2Int old = calculatePos(node.getObjectsInThisLayer().toList());
  44. Vector2Int p = node.getPosition();
  45. point = new Point(old.getX() - p.getX(), old.getY() - p.getY());
  46. unmakeNodesOfNodes(node, groupNode);
  47. if (groupNode == null)
  48. cvs.deleteObjectOnCanvas(node);
  49. else
  50. deleteObjectInGroupNode(node, groupNode);
  51. }
  52. /**
  53. * Put selected Nodes inside the Upper Node
  54. */
  55. private void makeGroupNode(GroupNode node, GroupNode groupNode, List<AbstractCanvasObject> toGroup) {
  56. // Put all selected Nodes into the Upper Node
  57. for (AbstractCanvasObject obj : toGroup) {
  58. addObjectInGroupNode(obj, node, false);
  59. }
  60. for (AbstractCanvasObject abs : toGroup) {
  61. if (groupNode == null)
  62. removeForNodeOfNode(abs);
  63. else
  64. removeForNodeOfNode(abs, groupNode);
  65. }
  66. }
  67. /**
  68. * Transfer all relevant data from Node into the next higher layer of Node
  69. * (upperNode)
  70. */
  71. private void unmakeNodesOfNodes(GroupNode node, GroupNode upperNode) {
  72. // add all nodes into upperNode
  73. node.getObjectsInThisLayer().forEach(obj -> {
  74. updatePosition(obj, upperNode);
  75. if (upperNode == null)
  76. obj.setSav("CVS");
  77. else
  78. obj.setSav("" + upperNode.getId());
  79. });
  80. if (upperNode == null) {
  81. model.getObjectsOnCanvas().addAll(node.getObjectsInThisLayer().toList());
  82. } else {
  83. node.getObjectsInThisLayer().forEach(obj -> upperNode.add(obj));
  84. }
  85. }
  86. /**
  87. * Calculate new Position of the Upper Node
  88. */
  89. Vector2Int calculatePos(Collection<AbstractCanvasObject> toGroup) {
  90. Vector2Int pos = new Vector2Int(0, 0);
  91. for (AbstractCanvasObject abs : toGroup) {
  92. pos = pos.add(abs.getPosition());
  93. }
  94. return pos.divide(toGroup.size());
  95. }
  96. /**
  97. * Removes the Given Obj from current Layer and adjusts the idx
  98. */
  99. private void removeForNodeOfNode(AbstractCanvasObject obj, GroupNode upperNode) {
  100. upperNode.remove(obj);
  101. }
  102. /**
  103. * Removes the Given Obj from current Layer and adjusts the idx
  104. */
  105. private void removeForNodeOfNode(AbstractCanvasObject obj) {
  106. model.getObjectsOnCanvas().remove(obj);
  107. }
  108. /**
  109. * Adds object to the upperNode, might replace objects if replace==true
  110. * @param object
  111. * @param upperNode
  112. * @param replace
  113. */
  114. void addObjectInGroupNode(AbstractCanvasObject object, GroupNode upperNode, boolean replace) {
  115. if(object == null){
  116. new Error("object == null while adding to "+upperNode.toString()).printStackTrace();
  117. return;
  118. }
  119. if(upperNode == null){
  120. new Error("upperNode == null while adding "+object.toString()).printStackTrace();
  121. return;
  122. }
  123. object.setSav("" + upperNode.getId());
  124. upperNode.add(object);
  125. /**
  126. * check if we should drag & drop replace
  127. */
  128. if(replace && !(object instanceof Node) ){
  129. /** x of the dragged Object */
  130. int x = object.getPosition().getX();
  131. /** y of the dragged Object */
  132. int y = object.getPosition().getY();
  133. /** distance threshold for replacement */
  134. int treshhold = GuiSettings.getPictureScaleDiv2();
  135. /** number of Objects that might be replaced (should be 1) */
  136. int replaceCounter = 0;
  137. /** last object that could be replaced */
  138. AbstractCanvasObject toBeReplaced = null;
  139. /** for each cps on Canvas */
  140. for (AbstractCanvasObject cps : upperNode.getObjectsInThisLayer().toList()){
  141. /** same object -> ignore */
  142. if(cps == object)continue;
  143. /** x of object that might get replaced */
  144. int c_x = cps.getPosition().getX();
  145. /** y of object that might get replaced */
  146. int c_y = cps.getPosition().getY();
  147. /** if near enough */
  148. if(Math.abs(x-c_x)<treshhold && Math.abs(y-c_y)<treshhold){
  149. replaceCounter++;
  150. toBeReplaced = cps;
  151. }
  152. }
  153. /** if replacement of exactly one object possible */
  154. if(replaceCounter == 1 && toBeReplaced != null){
  155. replaceObjectInUpperNode(toBeReplaced, object, upperNode);
  156. }
  157. }
  158. }
  159. /**
  160. * Delete a AbstactCpsObject from CPSUpperNode
  161. */
  162. void deleteObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
  163. LinkedList<Edge> edgesToDelete = new LinkedList<Edge>();
  164. for (Edge p : model.getEdgesOnCanvas()) {
  165. if(p.isConnectedTo(object)) {
  166. edgesToDelete.add(p);
  167. }
  168. }
  169. model.getEdgesOnCanvas().removeAll(edgesToDelete);
  170. groupNode.remove(object);
  171. }
  172. /**
  173. * Replaces {@code toBePlaced} by {@code by} in {@code upperNode}
  174. * @param toBeReplaced
  175. * @param by
  176. * @param upperNode
  177. */
  178. public void replaceObjectInUpperNode(AbstractCanvasObject toBeReplaced,
  179. AbstractCanvasObject by, GroupNode upperNode) {
  180. /** let all edges of 'toBeReplaced' connect to 'by' */
  181. /**
  182. * set Position of by to exactly toBeReplaced
  183. */
  184. by.setPosition(toBeReplaced.getPosition());
  185. deleteObjectInGroupNode(toBeReplaced, upperNode);
  186. }
  187. private void updatePosition(AbstractCanvasObject temp, GroupNode upperNode) {
  188. int x = temp.getPosition().getX() - point.x;
  189. int y = temp.getPosition().getY() - point.y;
  190. if (y < 0)
  191. y = 0 + GuiSettings.getPictureScaleDiv2() + 1;
  192. if (upperNode != null) {
  193. if (x < GuiSettings.getPictureScaleDiv2() + 1)
  194. x = GuiSettings.getPictureScaleDiv2() + 1;
  195. } else if (x < 0)
  196. x = 0 + GuiSettings.getPictureScaleDiv2() + 1;
  197. if (x > GuiSettings.canvasSize.getX())
  198. x = GuiSettings.canvasSize.getX() - GuiSettings.getPictureScaleDiv2() - 1;
  199. if (y > GuiSettings.canvasSize.getY())
  200. y = GuiSettings.canvasSize.getY() - GuiSettings.getPictureScaleDiv2() - 1;
  201. temp.setPosition(new Vector2Int(x, y));
  202. }
  203. }