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 org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IColor
;
17 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IGC
;
18 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.preferences
.ISDPreferences
;
21 * The base UML2 syncMessages implementation.<br>
22 * This abstract class only define one event occurrence to attach to the message.<br>
23 * Usually a message has two event occurrences attached, one for both ends. But some syncMessages(like synchronous
24 * syncMessages) only need one event occurrence to represent the time when they appear. Others kind of message
25 * representations (like asynchronous syncMessages) will be responsible to define the missing second eventOccurrence
29 * @see Lifeline Lifeline for more event occurence details
33 public abstract class BaseMessage
extends GraphNode
{
35 // ------------------------------------------------------------------------
37 // ------------------------------------------------------------------------
39 * The lifeline which send the message
41 protected Lifeline startLifeline
= null;
43 * The lifeline which receive the message
45 protected Lifeline endLifeline
= null;
47 * The visiblitiy flag.
49 protected boolean visible
= true;
51 // ------------------------------------------------------------------------
53 // ------------------------------------------------------------------------
56 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getX()
60 // returns the exact x coordinate
66 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getY()
71 * Note: lifeline.getY() return the y coordinate of the top left corner of the rectangle which contain the
72 * lifeline name getHeight return the height of this rectangle The message y coordinate is then relative to this
73 * position depending of its eventOccurrence Space between syncMessages is constant
75 if ((startLifeline
!= null) && (endLifeline
!= null)) {
77 * Regular message, both ends are attached to a lifeline
79 return endLifeline
.getY() + endLifeline
.getHeight() + (Metrics
.getMessageFontHeigth() + Metrics
.getMessagesSpacing()) * endEventOccurrence
;
83 * UML2 lost message kind
85 if (startLifeline
!= null) {
86 return startLifeline
.getY() + startLifeline
.getHeight() + (Metrics
.getMessageFontHeigth() + Metrics
.getMessagesSpacing()) * endEventOccurrence
;
90 * UML2 found message kind
92 if (endLifeline
!= null) {
93 return endLifeline
.getY() + endLifeline
.getHeight() + (Metrics
.getMessageFontHeigth() + Metrics
.getMessagesSpacing()) * endEventOccurrence
;
96 // return 0 by default
102 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getWidth()
105 public int getWidth() {
106 // Returns the exact width
107 return getWidth(false);
112 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getHeight()
115 public int getHeight() {
120 * Returns the graph node x coordinate.<br>
121 * Depending on the quick parameter a approximative or exact value is return.<br>
122 * The approximative value does not take into account if both message ends are connected to a Lifeline Execution
124 * Execution occurrence on a lifeline increase the vertical line width which represent the lifeline, this directly
125 * affect the message x coordinate and width.<br>
127 * This method is typically used to faster execute none graphical operation like tooltip lookup.<br>
130 * @param quick true to get an approximative value<br>
131 * false to get the exact x value<br>
132 * @return the graph node x coordinate
134 protected int getX(boolean quick
) {
136 int activationWidth
= Metrics
.EXECUTION_OCCURRENCE_WIDTH
/ 2;
137 if ((startLifeline
!= null) && (endLifeline
!= null)) {
138 x
= startLifeline
.getX() + Metrics
.getLifelineWidth() / 2;
140 if (startLifeline
!= null) {
141 x
= startLifeline
.getX() + Metrics
.getLifelineWidth() / 2;
144 if (endLifeline
!= null) {
145 x
= endLifeline
.getX() - Metrics
.LIFELINE_SPACING
/ 2;
153 if ((startLifeline
!= null) && (endLifeline
!= null) && (startLifeline
.getX() > endLifeline
.getX())) {
154 activationWidth
= -activationWidth
;
157 if (isMessageStartInActivation(endEventOccurrence
)) {
158 x
= x
+ activationWidth
;
165 * Returns the graph node width.<br>
166 * Depending on the quick parameter a approximative or exact value is returned.<br>
167 * The approximative value does not take into account if both message ends are connected to a Lifeline Execution
169 * Execution occurrence on a lifeline increase the vertical line width which represent the lifeline, this directly
170 * affect the message x coordinate and width.<br>
172 * This method is typically used to faster execute none graphical operation like tooltip lookup.<br>
175 * @param quick true to get an approximative value<br>
176 * false to get the exact x value
177 * @return the graph node width
179 protected int getWidth(boolean quick
) {
181 int activationWidth
= Metrics
.EXECUTION_OCCURRENCE_WIDTH
/ 2;
182 if ((startLifeline
!= null) && (endLifeline
!= null)) {
183 if (startLifeline
== endLifeline
) {
184 width
= Metrics
.INTERNAL_MESSAGE_WIDTH
+ Metrics
.EXECUTION_OCCURRENCE_WIDTH
;
186 width
= endLifeline
.getX() + Metrics
.getLifelineWidth() / 2 - getX(true);
189 if (startLifeline
!= null) {
190 width
= Metrics
.swimmingLaneWidth() / 2;
192 if (endLifeline
!= null) {
193 width
= Metrics
.swimmingLaneWidth() / 2;
201 if ((startLifeline
!= null) && (endLifeline
!= null) && (startLifeline
.getX() > endLifeline
.getX())) {
202 activationWidth
= -activationWidth
;
205 if (isMessageStartInActivation(endEventOccurrence
)) {
206 width
= width
- activationWidth
;
209 if (isMessageEndInActivation(endEventOccurrence
)) {
210 width
= width
- activationWidth
;
218 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#isVisible(int, int, int, int)
221 public boolean isVisible(int x
, int y
, int width
, int height
) {
222 // ***Common*** syncMessages visibility
223 // draw the message only if at least one end is visible
224 if (endLifeline
!= null && (endLifeline
.isVisible(x
, y
, width
, height
)) || (startLifeline
!= null && startLifeline
.isVisible(x
, y
, width
, height
))) {
227 // In this case it can be a message which cross the whole visible area
228 else if (endLifeline
!= null && (!endLifeline
.isVisible(x
, y
, width
, height
)) && (startLifeline
!= null && !startLifeline
.isVisible(x
, y
, width
, height
))) {
229 if (endLifeline
.getX() > x
+ width
&& startLifeline
.getX() < x
) {
231 } else if (startLifeline
.getX() > x
+ width
&& endLifeline
.getX() < x
) {
239 * Sets the visibility value.
241 * @param value The visibility to set.
243 public void setVisible(boolean value
) {
248 * @return the visibility value.
250 public boolean isVisible() {
255 * Set the lifeline from which this message has been sent.
257 * @param lifeline - the message sender
259 public void setStartLifeline(Lifeline lifeline
) {
260 startLifeline
= lifeline
;
264 * Returns the lifeline from which this message has been sent.
266 * @return the message sender
268 public Lifeline
getStartLifeline() {
269 return startLifeline
;
273 * Returns the lifeline which has received this message.
275 * @return the message receiver
277 public Lifeline
getEndLifeline() {
282 * Set the lifeline which has receive this message.
284 * @param lifeline the message receiver
286 public void setEndLifeline(Lifeline lifeline
) {
287 endLifeline
= lifeline
;
291 * Set the event occurrence when this message occurs.<br>
293 * @param occurrence the event occurrence to assign to this message.<br>
294 * @see Lifeline Lifeline for more event occurence details
296 protected void setEventOccurrence(int occurrence
) {
297 endEventOccurrence
= occurrence
;
301 * Returns the event occurence when is message occurs.<br>
303 * @return the event occurrence assigned to this message.<br>
304 * @see Lifeline Lifeline for more event occurence details
306 public int getEventOccurrence() {
307 return endEventOccurrence
;
311 * Determines if the given eventOccurence occurs on a executionOccurence owned by the sending lifeline.<br>
312 * WARNING: this method will return a valid result only for execution occurrences which are visible in the View.<br>
313 * As consequence this method is only used for drawing purpose, especially to determine the exact message x
314 * coordinate and width.<br>
316 * @see BaseMessage#getX(boolean)
317 * @param event the event occurrence to test
318 * @return true if occurs on a execution occurrence owned by the sending lifeine, false otherwise
320 protected boolean isMessageStartInActivation(int event
) {
321 boolean inActivation
= false;
322 if ((startLifeline
!= null) && (startLifeline
.getExecutions() != null)) {
323 // int acIndex=startLifeline.getExecOccurrenceDrawIndex();
324 // acIndex = first visible execution occurrence
325 // for drawing speed reason with only search on the visivle subset
327 for (int i
= 0; i
< startLifeline
.getExecutions().size(); i
++) {
328 BasicExecutionOccurrence toDraw
= (BasicExecutionOccurrence
) startLifeline
.getExecutions().get(i
);
329 if ((event
>= toDraw
.startEventOccurrence
) && (event
<= toDraw
.endEventOccurrence
)) {
332 // if we are outside the visible area we stop right now
333 // This works because execution occurrences are ordered along the Y axis
334 if (toDraw
.getY() > thisY
) {
343 * Determines if the given event occurrence occurs on a execution occurrence owned by the receiving lifeline.<br>
344 * WARNING: this method will return a valid result only for execution occurrences which are visible in the View.<br>
345 * As consequence this method is only used for drawing purpose, especially to determine the exact message x
346 * coordinate and width.<br>
348 * @see BaseMessage#getX(boolean)
349 * @param event the event occurrence to test
350 * @return true if occurs on a execution occurrence owned by the receiving lifeline, false otherwise
352 protected boolean isMessageEndInActivation(int event
) {
353 boolean inActivation
= false;
354 if ((endLifeline
!= null) && (endLifeline
.getExecutions() != null)) {
355 // acIndex = first visible execution occurrence
356 // for drawing speed reason with only search on the visivle subset
357 for (int i
= 0; i
< endLifeline
.getExecutions().size(); i
++) {
358 BasicExecutionOccurrence toDraw
= (BasicExecutionOccurrence
) endLifeline
.getExecutions().get(i
);
359 if ((event
>= toDraw
.startEventOccurrence
) && (event
<= toDraw
.endEventOccurrence
)) {
362 // if we are outside the visible area we stop right now
363 // This works because execution occurrences are ordered along the Y axis
364 if (toDraw
.getY() > getY()) {
374 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#contains(int, int)
377 public boolean contains(int _x
, int _y
) {
380 int width
= getWidth();
381 int height
= getHeight();
383 // Used to create a rectangle which contains the message label to allow selection when clicking the label
384 int tempHeight
= Metrics
.MESSAGES_NAME_SPACING
+ Metrics
.getMessageFontHeigth();
386 // Is it a self message?
387 if (startLifeline
== endLifeline
) {
389 * Rectangle.contains(x,y, width, height) does not works with negative height or width We check here if the
390 * rectangle width is negative.
392 if (getName().length() * Metrics
.getAverageCharWidth() > Metrics
.swimmingLaneWidth() - Metrics
.EXECUTION_OCCURRENCE_WIDTH
/ 2 + -Metrics
.INTERNAL_MESSAGE_WIDTH
) {
393 if (Frame
.contains(x
+ Metrics
.INTERNAL_MESSAGE_WIDTH
+ 10, y
, Metrics
.swimmingLaneWidth() - Metrics
.EXECUTION_OCCURRENCE_WIDTH
/ 2 + -Metrics
.INTERNAL_MESSAGE_WIDTH
, Metrics
.getMessageFontHeigth(), _x
, _y
)) {
397 if (Frame
.contains(x
+ Metrics
.INTERNAL_MESSAGE_WIDTH
+ 10, y
, getName().length() * Metrics
.getAverageCharWidth(), Metrics
.getMessageFontHeigth(), _x
, _y
)) {
402 // Test if the point is in part 1 of the self message
403 // see: "private void drawMessage (NGC context)" method for self message drawing schema
404 if (Frame
.contains(x
, y
- Metrics
.MESSAGE_SELECTION_TOLERANCE
/ 2, Metrics
.INTERNAL_MESSAGE_WIDTH
/ 2, Metrics
.MESSAGE_SELECTION_TOLERANCE
, _x
, _y
)) {
408 // Test if the point is in part 3 of the self message
409 if (Frame
.contains(x
+ Metrics
.INTERNAL_MESSAGE_WIDTH
- Metrics
.MESSAGE_SELECTION_TOLERANCE
/ 2, y
, Metrics
.MESSAGE_SELECTION_TOLERANCE
, height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
, _x
, _y
)) {
413 // Test if the point is in part 5 of the self message
414 if (Frame
.contains(x
, y
+ height
- Metrics
.MESSAGE_SELECTION_TOLERANCE
/ 2 + Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
, Metrics
.INTERNAL_MESSAGE_WIDTH
/ 2, Metrics
.MESSAGE_SELECTION_TOLERANCE
, _x
, _y
)) {
421 if (Frame
.contains(x
, y
- tempHeight
, width
, tempHeight
, _x
, _y
)) {
429 * Method to draw the message using the graphical context.
431 * @param context A graphical context to draw in.
433 protected void drawMessage(IGC context
) {
435 fX
= fY
= fW
= fH
= 0;
437 // temporay store the coordinates to avoid more methods calls
440 int width
= getWidth();
441 int height
= getHeight();
443 // UML2 found message (always drawn from left to right)
444 // or UML2 lost message (always drawn from left to right)
445 if ((startLifeline
== null || endLifeline
== null) && startLifeline
!= endLifeline
) {
446 // Draw the message label above the message and centered
447 // The label is truncated if it cannot fit between the two message end
448 // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label
449 IColor temp
= context
.getForeground();
450 context
.setForeground(Frame
.getUserPref().getFontColor(prefId
));
451 context
.drawTextTruncatedCentred(getName(), x
, y
- Metrics
.getMessageFontHeigth() - 2 * Metrics
.MESSAGES_NAME_SPACING
, width
, 2 * Metrics
.MESSAGES_NAME_SPACING
+ Metrics
.getMessageFontHeigth(), !isSelected());
452 context
.setForeground(temp
);
454 if (endLifeline
== null) {
455 margin
= Metrics
.MESSAGE_CIRCLE_RAY
;
458 // Draw the message main line
459 context
.drawLine(x
, y
, x
+ width
, y
+ height
);
460 // Draw the two little lines which make a arrow part of the message
461 Double xt
= new Double(Math
.cos(0.75) * 7);
462 Double yt
= new Double(Math
.sin(0.75) * 7);
463 if (context
.getLineStyle() == context
.getLineSolidStyle()) {
464 IColor backcolor
= context
.getBackground();
465 context
.setBackground(context
.getForeground());
466 int[] points
= { x
+ width
- margin
, y
+ height
, x
+ width
- xt
.intValue() - margin
, y
+ height
- yt
.intValue(), x
+ width
- xt
.intValue() - margin
, y
+ height
+ yt
.intValue(), x
+ width
- margin
, y
+ height
};
467 context
.fillPolygon(points
);
468 context
.drawPolygon(points
);
469 context
.setBackground(backcolor
);
471 int currentStyle
= context
.getLineStyle();
472 int currentWidth
= context
.getLineWidth();
473 context
.setLineWidth(currentWidth
+ 2);
474 context
.setLineStyle(context
.getLineSolidStyle());
475 context
.drawLine(x
+ width
- xt
.intValue() - margin
, y
+ height
- yt
.intValue(), x
+ width
- margin
, y
+ height
);
476 context
.drawLine(x
+ width
- xt
.intValue() - margin
, y
+ height
+ yt
.intValue(), x
+ width
- margin
, y
+ height
);
477 context
.setLineStyle(currentStyle
);
478 context
.setLineWidth(currentWidth
);
480 IColor storedColor
= context
.getBackground();
481 context
.setBackground(context
.getForeground());
483 // Draw a circle at the message end (endLifeline side)
484 int ray
= Metrics
.MESSAGE_CIRCLE_RAY
;
485 if (context
.getLineWidth() != Metrics
.NORMAL_LINE_WIDTH
) {
486 ray
= ray
+ Metrics
.SELECTION_LINE_WIDTH
- Metrics
.NORMAL_LINE_WIDTH
;
488 if (startLifeline
== null) {
489 context
.fillOval(x
- ray
, y
- ray
, ray
* 2, ray
* 2);
491 context
.fillOval(x
+ width
- ray
, y
+ height
- ray
, ray
* 2, ray
* 2);
493 context
.setBackground(storedColor
);
494 context
.setForeground(Frame
.getUserPref().getFontColor(prefId
));
496 fY
= y
- yt
.intValue();
498 fH
= height
+ 2 * yt
.intValue();
500 // it is self message (always drawn at the left side of the owning lifeLifeline)
501 else if (startLifeline
!= null && endLifeline
!= null && startLifeline
== endLifeline
) {
503 * Self syncMessages are drawn in 5 parts 1 -----------+ + 2 + | | | 3 | + 5 + 4 -----------+
505 int tempy
= Metrics
.INTERNAL_MESSAGE_WIDTH
/ 2;
506 if (Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
<= Metrics
.INTERNAL_MESSAGE_WIDTH
) {
507 tempy
= Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
/ 2;
511 context
.drawLine(x
, y
, x
+ Metrics
.INTERNAL_MESSAGE_WIDTH
/ 2, y
);
513 context
.drawLine(x
+ Metrics
.INTERNAL_MESSAGE_WIDTH
, y
+ tempy
, x
+ Metrics
.INTERNAL_MESSAGE_WIDTH
, y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
- tempy
);
515 context
.drawLine(x
, y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
, x
+ Metrics
.INTERNAL_MESSAGE_WIDTH
/ 2, y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
);
517 Double xt
= new Double(Math
.cos(0.75) * 7);
518 Double yt
= new Double(Math
.sin(0.75) * 7);
522 fW
= Metrics
.INTERNAL_MESSAGE_WIDTH
;
523 fH
= height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
;
525 // Draw the two little lines which make a arrow part of the message
526 if (context
.getLineStyle() == context
.getLineSolidStyle()) {
527 IColor backcolor
= context
.getBackground();
528 context
.setBackground(context
.getForeground());
529 int[] points
= { x
, y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
, x
+ xt
.intValue(), y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
+ yt
.intValue(), x
+ xt
.intValue(),
530 y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
- yt
.intValue(), x
, y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
};
531 context
.fillPolygon(points
);
532 context
.drawPolygon(points
);
533 context
.setBackground(backcolor
);
535 int currentStyle
= context
.getLineStyle();
536 int currentWidth
= context
.getLineWidth();
537 context
.setLineWidth(currentWidth
+ 2);
538 context
.setLineStyle(context
.getLineSolidStyle());
539 context
.drawLine(x
+ xt
.intValue(), y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
+ yt
.intValue(), x
, y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
);
540 context
.drawLine(x
+ xt
.intValue(), y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
- yt
.intValue(), x
, y
+ height
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
);
541 context
.setLineStyle(currentStyle
);
542 context
.setLineWidth(currentWidth
);
546 context
.drawArc(x
, y
, Metrics
.INTERNAL_MESSAGE_WIDTH
, 2 * tempy
, 0, 90);
548 context
.drawArc(x
, y
+ Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
, Metrics
.INTERNAL_MESSAGE_WIDTH
, -2 * tempy
, 0, -90);
550 // Draw the message label above the message and centered
551 // The label is truncated if it cannot fit between the two message end
552 // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label
554 // the space available for the text is sorter if are drawing internal message on the last lifeline
555 context
.setForeground(Frame
.getUserPref().getFontColor(prefId
));
556 if (startLifeline
.getIndex() == startLifeline
.getFrame().getHorizontalIndex()) {
557 context
.drawTextTruncated(getName(), x
+ width
+ Metrics
.INTERNAL_MESSAGE_V_MARGIN
/ 2, y
, Metrics
.swimmingLaneWidth() / 2 - Metrics
.EXECUTION_OCCURRENCE_WIDTH
+ -Metrics
.INTERNAL_MESSAGE_WIDTH
, +Metrics
.MESSAGES_NAME_SPACING
558 - Metrics
.getMessageFontHeigth(), !isSelected());
560 context
.drawTextTruncated(getName(), x
+ width
+ Metrics
.INTERNAL_MESSAGE_V_MARGIN
/ 2, y
, Metrics
.swimmingLaneWidth() - Metrics
.EXECUTION_OCCURRENCE_WIDTH
+ -Metrics
.INTERNAL_MESSAGE_WIDTH
,
561 +Metrics
.MESSAGES_NAME_SPACING
- Metrics
.getMessageFontHeigth(), !isSelected());
564 // it is regular message
565 else if (startLifeline
!= null && endLifeline
!= null) {
566 // Draw the message main line
567 context
.drawLine(x
, y
, x
+ width
, y
+ height
);
569 int spaceBTWStartEnd
= endLifeline
.getX() - startLifeline
.getX();
573 double angle
= Math
.atan(a
/ b
);
574 // Compute the coordinates of the two little lines which make the arrow part of the message
576 if (spaceBTWStartEnd
< 0) {
579 Double x1
= new Double(sign
* Math
.cos(angle
- 0.75) * 7);
580 Double y1
= new Double(sign
* Math
.sin(angle
- 0.75) * 7);
581 Double x2
= new Double(sign
* Math
.cos(angle
+ 0.75) * 7);
582 Double y2
= new Double(sign
* Math
.sin(angle
+ 0.75) * 7);
585 fY
= y
+ height
- y2
.intValue();
587 fH
= y2
.intValue() - y1
.intValue() + 1;
598 // Draw the two little lines which make a arrow part of the message
599 if (context
.getLineStyle() == context
.getLineSolidStyle()) {
600 IColor backcolor
= context
.getBackground();
601 context
.setBackground(context
.getForeground());
602 int[] points
= { x
+ width
- x1
.intValue(), y
+ height
- y1
.intValue(), x
+ width
, y
+ height
, x
+ width
- x2
.intValue(), y
+ height
- y2
.intValue(), x
+ width
- x1
.intValue(), y
+ height
- y1
.intValue() };
603 context
.fillPolygon(points
);
604 context
.drawPolygon(points
);
605 context
.setBackground(backcolor
);
607 int currentStyle
= context
.getLineStyle();
608 int currentWidth
= context
.getLineWidth();
609 context
.setLineWidth(currentWidth
+ 2);
610 context
.setLineStyle(context
.getLineSolidStyle());
611 context
.drawLine(x
+ width
- x1
.intValue(), y
+ height
- y1
.intValue(), x
+ width
, y
+ height
);
612 context
.drawLine(x
+ width
- x2
.intValue(), y
+ height
- y2
.intValue(), x
+ width
, y
+ height
);
613 context
.setLineStyle(currentStyle
);
614 context
.setLineWidth(currentWidth
);
617 // Draw the message label above the message and centered
618 // The label is truncated if it cannot fit between the two message end
619 // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label
620 context
.setForeground(Frame
.getUserPref().getFontColor(prefId
));
621 if (spaceBTWStartEnd
> 0) {
622 context
.drawTextTruncatedCentred(getName(), x
, y
+ height
/ 2 - (2 * Metrics
.MESSAGES_NAME_SPACING
+ Metrics
.getMessageFontHeigth()), width
, 2 * Metrics
.MESSAGES_NAME_SPACING
+ Metrics
.getMessageFontHeigth(), !isSelected());
624 context
.drawTextTruncatedCentred(getName(), x
+ width
, y
+ height
/ 2 - (2 * Metrics
.MESSAGES_NAME_SPACING
+ Metrics
.getMessageFontHeigth()), -width
, 2 * Metrics
.MESSAGES_NAME_SPACING
+ +Metrics
.getMessageFontHeigth(), !isSelected());
631 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNodee#draw(org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC)
634 public void draw(IGC context
) {
638 // Draw it selected?*/
642 * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection
643 * colors This create the highlight effect
645 context
.setForeground(Frame
.getUserPref().getBackGroundColorSelection());
646 context
.setLineWidth(Metrics
.SELECTION_LINE_WIDTH
);
647 drawMessage(context
);
648 context
.setBackground(Frame
.getUserPref().getBackGroundColorSelection());
649 context
.setForeground(Frame
.getUserPref().getForeGroundColorSelection());
650 // Second drawing is done after
652 context
.setLineWidth(Metrics
.NORMAL_LINE_WIDTH
);
654 context
.setDrawTextWithFocusStyle(true);
656 drawMessage(context
);
657 int oldStyle
= context
.getLineStyle();
659 context
.setDrawTextWithFocusStyle(false);
662 // restore the context
663 context
.setLineStyle(oldStyle
);
667 * Determine if two messages are identical. This default implementation considers that overlapping messages with
668 * same coordinates are identical.
670 * @param message - the message to compare with
671 * @return true if identical false otherwise
673 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#isSameAs(org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode)
676 public boolean isSameAs(GraphNode message
) {
677 if (message
== null) {
680 if (!(message
instanceof BaseMessage
)) {
681 return super.isSameAs(message
);
683 if (getX() == message
.getX() && getY() == message
.getY() && getWidth() == message
.getWidth() && getHeight() == message
.getHeight()) {
693 * @param x A x coordinate
694 * @param y A y coordinate
697 * @param context A graphical context
699 public void drawRot(int x
, int y
, int w
, int h
, IGC context
) {
700 double angleA
= Math
.atan2(getHeight(), getWidth());
701 double cosA
= Math
.cos(angleA
);
702 double sinA
= Math
.sin(angleA
);
709 double cw
= Math
.sqrt(w
* w
+ getHeight() * getHeight());
711 int x1
= Math
.round((float) ((x
- gx
) * cosA
- (y
- gy
) * sinA
));
712 int y1
= Math
.round((float) ((x
- gx
) * sinA
+ (y
- gy
) * cosA
));
714 int x2
= Math
.round((float) (cw
* cosA
- (y
- gy
) * sinA
));
715 int y2
= Math
.round((float) (cw
* sinA
+ (y
- gy
) * cosA
));
717 int x3
= Math
.round((float) (cw
* cosA
- (h
) * sinA
));
718 int y3
= Math
.round((float) (cw
* sinA
+ (h
) * cosA
));
720 int x4
= Math
.round((float) ((x
- gx
) * cosA
- (h
) * sinA
));
721 int y4
= Math
.round((float) ((x
- gx
) * sinA
+ (h
) * cosA
));
723 int[] points
= { x1
+ getX(), y1
+ getY(), x2
+ getX(), y2
+ getY(), x3
+ getX(), y3
+ getY(), x4
+ getX(), y4
+ getY() };
724 context
.drawPolygon(points
);
729 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#drawFocus(org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC)
732 public void drawFocus(IGC context
) {
733 if ((startLifeline
!= endLifeline
) && (startEventOccurrence
== endEventOccurrence
)) {
734 context
.setLineStyle(context
.getLineDotStyle());
735 context
.setLineWidth(Metrics
.NORMAL_LINE_WIDTH
);
736 context
.setBackground(Frame
.getUserPref().getBackGroundColorSelection());
737 context
.setForeground(Frame
.getUserPref().getForeGroundColorSelection());
738 context
.drawFocus(getX(), getY() - 3, getWidth(), getHeight() + 6);
739 } else if ((startLifeline
== endLifeline
) && (startEventOccurrence
== endEventOccurrence
)) {
740 context
.drawFocus(getX(), getY() - 3, getWidth(), Metrics
.SYNC_INTERNAL_MESSAGE_HEIGHT
+ 6);
741 } else if ((startLifeline
!= endLifeline
) && (startEventOccurrence
!= endEventOccurrence
)) {
742 context
.setLineStyle(context
.getLineDotStyle());
743 context
.setLineWidth(Metrics
.NORMAL_LINE_WIDTH
);
744 context
.setBackground(Frame
.getUserPref().getBackGroundColor(ISDPreferences
.PREF_LIFELINE_HEADER
));
745 context
.setForeground(Frame
.getUserPref().getForeGroundColor(ISDPreferences
.PREF_LIFELINE_HEADER
));
746 drawRot(getX(), getY() - 5, getWidth(), 10, context
);
748 super.drawFocus(context
);