NodeController.java 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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.math.vector.Vec2i;
  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. Vec2i old = calculatePos(node.getObjectsInThisLayer().toList());
  44. Vec2i 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. });
  76. if (upperNode == null) {
  77. model.getCanvas().addAll(node.getObjectsInThisLayer());
  78. } else {
  79. node.getObjectsInThisLayer().forEach(obj -> upperNode.add(obj));
  80. }
  81. }
  82. /**
  83. * Calculate new Position of the Upper Node
  84. */
  85. Vec2i calculatePos(Collection<AbstractCanvasObject> toGroup) {
  86. Vec2i pos = new Vec2i(0, 0);
  87. for (AbstractCanvasObject abs : toGroup) {
  88. pos = pos.add(abs.getPosition());
  89. }
  90. return pos.divide(toGroup.size());
  91. }
  92. /**
  93. * Removes the Given Obj from current Layer and adjusts the idx
  94. */
  95. private void removeForNodeOfNode(AbstractCanvasObject obj, GroupNode upperNode) {
  96. upperNode.remove(obj);
  97. }
  98. /**
  99. * Removes the Given Obj from current Layer and adjusts the idx
  100. */
  101. private void removeForNodeOfNode(AbstractCanvasObject obj) {
  102. model.getCanvas().remove(obj);
  103. }
  104. /**
  105. * Adds object to the upperNode, might replace objects if replace==true
  106. * @param object
  107. * @param upperNode
  108. * @param replace
  109. */
  110. void addObjectInGroupNode(AbstractCanvasObject object, GroupNode upperNode, boolean replace) {
  111. if(object == null){
  112. new Error("object == null while adding to "+upperNode.toString()).printStackTrace();
  113. return;
  114. }
  115. if(upperNode == null){
  116. new Error("upperNode == null while adding "+object.toString()).printStackTrace();
  117. return;
  118. }
  119. upperNode.add(object);
  120. /**
  121. * check if we should drag & drop replace
  122. */
  123. if(replace && !(object instanceof Node) ){
  124. /** x of the dragged Object */
  125. int x = object.getPosition().getX();
  126. /** y of the dragged Object */
  127. int y = object.getPosition().getY();
  128. /** distance threshold for replacement */
  129. int treshhold = GuiSettings.getPictureScaleDiv2();
  130. /** number of Objects that might be replaced (should be 1) */
  131. int replaceCounter = 0;
  132. /** last object that could be replaced */
  133. AbstractCanvasObject toBeReplaced = null;
  134. /** for each cps on Canvas */
  135. for (AbstractCanvasObject cps : upperNode.getObjectsInThisLayer().toList()){
  136. /** same object -> ignore */
  137. if(cps == object)continue;
  138. /** x of object that might get replaced */
  139. int c_x = cps.getPosition().getX();
  140. /** y of object that might get replaced */
  141. int c_y = cps.getPosition().getY();
  142. /** if near enough */
  143. if(Math.abs(x-c_x)<treshhold && Math.abs(y-c_y)<treshhold){
  144. replaceCounter++;
  145. toBeReplaced = cps;
  146. }
  147. }
  148. /** if replacement of exactly one object possible */
  149. if(replaceCounter == 1 && toBeReplaced != null){
  150. replaceObjectInUpperNode(toBeReplaced, object, upperNode);
  151. }
  152. }
  153. }
  154. /**
  155. * Delete a AbstactCpsObject from CPSUpperNode
  156. */
  157. void deleteObjectInGroupNode(AbstractCanvasObject object, GroupNode groupNode) {
  158. LinkedList<Edge> edgesToDelete = new LinkedList<Edge>();
  159. for (Edge p : model.getEdgesOnCanvas()) {
  160. if(p.isConnectedTo(object)) {
  161. edgesToDelete.add(p);
  162. }
  163. }
  164. model.getEdgesOnCanvas().removeAll(edgesToDelete);
  165. groupNode.remove(object);
  166. }
  167. /**
  168. * Replaces {@code toBePlaced} by {@code by} in {@code upperNode}
  169. * @param toBeReplaced
  170. * @param by
  171. * @param upperNode
  172. */
  173. public void replaceObjectInUpperNode(AbstractCanvasObject toBeReplaced,
  174. AbstractCanvasObject by, GroupNode upperNode) {
  175. /** let all edges of 'toBeReplaced' connect to 'by' */
  176. /**
  177. * set Position of by to exactly toBeReplaced
  178. */
  179. by.setPosition(toBeReplaced.getPosition());
  180. deleteObjectInGroupNode(toBeReplaced, upperNode);
  181. }
  182. private void updatePosition(AbstractCanvasObject temp, GroupNode upperNode) {
  183. int x = temp.getPosition().getX() - point.x;
  184. int y = temp.getPosition().getY() - point.y;
  185. if (y < 0)
  186. y = 0 + GuiSettings.getPictureScaleDiv2() + 1;
  187. if (upperNode != null) {
  188. if (x < GuiSettings.getPictureScaleDiv2() + 1)
  189. x = GuiSettings.getPictureScaleDiv2() + 1;
  190. } else if (x < 0)
  191. x = 0 + GuiSettings.getPictureScaleDiv2() + 1;
  192. if (x > GuiSettings.canvasSize.getX())
  193. x = GuiSettings.canvasSize.getX() - GuiSettings.getPictureScaleDiv2() - 1;
  194. if (y > GuiSettings.canvasSize.getY())
  195. y = GuiSettings.canvasSize.getY() - GuiSettings.getPictureScaleDiv2() - 1;
  196. temp.setPosition(new Vec2i(x, y));
  197. }
  198. }