CanvasController.java 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. package ui.controller;
  2. import java.awt.Point;
  3. import java.util.ArrayList;
  4. import java.util.Collection;
  5. import java.util.List;
  6. import java.util.ListIterator;
  7. import java.util.Optional;
  8. import java.util.stream.Collectors;
  9. import model.AbstractCanvasObject;
  10. import model.Edge;
  11. import model.GroupNode;
  12. import model.HolonObject;
  13. import model.HolonSwitch;
  14. import model.Node;
  15. import ui.model.DecoratedState;
  16. import ui.model.Model;
  17. import ui.view.main.GUI;
  18. import utility.Vector2Int;
  19. /**
  20. * Controller for the Canvas.
  21. *
  22. * @author Gruppe14
  23. */
  24. public class CanvasController {
  25. private Model model;
  26. private MultiPurposeController mpC;
  27. private GUI gui;
  28. /**
  29. * Constructor.
  30. *
  31. * @param model
  32. * the Model
  33. * @param mp
  34. * the MultipurposeController
  35. */
  36. public CanvasController(Model model, MultiPurposeController mp) {
  37. this.model = model;
  38. this.mpC = mp;
  39. }
  40. /**
  41. * Add an CpsObject to the model and notify the ObjectListener for update.
  42. *
  43. * @param object
  44. * CpsObject to be added.
  45. * @param replace when true objects could be replaced
  46. */
  47. public void addObject(AbstractCanvasObject object, boolean replace) {
  48. model.getCvsObjIdx().put(object.getId(), model.getObjectsOnCanvas().size());
  49. model.getObjectsOnCanvas().add(object);
  50. /**
  51. * check if we should drag & drop replace
  52. */
  53. if(!(object instanceof Node) && replace){
  54. /** x of the dragged Object */
  55. int x = object.getPosition().getX();
  56. /** y of the dragged Object */
  57. int y = object.getPosition().getY();
  58. /** distance treshold for replacement */
  59. int treshhold = model.getScale()/2;
  60. /** number of Objects that might be replaced (should be 1) */
  61. int replaceCounter = 0;
  62. /** last object that could be replaced */
  63. AbstractCanvasObject toBeReplaced = null;
  64. /** for each cps on Canvas */
  65. for (AbstractCanvasObject cps : model.getObjectsOnCanvas()){
  66. /** same object -> ignore */
  67. if(cps == object)continue;
  68. /** x of object that might get replaced */
  69. int c_x = cps.getPosition().getX();
  70. /** y of object that might get replaced */
  71. int c_y = cps.getPosition().getY();
  72. /** if near enough */
  73. if(Math.abs(x-c_x)<treshhold && Math.abs(y-c_y)<treshhold){
  74. replaceCounter++;
  75. toBeReplaced = cps;
  76. }
  77. }
  78. /** if replacement of exactly one object possible */
  79. if(replaceCounter == 1 && toBeReplaced != null){
  80. replaceObjectOnCanvas(toBeReplaced, object);
  81. }
  82. }
  83. }
  84. /**
  85. * Add a new Object.
  86. *
  87. * @param object
  88. * the Object
  89. */
  90. public void addNewObject(AbstractCanvasObject object) {
  91. object.setSav("CVS");
  92. // object.setConnections(new ArrayList<CpsEdge>());
  93. addObject(object, true);
  94. }
  95. /**
  96. * Deletes an CpsObject on the Canvas and its connections.
  97. *
  98. * @param obj
  99. * AbstractCpsObject
  100. */
  101. public void deleteObjectOnCanvas(AbstractCanvasObject obj) {
  102. removeAllConnectionsFromObject(obj);
  103. mpC.decIdx(obj.getId(), model.getCvsObjIdx());
  104. model.getCvsObjIdx().remove(obj.getId());
  105. model.getObjectsOnCanvas().remove(obj);
  106. }
  107. public void deleteObjectsOnCanvas(Collection<AbstractCanvasObject> objects) {
  108. for(AbstractCanvasObject obj: objects) {
  109. removeAllConnectionsFromObject(obj);
  110. mpC.decIdx(obj.getId(), model.getCvsObjIdx());
  111. model.getCvsObjIdx().remove(obj.getId());
  112. model.getObjectsOnCanvas().remove(obj);
  113. }
  114. }
  115. /**
  116. * Replaces {@code toBeReplaced} by {@code by} on the canvas
  117. * @param toBeReplaced the object that will be replaced
  118. * @param by the object that will replace it
  119. */
  120. public void replaceObjectOnCanvas(AbstractCanvasObject toBeReplaced, AbstractCanvasObject by) {
  121. //Replace edges
  122. ListIterator<Edge> iter = model.getEdgesOnCanvas().listIterator();
  123. while(iter.hasNext() ) {
  124. Edge edge = iter.next();
  125. if(edge.getA() == toBeReplaced && edge.getB() != by) {
  126. edge.setA(by);
  127. }
  128. else if( edge.getB() == toBeReplaced && edge.getA() != by) {
  129. edge.setB(by);
  130. }
  131. }
  132. /** delete 'toBeReplaced' new empty connections, to prevent Nullpointer*/
  133. toBeReplaced.setConnections(new ArrayList<Edge>(1));
  134. /**
  135. * set Position of by to exactly toBeReplaced
  136. */
  137. by.setPosition(toBeReplaced.getPosition());
  138. deleteObjectOnCanvas(toBeReplaced);
  139. }
  140. /**
  141. * Add an edge to the Canvas.
  142. *
  143. * @param edge
  144. * the edge
  145. */
  146. public void addEdgeOnCanvas(Edge edge) {
  147. model.getEdgesOnCanvas().add(edge);
  148. }
  149. /**
  150. * Removes an Edge from the Canvas.
  151. *
  152. * @param edge
  153. * the edge to remove
  154. */
  155. public void removeEdgesOnCanvas(Edge edge) {
  156. edge.getA().getConnections().remove(edge);
  157. edge.getB().getConnections().remove(edge);
  158. model.getEdgesOnCanvas().remove(edge);
  159. }
  160. /**
  161. * Paste all Selected Objects.
  162. *
  163. * @param p
  164. * the mouse Position
  165. */
  166. public void pasteObjects(Point p) {
  167. model.getSelectedObjects().clear();
  168. AbstractCanvasObject tCps = null;
  169. int x = Integer.MAX_VALUE, y = Integer.MAX_VALUE;
  170. // Location whre to copy the Elements
  171. for (AbstractCanvasObject cps : model.getClipboradObjects()) {
  172. if (cps.getPosition().getX() < x) {
  173. x = cps.getPosition().getX();
  174. }
  175. if (cps.getPosition().getY() < y) {
  176. y = cps.getPosition().getY();
  177. }
  178. }
  179. // Objects
  180. for (AbstractCanvasObject cps : model.getClipboradObjects()) {
  181. if (cps instanceof HolonObject) {
  182. tCps = new HolonObject((HolonObject) cps);
  183. } else if (cps instanceof HolonSwitch) {
  184. tCps = new HolonSwitch((HolonSwitch) cps);
  185. } else {
  186. tCps = new Node("Node");
  187. }
  188. tCps.setPosition(new Vector2Int(p.x + (cps.getPosition().getX() - x), p.y + (cps.getPosition().getY() - y)));
  189. tCps.setSav(cps.getSav());
  190. addObject(tCps, false);
  191. }
  192. // Edges
  193. for (AbstractCanvasObject cps : model.getClipboradObjects()) {
  194. for (Edge e : cps.getConnectedTo()) {
  195. // A and B of e in the copied Elements?
  196. if (model.getClipboradObjects().contains(e.getA())
  197. && model.getClipboradObjects().contains(e.getB())) {
  198. AbstractCanvasObject a = e.getA();
  199. AbstractCanvasObject b = e.getB();
  200. boolean newEdge = true;
  201. // was this Edge created or not?
  202. for (Edge et : cps.getConnectedTo()) {
  203. for (Edge etA : et.getA().getConnectedTo()) {
  204. if (etA.getA() == a && etA.getB() == b) {
  205. newEdge = false;
  206. }
  207. }
  208. for (Edge etB : et.getB().getConnectedTo()) {
  209. if (etB.getA() == a && etB.getB() == b) {
  210. newEdge = false;
  211. }
  212. }
  213. }
  214. if (newEdge) {
  215. Edge tempE = new Edge(e);
  216. addEdgeOnCanvas(tempE);
  217. }
  218. }
  219. }
  220. }
  221. }
  222. /**
  223. * Cut all Selected Objects.
  224. */
  225. public void cutObjects() {
  226. model.setClipboradObjects(model.getSelectedObjects().stream().collect(Collectors.toSet()));
  227. for (AbstractCanvasObject cps : model.getClipboradObjects()) {
  228. deleteObjectOnCanvas(cps);
  229. }
  230. model.getSelectedObjects().clear();
  231. }
  232. /**
  233. * Some cleaning Algorithm which traverses the UpperNode through BFS Can be
  234. * extended with other cleaning stuff No need for coloring since there tree
  235. * is only directed in one direction
  236. *
  237. * @param node
  238. */
  239. public void bfsNodeCleaner(GroupNode node) {
  240. List<AbstractCanvasObject> objectsInGroupNode = node.getNodesAndGroupnodeNodes();
  241. ListIterator<Edge> iter = model.getEdgesOnCanvas().listIterator();
  242. while(iter.hasNext() ) {
  243. Edge edge = iter.next();
  244. if(objectsInGroupNode.contains(edge.getA()) || objectsInGroupNode.contains(edge.getB())) {
  245. iter.remove();
  246. }
  247. }
  248. }
  249. public void removeAllConnectionsFromObject(AbstractCanvasObject obj) {
  250. ListIterator<Edge> iter = model.getEdgesOnCanvas().listIterator();
  251. while(iter.hasNext() ) {
  252. Edge edge = iter.next();
  253. if(edge.getA() == obj || edge.getB() == obj) {
  254. iter.remove();
  255. }
  256. }
  257. }
  258. public void updateOutliner(SimulationManager manager ) {
  259. Optional<DecoratedState> decorState = manager.getActualDecorState();
  260. decorState.ifPresent(state -> gui.updateOutliners(state));
  261. }
  262. public void updateFlexWindow() {
  263. gui.updateFlexWindows();
  264. }
  265. public void updateCanvas() {
  266. gui.repaintCanvas();
  267. }
  268. public GUI getGui() {
  269. return gui;
  270. }
  271. public void guiDisable(boolean state) {
  272. gui.guiDisable(state);
  273. }
  274. public void setGui(GUI gui) {
  275. this.gui = gui;
  276. }
  277. /**
  278. * Set the Background Image;
  279. *
  280. * @param imagePath
  281. * Image Path
  282. * @param mode
  283. * Image Mode
  284. * @param width
  285. * Image custom width
  286. * @param height
  287. * Image custom height
  288. */
  289. public void setBackgroundImage(String imagePath, int mode, int width, int height) {
  290. model.setCanvasImagePath(imagePath);
  291. model.setCanvasImageMode(mode);
  292. model.setCanvasImageWidth(width);
  293. model.setCanvasImageHeight(height);
  294. }
  295. }