tmf: Avoid duplicate literals in GraphNode
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / uml2sd / core / GraphNode.java
CommitLineData
73005152 1/**********************************************************************
ed902a2b 2 * Copyright (c) 2005, 2014 IBM Corporation, Ericsson
73005152
BH
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
a55887ca
AM
7 *
8 * Contributors:
c8422608
AM
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
73005152 11 **********************************************************************/
c8422608 12
2bdf0193 13package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core;
73005152
BH
14
15import java.util.ArrayList;
16import java.util.Arrays;
17import java.util.Comparator;
18import java.util.HashMap;
19import java.util.Iterator;
20import java.util.List;
eb63f5ff 21import java.util.Map;
73005152 22
2bdf0193
AM
23import org.eclipse.tracecompass.internal.tmf.ui.TmfUiTracer;
24import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC;
25import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences;
26import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref;
73005152
BH
27
28/**
29 * The base class used for all UML2 graph nodes displayed in the Sequence Diagram SDWidget.
a55887ca 30 *
73005152
BH
31 * @author sveyrier
32 * @version 1.0
33 */
73005152
BH
34public abstract class GraphNode {
35
42618bb1 36 private static final String UI_DELIMITER = "*****************************\n"; //$NON-NLS-1$
df0b8ff4
BH
37 // ------------------------------------------------------------------------
38 // Attributes
39 // ------------------------------------------------------------------------
40 /**
41 * The start event occurrence.
42 */
cab6c8ff 43 private int fStartEventOccurrence = 0;
df0b8ff4
BH
44 /**
45 * The event event occurrence.
46 */
cab6c8ff 47 private int fEndEventOccurrence = 0;
73005152
BH
48 /**
49 * Preference ColorId to use to draw font
50 */
cab6c8ff 51 private String fPrefId = ISDPreferences.PREF_SYNC_MESS;
73005152
BH
52 /**
53 * The selection state of the graph node.
54 */
cab6c8ff 55 private boolean fSelected = false;
73005152
BH
56 /**
57 * The focus state of the graph node.
58 */
cab6c8ff 59 private boolean fFocused = false;
df0b8ff4 60 /**
a55887ca 61 * Flag to indicate whether node has children or not.
df0b8ff4 62 */
cab6c8ff 63 private boolean fHasChilden = false;
73005152
BH
64 /**
65 * The graph node name used to label the graph node in the View.
66 */
cab6c8ff 67 private String fName = ""; //$NON-NLS-1$
df0b8ff4
BH
68 /**
69 * A map from node name to graph node.
70 */
cab6c8ff 71 private Map<String, List<GraphNode>> fNodes;
df0b8ff4
BH
72 /**
73 * A map from node name to graph node for forward sorting
74 */
cab6c8ff 75 private Map<String, List<GraphNode>> fForwardNodes;
df0b8ff4
BH
76 /**
77 * A map from node name to graph node for backwards sorting.
78 */
cab6c8ff 79 private Map<String, List<GraphNode>> fBackwardNodes;
df0b8ff4
BH
80 /**
81 * A map from node name to index.
82 */
cab6c8ff 83 private Map<String, Integer> fIndexes;
df0b8ff4 84 /**
cab6c8ff 85 * A map from node name to flag for forwards sorting.
df0b8ff4 86 */
cab6c8ff 87 private Map<String, Boolean> fForwardSort;
df0b8ff4 88 /**
cab6c8ff 89 * A map from node name to flag for backwards sorting.
df0b8ff4 90 */
cab6c8ff 91 private Map<String, Boolean> fBackwardSort;
73005152 92
df0b8ff4
BH
93 // ------------------------------------------------------------------------
94 // Methods
95 // ------------------------------------------------------------------------
a55887ca 96
73005152
BH
97 /**
98 * Reset the internal index of the first visible GraphNode for each ordered GraphNode lists
73005152
BH
99 */
100 public void resetIndex() {
eb63f5ff 101 if (!fHasChilden) {
73005152 102 return;
df0b8ff4
BH
103 }
104
eb63f5ff 105 Iterator<String> it = fIndexes.keySet().iterator();
73005152
BH
106 while (it.hasNext()) {
107 String nodeType = it.next();
eb63f5ff 108 fIndexes.put(nodeType, Integer.valueOf(0));
73005152
BH
109 }
110 }
111
112 /**
113 * Add a GraphNode into the receiver
a55887ca 114 *
73005152
BH
115 * @param nodeToAdd the node to add
116 */
117 public void addNode(GraphNode nodeToAdd) {
eb63f5ff 118 if (!fHasChilden) {
507b1336
AM
119 fNodes = new HashMap<>(2);
120 fForwardNodes = new HashMap<>(2);
121 fBackwardNodes = new HashMap<>(2);
122 fIndexes = new HashMap<>(2);
123 fBackwardSort = new HashMap<>(2);
124 fForwardSort = new HashMap<>(2);
eb63f5ff 125 fHasChilden = true;
73005152
BH
126 }
127
128 // Nothing to add
df0b8ff4 129 if (nodeToAdd == null) {
73005152 130 return;
df0b8ff4 131 }
73005152 132
eb63f5ff
BH
133 if (fNodes.get(nodeToAdd.getArrayId()) == null) {
134 fNodes.put(nodeToAdd.getArrayId(), new ArrayList<GraphNode>(1));
135 fIndexes.put(nodeToAdd.getArrayId(), Integer.valueOf(0));
136 fForwardNodes.put(nodeToAdd.getArrayId(), new ArrayList<GraphNode>(1));
3145ec83 137 fForwardSort.put(nodeToAdd.getArrayId(), Boolean.FALSE);
73005152 138 if (nodeToAdd.getBackComparator() != null) {
eb63f5ff 139 fBackwardNodes.put(nodeToAdd.getArrayId(), new ArrayList<GraphNode>(1));
3145ec83 140 fBackwardSort.put(nodeToAdd.getArrayId(), Boolean.FALSE);
73005152
BH
141 }
142 }
143
abbdd66a 144 List<GraphNode> fNodeList = fForwardNodes.get(nodeToAdd.getArrayId());
73005152 145 List<GraphNode> bNodeList = null;
eb63f5ff 146 if (fBackwardNodes != null) {
abbdd66a 147 bNodeList = fBackwardNodes.get(nodeToAdd.getArrayId());
df0b8ff4 148 }
73005152
BH
149 if (fNodeList != null && fNodeList.size() > 0) {
150 // check if the nodes are added y ordered
151 // if not, tag the list to sort it later (during draw)
abbdd66a 152 GraphNode node = fNodeList.get(fNodeList.size() - 1);
73005152
BH
153 Comparator<GraphNode> fcomp = nodeToAdd.getComparator();
154 Comparator<GraphNode> bcomp = nodeToAdd.getBackComparator();
f9a8715c 155 if ((fcomp != null) && (fcomp.compare(node, nodeToAdd) > 0)) {
3145ec83 156 fForwardSort.put(nodeToAdd.getArrayId(), Boolean.TRUE);
73005152 157 }
f9a8715c 158 if ((bcomp != null) && (bcomp.compare(node, nodeToAdd) > 0)) {
3145ec83 159 fBackwardSort.put(nodeToAdd.getArrayId(), Boolean.TRUE);
73005152
BH
160 }
161 }
162
163 if (fNodeList == null) {
507b1336 164 fNodeList = new ArrayList<>();
73005152
BH
165 }
166
167 fNodeList.add(nodeToAdd);
eb63f5ff
BH
168 fNodes.put(nodeToAdd.getArrayId(), fNodeList);
169 fForwardNodes.put(nodeToAdd.getArrayId(), fNodeList);
64636df8 170 if ((bNodeList != null) && (nodeToAdd.getBackComparator() != null)) {
73005152 171 bNodeList.add(nodeToAdd);
eb63f5ff 172 fBackwardNodes.put(nodeToAdd.getArrayId(), bNodeList);
73005152
BH
173 }
174 }
175
176 /**
177 * Set the graph node name.<br>
178 * It is the name display in the view to label the graph node.
a55887ca 179 *
0d9a6d76 180 * @param nodeName the name to set
73005152
BH
181 */
182 public void setName(String nodeName) {
eb63f5ff 183 fName = nodeName;
73005152
BH
184 }
185
186 /**
187 * Returns the graph node name.<br>
188 * It is the name display in the view to label the graph node.
a55887ca 189 *
73005152
BH
190 * @return the graph node name
191 */
192 public String getName() {
eb63f5ff 193 return fName;
73005152
BH
194 }
195
196 /**
197 * Tags the the graph node has selected.<br>
198 * WARNING: This method is only used to draw the graph node using the system selection colors. <br>
199 * To use the complete SDViewer selection mechanism (selection management, notification, etc..) see SDWidget class
a55887ca 200 *
2bdf0193
AM
201 * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode)
202 * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode)
203 * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#clearSelection()
73005152
BH
204 * @param selection - true to set selected, false to set unselected
205 */
206 public void setSelected(boolean selection) {
eb63f5ff 207 fSelected = selection;
73005152
BH
208 }
209
210 /**
211 * Tags the the graph node as focused.<br>
212 * WARNING: This method is only used to draw the graph node using the system focus style. <br>
213 * To use the complete SDViewer focus mechanism see SDWidget class
a55887ca 214 *
2bdf0193
AM
215 * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode)
216 * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode)
217 * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.SDWidget#clearSelection()
73005152
BH
218 * @param focus - true to set focued, false otherwise
219 */
220 public void setFocused(boolean focus) {
eb63f5ff 221 fFocused = focus;
73005152
BH
222 }
223
224 /**
225 * Returns true if the graph node is selected, false otherwise.<br>
226 * The returned value is used to highlight the graph node in the View.
a55887ca 227 *
73005152 228 * @return true if selected, false otherwise
73005152
BH
229 */
230 public boolean isSelected() {
eb63f5ff 231 return fSelected;
73005152
BH
232 }
233
234 /**
235 * Returns true if the graph node is focused, false otherwise.<br>
236 * The returned value is used to highlight the graph node in the View.
a55887ca
AM
237 *
238 * @return true if focused, false otherwise
73005152
BH
239 */
240 public boolean hasFocus() {
eb63f5ff 241 return fFocused;
73005152
BH
242 }
243
244 /**
a55887ca
AM
245 * Returns true if the graph node contains the point given in parameter,
246 * return false otherwise.
247 *
248 * @param x
249 * the x coordinate of the point to test containment
250 * @param y
251 * the y coordinate of the point to test containment
73005152
BH
252 * @return true if contained, false otherwise
253 */
574f43ad 254 public abstract boolean contains(int x, int y);
73005152
BH
255
256 /**
257 * Returns the x coordinate of the graph node
a55887ca 258 *
73005152
BH
259 * @return the x coordinate
260 */
574f43ad 261 public abstract int getX();
73005152
BH
262
263 /**
264 * Returns the y coordinate of the graph node
a55887ca 265 *
73005152
BH
266 * @return the y coordinate
267 */
574f43ad 268 public abstract int getY();
73005152
BH
269
270 /**
271 * Returns the graph node height
a55887ca 272 *
73005152
BH
273 * @return the graph node height
274 */
574f43ad 275 public abstract int getHeight();
73005152
BH
276
277 /**
278 * Returns the graph node width
a55887ca 279 *
73005152
BH
280 * @return the graph node width
281 */
574f43ad 282 public abstract int getWidth();
73005152
BH
283
284 /**
285 * Draws the graph node in the given context
a55887ca 286 *
73005152
BH
287 * @param context the graphical context to draw in
288 */
574f43ad 289 protected abstract void draw(IGC context);
73005152
BH
290
291 /**
a55887ca
AM
292 * Returns the GraphNode visibility for the given visible area. Wrong
293 * visibility calculation, may strongly impact drawing performance
294 *
0d9a6d76 295 * @param x
a55887ca 296 * The X coordinate
0d9a6d76 297 * @param y
a55887ca 298 * The Y coordinate
0d9a6d76 299 * @param width
a55887ca 300 * The width of the area
0d9a6d76 301 * @param height
a55887ca
AM
302 * The height of the area
303 * @return true if visible, false otherwise
73005152
BH
304 */
305 public boolean isVisible(int x, int y, int width, int height) {
306 return true;
307 }
308
309 /**
a55887ca
AM
310 * Return a comparator to sort the GraphNode of the same type This
311 * comparator is used to order the GraphNode array of the given node type.
312 * (see getArrayId).
313 *
73005152
BH
314 * @return the comparator
315 */
316 public Comparator<GraphNode> getComparator() {
317 return null;
318 }
319
320 /**
a55887ca
AM
321 * If needed, return a different comparator to backward scan the GraphNode
322 * array
323 *
73005152
BH
324 * @return the backward comparator or null if not needed
325 */
326 public Comparator<GraphNode> getBackComparator() {
327 return null;
328 }
329
330 /**
331 * Compare two graphNodes
a55887ca
AM
332 *
333 * @param node
334 * the node to compare to
73005152
BH
335 * @return true if equal false otherwise
336 */
337 public boolean isSameAs(GraphNode node) {
338 return false;
339 }
340
341 /**
342 * Return the node type for all class instances. This id is used to store the same nodes kind in the same ordered
343 * array.
a55887ca 344 *
73005152
BH
345 * @return the node type identifier
346 */
574f43ad 347 public abstract String getArrayId();
73005152
BH
348
349 /**
350 * Return true if the distance from the GraphNode to the given point is positive
a55887ca 351 *
73005152
BH
352 * @param x the point x coordinate
353 * @param y the point y coordinate
354 * @return true if positive false otherwise
355 */
356 public boolean positiveDistanceToPoint(int x, int y) {
357 return false;
358 }
359
360 /**
361 * Returns the graph node which contains the point given in parameter WARNING: Only graph nodes in the current
362 * visible area can be returned
a55887ca 363 *
73005152
BH
364 * @param x the x coordinate of the point to test
365 * @param y the y coordinate of the point to test
366 * @return the graph node containing the point given in parameter, null otherwise
367 */
368 public GraphNode getNodeAt(int x, int y) {
369 GraphNode toReturn = null;
370
eb63f5ff 371 if (!fHasChilden) {
73005152 372 return null;
df0b8ff4 373 }
73005152 374
73005152 375 GraphNode node = null;
22740f50
JCK
376 for (Map.Entry<String, List<GraphNode>> entry : fNodes.entrySet()) {
377 List<GraphNode> list = entry.getValue();
378 int index = fIndexes.get(entry.getKey()).intValue();
73005152 379 node = getNodeFromListAt(x, y, list, index);
df0b8ff4 380 if (toReturn == null) {
73005152 381 toReturn = node;
df0b8ff4 382 }
73005152
BH
383 if (node != null) {
384 GraphNode internalNode = node.getNodeAt(x, y);
df0b8ff4 385 if (internalNode != null) {
73005152 386 return internalNode;
df0b8ff4 387 } else if (Math.abs(node.getWidth()) < Math.abs(toReturn.getWidth()) || Math.abs(node.getHeight()) < Math.abs(toReturn.getHeight())) {
73005152 388 toReturn = node;
df0b8ff4 389 }
73005152
BH
390 }
391 }
392 return toReturn;
393 }
394
df0b8ff4
BH
395 /**
396 * Gets node list from node A to node B
397
398 * @param from A from node
399 * @param to A to node
400 * @return the list of nodes
401 */
eb63f5ff 402 public List<GraphNode> getNodeList(GraphNode from, GraphNode to) {
507b1336 403 List<GraphNode> result = new ArrayList<>();
73005152
BH
404
405 if (from != null) {
406 result.add(from);
407 } else if (to != null) {
408 result.add(to);
409 }
410
eb63f5ff 411 if ((from == null) || (to == null)) {
73005152 412 return result;
df0b8ff4 413 }
73005152 414
df0b8ff4 415 if (from == to) {
73005152 416 return result;
df0b8ff4 417 }
73005152
BH
418
419 int startX = Math.min(from.getX(), Math.min(to.getX(), Math.min(from.getX() + from.getWidth(), to.getX() + to.getWidth())));
420 int endX = Math.max(from.getX(), Math.max(to.getX(), Math.max(from.getX() + from.getWidth(), to.getX() + to.getWidth())));
421 int startY = Math.min(from.getY(), Math.min(to.getY(), Math.min(from.getY() + from.getHeight(), to.getY() + to.getHeight())));
422 int endY = Math.max(from.getY(), Math.max(to.getY(), Math.max(from.getY() + from.getHeight(), to.getY() + to.getHeight())));
423
eb63f5ff 424 if (!fHasChilden) {
73005152 425 return result;
df0b8ff4 426 }
73005152 427
22740f50
JCK
428 for (Map.Entry<String, List<GraphNode>> entry : fNodes.entrySet()) {
429 List<GraphNode> nodesList = entry.getValue();
df0b8ff4 430 if (nodesList == null || nodesList.isEmpty()) {
73005152 431 return null;
df0b8ff4 432 }
73005152 433 for (int i = 0; i < nodesList.size(); i++) {
abbdd66a 434 GraphNode node = nodesList.get(i);
73005152
BH
435 int nw = node.getWidth();
436 int nh = node.getHeight();
437 int nx = node.getX();
438 int ny = node.getY();
df0b8ff4 439 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)) {
73005152 440 result.add(node);
df0b8ff4 441 }
73005152
BH
442 result.addAll(node.getNodeList(from, to));
443 }
444 }
eb63f5ff
BH
445
446 if (!result.contains(to)) {
73005152 447 result.add(to);
df0b8ff4 448 }
73005152
BH
449 return result;
450 }
451
452 /**
453 * Returns the graph node which contains the point given in parameter for the given graph node list and starting the
454 * iteration at the given index<br>
455 * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.<br>
a55887ca 456 *
73005152
BH
457 * @param x the x coordinate of the point to test
458 * @param y the y coordinate of the point to test
459 * @param list the list to search in
460 * @param fromIndex list browsing starting point
461 * @return the graph node containing the point given in parameter, null otherwise
462 */
463 protected GraphNode getNodeFromListAt(int x, int y, List<GraphNode> list, int fromIndex) {
df0b8ff4 464 if (list == null) {
73005152 465 return null;
df0b8ff4 466 }
73005152 467 for (int i = fromIndex; i < list.size(); i++) {
abbdd66a 468 GraphNode node = list.get(i);
df0b8ff4 469 if (node.contains(x, y)) {
73005152 470 return node;
df0b8ff4 471 }
73005152
BH
472 }
473 return null;
474 }
475
476 /**
477 * Returns the start event occurrence attached to this graphNode.
a55887ca 478 *
73005152
BH
479 * @return the start event occurrence attached to the graphNode
480 */
481 public int getStartOccurrence() {
eb63f5ff 482 return fStartEventOccurrence;
73005152
BH
483 }
484
485 /**
486 * Returns the end event occurrence attached to this graphNode
a55887ca 487 *
73005152
BH
488 * @return the start event occurrence attached to the graphNode
489 */
490 public int getEndOccurrence() {
eb63f5ff 491 return fEndEventOccurrence;
73005152
BH
492 }
493
494 /**
495 * Computes the index of the first visible GraphNode for each ordered graph node lists depending on the visible area
496 * given in parameter
a55887ca 497 *
73005152
BH
498 * @param x visible area top left corner x coordinate
499 * @param y visible area top left corner y coordinate
500 * @param width visible area width
501 * @param height visible area height
502 */
503 public void updateIndex(int x, int y, int width, int height) {
eb63f5ff 504 if (!fHasChilden) {
73005152 505 return;
df0b8ff4 506 }
73005152 507 if(TmfUiTracer.isIndexTraced()) {
42618bb1 508 TmfUiTracer.traceIndex(UI_DELIMITER);
73005152
BH
509 TmfUiTracer.traceIndex("Visible area position in virtual screen (x,y)= " + x + " " + y + "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
510 }
511
22740f50
JCK
512 for (Map.Entry<String, List<GraphNode>> entry : fNodes.entrySet()) {
513 String nodeType = entry.getKey();
73005152 514 int direction = 1;
abbdd66a 515 int drawIndex = fIndexes.get(nodeType).intValue();
73005152
BH
516 /*
517 * if (x==0) { drawIndex = 0; indexes.put(nodeType,new Integer(drawIndex)); }
518 */
22740f50
JCK
519 if ((entry.getValue() != null) && (entry.getValue().size() > 1)) {
520 if (entry.getValue().get(drawIndex).positiveDistanceToPoint(x, y)) {
73005152 521 direction = -1;
df0b8ff4 522 }
73005152 523
df0b8ff4 524 if (drawIndex == 0) {
73005152 525 direction = 1;
df0b8ff4 526 }
73005152 527
eb63f5ff 528 if ((direction == -1) && (fBackwardNodes.get(nodeType) != null)) {
22740f50 529 GraphNode currentNode = entry.getValue().get(drawIndex);
abbdd66a 530 drawIndex = Arrays.binarySearch(fBackwardNodes.get(nodeType).toArray(new GraphNode[fBackwardNodes.get(nodeType).size()]),
22740f50
JCK
531 entry.getValue().get(drawIndex), currentNode.getBackComparator());
532 entry.setValue(fBackwardNodes.get(nodeType));
73005152
BH
533 if (drawIndex < 0) {
534 drawIndex = 0;
535 direction = 1;
df0b8ff4 536 } else {
22740f50 537 entry.setValue(fBackwardNodes.get(nodeType));
df0b8ff4 538 }
73005152
BH
539 }
540 GraphNode prev = null;
541
22740f50 542 for (int i = drawIndex; i < entry.getValue().size() && i >= 0; i = i + direction) {
73005152 543 drawIndex = i;
eb63f5ff 544 fIndexes.put(nodeType, Integer.valueOf(i));
73005152 545
22740f50 546 GraphNode currentNode = entry.getValue().get(i);
73005152 547
df0b8ff4 548 if (prev == null) {
73005152 549 prev = currentNode;
df0b8ff4 550 }
73005152
BH
551
552 Comparator<GraphNode> comp = currentNode.getComparator();
eb63f5ff 553 Map<String, Boolean> sort = fForwardSort;
73005152 554
eb63f5ff
BH
555 if ((direction == -1) && (currentNode.getBackComparator() != null)) {
556 comp = currentNode.getBackComparator();
557 sort = fBackwardSort;
73005152
BH
558 }
559
22740f50
JCK
560 if (i < entry.getValue().size() - 1) {
561 GraphNode next = entry.getValue().get(i + 1);
73005152 562
df0b8ff4 563 if ((comp != null) && (comp.compare(currentNode, next) > 0)) {
3145ec83 564 sort.put(nodeType, Boolean.TRUE);
df0b8ff4 565 }
73005152
BH
566 }
567 if (direction == 1) {
22740f50 568 if (entry.getValue().get(i).positiveDistanceToPoint(x, y)) {
73005152 569 break;
df0b8ff4 570 }
73005152
BH
571 } else {
572 if (currentNode.getBackComparator() == null) {
573 if // (currentNode.isVisible(x,y,width,height)
df0b8ff4 574 (!currentNode.positiveDistanceToPoint(x, y)) {
73005152 575 break;
df0b8ff4 576 }
73005152
BH
577 } else {
578 if (currentNode.isVisible(x, y, width, height) && !currentNode.positiveDistanceToPoint(x, y)) {
df0b8ff4 579 if ((comp != null) && (comp.compare(currentNode, prev) <= 0)) {
73005152 580 break;
df0b8ff4
BH
581 }
582 } else if ((comp != null) && (comp.compare(currentNode, prev) <= 0)) {
73005152 583 prev = currentNode;
df0b8ff4 584 }
73005152
BH
585 }
586 }
587 }
588
22740f50 589 entry.setValue(fForwardNodes.get(nodeType));
eb63f5ff 590 if ((fBackwardNodes.get(nodeType) != null) && (direction == -1)) {
73005152 591 // nodes.put(nodeType,fnodes.get(nodeType));
abbdd66a 592 int index = fIndexes.get(nodeType).intValue();
22740f50 593 List<GraphNode> list = entry.getValue();
abbdd66a
AM
594 List<GraphNode> backList = fBackwardNodes.get(nodeType);
595 GraphNode currentNode = (backList.get(index));
73005152 596 if (index > 0) {
eb63f5ff 597 index = Arrays.binarySearch(list.toArray(new GraphNode[list.size()]), backList.get(index), currentNode.getComparator());
df0b8ff4 598 if (index < 0) {
73005152 599 index = 0;
df0b8ff4 600 }
eb63f5ff 601 fIndexes.put(nodeType, Integer.valueOf(index));
73005152
BH
602 }
603 }
604
22740f50
JCK
605 for (int i = drawIndex; i < entry.getValue().size() && i >= 0; i++) {
606 GraphNode toDraw = entry.getValue().get(i);
73005152 607 toDraw.updateIndex(x, y, width, height);
df0b8ff4 608 if (!toDraw.isVisible(x, y, width, height)) {
73005152 609 break;
df0b8ff4 610 }
73005152
BH
611 }
612 }
613 if (TmfUiTracer.isIndexTraced()) {
a55887ca 614 TmfUiTracer.traceIndex("First drawn " + nodeType + " index = " + drawIndex + "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
73005152
BH
615 TmfUiTracer.traceIndex(nodeType + " found in " + 0 + " iterations\n"); //$NON-NLS-1$ //$NON-NLS-2$
616 }
617 }
618
619 if (TmfUiTracer.isIndexTraced()) {
42618bb1 620 TmfUiTracer.traceIndex(UI_DELIMITER);
73005152
BH
621 }
622 }
623
624 /**
625 * Draws the children nodes on the given context.<br>
626 * This method start width GraphNodes ordering if needed.<br>
627 * After, depending on the visible area, only visible GraphNodes are drawn.<br>
a55887ca 628 *
73005152 629 * @param context the context to draw to
2bdf0193 630 * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC)
73005152
BH
631 */
632 protected void drawChildenNodes(IGC context) {
633
eb63f5ff 634 if (!fHasChilden) {
73005152 635 return;
df0b8ff4 636 }
73005152 637 // If the nodes have not been added ordered, the array is ordered
22740f50
JCK
638 for (Map.Entry<String, Boolean> entry : fForwardSort.entrySet()) {
639 String nodeType = entry.getKey();
640 boolean sort = entry.getValue().booleanValue();
73005152 641 if (sort) {
abbdd66a
AM
642 GraphNode[] temp = fForwardNodes.get(nodeType).toArray(new GraphNode[fForwardNodes.get(nodeType).size()]);
643 GraphNode node = fNodes.get(nodeType).get(0);
73005152 644 Arrays.sort(temp, node.getComparator());
22740f50 645 entry.setValue(Boolean.FALSE);
eb63f5ff
BH
646 fNodes.put(nodeType, Arrays.asList(temp));
647 fForwardNodes.put(nodeType, Arrays.asList(temp));
df0b8ff4 648 if (TmfUiTracer.isSortingTraced()) {
73005152 649 TmfUiTracer.traceSorting(nodeType + " array sorted\n"); //$NON-NLS-1$
df0b8ff4 650 }
73005152
BH
651 }
652 }
653
22740f50
JCK
654 for (Map.Entry<String, Boolean> entry : fBackwardSort.entrySet()) {
655 String nodeType = entry.getKey();
656 boolean sort = entry.getValue().booleanValue();
73005152 657 if (sort) {
abbdd66a
AM
658 GraphNode[] temp = fBackwardNodes.get(nodeType).toArray(new GraphNode[fBackwardNodes.get(nodeType).size()]);
659 GraphNode node = fNodes.get(nodeType).get(0);
73005152 660 Arrays.sort(temp, node.getBackComparator());
22740f50 661 entry.setValue(Boolean.FALSE);
eb63f5ff 662 fBackwardNodes.put(nodeType, Arrays.asList(temp));
df0b8ff4 663 if (TmfUiTracer.isSortingTraced()) {
73005152 664 TmfUiTracer.traceSorting(nodeType + " back array sorted\n"); //$NON-NLS-1$
df0b8ff4 665 }
73005152
BH
666 }
667 }
668
669 if (TmfUiTracer.isDisplayTraced()) {
42618bb1 670 TmfUiTracer.traceDisplay(UI_DELIMITER);
73005152
BH
671 }
672
673 int arrayStep = 1;
df0b8ff4 674 if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * context.getZoom() < Metrics.MESSAGE_SIGNIFICANT_VSPACING) {
73005152 675 arrayStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * context.getZoom()));
df0b8ff4 676 }
73005152
BH
677
678 int count = 0;
eb63f5ff 679 Iterator<String> it3 = fForwardSort.keySet().iterator();
73005152
BH
680 while (it3.hasNext()) {
681 count = 0;
682 Object nodeType = it3.next();
abbdd66a 683 GraphNode node = fNodes.get(nodeType).get(0);
3145ec83 684 context.setFont(SDViewPref.getInstance().getFont(node.fPrefId));
abbdd66a
AM
685 int index = fIndexes.get(nodeType).intValue();
686 count = drawNodes(context, fNodes.get(nodeType), index, arrayStep);
df0b8ff4 687 if (TmfUiTracer.isDisplayTraced()) {
73005152 688 TmfUiTracer.traceDisplay(count + " " + nodeType + " drawn, starting from index " + index + "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
df0b8ff4 689 }
73005152
BH
690 }
691 if (TmfUiTracer.isDisplayTraced()) {
42618bb1 692 TmfUiTracer.traceDisplay(UI_DELIMITER);
73005152
BH
693 }
694
695 }
696
697 /**
698 * Draw the GraphNode stored in the given list, starting at index startIndex with the given step
a55887ca 699 *
73005152
BH
700 * @param context the context to draw to
701 * @param list the GraphNodes list
702 * @param startIndex the start index
703 * @param step the step to browse the list
704 * @return the number of GraphNodes drawn
705 */
706 protected int drawNodes(IGC context, List<GraphNode> list, int startIndex, int step) {
eb63f5ff 707 if (!fHasChilden) {
73005152 708 return 0;
df0b8ff4 709 }
73005152
BH
710
711 GraphNode last = null;
712 int nodesCount = 0;
54cb184d 713 if (list.isEmpty()) {
73005152 714 return 0;
df0b8ff4 715 }
73005152 716
abbdd66a 717 GraphNode node = list.get(0);
3145ec83 718 context.setFont(SDViewPref.getInstance().getFont(node.fPrefId));
73005152
BH
719 Comparator<GraphNode> comparator = node.getComparator();
720 for (int i = startIndex; i < list.size(); i = i + step) {
abbdd66a 721 GraphNode toDraw = list.get(i);
73005152 722 if (i < list.size() - 1) {
abbdd66a 723 GraphNode next = list.get(i + 1);
f9a8715c 724 if ((comparator != null) && (comparator.compare(toDraw, next) > 0)) {
3145ec83 725 fForwardSort.put(next.getArrayId(), Boolean.TRUE);
73005152
BH
726 }
727 }
728 int cx = context.getContentsX();
729 int cy = context.getContentsY();
730 int cw = context.getVisibleWidth();
731 int ch = context.getVisibleHeight();
732 // The arrays should be ordered, no needs to continue for this one
df0b8ff4 733 if (!toDraw.isVisible(cx, cy, cw, ch) && toDraw.positiveDistanceToPoint(cx + cw, cy + ch)) {
73005152 734 break;
df0b8ff4 735 }
73005152
BH
736 // ***Common*** nodes visibility
737 if ((!toDraw.isSameAs(last) || toDraw.isSelected()) && (toDraw.isVisible(context.getContentsX(), context.getContentsY(), context.getVisibleWidth(), context.getVisibleHeight()))) {
738 nodesCount++;
a55887ca 739
73005152 740 toDraw.draw(context);
df0b8ff4 741 if (hasFocus()) {
73005152 742 toDraw.drawFocus(context);
df0b8ff4 743 }
73005152
BH
744 }
745 last = toDraw;
746 }
747 return nodesCount;
748 }
749
df0b8ff4
BH
750 /**
751 * Draws the focus within the graphical context.
a55887ca 752 *
df0b8ff4 753 * @param context
a55887ca 754 * The context
df0b8ff4 755 */
73005152
BH
756 public void drawFocus(IGC context) {
757 context.drawFocus(getX(), getY(), getWidth(), getHeight());
758 }
759
760 /**
761 * Determine if the given point (px,py) is contained in the rectangle (x,y,width,height)
a55887ca 762 *
73005152
BH
763 * @param x the rectangle x coordinate
764 * @param y the rectangle y coordinate
765 * @param width the rectangle width
766 * @param height the rectangle height
767 * @param px the x coordinate of the point to test
768 * @param py the y coordinate of the point to test
769 * @return true if contained false otherwise
770 */
771 public static boolean contains(int x, int y, int width, int height, int px, int py) {
772 int locX = x;
773 int locY = y;
774 int locWidth = width;
775 int locHeight = height;
776
777 if (width < 0) {
778 locX = locX + width;
779 locWidth = -locWidth;
780 }
781
782 if (height < 0) {
783 locY = locY + height;
784 locHeight = -locHeight;
785 }
786 return (px >= locX) && (py >= locY) && ((px - locX) <= locWidth) && ((py - locY) <= locHeight);
787 }
cab6c8ff
BH
788
789 /**
790 * Sets the start event occurrence attached to this graphNode.
791 *
792 * @param occurence
793 * the start event occurrence attached to the graphNode
cab6c8ff
BH
794 */
795 protected void setStartOccurrence(int occurence) {
796 fStartEventOccurrence = occurence;
797 }
798
799 /**
800 * Sets the end event occurrence attached to this graphNode
801 *
802 * @param occurence
803 * the start event occurrence attached to the graphNode
cab6c8ff
BH
804 */
805 protected void setEndOccurrence(int occurence) {
806 fEndEventOccurrence = occurence;
807 }
808
809 /**
810 * Sets the color preference id
811 * @param id
812 * The color preference id
cab6c8ff
BH
813 */
814 protected void setColorPrefId(String id) {
815 fPrefId = id;
816 }
817
818 /**
819 * Gets the color preference id
820 * @return the color preference id
cab6c8ff
BH
821 */
822 protected String getColorPrefId() {
823 return fPrefId;
824 }
825
826 /**
827 * @return if node has children or not
cab6c8ff
BH
828 */
829 protected boolean hasChildren() {
830 return fHasChilden;
831 }
832
833 /**
834 * Sets the flag indicating where the node has children or not.
835 * @param hasChildren
836 * if node has children or not
cab6c8ff
BH
837 */
838 protected void hasChildren(boolean hasChildren) {
839 fHasChilden = hasChildren;
840 }
841 /**
842 * Returns a map from node name to graph node.
843 *
844 * @return map with children graph bodes
cab6c8ff
BH
845 */
846 protected Map<String, List<GraphNode>> getNodeMap() {
847 return fNodes;
848 }
849 /**
850 * Returns a map from node name to graph node for forward sorting
851 *
852 * @return forward sorting map
cab6c8ff
BH
853 */
854 protected Map<String, List<GraphNode>> getForwardNodes() {
855 return fForwardNodes;
856 }
857 /**
858 * Returns a map from node name to graph node for backwards sorting.
859 *
860 * @return backwards sorting map
cab6c8ff
BH
861 */
862 protected Map<String, List<GraphNode>> getBackwardNodes() {
863 return fBackwardNodes;
864 }
865 /**
866 * Returns a map from node name to index.
867 *
868 * @return map with node name to index
cab6c8ff
BH
869 */
870 protected Map<String, Integer> getIndexes() {
871 return fIndexes;
872 }
873
874 /**
875 * Returns a map from node name to sort flag for forwards sorting.
876 * @return a map from node name to sort flag
cab6c8ff
BH
877 */
878 protected Map<String, Boolean> getForwardSortMap() {
879 return fForwardSort;
880 }
881 /**
882 * Returns a map from node name to flag for backwards sorting.
883 * @return map from node name to flag for backwards sorting.
cab6c8ff
BH
884 */
885 protected Map<String, Boolean> getBackwardSortMap() {
886 return fBackwardSort;
887 }
73005152 888}
This page took 0.131595 seconds and 5 git commands to generate.