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 }