1 /**********************************************************************
2 * Copyright (c) 2005, 2008 IBM Corporation and others.
3 * Copyright (c) 2011, 2012 Ericsson.
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * which accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
11 * IBM - Initial API and implementation
12 * Bernd Hufmann - Updated for TMF
13 **********************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Arrays
;
18 import java
.util
.Comparator
;
19 import java
.util
.HashMap
;
20 import java
.util
.Iterator
;
21 import java
.util
.List
;
23 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.TmfUiTracer
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IGC
;
25 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.preferences
.ISDPreferences
;
28 * The base class used for all UML2 graph nodes displayed in the Sequence Diagram SDWidget.
33 public abstract class GraphNode
{
35 // ------------------------------------------------------------------------
37 // ------------------------------------------------------------------------
39 * The start event occurrence.
41 protected int startEventOccurrence
= 0;
43 * The event event occurrence.
45 protected int endEventOccurrence
= 0;
47 * Preference ColorId to use to draw font
49 public String prefId
= ISDPreferences
.PREF_SYNC_MESS
;
51 * The selection state of the graph node.
53 protected boolean selected
= false;
55 * The focus state of the graph node.
57 protected boolean focused
= false;
59 * Flag to indicate whether node has children or not.
61 protected boolean hasChilden
= false;
63 * The graph node name used to label the graph node in the View.
65 protected String name
= ""; //$NON-NLS-1$
67 * A map from node name to graph node.
69 protected HashMap
<String
, List
<GraphNode
>> nodes
;
71 * A map from node name to graph node for forward sorting
73 protected HashMap
<String
, List
<GraphNode
>> fnodes
;
75 * A map from node name to graph node for backwards sorting.
77 protected HashMap
<String
, List
<GraphNode
>> bnodes
;
79 * A map from node name to index.
81 protected HashMap
<String
, Integer
> indexes
;
83 * A map from node name to index for forwards sorting.
85 protected HashMap
<String
, Boolean
> fSort
;
87 * A map from node name to indexfor forwards sorting.
89 protected HashMap
<String
, Boolean
> bSort
;
91 // ------------------------------------------------------------------------
93 // ------------------------------------------------------------------------
96 * Reset the internal index of the first visible GraphNode for each ordered GraphNode lists
98 public void resetIndex() {
103 Iterator
<String
> it
= indexes
.keySet().iterator();
104 while (it
.hasNext()) {
105 String nodeType
= it
.next();
106 indexes
.put(nodeType
, Integer
.valueOf(0));
111 * Add a GraphNode into the receiver
113 * @param nodeToAdd the node to add
115 public void addNode(GraphNode nodeToAdd
) {
117 nodes
= new HashMap
<String
, List
<GraphNode
>>(2);
118 fnodes
= new HashMap
<String
, List
<GraphNode
>>(2);
119 bnodes
= new HashMap
<String
, List
<GraphNode
>>(2);
120 indexes
= new HashMap
<String
, Integer
>(2);
121 bSort
= new HashMap
<String
, Boolean
>(2);
122 fSort
= new HashMap
<String
, Boolean
>(2);
127 if (nodeToAdd
== null) {
131 if (nodes
.get(nodeToAdd
.getArrayId()) == null) {
132 nodes
.put(nodeToAdd
.getArrayId(), new ArrayList
<GraphNode
>(1));
133 indexes
.put(nodeToAdd
.getArrayId(), Integer
.valueOf(0));
134 fnodes
.put(nodeToAdd
.getArrayId(), new ArrayList
<GraphNode
>(1));
135 fSort
.put(nodeToAdd
.getArrayId(), Boolean
.valueOf(false));
136 if (nodeToAdd
.getBackComparator() != null) {
137 bnodes
.put(nodeToAdd
.getArrayId(), new ArrayList
<GraphNode
>(1));
138 bSort
.put(nodeToAdd
.getArrayId(), Boolean
.valueOf(false));
142 List
<GraphNode
> fNodeList
= (List
<GraphNode
>) fnodes
.get(nodeToAdd
.getArrayId());
143 List
<GraphNode
> bNodeList
= null;
144 if (bnodes
!= null) {
145 bNodeList
= (List
<GraphNode
>) bnodes
.get(nodeToAdd
.getArrayId());
147 if (fNodeList
!= null && fNodeList
.size() > 0) {
148 // check if the nodes are added y ordered
149 // if not, tag the list to sort it later (during draw)
150 GraphNode node
= (GraphNode
) fNodeList
.get(fNodeList
.size() - 1);
151 Comparator
<GraphNode
> fcomp
= nodeToAdd
.getComparator();
152 Comparator
<GraphNode
> bcomp
= nodeToAdd
.getBackComparator();
153 if ((fcomp
!= null) && (fcomp
.compare(node
, nodeToAdd
) > 0)) {
154 fSort
.put(nodeToAdd
.getArrayId(), Boolean
.valueOf(true));
156 if ((bcomp
!= null) && (bcomp
.compare(node
, nodeToAdd
) > 0)) {
157 bSort
.put(nodeToAdd
.getArrayId(), Boolean
.valueOf(true));
161 if (fNodeList
== null) {
162 fNodeList
= new ArrayList
<GraphNode
>();
165 fNodeList
.add(nodeToAdd
);
166 nodes
.put(nodeToAdd
.getArrayId(), fNodeList
);
167 fnodes
.put(nodeToAdd
.getArrayId(), fNodeList
);
168 if (nodeToAdd
.getBackComparator() != null) {
169 bNodeList
.add(nodeToAdd
);
170 bnodes
.put(nodeToAdd
.getArrayId(), bNodeList
);
175 * Set the graph node name.<br>
176 * It is the name display in the view to label the graph node.
178 * @param nodeName the name to set
180 public void setName(String nodeName
) {
185 * Returns the graph node name.<br>
186 * It is the name display in the view to label the graph node.
188 * @return the graph node name
190 public String
getName() {
195 * Tags the the graph node has selected.<br>
196 * WARNING: This method is only used to draw the graph node using the system selection colors. <br>
197 * To use the complete SDViewer selection mechanism (selection management, notification, etc..) see SDWidget class
199 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode)
200 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode)
201 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection()
202 * @param selection - true to set selected, false to set unselected
204 public void setSelected(boolean selection
) {
205 selected
= selection
;
209 * Tags the the graph node as focused.<br>
210 * WARNING: This method is only used to draw the graph node using the system focus style. <br>
211 * To use the complete SDViewer focus mechanism see SDWidget class
213 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode)
214 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode)
215 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection()
216 * @param focus - true to set focued, false otherwise
218 public void setFocused(boolean focus
) {
223 * Returns true if the graph node is selected, false otherwise.<br>
224 * The returned value is used to highlight the graph node in the View.
226 * @return true if selected, false otherwise
228 public boolean isSelected() {
233 * Returns true if the graph node is focused, false otherwise.<br>
234 * The returned value is used to highlight the graph node in the View.
236 * @return true if focued, false otherwise
238 public boolean hasFocus() {
243 * Returns true if the graph node contains the point given in parameter, return false otherwise.
245 * @param x the x coordinate of the point to test containment <br>
246 * y the y coordinate of the point to test containment
247 * @return true if contained, false otherwise
249 abstract public boolean contains(int x
, int y
);
252 * Returns the x coordinate of the graph node
254 * @return the x coordinate
256 abstract public int getX();
259 * Returns the y coordinate of the graph node
261 * @return the y coordinate
263 abstract public int getY();
266 * Returns the graph node height
268 * @return the graph node height
270 abstract public int getHeight();
273 * Returns the graph node width
275 * @return the graph node width
277 abstract public int getWidth();
280 * Draws the graph node in the given context
282 * @param context the graphical context to draw in
284 abstract protected void draw(IGC context
);
287 * Returns the GraphNode visibility for the given visible area. Wrong visibility calculation, may strongly impact
288 * drawing performance
294 * @return true if visible false otherwise
296 public boolean isVisible(int x
, int y
, int width
, int height
) {
301 * Return a comparator to sort the GraphNode of the same type This comparator is used to order the GraphNode array
302 * of the given node type. (see getArrayId).
304 * @return the comparator
306 public Comparator
<GraphNode
> getComparator() {
311 * If needed, return a different comparator to backward scan the GraphNode array
313 * @return the backward comparator or null if not needed
315 public Comparator
<GraphNode
> getBackComparator() {
320 * Compare two graphNodes
322 * @param node the node to compare to
323 * @return true if equal false otherwise
325 public boolean isSameAs(GraphNode node
) {
330 * Return the node type for all class instances. This id is used to store the same nodes kind in the same ordered
333 * @return the node type identifier
335 abstract public String
getArrayId();
338 * Return true if the distance from the GraphNode to the given point is positive
340 * @param x the point x coordinate
341 * @param y the point y coordinate
342 * @return true if positive false otherwise
344 public boolean positiveDistanceToPoint(int x
, int y
) {
349 * Returns the graph node which contains the point given in parameter WARNING: Only graph nodes in the current
350 * visible area can be returned
352 * @param x the x coordinate of the point to test
353 * @param y the y coordinate of the point to test
354 * @return the graph node containing the point given in parameter, null otherwise
356 public GraphNode
getNodeAt(int x
, int y
) {
357 GraphNode toReturn
= null;
363 Iterator
<String
> it
= nodes
.keySet().iterator();
364 GraphNode node
= null;
365 while (it
.hasNext()) {
366 Object nodeType
= it
.next();
367 List
<GraphNode
> list
= (List
<GraphNode
>) nodes
.get(nodeType
);
368 int index
= ((Integer
) indexes
.get(nodeType
)).intValue();
369 node
= getNodeFromListAt(x
, y
, list
, index
);
370 if (toReturn
== null) {
374 GraphNode internalNode
= node
.getNodeAt(x
, y
);
375 if (internalNode
!= null) {
377 } else if (Math
.abs(node
.getWidth()) < Math
.abs(toReturn
.getWidth()) || Math
.abs(node
.getHeight()) < Math
.abs(toReturn
.getHeight())) {
386 * Gets node list from node A to node B
388 * @param from A from node
389 * @param to A to node
390 * @return the list of nodes
392 public ArrayList
<GraphNode
> getNodeList(GraphNode from
, GraphNode to
) {
393 ArrayList
<GraphNode
> result
= new ArrayList
<GraphNode
>();
397 } else if (to
!= null) {
401 if (from
== null || to
== null) {
409 int startX
= Math
.min(from
.getX(), Math
.min(to
.getX(), Math
.min(from
.getX() + from
.getWidth(), to
.getX() + to
.getWidth())));
410 int endX
= Math
.max(from
.getX(), Math
.max(to
.getX(), Math
.max(from
.getX() + from
.getWidth(), to
.getX() + to
.getWidth())));
411 int startY
= Math
.min(from
.getY(), Math
.min(to
.getY(), Math
.min(from
.getY() + from
.getHeight(), to
.getY() + to
.getHeight())));
412 int endY
= Math
.max(from
.getY(), Math
.max(to
.getY(), Math
.max(from
.getY() + from
.getHeight(), to
.getY() + to
.getHeight())));
418 Iterator
<String
> it
= nodes
.keySet().iterator();
419 while (it
.hasNext()) {
420 Object nodeType
= it
.next();
421 List
<GraphNode
> nodesList
= (List
<GraphNode
>) nodes
.get(nodeType
);
422 if (nodesList
== null || nodesList
.isEmpty()) {
425 for (int i
= 0; i
< nodesList
.size(); i
++) {
426 GraphNode node
= (GraphNode
) nodesList
.get(i
);
427 int nw
= node
.getWidth();
428 int nh
= node
.getHeight();
429 int nx
= node
.getX();
430 int ny
= node
.getY();
431 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)) {
434 result
.addAll(node
.getNodeList(from
, to
));
437 if ((to
!= null) && (!result
.contains(to
))) {
444 * Returns the graph node which contains the point given in parameter for the given graph node list and starting the
445 * iteration at the given index<br>
446 * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.<br>
448 * @param x the x coordinate of the point to test
449 * @param y the y coordinate of the point to test
450 * @param list the list to search in
451 * @param fromIndex list browsing starting point
452 * @return the graph node containing the point given in parameter, null otherwise
454 protected GraphNode
getNodeFromListAt(int x
, int y
, List
<GraphNode
> list
, int fromIndex
) {
458 for (int i
= fromIndex
; i
< list
.size(); i
++) {
459 GraphNode node
= (GraphNode
) list
.get(i
);
460 if (node
.contains(x
, y
)) {
468 * Returns the start event occurrence attached to this graphNode.
470 * @return the start event occurrence attached to the graphNode
472 public int getStartOccurrence() {
473 return startEventOccurrence
;
477 * Returns the end event occurrence attached to this graphNode
479 * @return the start event occurrence attached to the graphNode
481 public int getEndOccurrence() {
482 return endEventOccurrence
;
486 * Computes the index of the first visible GraphNode for each ordered graph node lists depending on the visible area
489 * @param x visible area top left corner x coordinate
490 * @param y visible area top left corner y coordinate
491 * @param width visible area width
492 * @param height visible area height
494 public void updateIndex(int x
, int y
, int width
, int height
) {
498 if(TmfUiTracer
.isIndexTraced()) {
499 TmfUiTracer
.traceIndex("*****************************\n"); //$NON-NLS-1$
500 TmfUiTracer
.traceIndex("Visible area position in virtual screen (x,y)= " + x
+ " " + y
+ "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
503 Iterator
<String
> it
= nodes
.keySet().iterator();
504 while (it
.hasNext()) {
505 String nodeType
= it
.next();
507 int drawIndex
= ((Integer
) indexes
.get(nodeType
)).intValue();
509 * if (x==0) { drawIndex = 0; indexes.put(nodeType,new Integer(drawIndex)); }
511 if ((nodes
.get(nodeType
) != null) && (((List
<GraphNode
>) nodes
.get(nodeType
)).size() > 1)) {
512 if (((GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(drawIndex
)).positiveDistanceToPoint(x
, y
)) {
516 if (drawIndex
== 0) {
520 if ((direction
== -1) && (bnodes
.get(nodeType
) != null)) {
521 GraphNode currentNode
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(drawIndex
);
522 drawIndex
= Arrays
.binarySearch(((List
<GraphNode
>) bnodes
.get(nodeType
)).toArray(new GraphNode
[0]), ((List
<GraphNode
>) nodes
.get(nodeType
)).get(drawIndex
), currentNode
.getBackComparator());
523 nodes
.put(nodeType
, (List
<GraphNode
>) bnodes
.get(nodeType
));
528 nodes
.put(nodeType
, (List
<GraphNode
>) bnodes
.get(nodeType
));
531 GraphNode prev
= null;
533 for (int i
= drawIndex
; i
< ((List
<GraphNode
>) nodes
.get(nodeType
)).size() && i
>= 0; i
= i
+ direction
) {
535 indexes
.put(nodeType
, Integer
.valueOf(i
));
537 GraphNode currentNode
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(i
);
543 Comparator
<GraphNode
> comp
= currentNode
.getComparator();
544 HashMap
<String
, Boolean
> sort
= fSort
;
546 if (direction
== -1) {
547 if (currentNode
.getBackComparator() != null) {
548 comp
= currentNode
.getBackComparator();
553 if (i
< ((List
<GraphNode
>) nodes
.get(nodeType
)).size() - 1) {
554 GraphNode next
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(i
+ 1);
556 if ((comp
!= null) && (comp
.compare(currentNode
, next
) > 0)) {
557 sort
.put(nodeType
, Boolean
.valueOf(true));
560 if (direction
== 1) {
561 if (((GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(i
)).positiveDistanceToPoint(x
, y
)) {
565 if (currentNode
.getBackComparator() == null) {
566 if // (currentNode.isVisible(x,y,width,height)
567 (!currentNode
.positiveDistanceToPoint(x
, y
)) {
571 if (currentNode
.isVisible(x
, y
, width
, height
) && !currentNode
.positiveDistanceToPoint(x
, y
)) {
572 if ((comp
!= null) && (comp
.compare(currentNode
, prev
) <= 0)) {
575 } else if ((comp
!= null) && (comp
.compare(currentNode
, prev
) <= 0)) {
582 nodes
.put(nodeType
, fnodes
.get(nodeType
));
583 if ((bnodes
.get(nodeType
) != null) && (direction
== -1)) {
584 // nodes.put(nodeType,fnodes.get(nodeType));
585 int index
= ((Integer
) indexes
.get(nodeType
)).intValue();
586 List
<GraphNode
> list
= (List
<GraphNode
>) nodes
.get(nodeType
);
587 List
<GraphNode
> backList
= (List
<GraphNode
>) bnodes
.get(nodeType
);
588 GraphNode currentNode
= (GraphNode
) (backList
.get(index
));
590 index
= Arrays
.binarySearch(list
.toArray(new GraphNode
[0]), backList
.get(index
), currentNode
.getComparator());
594 indexes
.put(nodeType
, Integer
.valueOf(index
));
598 for (int i
= drawIndex
; i
< ((List
<GraphNode
>) nodes
.get(nodeType
)).size() && i
>= 0; i
++) {
599 GraphNode toDraw
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(i
);
600 toDraw
.updateIndex(x
, y
, width
, height
);
601 if (!toDraw
.isVisible(x
, y
, width
, height
)) {
606 if (TmfUiTracer
.isIndexTraced()) {
607 TmfUiTracer
.traceIndex("First drawn " + nodeType
+ " index = " + drawIndex
+ "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
608 TmfUiTracer
.traceIndex(nodeType
+ " found in " + 0 + " iterations\n"); //$NON-NLS-1$ //$NON-NLS-2$
612 if (TmfUiTracer
.isIndexTraced()) {
613 TmfUiTracer
.traceIndex("*****************************\n"); //$NON-NLS-1$
618 * Draws the children nodes on the given context.<br>
619 * This method start width GraphNodes ordering if needed.<br>
620 * After, depending on the visible area, only visible GraphNodes are drawn.<br>
622 * @param context the context to draw to
623 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC)
625 protected void drawChildenNodes(IGC context
) {
630 // If the nodes have not been added ordered, the array is ordered
631 Iterator
<String
> it
= fSort
.keySet().iterator();
632 while (it
.hasNext()) {
633 String nodeType
= it
.next();
634 boolean sort
= ((Boolean
) fSort
.get(nodeType
)).booleanValue();
636 GraphNode
[] temp
= ((List
<GraphNode
>) fnodes
.get(nodeType
)).toArray(new GraphNode
[0]);
637 GraphNode node
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(0);
638 Arrays
.sort(temp
, node
.getComparator());
639 fSort
.put(nodeType
, Boolean
.valueOf(false));
640 nodes
.put(nodeType
, Arrays
.asList(temp
));
641 fnodes
.put(nodeType
, Arrays
.asList(temp
));
642 if (TmfUiTracer
.isSortingTraced()) {
643 TmfUiTracer
.traceSorting(nodeType
+ " array sorted\n"); //$NON-NLS-1$
648 Iterator
<String
> it2
= bSort
.keySet().iterator();
649 while (it2
.hasNext()) {
650 String nodeType
= it2
.next();
651 boolean sort
= ((Boolean
) bSort
.get(nodeType
)).booleanValue();
653 GraphNode
[] temp
= ((List
<GraphNode
>) bnodes
.get(nodeType
)).toArray(new GraphNode
[0]);
654 GraphNode node
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(0);
655 Arrays
.sort(temp
, node
.getBackComparator());
656 bSort
.put(nodeType
, Boolean
.valueOf(false));
657 bnodes
.put(nodeType
, Arrays
.asList(temp
));
658 if (TmfUiTracer
.isSortingTraced()) {
659 TmfUiTracer
.traceSorting(nodeType
+ " back array sorted\n"); //$NON-NLS-1$
664 if (TmfUiTracer
.isDisplayTraced()) {
665 TmfUiTracer
.traceDisplay("*****************************\n"); //$NON-NLS-1$
669 if ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * context
.getZoom() < Metrics
.MESSAGE_SIGNIFICANT_VSPACING
) {
670 arrayStep
= Math
.round(Metrics
.MESSAGE_SIGNIFICANT_VSPACING
/ ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * context
.getZoom()));
674 Iterator
<String
> it3
= fSort
.keySet().iterator();
675 while (it3
.hasNext()) {
677 Object nodeType
= it3
.next();
678 GraphNode node
= (GraphNode
) ((List
<GraphNode
>) nodes
.get(nodeType
)).get(0);
679 context
.setFont(Frame
.getUserPref().getFont(node
.prefId
));
680 int index
= ((Integer
) indexes
.get(nodeType
)).intValue();
681 count
= drawNodes(context
, (List
<GraphNode
>) nodes
.get(nodeType
), index
, arrayStep
);
682 if (TmfUiTracer
.isDisplayTraced()) {
683 TmfUiTracer
.traceDisplay(count
+ " " + nodeType
+ " drawn, starting from index " + index
+ "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
686 if (TmfUiTracer
.isDisplayTraced()) {
687 TmfUiTracer
.traceDisplay("*****************************\n"); //$NON-NLS-1$
693 * Draw the GraphNode stored in the given list, starting at index startIndex with the given step
695 * @param context the context to draw to
696 * @param list the GraphNodes list
697 * @param startIndex the start index
698 * @param step the step to browse the list
699 * @return the number of GraphNodes drawn
701 protected int drawNodes(IGC context
, List
<GraphNode
> list
, int startIndex
, int step
) {
706 GraphNode last
= null;
708 if (list
.size() < 0) {
712 GraphNode node
= (GraphNode
) list
.get(0);
713 context
.setFont(Frame
.getUserPref().getFont(node
.prefId
));
714 Comparator
<GraphNode
> comparator
= node
.getComparator();
715 for (int i
= startIndex
; i
< list
.size(); i
= i
+ step
) {
716 GraphNode toDraw
= (GraphNode
) list
.get(i
);
717 if (i
< list
.size() - 1) {
718 GraphNode next
= (GraphNode
) list
.get(i
+ 1);
719 if ((comparator
!= null) && (comparator
.compare(toDraw
, next
) > 0)) {
720 fSort
.put(next
.getArrayId(), Boolean
.valueOf(true));
723 int cx
= context
.getContentsX();
724 int cy
= context
.getContentsY();
725 int cw
= context
.getVisibleWidth();
726 int ch
= context
.getVisibleHeight();
727 // The arrays should be ordered, no needs to continue for this one
728 if (!toDraw
.isVisible(cx
, cy
, cw
, ch
) && toDraw
.positiveDistanceToPoint(cx
+ cw
, cy
+ ch
)) {
731 // ***Common*** nodes visibility
732 if ((!toDraw
.isSameAs(last
) || toDraw
.isSelected()) && (toDraw
.isVisible(context
.getContentsX(), context
.getContentsY(), context
.getVisibleWidth(), context
.getVisibleHeight()))) {
735 toDraw
.draw(context
);
737 toDraw
.drawFocus(context
);
746 * Draws the focus within the graphical context.
749 public void drawFocus(IGC context
) {
750 context
.drawFocus(getX(), getY(), getWidth(), getHeight());
754 * Determine if the given point (px,py) is contained in the rectangle (x,y,width,height)
756 * @param x the rectangle x coordinate
757 * @param y the rectangle y coordinate
758 * @param width the rectangle width
759 * @param height the rectangle height
760 * @param px the x coordinate of the point to test
761 * @param py the y coordinate of the point to test
762 * @return true if contained false otherwise
764 public static boolean contains(int x
, int y
, int width
, int height
, int px
, int py
) {
767 int locWidth
= width
;
768 int locHeight
= height
;
772 locWidth
= -locWidth
;
776 locY
= locY
+ height
;
777 locHeight
= -locHeight
;
779 return (px
>= locX
) && (py
>= locY
) && ((px
- locX
) <= locWidth
) && ((py
- locY
) <= locHeight
);