Commit | Line | Data |
---|---|---|
73005152 BH |
1 | /********************************************************************** |
2 | * Copyright (c) 2005, 2008, 2011 IBM Corporation and others. | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * $Id: GraphNode.java,v 1.3 2008/01/24 02:28:49 apnan Exp $ | |
8 | * | |
9 | * Contributors: | |
10 | * IBM - Initial API and implementation | |
11 | * Bernd Hufmann - Updated for TMF | |
12 | **********************************************************************/ | |
13 | package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core; | |
14 | ||
15 | import java.util.ArrayList; | |
16 | import java.util.Arrays; | |
17 | import java.util.Comparator; | |
18 | import java.util.HashMap; | |
19 | import java.util.Iterator; | |
20 | import java.util.List; | |
21 | ||
d34665f9 | 22 | import org.eclipse.linuxtools.internal.tmf.ui.TmfUiTracer; |
73005152 BH |
23 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC; |
24 | import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.ISDPreferences; | |
25 | ||
26 | /** | |
27 | * The base class used for all UML2 graph nodes displayed in the Sequence Diagram SDWidget. | |
28 | * | |
29 | * @author sveyrier | |
30 | * @version 1.0 | |
31 | */ | |
32 | ||
33 | public abstract class GraphNode { | |
34 | ||
35 | protected int startEventOccurrence = 0; | |
36 | ||
37 | protected int endEventOccurrence = 0; | |
38 | ||
39 | /** | |
40 | * Preference ColorId to use to draw font | |
41 | */ | |
42 | public String prefId = ISDPreferences.PREF_SYNC_MESS; | |
43 | ||
44 | /** | |
45 | * The selection state of the graph node. | |
46 | */ | |
47 | protected boolean selected = false; | |
48 | ||
49 | /** | |
50 | * The focus state of the graph node. | |
51 | */ | |
52 | protected boolean focused = false; | |
53 | ||
54 | protected boolean hasChilden = false; | |
55 | ||
56 | /** | |
57 | * The graph node name used to label the graph node in the View. | |
58 | */ | |
59 | protected String name = ""; //$NON-NLS-1$ | |
60 | ||
61 | protected HashMap<String, List<GraphNode>> nodes; | |
62 | protected HashMap<String, List<GraphNode>> fnodes; | |
63 | protected HashMap<String, List<GraphNode>> bnodes; | |
64 | ||
65 | protected HashMap<String, Integer> indexes; | |
66 | protected HashMap<String, Boolean> fSort; | |
67 | protected HashMap<String, Boolean> bSort; | |
68 | ||
69 | /** | |
70 | * Reset the internal index of the first visible GraphNode for each ordered GraphNode lists | |
71 | * | |
72 | */ | |
73 | public void resetIndex() { | |
74 | if (!hasChilden) | |
75 | return; | |
76 | Iterator<String> it = indexes.keySet().iterator(); | |
77 | while (it.hasNext()) { | |
78 | String nodeType = it.next(); | |
79 | indexes.put(nodeType, Integer.valueOf(0)); | |
80 | } | |
81 | } | |
82 | ||
83 | /** | |
84 | * Add a GraphNode into the receiver | |
85 | * | |
86 | * @param nodeToAdd the node to add | |
87 | */ | |
88 | public void addNode(GraphNode nodeToAdd) { | |
89 | if (!hasChilden) { | |
90 | nodes = new HashMap<String, List<GraphNode>>(2); | |
91 | fnodes = new HashMap<String, List<GraphNode>>(2); | |
92 | bnodes = new HashMap<String, List<GraphNode>>(2); | |
93 | indexes = new HashMap<String, Integer>(2); | |
94 | bSort = new HashMap<String, Boolean>(2); | |
95 | fSort = new HashMap<String, Boolean>(2); | |
96 | hasChilden = true; | |
97 | } | |
98 | ||
99 | // Nothing to add | |
100 | if (nodeToAdd == null) | |
101 | return; | |
102 | ||
103 | if (nodes.get(nodeToAdd.getArrayId()) == null) { | |
104 | nodes.put(nodeToAdd.getArrayId(), new ArrayList<GraphNode>(1)); | |
105 | indexes.put(nodeToAdd.getArrayId(), Integer.valueOf(0)); | |
106 | fnodes.put(nodeToAdd.getArrayId(), new ArrayList<GraphNode>(1)); | |
107 | fSort.put(nodeToAdd.getArrayId(), Boolean.valueOf(false)); | |
108 | if (nodeToAdd.getBackComparator() != null) { | |
109 | bnodes.put(nodeToAdd.getArrayId(), new ArrayList<GraphNode>(1)); | |
110 | bSort.put(nodeToAdd.getArrayId(), Boolean.valueOf(false)); | |
111 | } | |
112 | } | |
113 | ||
114 | List<GraphNode> fNodeList = (List<GraphNode>) fnodes.get(nodeToAdd.getArrayId()); | |
115 | List<GraphNode> bNodeList = null; | |
116 | if (bnodes != null) | |
117 | bNodeList = (List<GraphNode>) bnodes.get(nodeToAdd.getArrayId()); | |
118 | if (fNodeList != null && fNodeList.size() > 0) { | |
119 | // check if the nodes are added y ordered | |
120 | // if not, tag the list to sort it later (during draw) | |
121 | GraphNode node = (GraphNode) fNodeList.get(fNodeList.size() - 1); | |
122 | Comparator<GraphNode> fcomp = nodeToAdd.getComparator(); | |
123 | Comparator<GraphNode> bcomp = nodeToAdd.getBackComparator(); | |
f9a8715c | 124 | if ((fcomp != null) && (fcomp.compare(node, nodeToAdd) > 0)) { |
73005152 BH |
125 | fSort.put(nodeToAdd.getArrayId(), Boolean.valueOf(true)); |
126 | } | |
f9a8715c | 127 | if ((bcomp != null) && (bcomp.compare(node, nodeToAdd) > 0)) { |
73005152 BH |
128 | bSort.put(nodeToAdd.getArrayId(), Boolean.valueOf(true)); |
129 | } | |
130 | } | |
131 | ||
132 | if (fNodeList == null) { | |
133 | fNodeList = new ArrayList<GraphNode>(); | |
134 | } | |
135 | ||
136 | fNodeList.add(nodeToAdd); | |
137 | nodes.put(nodeToAdd.getArrayId(), fNodeList); | |
138 | fnodes.put(nodeToAdd.getArrayId(), fNodeList); | |
139 | if (nodeToAdd.getBackComparator() != null) { | |
140 | bNodeList.add(nodeToAdd); | |
141 | bnodes.put(nodeToAdd.getArrayId(), bNodeList); | |
142 | } | |
143 | } | |
144 | ||
145 | /** | |
146 | * Set the graph node name.<br> | |
147 | * It is the name display in the view to label the graph node. | |
148 | * | |
0d9a6d76 | 149 | * @param nodeName the name to set |
73005152 BH |
150 | */ |
151 | public void setName(String nodeName) { | |
152 | name = nodeName; | |
153 | } | |
154 | ||
155 | /** | |
156 | * Returns the graph node name.<br> | |
157 | * It is the name display in the view to label the graph node. | |
158 | * | |
159 | * @return the graph node name | |
160 | */ | |
161 | public String getName() { | |
162 | return name; | |
163 | } | |
164 | ||
165 | /** | |
166 | * Tags the the graph node has selected.<br> | |
167 | * WARNING: This method is only used to draw the graph node using the system selection colors. <br> | |
168 | * To use the complete SDViewer selection mechanism (selection management, notification, etc..) see SDWidget class | |
169 | * | |
170 | * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode) | |
171 | * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode) | |
172 | * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection() | |
173 | * @param selection - true to set selected, false to set unselected | |
174 | */ | |
175 | public void setSelected(boolean selection) { | |
176 | selected = selection; | |
177 | } | |
178 | ||
179 | /** | |
180 | * Tags the the graph node as focused.<br> | |
181 | * WARNING: This method is only used to draw the graph node using the system focus style. <br> | |
182 | * To use the complete SDViewer focus mechanism see SDWidget class | |
183 | * | |
184 | * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode) | |
185 | * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode) | |
186 | * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection() | |
187 | * @param focus - true to set focued, false otherwise | |
188 | */ | |
189 | public void setFocused(boolean focus) { | |
190 | focused = focus; | |
191 | } | |
192 | ||
193 | /** | |
194 | * Returns true if the graph node is selected, false otherwise.<br> | |
195 | * The returned value is used to highlight the graph node in the View. | |
196 | * | |
197 | * @return true if selected, false otherwise | |
198 | * | |
199 | */ | |
200 | public boolean isSelected() { | |
201 | return selected; | |
202 | } | |
203 | ||
204 | /** | |
205 | * Returns true if the graph node is focused, false otherwise.<br> | |
206 | * The returned value is used to highlight the graph node in the View. | |
207 | * | |
208 | * @return true if focued, false otherwise | |
209 | * | |
210 | */ | |
211 | public boolean hasFocus() { | |
212 | return focused; | |
213 | } | |
214 | ||
215 | /** | |
216 | * Returns true if the graph node contains the point given in parameter, return false otherwise. | |
217 | * | |
218 | * @param x the x coordinate of the point to test containment <br> | |
219 | * y the y coordinate of the point to test containment | |
220 | * @return true if contained, false otherwise | |
221 | */ | |
222 | abstract public boolean contains(int x, int y); | |
223 | ||
224 | /** | |
225 | * Returns the x coordinate of the graph node | |
226 | * | |
227 | * @return the x coordinate | |
228 | */ | |
229 | abstract public int getX(); | |
230 | ||
231 | /** | |
232 | * Returns the y coordinate of the graph node | |
233 | * | |
234 | * @return the y coordinate | |
235 | */ | |
236 | abstract public int getY(); | |
237 | ||
238 | /** | |
239 | * Returns the graph node height | |
240 | * | |
241 | * @return the graph node height | |
242 | */ | |
243 | abstract public int getHeight(); | |
244 | ||
245 | /** | |
246 | * Returns the graph node width | |
247 | * | |
248 | * @return the graph node width | |
249 | */ | |
250 | abstract public int getWidth(); | |
251 | ||
252 | /** | |
253 | * Draws the graph node in the given context | |
254 | * | |
255 | * @param context the graphical context to draw in | |
256 | */ | |
257 | abstract protected void draw(IGC context); | |
258 | ||
259 | /** | |
260 | * Returns the GraphNode visibility for the given visible area. Wrong visibility calculation, may strongly impact | |
261 | * drawing performance | |
262 | * | |
0d9a6d76 FC |
263 | * @param x |
264 | * @param y | |
265 | * @param width | |
266 | * @param height | |
73005152 BH |
267 | * @return true if visible false otherwise |
268 | */ | |
269 | public boolean isVisible(int x, int y, int width, int height) { | |
270 | return true; | |
271 | } | |
272 | ||
273 | /** | |
274 | * Return a comparator to sort the GraphNode of the same type This comparator is used to order the GraphNode array | |
275 | * of the given node type. (see getArrayId). | |
276 | * | |
277 | * @return the comparator | |
278 | */ | |
279 | public Comparator<GraphNode> getComparator() { | |
280 | return null; | |
281 | } | |
282 | ||
283 | /** | |
284 | * If needed, return a different comparator to backward scan the GraphNode array | |
285 | * | |
286 | * @return the backward comparator or null if not needed | |
287 | */ | |
288 | public Comparator<GraphNode> getBackComparator() { | |
289 | return null; | |
290 | } | |
291 | ||
292 | /** | |
293 | * Compare two graphNodes | |
294 | * | |
295 | * @param node the node to compare to | |
296 | * @return true if equal false otherwise | |
297 | */ | |
298 | public boolean isSameAs(GraphNode node) { | |
299 | return false; | |
300 | } | |
301 | ||
302 | /** | |
303 | * Return the node type for all class instances. This id is used to store the same nodes kind in the same ordered | |
304 | * array. | |
305 | * | |
306 | * @return the node type identifier | |
307 | */ | |
308 | abstract public String getArrayId(); | |
309 | ||
310 | /** | |
311 | * Return true if the distance from the GraphNode to the given point is positive | |
312 | * | |
313 | * @param x the point x coordinate | |
314 | * @param y the point y coordinate | |
315 | * @return true if positive false otherwise | |
316 | */ | |
317 | public boolean positiveDistanceToPoint(int x, int y) { | |
318 | return false; | |
319 | } | |
320 | ||
321 | /** | |
322 | * Returns the graph node which contains the point given in parameter WARNING: Only graph nodes in the current | |
323 | * visible area can be returned | |
324 | * | |
325 | * @param x the x coordinate of the point to test | |
326 | * @param y the y coordinate of the point to test | |
327 | * @return the graph node containing the point given in parameter, null otherwise | |
328 | */ | |
329 | public GraphNode getNodeAt(int x, int y) { | |
330 | GraphNode toReturn = null; | |
331 | ||
332 | if (!hasChilden) | |
333 | return null; | |
334 | ||
335 | Iterator<String> it = nodes.keySet().iterator(); | |
336 | GraphNode node = null; | |
337 | while (it.hasNext()) { | |
338 | Object nodeType = it.next(); | |
339 | List<GraphNode> list = (List<GraphNode>) nodes.get(nodeType); | |
340 | int index = ((Integer) indexes.get(nodeType)).intValue(); | |
341 | node = getNodeFromListAt(x, y, list, index); | |
342 | if (toReturn == null) | |
343 | toReturn = node; | |
344 | if (node != null) { | |
345 | GraphNode internalNode = node.getNodeAt(x, y); | |
346 | if (internalNode != null) | |
347 | return internalNode; | |
348 | // else return node; | |
349 | else if (Math.abs(node.getWidth()) < Math.abs(toReturn.getWidth()) || Math.abs(node.getHeight()) < Math.abs(toReturn.getHeight())) | |
350 | toReturn = node; | |
351 | } | |
352 | } | |
353 | return toReturn; | |
354 | } | |
355 | ||
356 | public ArrayList<GraphNode> getNodeList(GraphNode from, GraphNode to) { | |
357 | ArrayList<GraphNode> result = new ArrayList<GraphNode>(); | |
358 | ||
359 | if (from != null) { | |
360 | result.add(from); | |
361 | } else if (to != null) { | |
362 | result.add(to); | |
363 | } | |
364 | ||
365 | if (from == null || to == null) | |
366 | return result; | |
367 | ||
368 | if (from == to) | |
369 | return result; | |
370 | ||
371 | int startX = Math.min(from.getX(), Math.min(to.getX(), Math.min(from.getX() + from.getWidth(), to.getX() + to.getWidth()))); | |
372 | int endX = Math.max(from.getX(), Math.max(to.getX(), Math.max(from.getX() + from.getWidth(), to.getX() + to.getWidth()))); | |
373 | int startY = Math.min(from.getY(), Math.min(to.getY(), Math.min(from.getY() + from.getHeight(), to.getY() + to.getHeight()))); | |
374 | int endY = Math.max(from.getY(), Math.max(to.getY(), Math.max(from.getY() + from.getHeight(), to.getY() + to.getHeight()))); | |
375 | ||
376 | if (!hasChilden) | |
377 | return result; | |
378 | ||
379 | Iterator<String> it = nodes.keySet().iterator(); | |
380 | while (it.hasNext()) { | |
381 | Object nodeType = it.next(); | |
382 | List<GraphNode> nodesList = (List<GraphNode>) nodes.get(nodeType); | |
383 | if (nodesList == null || nodesList.isEmpty()) | |
384 | return null; | |
385 | for (int i = 0; i < nodesList.size(); i++) { | |
386 | GraphNode node = (GraphNode) nodesList.get(i); | |
387 | int nw = node.getWidth(); | |
388 | int nh = node.getHeight(); | |
389 | int nx = node.getX(); | |
390 | int ny = node.getY(); | |
391 | if (contains(startX, startY, endX - startX, endY - startY, nx + 1, ny + 1) && contains(startX, startY, endX - startX, endY - startY, nx + nw - 2, ny + nh - 2)) | |
392 | result.add(node); | |
393 | result.addAll(node.getNodeList(from, to)); | |
394 | } | |
395 | } | |
396 | if ((to != null) && (!result.contains(to))) | |
397 | result.add(to); | |
398 | return result; | |
399 | } | |
400 | ||
401 | /** | |
402 | * Returns the graph node which contains the point given in parameter for the given graph node list and starting the | |
403 | * iteration at the given index<br> | |
404 | * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.<br> | |
405 | * | |
406 | * @param x the x coordinate of the point to test | |
407 | * @param y the y coordinate of the point to test | |
408 | * @param list the list to search in | |
409 | * @param fromIndex list browsing starting point | |
410 | * @return the graph node containing the point given in parameter, null otherwise | |
411 | */ | |
412 | protected GraphNode getNodeFromListAt(int x, int y, List<GraphNode> list, int fromIndex) { | |
413 | if (list == null) | |
414 | return null; | |
415 | for (int i = fromIndex; i < list.size(); i++) { | |
416 | GraphNode node = (GraphNode) list.get(i); | |
417 | if (node.contains(x, y)) | |
418 | return node; | |
419 | } | |
420 | return null; | |
421 | } | |
422 | ||
423 | /** | |
424 | * Returns the start event occurrence attached to this graphNode. | |
425 | * | |
426 | * @return the start event occurrence attached to the graphNode | |
427 | */ | |
428 | public int getStartOccurrence() { | |
429 | return startEventOccurrence; | |
430 | } | |
431 | ||
432 | /** | |
433 | * Returns the end event occurrence attached to this graphNode | |
434 | * | |
435 | * @return the start event occurrence attached to the graphNode | |
436 | */ | |
437 | public int getEndOccurrence() { | |
438 | return endEventOccurrence; | |
439 | } | |
440 | ||
441 | /** | |
442 | * Computes the index of the first visible GraphNode for each ordered graph node lists depending on the visible area | |
443 | * given in parameter | |
444 | * | |
445 | * @param x visible area top left corner x coordinate | |
446 | * @param y visible area top left corner y coordinate | |
447 | * @param width visible area width | |
448 | * @param height visible area height | |
449 | */ | |
450 | public void updateIndex(int x, int y, int width, int height) { | |
451 | if (!hasChilden) | |
452 | return; | |
453 | if(TmfUiTracer.isIndexTraced()) { | |
454 | TmfUiTracer.traceIndex("*****************************\n"); //$NON-NLS-1$ | |
455 | TmfUiTracer.traceIndex("Visible area position in virtual screen (x,y)= " + x + " " + y + "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
456 | } | |
457 | ||
458 | Iterator<String> it = nodes.keySet().iterator(); | |
459 | while (it.hasNext()) { | |
460 | String nodeType = it.next(); | |
461 | int direction = 1; | |
462 | int drawIndex = ((Integer) indexes.get(nodeType)).intValue(); | |
463 | /* | |
464 | * if (x==0) { drawIndex = 0; indexes.put(nodeType,new Integer(drawIndex)); } | |
465 | */ | |
466 | if ((nodes.get(nodeType) != null) && (((List<GraphNode>) nodes.get(nodeType)).size() > 1)) { | |
467 | if (((GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(drawIndex)).positiveDistanceToPoint(x, y)) | |
468 | direction = -1; | |
469 | ||
470 | if (drawIndex == 0) | |
471 | direction = 1; | |
472 | ||
473 | if ((direction == -1) && (bnodes.get(nodeType) != null)) { | |
474 | GraphNode currentNode = (GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(drawIndex); | |
475 | drawIndex = Arrays.binarySearch(((List<GraphNode>) bnodes.get(nodeType)).toArray(new GraphNode[0]), ((List<GraphNode>) nodes.get(nodeType)).get(drawIndex), currentNode.getBackComparator()); | |
476 | nodes.put(nodeType, (List<GraphNode>) bnodes.get(nodeType)); | |
477 | if (drawIndex < 0) { | |
478 | drawIndex = 0; | |
479 | direction = 1; | |
480 | } else | |
481 | nodes.put(nodeType, (List<GraphNode>) bnodes.get(nodeType)); | |
482 | } | |
483 | GraphNode prev = null; | |
484 | ||
485 | for (int i = drawIndex; i < ((List<GraphNode>) nodes.get(nodeType)).size() && i >= 0; i = i + direction) { | |
486 | drawIndex = i; | |
487 | indexes.put(nodeType, Integer.valueOf(i)); | |
488 | ||
489 | GraphNode currentNode = (GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(i); | |
490 | ||
491 | if (prev == null) | |
492 | prev = currentNode; | |
493 | ||
494 | Comparator<GraphNode> comp = currentNode.getComparator(); | |
495 | HashMap<String, Boolean> sort = fSort; | |
496 | ||
497 | if (direction == -1) { | |
498 | if (currentNode.getBackComparator() != null) { | |
499 | comp = currentNode.getBackComparator(); | |
500 | sort = bSort; | |
501 | } | |
502 | } | |
503 | ||
504 | if (i < ((List<GraphNode>) nodes.get(nodeType)).size() - 1) { | |
505 | GraphNode next = (GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(i + 1); | |
506 | ||
f9a8715c | 507 | if ((comp != null) && (comp.compare(currentNode, next) > 0)) |
73005152 BH |
508 | sort.put(nodeType, Boolean.valueOf(true)); |
509 | } | |
510 | if (direction == 1) { | |
511 | if (((GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(i)).positiveDistanceToPoint(x, y)) | |
512 | break; | |
513 | } else { | |
514 | if (currentNode.getBackComparator() == null) { | |
515 | if // (currentNode.isVisible(x,y,width,height) | |
516 | (!currentNode.positiveDistanceToPoint(x, y)) | |
517 | break; | |
518 | } else { | |
519 | if (currentNode.isVisible(x, y, width, height) && !currentNode.positiveDistanceToPoint(x, y)) { | |
520 | if ((comp != null) && (comp.compare(currentNode, prev) <= 0)) | |
521 | break; | |
522 | } else if ((comp != null) && (comp.compare(currentNode, prev) <= 0)) | |
523 | prev = currentNode; | |
524 | } | |
525 | } | |
526 | } | |
527 | ||
528 | nodes.put(nodeType, fnodes.get(nodeType)); | |
529 | if ((bnodes.get(nodeType) != null) && (direction == -1)) { | |
530 | // nodes.put(nodeType,fnodes.get(nodeType)); | |
531 | int index = ((Integer) indexes.get(nodeType)).intValue(); | |
532 | List<GraphNode> list = (List<GraphNode>) nodes.get(nodeType); | |
533 | List<GraphNode> backList = (List<GraphNode>) bnodes.get(nodeType); | |
534 | GraphNode currentNode = (GraphNode) (backList.get(index)); | |
535 | if (index > 0) { | |
536 | index = Arrays.binarySearch(list.toArray(new GraphNode[0]), backList.get(index), currentNode.getComparator()); | |
537 | if (index < 0) | |
538 | index = 0; | |
539 | indexes.put(nodeType, Integer.valueOf(index)); | |
540 | } | |
541 | } | |
542 | ||
543 | for (int i = drawIndex; i < ((List<GraphNode>) nodes.get(nodeType)).size() && i >= 0; i++) { | |
544 | GraphNode toDraw = (GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(i); | |
545 | toDraw.updateIndex(x, y, width, height); | |
546 | if (!toDraw.isVisible(x, y, width, height)) | |
547 | break; | |
548 | } | |
549 | } | |
550 | if (TmfUiTracer.isIndexTraced()) { | |
551 | TmfUiTracer.traceIndex("First drawn " + nodeType + " index = " + drawIndex + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
552 | TmfUiTracer.traceIndex(nodeType + " found in " + 0 + " iterations\n"); //$NON-NLS-1$ //$NON-NLS-2$ | |
553 | } | |
554 | } | |
555 | ||
556 | if (TmfUiTracer.isIndexTraced()) { | |
557 | TmfUiTracer.traceIndex("*****************************\n"); //$NON-NLS-1$ | |
558 | } | |
559 | } | |
560 | ||
561 | /** | |
562 | * Draws the children nodes on the given context.<br> | |
563 | * This method start width GraphNodes ordering if needed.<br> | |
564 | * After, depending on the visible area, only visible GraphNodes are drawn.<br> | |
565 | * | |
566 | * @param context the context to draw to | |
73005152 BH |
567 | * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC) |
568 | */ | |
569 | protected void drawChildenNodes(IGC context) { | |
570 | ||
571 | if (!hasChilden) | |
572 | return; | |
573 | // If the nodes have not been added ordered, the array is ordered | |
574 | Iterator<String> it = fSort.keySet().iterator(); | |
575 | while (it.hasNext()) { | |
576 | String nodeType = it.next(); | |
577 | boolean sort = ((Boolean) fSort.get(nodeType)).booleanValue(); | |
578 | if (sort) { | |
579 | GraphNode[] temp = ((List<GraphNode>) fnodes.get(nodeType)).toArray(new GraphNode[0]); | |
580 | GraphNode node = (GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(0); | |
581 | Arrays.sort(temp, node.getComparator()); | |
582 | fSort.put(nodeType, Boolean.valueOf(false)); | |
583 | nodes.put(nodeType, Arrays.asList(temp)); | |
584 | fnodes.put(nodeType, Arrays.asList(temp)); | |
585 | if (TmfUiTracer.isSortingTraced()) | |
586 | TmfUiTracer.traceSorting(nodeType + " array sorted\n"); //$NON-NLS-1$ | |
587 | } | |
588 | } | |
589 | ||
590 | Iterator<String> it2 = bSort.keySet().iterator(); | |
591 | while (it2.hasNext()) { | |
592 | String nodeType = it2.next(); | |
593 | boolean sort = ((Boolean) bSort.get(nodeType)).booleanValue(); | |
594 | if (sort) { | |
595 | GraphNode[] temp = ((List<GraphNode>) bnodes.get(nodeType)).toArray(new GraphNode[0]); | |
596 | GraphNode node = (GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(0); | |
597 | Arrays.sort(temp, node.getBackComparator()); | |
598 | bSort.put(nodeType, Boolean.valueOf(false)); | |
599 | bnodes.put(nodeType, Arrays.asList(temp)); | |
600 | if (TmfUiTracer.isSortingTraced()) | |
601 | TmfUiTracer.traceSorting(nodeType + " back array sorted\n"); //$NON-NLS-1$ | |
602 | } | |
603 | } | |
604 | ||
605 | if (TmfUiTracer.isDisplayTraced()) { | |
606 | TmfUiTracer.traceDisplay("*****************************\n"); //$NON-NLS-1$ | |
607 | } | |
608 | ||
609 | int arrayStep = 1; | |
610 | if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * context.getZoom() < Metrics.MESSAGE_SIGNIFICANT_VSPACING) | |
611 | arrayStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * context.getZoom())); | |
612 | ||
613 | int count = 0; | |
614 | Iterator<String> it3 = fSort.keySet().iterator(); | |
615 | while (it3.hasNext()) { | |
616 | count = 0; | |
617 | Object nodeType = it3.next(); | |
618 | GraphNode node = (GraphNode) ((List<GraphNode>) nodes.get(nodeType)).get(0); | |
619 | context.setFont(Frame.getUserPref().getFont(node.prefId)); | |
620 | int index = ((Integer) indexes.get(nodeType)).intValue(); | |
621 | count = drawNodes(context, (List<GraphNode>) nodes.get(nodeType), index, arrayStep); | |
622 | if (TmfUiTracer.isDisplayTraced()) | |
623 | TmfUiTracer.traceDisplay(count + " " + nodeType + " drawn, starting from index " + index + "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ | |
624 | } | |
625 | if (TmfUiTracer.isDisplayTraced()) { | |
626 | TmfUiTracer.traceDisplay("*****************************\n"); //$NON-NLS-1$ | |
627 | } | |
628 | ||
629 | } | |
630 | ||
631 | /** | |
632 | * Draw the GraphNode stored in the given list, starting at index startIndex with the given step | |
633 | * | |
634 | * @param context the context to draw to | |
635 | * @param list the GraphNodes list | |
636 | * @param startIndex the start index | |
637 | * @param step the step to browse the list | |
638 | * @return the number of GraphNodes drawn | |
639 | */ | |
640 | protected int drawNodes(IGC context, List<GraphNode> list, int startIndex, int step) { | |
641 | if (!hasChilden) | |
642 | return 0; | |
643 | ||
644 | GraphNode last = null; | |
645 | int nodesCount = 0; | |
646 | if (list.size() < 0) | |
647 | return 0; | |
648 | ||
649 | GraphNode node = (GraphNode) list.get(0); | |
650 | context.setFont(Frame.getUserPref().getFont(node.prefId)); | |
651 | Comparator<GraphNode> comparator = node.getComparator(); | |
652 | for (int i = startIndex; i < list.size(); i = i + step) { | |
653 | GraphNode toDraw = (GraphNode) list.get(i); | |
654 | if (i < list.size() - 1) { | |
655 | GraphNode next = (GraphNode) list.get(i + 1); | |
f9a8715c | 656 | if ((comparator != null) && (comparator.compare(toDraw, next) > 0)) { |
73005152 BH |
657 | fSort.put(next.getArrayId(), Boolean.valueOf(true)); |
658 | } | |
659 | } | |
660 | int cx = context.getContentsX(); | |
661 | int cy = context.getContentsY(); | |
662 | int cw = context.getVisibleWidth(); | |
663 | int ch = context.getVisibleHeight(); | |
664 | // The arrays should be ordered, no needs to continue for this one | |
665 | if (!toDraw.isVisible(cx, cy, cw, ch) && toDraw.positiveDistanceToPoint(cx + cw, cy + ch)) | |
666 | break; | |
667 | // ***Common*** nodes visibility | |
668 | if ((!toDraw.isSameAs(last) || toDraw.isSelected()) && (toDraw.isVisible(context.getContentsX(), context.getContentsY(), context.getVisibleWidth(), context.getVisibleHeight()))) { | |
669 | nodesCount++; | |
670 | ||
671 | toDraw.draw(context); | |
672 | if (hasFocus()) | |
673 | toDraw.drawFocus(context); | |
674 | } | |
675 | last = toDraw; | |
676 | } | |
677 | return nodesCount; | |
678 | } | |
679 | ||
680 | public void drawFocus(IGC context) { | |
681 | context.drawFocus(getX(), getY(), getWidth(), getHeight()); | |
682 | } | |
683 | ||
684 | /** | |
685 | * Determine if the given point (px,py) is contained in the rectangle (x,y,width,height) | |
686 | * | |
687 | * @param x the rectangle x coordinate | |
688 | * @param y the rectangle y coordinate | |
689 | * @param width the rectangle width | |
690 | * @param height the rectangle height | |
691 | * @param px the x coordinate of the point to test | |
692 | * @param py the y coordinate of the point to test | |
693 | * @return true if contained false otherwise | |
694 | */ | |
695 | public static boolean contains(int x, int y, int width, int height, int px, int py) { | |
696 | int locX = x; | |
697 | int locY = y; | |
698 | int locWidth = width; | |
699 | int locHeight = height; | |
700 | ||
701 | if (width < 0) { | |
702 | locX = locX + width; | |
703 | locWidth = -locWidth; | |
704 | } | |
705 | ||
706 | if (height < 0) { | |
707 | locY = locY + height; | |
708 | locHeight = -locHeight; | |
709 | } | |
710 | return (px >= locX) && (py >= locY) && ((px - locX) <= locWidth) && ((py - locY) <= locHeight); | |
711 | } | |
712 | } |