Mercurial > hg > accesspd
comparison java/src/uk/ac/qmul/eecs/ccmi/gui/Diagram.java @ 0:78b7fc5391a2
first import, outcome of NIME 2014 hackaton
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Tue, 08 Jul 2014 16:28:59 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:78b7fc5391a2 |
---|---|
1 /* | |
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool | |
3 | |
4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) | |
5 | |
6 This program is free software: you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation, either version 3 of the License, or | |
9 (at your option) any later version. | |
10 | |
11 This program is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with this program. If not, see <http://www.gnu.org/licenses/>. | |
18 */ | |
19 package uk.ac.qmul.eecs.ccmi.gui; | |
20 | |
21 import java.awt.geom.Point2D; | |
22 import java.util.Set; | |
23 | |
24 import uk.ac.qmul.eecs.ccmi.diagrammodel.CollectionModel; | |
25 import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramElement; | |
26 import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel; | |
27 import uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramTreeNode; | |
28 import uk.ac.qmul.eecs.ccmi.diagrammodel.NodeProperties; | |
29 import uk.ac.qmul.eecs.ccmi.diagrammodel.TreeModel; | |
30 import uk.ac.qmul.eecs.ccmi.gui.persistence.PrototypePersistenceDelegate; | |
31 import uk.ac.qmul.eecs.ccmi.network.AwarenessMessage; | |
32 import uk.ac.qmul.eecs.ccmi.network.DiagramEventActionSource; | |
33 | |
34 /** | |
35 * The {@code Diagram} class holds all the data needed for a representation of the diagram. It is used by component classes | |
36 * such as {@link GraphPanel} and {@link DiagramTree} to draw the diagram by accessing the diagram model or by | |
37 * {@link EditorTabbedPane} to assign a title to the tabs out of the diagram name. | |
38 * | |
39 */ | |
40 public abstract class Diagram implements Cloneable { | |
41 | |
42 /** | |
43 * Crates a new instance of a Diagram. The diagram created through this method is not shared with any peer via | |
44 * a server. | |
45 * @param name the name of the diagram. | |
46 * @param nodes an array of node prototypes. Nodes inserted by users in the diagram will be created by cloning these nodes. | |
47 * @param edges an array of edge prototypes. Edges inserted by users in the diagram will be created by cloning these edges. | |
48 * @param prototypePersistenceDelegate a delegate class to handle nodes and edges persistence. | |
49 * @return a new instance of {@code Diagram} | |
50 */ | |
51 public static Diagram newInstance(String name, Node[] nodes, Edge[] edges, PrototypePersistenceDelegate prototypePersistenceDelegate){ | |
52 return new LocalDiagram(name,nodes,edges,prototypePersistenceDelegate); | |
53 } | |
54 | |
55 /** | |
56 * Returns the name of the diagram. The name identifies the diagram uniquely in the editor. There cannot | |
57 * be two diagrams with the same name open at the same time. This makes things easier when sharing diagrams | |
58 * with other users via the network. | |
59 * | |
60 * @return the name of the diagram | |
61 */ | |
62 public abstract String getName(); | |
63 | |
64 /** | |
65 * Assign this diagram a new name. | |
66 * @param name the new name of the diagram | |
67 */ | |
68 public abstract void setName(String name); | |
69 | |
70 /** | |
71 * Returns an array with the node prototypes. Node prototypes are used when creating new node | |
72 * instances via the {@code clone()} method. | |
73 * | |
74 * @return an array of nodes | |
75 */ | |
76 public abstract Node[] getNodePrototypes(); | |
77 | |
78 /** | |
79 * Returns an array with the edge prototypes. Edge prototypes are used when creating new edge | |
80 * instances via the {@code clone()} method. | |
81 * | |
82 * @return an array of edges | |
83 */ | |
84 public abstract Edge[] getEdgePrototypes(); | |
85 | |
86 /** | |
87 * Returns the tree model of this diagram. Note that each diagram holds a {@code DiagramModel} | |
88 * which has two sub-models ({@code TreeModel} and {@code CollectionModel}). Changes on one | |
89 * sub-model will affect the other model as well. | |
90 * | |
91 * @return the tree model of this diagram | |
92 * | |
93 * @see uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel | |
94 */ | |
95 public abstract TreeModel<Node,Edge> getTreeModel(); | |
96 | |
97 /** | |
98 * Returns the collection model of this diagram. Note that each diagram holds a {@code DiagramModel} | |
99 * which has two sub-models ({@code TreeModel} and {@code CollectionModel}). Changes on one | |
100 * sub-model will affect the other model as well. | |
101 * | |
102 * @return the tree model of this diagram | |
103 * | |
104 * @see uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel uk.ac.qmul.eecs.ccmi.diagrammodel.DiagramModel | |
105 */ | |
106 public abstract CollectionModel<Node,Edge> getCollectionModel(); | |
107 | |
108 /** | |
109 * Returns the model updater of this diagram. The model updater is the delegate for all the | |
110 * update operations affecting the diagram model. | |
111 * | |
112 * @return the model updater for this diagram | |
113 */ | |
114 public abstract DiagramModelUpdater getModelUpdater(); | |
115 | |
116 /** | |
117 * Returns the label of the diagram. The label is slightly different from the name as it's the string | |
118 * appearing in the tabbed pane of the editor. It includes asterisk character at the end when the {@code DiagramModel} | |
119 * of this class has been changed and not yet saved on hard disk. | |
120 * | |
121 * @return a label for this diagram | |
122 */ | |
123 public abstract String getLabel(); | |
124 | |
125 /** | |
126 * Returns the delegates for this diagram for nodes and edges prototypes persistence. | |
127 * When saving a diagram to an xml file each node and edge of the prototypes is encoded | |
128 * in the xml file. Indeed the template of a diagram is made of of its prototypes. | |
129 * In the template is held the general attributes common to all the nodes and edges, like | |
130 * for instance the type of a node but not its current position. | |
131 * | |
132 * @return the PrototypePersistenceDelegate for this diagram | |
133 */ | |
134 public abstract PrototypePersistenceDelegate getPrototypePersistenceDelegate(); | |
135 | |
136 @Override | |
137 public Object clone(){ | |
138 try { | |
139 return super.clone(); | |
140 } catch (CloneNotSupportedException e) { | |
141 throw new RuntimeException(e); | |
142 } | |
143 } | |
144 | |
145 public static class LocalDiagram extends Diagram { | |
146 | |
147 protected LocalDiagram(String name, Node[] nodes, Edge[] edges,PrototypePersistenceDelegate prototypePersistenceDelegate){ | |
148 this.name = name; | |
149 this.nodes = nodes; | |
150 this.edges = edges; | |
151 this.prototypePersistenceDelegate = prototypePersistenceDelegate; | |
152 diagramModel = new DiagramModel<Node,Edge>(nodes,edges); | |
153 innerModelUpdater = new InnerModelUpdater(); | |
154 } | |
155 | |
156 @Override | |
157 public String getName(){ | |
158 return name; | |
159 } | |
160 | |
161 @Override | |
162 public void setName(String name){ | |
163 this.name = name; | |
164 } | |
165 | |
166 @Override | |
167 public Node[] getNodePrototypes(){ | |
168 return nodes; | |
169 } | |
170 | |
171 @Override | |
172 public Edge[] getEdgePrototypes(){ | |
173 return edges; | |
174 } | |
175 | |
176 @Override | |
177 public TreeModel<Node,Edge> getTreeModel(){ | |
178 return diagramModel.getTreeModel(); | |
179 } | |
180 | |
181 @Override | |
182 public CollectionModel<Node,Edge> getCollectionModel(){ | |
183 return diagramModel.getDiagramCollection(); | |
184 } | |
185 | |
186 @Override | |
187 public String getLabel(){ | |
188 return name; | |
189 } | |
190 | |
191 @Override | |
192 public DiagramModelUpdater getModelUpdater(){ | |
193 return innerModelUpdater; | |
194 } | |
195 | |
196 @Override | |
197 public String toString(){ | |
198 return name; | |
199 } | |
200 | |
201 @Override | |
202 public PrototypePersistenceDelegate getPrototypePersistenceDelegate(){ | |
203 return prototypePersistenceDelegate; | |
204 } | |
205 | |
206 /** | |
207 * Creates a new {@code Diagram} by clonation. | |
208 */ | |
209 @Override | |
210 public Object clone(){ | |
211 LocalDiagram clone = (LocalDiagram)super.clone(); | |
212 clone.name = getName(); | |
213 clone.nodes = getNodePrototypes(); | |
214 clone.edges = getEdgePrototypes(); | |
215 /* constructor with no args makes just a dummy wrapper */ | |
216 clone.diagramModel = new DiagramModel<Node,Edge>(nodes,edges); | |
217 clone.innerModelUpdater = clone.new InnerModelUpdater(); | |
218 return clone; | |
219 } | |
220 | |
221 private DiagramModel<Node,Edge> diagramModel; | |
222 private InnerModelUpdater innerModelUpdater; | |
223 private PrototypePersistenceDelegate prototypePersistenceDelegate; | |
224 private String name; | |
225 private Node[] nodes; | |
226 private Edge[] edges; | |
227 | |
228 private class InnerModelUpdater implements DiagramModelUpdater { | |
229 | |
230 @Override | |
231 public boolean getLock(DiagramTreeNode treeNode, Lock lock, DiagramEventActionSource source) { | |
232 /* using a non shared diagram requires no actual lock, therefore the answer is always yes */ | |
233 return true; | |
234 } | |
235 | |
236 @Override | |
237 public void yieldLock(DiagramTreeNode treeNode, Lock lock, DiagramEventActionSource actionSource) {} | |
238 | |
239 @Override | |
240 public void sendAwarenessMessage(AwarenessMessage.Name awMsgName, Object source){} | |
241 | |
242 @Override | |
243 public void insertInCollection(DiagramElement element,DiagramEventSource source) { | |
244 if(element instanceof Node) | |
245 diagramModel.getDiagramCollection().insert((Node)element,source); | |
246 else | |
247 diagramModel.getDiagramCollection().insert((Edge)element,source); | |
248 } | |
249 | |
250 @Override | |
251 public void insertInTree(DiagramElement element) { | |
252 if(element instanceof Node) | |
253 diagramModel.getTreeModel().insertTreeNode((Node)element,DiagramEventSource.TREE); | |
254 else | |
255 diagramModel.getTreeModel().insertTreeNode((Edge)element,DiagramEventSource.TREE); | |
256 } | |
257 | |
258 @Override | |
259 public void takeOutFromCollection(DiagramElement element, DiagramEventSource source) { | |
260 diagramModel.getDiagramCollection().takeOut(element,source); | |
261 } | |
262 | |
263 @Override | |
264 public void takeOutFromTree(DiagramElement element) { | |
265 diagramModel.getTreeModel().takeTreeNodeOut(element,DiagramEventSource.TREE); | |
266 } | |
267 | |
268 @Override | |
269 public void setName(DiagramElement element, String name,DiagramEventSource source) { | |
270 element.setName(name,source); | |
271 } | |
272 | |
273 @Override | |
274 public void setNotes(DiagramTreeNode treeNode, String notes,DiagramEventSource source) { | |
275 diagramModel.getTreeModel().setNotes(treeNode, notes,source); | |
276 } | |
277 | |
278 @Override | |
279 public void setProperty(Node node, String type, int index, | |
280 String value,DiagramEventSource source) { | |
281 node.setProperty(type, index, value,source); | |
282 } | |
283 | |
284 @Override | |
285 public void setProperties(Node node, NodeProperties properties,DiagramEventSource source) { | |
286 node.setProperties(properties,source); | |
287 } | |
288 | |
289 @Override | |
290 public void clearProperties(Node node,DiagramEventSource source) { | |
291 node.clearProperties(source); | |
292 } | |
293 | |
294 @Override | |
295 public void addProperty(Node node, String type, String value,DiagramEventSource source) { | |
296 node.addProperty(type, value,source); | |
297 } | |
298 | |
299 @Override | |
300 public void removeProperty(Node node, String type, int index,DiagramEventSource source) { | |
301 node.removeProperty(type, index,source); | |
302 } | |
303 | |
304 @Override | |
305 public void setModifiers(Node node, String type, int index, | |
306 Set<Integer> modifiers,DiagramEventSource source) { | |
307 node.setModifierIndexes(type, index, modifiers,source); | |
308 } | |
309 | |
310 @Override | |
311 public void setEndLabel(Edge edge, Node node, String label,DiagramEventSource source) { | |
312 edge.setEndLabel(node, label,source); | |
313 } | |
314 | |
315 @Override | |
316 public void setEndDescription(Edge edge, Node node, | |
317 int index,DiagramEventSource source) { | |
318 edge.setEndDescription(node, index,source); | |
319 } | |
320 | |
321 @Override | |
322 public void translate(GraphElement ge, Point2D p, double x, double y,DiagramEventSource source) { | |
323 ge.translate(p, x, y,source); | |
324 } | |
325 | |
326 @Override | |
327 public void startMove(GraphElement ge, Point2D p,DiagramEventSource source) { | |
328 ge.startMove(p,source); | |
329 } | |
330 | |
331 @Override | |
332 public void bend(Edge edge, Point2D p,DiagramEventSource source) { | |
333 edge.bend(p,source); | |
334 } | |
335 | |
336 @Override | |
337 public void stopMove(GraphElement ge,DiagramEventSource source) { | |
338 ge.stopMove(source); | |
339 } | |
340 } | |
341 } | |
342 | |
343 } |