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