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
;
24 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.TmfUiTracer
;
25 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IGC
;
26 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.preferences
.ISDPreferences
;
27 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.preferences
.SDViewPref
;
30 * The base class used for all UML2 graph nodes displayed in the Sequence Diagram SDWidget.
35 public abstract class GraphNode
{
37 // ------------------------------------------------------------------------
39 // ------------------------------------------------------------------------
41 * The start event occurrence.
43 protected int fStartEventOccurrence
= 0;
45 * The event event occurrence.
47 protected int fEndEventOccurrence
= 0;
49 * Preference ColorId to use to draw font
51 public String fPrefId
= ISDPreferences
.PREF_SYNC_MESS
;
53 * The selection state of the graph node.
55 protected boolean fSelected
= false;
57 * The focus state of the graph node.
59 protected boolean fFocused
= false;
61 * Flag to indicate whether node has children or not.
63 protected boolean fHasChilden
= false;
65 * The graph node name used to label the graph node in the View.
67 protected String fName
= ""; //$NON-NLS-1$
69 * A map from node name to graph node.
71 protected Map
<String
, List
<GraphNode
>> fNodes
;
73 * A map from node name to graph node for forward sorting
75 protected Map
<String
, List
<GraphNode
>> fForwardNodes
;
77 * A map from node name to graph node for backwards sorting.
79 protected Map
<String
, List
<GraphNode
>> fBackwardNodes
;
81 * A map from node name to index.
83 protected Map
<String
, Integer
> fIndexes
;
85 * A map from node name to index for forwards sorting.
87 protected Map
<String
, Boolean
> fForwardSort
;
89 * A map from node name to index for forwards sorting.
91 protected Map
<String
, Boolean
> fBackwardSort
;
93 // ------------------------------------------------------------------------
95 // ------------------------------------------------------------------------
98 * Reset the internal index of the first visible GraphNode for each ordered GraphNode lists
100 public void resetIndex() {
105 Iterator
<String
> it
= fIndexes
.keySet().iterator();
106 while (it
.hasNext()) {
107 String nodeType
= it
.next();
108 fIndexes
.put(nodeType
, Integer
.valueOf(0));
113 * Add a GraphNode into the receiver
115 * @param nodeToAdd the node to add
117 public void addNode(GraphNode nodeToAdd
) {
119 fNodes
= new HashMap
<String
, List
<GraphNode
>>(2);
120 fForwardNodes
= new HashMap
<String
, List
<GraphNode
>>(2);
121 fBackwardNodes
= new HashMap
<String
, List
<GraphNode
>>(2);
122 fIndexes
= new HashMap
<String
, Integer
>(2);
123 fBackwardSort
= new HashMap
<String
, Boolean
>(2);
124 fForwardSort
= new HashMap
<String
, Boolean
>(2);
129 if (nodeToAdd
== null) {
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));
137 fForwardSort
.put(nodeToAdd
.getArrayId(), Boolean
.FALSE
);
138 if (nodeToAdd
.getBackComparator() != null) {
139 fBackwardNodes
.put(nodeToAdd
.getArrayId(), new ArrayList
<GraphNode
>(1));
140 fBackwardSort
.put(nodeToAdd
.getArrayId(), Boolean
.FALSE
);
144 List
<GraphNode
> fNodeList
= fForwardNodes
.get(nodeToAdd
.getArrayId());
145 List
<GraphNode
> bNodeList
= null;
146 if (fBackwardNodes
!= null) {
147 bNodeList
= fBackwardNodes
.get(nodeToAdd
.getArrayId());
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)
152 GraphNode node
= fNodeList
.get(fNodeList
.size() - 1);
153 Comparator
<GraphNode
> fcomp
= nodeToAdd
.getComparator();
154 Comparator
<GraphNode
> bcomp
= nodeToAdd
.getBackComparator();
155 if ((fcomp
!= null) && (fcomp
.compare(node
, nodeToAdd
) > 0)) {
156 fForwardSort
.put(nodeToAdd
.getArrayId(), Boolean
.TRUE
);
158 if ((bcomp
!= null) && (bcomp
.compare(node
, nodeToAdd
) > 0)) {
159 fBackwardSort
.put(nodeToAdd
.getArrayId(), Boolean
.TRUE
);
163 if (fNodeList
== null) {
164 fNodeList
= new ArrayList
<GraphNode
>();
167 fNodeList
.add(nodeToAdd
);
168 fNodes
.put(nodeToAdd
.getArrayId(), fNodeList
);
169 fForwardNodes
.put(nodeToAdd
.getArrayId(), fNodeList
);
170 if ((bNodeList
!= null) && (nodeToAdd
.getBackComparator() != null)) {
171 bNodeList
.add(nodeToAdd
);
172 fBackwardNodes
.put(nodeToAdd
.getArrayId(), bNodeList
);
177 * Set the graph node name.<br>
178 * It is the name display in the view to label the graph node.
180 * @param nodeName the name to set
182 public void setName(String nodeName
) {
187 * Returns the graph node name.<br>
188 * It is the name display in the view to label the graph node.
190 * @return the graph node name
192 public String
getName() {
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
201 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode)
202 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode)
203 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection()
204 * @param selection - true to set selected, false to set unselected
206 public void setSelected(boolean selection
) {
207 fSelected
= selection
;
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
215 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#addSelection(GraphNode)
216 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#removeSelection(GraphNode)
217 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.SDWidget#clearSelection()
218 * @param focus - true to set focued, false otherwise
220 public void setFocused(boolean focus
) {
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.
228 * @return true if selected, false otherwise
230 public boolean isSelected() {
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.
238 * @return true if focused, false otherwise
240 public boolean hasFocus() {
245 * Returns true if the graph node contains the point given in parameter,
246 * return false otherwise.
249 * the x coordinate of the point to test containment
251 * the y coordinate of the point to test containment
252 * @return true if contained, false otherwise
254 abstract public boolean contains(int x
, int y
);
257 * Returns the x coordinate of the graph node
259 * @return the x coordinate
261 abstract public int getX();
264 * Returns the y coordinate of the graph node
266 * @return the y coordinate
268 abstract public int getY();
271 * Returns the graph node height
273 * @return the graph node height
275 abstract public int getHeight();
278 * Returns the graph node width
280 * @return the graph node width
282 abstract public int getWidth();
285 * Draws the graph node in the given context
287 * @param context the graphical context to draw in
289 abstract protected void draw(IGC context
);
292 * Returns the GraphNode visibility for the given visible area. Wrong
293 * visibility calculation, may strongly impact drawing performance
300 * The width of the area
302 * The height of the area
303 * @return true if visible, false otherwise
305 public boolean isVisible(int x
, int y
, int width
, int height
) {
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.
314 * @return the comparator
316 public Comparator
<GraphNode
> getComparator() {
321 * If needed, return a different comparator to backward scan the GraphNode
324 * @return the backward comparator or null if not needed
326 public Comparator
<GraphNode
> getBackComparator() {
331 * Compare two graphNodes
334 * the node to compare to
335 * @return true if equal false otherwise
337 public boolean isSameAs(GraphNode node
) {
342 * Return the node type for all class instances. This id is used to store the same nodes kind in the same ordered
345 * @return the node type identifier
347 abstract public String
getArrayId();
350 * Return true if the distance from the GraphNode to the given point is positive
352 * @param x the point x coordinate
353 * @param y the point y coordinate
354 * @return true if positive false otherwise
356 public boolean positiveDistanceToPoint(int x
, int y
) {
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
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
368 public GraphNode
getNodeAt(int x
, int y
) {
369 GraphNode toReturn
= null;
375 Iterator
<String
> it
= fNodes
.keySet().iterator();
376 GraphNode node
= null;
377 while (it
.hasNext()) {
378 Object nodeType
= it
.next();
379 List
<GraphNode
> list
= fNodes
.get(nodeType
);
380 int index
= fIndexes
.get(nodeType
).intValue();
381 node
= getNodeFromListAt(x
, y
, list
, index
);
382 if (toReturn
== null) {
386 GraphNode internalNode
= node
.getNodeAt(x
, y
);
387 if (internalNode
!= null) {
389 } else if (Math
.abs(node
.getWidth()) < Math
.abs(toReturn
.getWidth()) || Math
.abs(node
.getHeight()) < Math
.abs(toReturn
.getHeight())) {
398 * Gets node list from node A to node B
400 * @param from A from node
401 * @param to A to node
402 * @return the list of nodes
404 public List
<GraphNode
> getNodeList(GraphNode from
, GraphNode to
) {
405 List
<GraphNode
> result
= new ArrayList
<GraphNode
>();
409 } else if (to
!= null) {
413 if ((from
== null) || (to
== null)) {
421 int startX
= Math
.min(from
.getX(), Math
.min(to
.getX(), Math
.min(from
.getX() + from
.getWidth(), to
.getX() + to
.getWidth())));
422 int endX
= Math
.max(from
.getX(), Math
.max(to
.getX(), Math
.max(from
.getX() + from
.getWidth(), to
.getX() + to
.getWidth())));
423 int startY
= Math
.min(from
.getY(), Math
.min(to
.getY(), Math
.min(from
.getY() + from
.getHeight(), to
.getY() + to
.getHeight())));
424 int endY
= Math
.max(from
.getY(), Math
.max(to
.getY(), Math
.max(from
.getY() + from
.getHeight(), to
.getY() + to
.getHeight())));
430 Iterator
<String
> it
= fNodes
.keySet().iterator();
431 while (it
.hasNext()) {
432 Object nodeType
= it
.next();
433 List
<GraphNode
> nodesList
= fNodes
.get(nodeType
);
434 if (nodesList
== null || nodesList
.isEmpty()) {
437 for (int i
= 0; i
< nodesList
.size(); i
++) {
438 GraphNode node
= nodesList
.get(i
);
439 int nw
= node
.getWidth();
440 int nh
= node
.getHeight();
441 int nx
= node
.getX();
442 int ny
= node
.getY();
443 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)) {
446 result
.addAll(node
.getNodeList(from
, to
));
450 if (!result
.contains(to
)) {
457 * Returns the graph node which contains the point given in parameter for the given graph node list and starting the
458 * iteration at the given index<br>
459 * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.<br>
461 * @param x the x coordinate of the point to test
462 * @param y the y coordinate of the point to test
463 * @param list the list to search in
464 * @param fromIndex list browsing starting point
465 * @return the graph node containing the point given in parameter, null otherwise
467 protected GraphNode
getNodeFromListAt(int x
, int y
, List
<GraphNode
> list
, int fromIndex
) {
471 for (int i
= fromIndex
; i
< list
.size(); i
++) {
472 GraphNode node
= list
.get(i
);
473 if (node
.contains(x
, y
)) {
481 * Returns the start event occurrence attached to this graphNode.
483 * @return the start event occurrence attached to the graphNode
485 public int getStartOccurrence() {
486 return fStartEventOccurrence
;
490 * Returns the end event occurrence attached to this graphNode
492 * @return the start event occurrence attached to the graphNode
494 public int getEndOccurrence() {
495 return fEndEventOccurrence
;
499 * Computes the index of the first visible GraphNode for each ordered graph node lists depending on the visible area
502 * @param x visible area top left corner x coordinate
503 * @param y visible area top left corner y coordinate
504 * @param width visible area width
505 * @param height visible area height
507 public void updateIndex(int x
, int y
, int width
, int height
) {
511 if(TmfUiTracer
.isIndexTraced()) {
512 TmfUiTracer
.traceIndex("*****************************\n"); //$NON-NLS-1$
513 TmfUiTracer
.traceIndex("Visible area position in virtual screen (x,y)= " + x
+ " " + y
+ "\n\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
516 Iterator
<String
> it
= fNodes
.keySet().iterator();
517 while (it
.hasNext()) {
518 String nodeType
= it
.next();
520 int drawIndex
= fIndexes
.get(nodeType
).intValue();
522 * if (x==0) { drawIndex = 0; indexes.put(nodeType,new Integer(drawIndex)); }
524 if ((fNodes
.get(nodeType
) != null) && (fNodes
.get(nodeType
).size() > 1)) {
525 if (fNodes
.get(nodeType
).get(drawIndex
).positiveDistanceToPoint(x
, y
)) {
529 if (drawIndex
== 0) {
533 if ((direction
== -1) && (fBackwardNodes
.get(nodeType
) != null)) {
534 GraphNode currentNode
= fNodes
.get(nodeType
).get(drawIndex
);
535 drawIndex
= Arrays
.binarySearch(fBackwardNodes
.get(nodeType
).toArray(new GraphNode
[fBackwardNodes
.get(nodeType
).size()]),
536 fNodes
.get(nodeType
).get(drawIndex
), currentNode
.getBackComparator());
537 fNodes
.put(nodeType
, fBackwardNodes
.get(nodeType
));
542 fNodes
.put(nodeType
, fBackwardNodes
.get(nodeType
));
545 GraphNode prev
= null;
547 for (int i
= drawIndex
; i
< fNodes
.get(nodeType
).size() && i
>= 0; i
= i
+ direction
) {
549 fIndexes
.put(nodeType
, Integer
.valueOf(i
));
551 GraphNode currentNode
= fNodes
.get(nodeType
).get(i
);
557 Comparator
<GraphNode
> comp
= currentNode
.getComparator();
558 Map
<String
, Boolean
> sort
= fForwardSort
;
560 if ((direction
== -1) && (currentNode
.getBackComparator() != null)) {
561 comp
= currentNode
.getBackComparator();
562 sort
= fBackwardSort
;
565 if (i
< fNodes
.get(nodeType
).size() - 1) {
566 GraphNode next
= fNodes
.get(nodeType
).get(i
+ 1);
568 if ((comp
!= null) && (comp
.compare(currentNode
, next
) > 0)) {
569 sort
.put(nodeType
, Boolean
.TRUE
);
572 if (direction
== 1) {
573 if (fNodes
.get(nodeType
).get(i
).positiveDistanceToPoint(x
, y
)) {
577 if (currentNode
.getBackComparator() == null) {
578 if // (currentNode.isVisible(x,y,width,height)
579 (!currentNode
.positiveDistanceToPoint(x
, y
)) {
583 if (currentNode
.isVisible(x
, y
, width
, height
) && !currentNode
.positiveDistanceToPoint(x
, y
)) {
584 if ((comp
!= null) && (comp
.compare(currentNode
, prev
) <= 0)) {
587 } else if ((comp
!= null) && (comp
.compare(currentNode
, prev
) <= 0)) {
594 fNodes
.put(nodeType
, fForwardNodes
.get(nodeType
));
595 if ((fBackwardNodes
.get(nodeType
) != null) && (direction
== -1)) {
596 // nodes.put(nodeType,fnodes.get(nodeType));
597 int index
= fIndexes
.get(nodeType
).intValue();
598 List
<GraphNode
> list
= fNodes
.get(nodeType
);
599 List
<GraphNode
> backList
= fBackwardNodes
.get(nodeType
);
600 GraphNode currentNode
= (backList
.get(index
));
602 index
= Arrays
.binarySearch(list
.toArray(new GraphNode
[list
.size()]), backList
.get(index
), currentNode
.getComparator());
606 fIndexes
.put(nodeType
, Integer
.valueOf(index
));
610 for (int i
= drawIndex
; i
< fNodes
.get(nodeType
).size() && i
>= 0; i
++) {
611 GraphNode toDraw
= fNodes
.get(nodeType
).get(i
);
612 toDraw
.updateIndex(x
, y
, width
, height
);
613 if (!toDraw
.isVisible(x
, y
, width
, height
)) {
618 if (TmfUiTracer
.isIndexTraced()) {
619 TmfUiTracer
.traceIndex("First drawn " + nodeType
+ " index = " + drawIndex
+ "\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
620 TmfUiTracer
.traceIndex(nodeType
+ " found in " + 0 + " iterations\n"); //$NON-NLS-1$ //$NON-NLS-2$
624 if (TmfUiTracer
.isIndexTraced()) {
625 TmfUiTracer
.traceIndex("*****************************\n"); //$NON-NLS-1$
630 * Draws the children nodes on the given context.<br>
631 * This method start width GraphNodes ordering if needed.<br>
632 * After, depending on the visible area, only visible GraphNodes are drawn.<br>
634 * @param context the context to draw to
635 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC)
637 protected void drawChildenNodes(IGC context
) {
642 // If the nodes have not been added ordered, the array is ordered
643 Iterator
<String
> it
= fForwardSort
.keySet().iterator();
644 while (it
.hasNext()) {
645 String nodeType
= it
.next();
646 boolean sort
= fForwardSort
.get(nodeType
).booleanValue();
648 GraphNode
[] temp
= fForwardNodes
.get(nodeType
).toArray(new GraphNode
[fForwardNodes
.get(nodeType
).size()]);
649 GraphNode node
= fNodes
.get(nodeType
).get(0);
650 Arrays
.sort(temp
, node
.getComparator());
651 fForwardSort
.put(nodeType
, Boolean
.FALSE
);
652 fNodes
.put(nodeType
, Arrays
.asList(temp
));
653 fForwardNodes
.put(nodeType
, Arrays
.asList(temp
));
654 if (TmfUiTracer
.isSortingTraced()) {
655 TmfUiTracer
.traceSorting(nodeType
+ " array sorted\n"); //$NON-NLS-1$
660 Iterator
<String
> it2
= fBackwardSort
.keySet().iterator();
661 while (it2
.hasNext()) {
662 String nodeType
= it2
.next();
663 boolean sort
= fBackwardSort
.get(nodeType
).booleanValue();
665 GraphNode
[] temp
= fBackwardNodes
.get(nodeType
).toArray(new GraphNode
[fBackwardNodes
.get(nodeType
).size()]);
666 GraphNode node
= fNodes
.get(nodeType
).get(0);
667 Arrays
.sort(temp
, node
.getBackComparator());
668 fBackwardSort
.put(nodeType
, Boolean
.FALSE
);
669 fBackwardNodes
.put(nodeType
, Arrays
.asList(temp
));
670 if (TmfUiTracer
.isSortingTraced()) {
671 TmfUiTracer
.traceSorting(nodeType
+ " back array sorted\n"); //$NON-NLS-1$
676 if (TmfUiTracer
.isDisplayTraced()) {
677 TmfUiTracer
.traceDisplay("*****************************\n"); //$NON-NLS-1$
681 if ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * context
.getZoom() < Metrics
.MESSAGE_SIGNIFICANT_VSPACING
) {
682 arrayStep
= Math
.round(Metrics
.MESSAGE_SIGNIFICANT_VSPACING
/ ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * context
.getZoom()));
686 Iterator
<String
> it3
= fForwardSort
.keySet().iterator();
687 while (it3
.hasNext()) {
689 Object nodeType
= it3
.next();
690 GraphNode node
= fNodes
.get(nodeType
).get(0);
691 context
.setFont(SDViewPref
.getInstance().getFont(node
.fPrefId
));
692 int index
= fIndexes
.get(nodeType
).intValue();
693 count
= drawNodes(context
, fNodes
.get(nodeType
), index
, arrayStep
);
694 if (TmfUiTracer
.isDisplayTraced()) {
695 TmfUiTracer
.traceDisplay(count
+ " " + nodeType
+ " drawn, starting from index " + index
+ "\r\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
698 if (TmfUiTracer
.isDisplayTraced()) {
699 TmfUiTracer
.traceDisplay("*****************************\n"); //$NON-NLS-1$
705 * Draw the GraphNode stored in the given list, starting at index startIndex with the given step
707 * @param context the context to draw to
708 * @param list the GraphNodes list
709 * @param startIndex the start index
710 * @param step the step to browse the list
711 * @return the number of GraphNodes drawn
713 protected int drawNodes(IGC context
, List
<GraphNode
> list
, int startIndex
, int step
) {
718 GraphNode last
= null;
720 if (list
.size() < 0) {
724 GraphNode node
= list
.get(0);
725 context
.setFont(SDViewPref
.getInstance().getFont(node
.fPrefId
));
726 Comparator
<GraphNode
> comparator
= node
.getComparator();
727 for (int i
= startIndex
; i
< list
.size(); i
= i
+ step
) {
728 GraphNode toDraw
= list
.get(i
);
729 if (i
< list
.size() - 1) {
730 GraphNode next
= list
.get(i
+ 1);
731 if ((comparator
!= null) && (comparator
.compare(toDraw
, next
) > 0)) {
732 fForwardSort
.put(next
.getArrayId(), Boolean
.TRUE
);
735 int cx
= context
.getContentsX();
736 int cy
= context
.getContentsY();
737 int cw
= context
.getVisibleWidth();
738 int ch
= context
.getVisibleHeight();
739 // The arrays should be ordered, no needs to continue for this one
740 if (!toDraw
.isVisible(cx
, cy
, cw
, ch
) && toDraw
.positiveDistanceToPoint(cx
+ cw
, cy
+ ch
)) {
743 // ***Common*** nodes visibility
744 if ((!toDraw
.isSameAs(last
) || toDraw
.isSelected()) && (toDraw
.isVisible(context
.getContentsX(), context
.getContentsY(), context
.getVisibleWidth(), context
.getVisibleHeight()))) {
747 toDraw
.draw(context
);
749 toDraw
.drawFocus(context
);
758 * Draws the focus within the graphical context.
763 public void drawFocus(IGC context
) {
764 context
.drawFocus(getX(), getY(), getWidth(), getHeight());
768 * Determine if the given point (px,py) is contained in the rectangle (x,y,width,height)
770 * @param x the rectangle x coordinate
771 * @param y the rectangle y coordinate
772 * @param width the rectangle width
773 * @param height the rectangle height
774 * @param px the x coordinate of the point to test
775 * @param py the y coordinate of the point to test
776 * @return true if contained false otherwise
778 public static boolean contains(int x
, int y
, int width
, int height
, int px
, int py
) {
781 int locWidth
= width
;
782 int locHeight
= height
;
786 locWidth
= -locWidth
;
790 locY
= locY
+ height
;
791 locHeight
= -locHeight
;
793 return (px
>= locX
) && (py
>= locY
) && ((px
- locX
) <= locWidth
) && ((py
- locY
) <= locHeight
);