tmf.ui: Change the == operator with the equals() method
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / uml2sd / core / BaseMessage.java
CommitLineData
73005152 1/**********************************************************************
ed902a2b 2 * Copyright (c) 2005, 2014 IBM Corporation, Ericsson
73005152
BH
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
abbdd66a
AM
7 *
8 * Contributors:
c8422608
AM
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
73005152 11 **********************************************************************/
c8422608 12
2bdf0193 13package org.eclipse.tracecompass.tmf.ui.views.uml2sd.core;
73005152 14
2bdf0193
AM
15import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor;
16import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC;
17import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences;
18import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref;
73005152
BH
19
20/**
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
26 * property.<br>
27 * <br>
abbdd66a 28 *
73005152 29 * @see Lifeline Lifeline for more event occurence details
df0b8ff4 30 * @version 1.0
73005152
BH
31 * @author sveyrier
32 */
33public abstract class BaseMessage extends GraphNode {
abbdd66a 34
83dcfe09
MK
35 private static final int ARROW_LENGTH = 7;
36 private static final double ARROW_ANGLE = 0.75;
37 private static final Double ARROW_HEAD_Y = Double.valueOf(Math.sin(ARROW_ANGLE) * ARROW_LENGTH);
38 private static final Double ARROW_HEAD_X = Double.valueOf(Math.cos(ARROW_ANGLE) * ARROW_LENGTH);
df0b8ff4
BH
39 // ------------------------------------------------------------------------
40 // Attributes
41 // ------------------------------------------------------------------------
73005152
BH
42 /**
43 * The lifeline which send the message
44 */
cab6c8ff 45 private Lifeline fStartLifeline = null;
73005152
BH
46 /**
47 * The lifeline which receive the message
48 */
cab6c8ff 49 private Lifeline fEndLifeline = null;
df0b8ff4 50 /**
abbdd66a 51 * The visiblitiy flag.
df0b8ff4 52 */
cab6c8ff 53 private boolean fVisible = true;
73005152 54
df0b8ff4
BH
55 // ------------------------------------------------------------------------
56 // Methods
57 // ------------------------------------------------------------------------
11252342 58
73005152
BH
59 @Override
60 public int getX() {
61 // returns the exact x coordinate
62 return getX(false);
63 }
64
65 @Override
66 public int getY() {
67 /*
68 * Note: lifeline.getY() return the y coordinate of the top left corner of the rectangle which contain the
69 * lifeline name getHeight return the height of this rectangle The message y coordinate is then relative to this
70 * position depending of its eventOccurrence Space between syncMessages is constant
71 */
eb63f5ff 72 if ((fStartLifeline != null) && (fEndLifeline != null)) {
73005152
BH
73 /*
74 * Regular message, both ends are attached to a lifeline
75 */
cab6c8ff 76 return fEndLifeline.getY() + fEndLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence();
73005152 77
abbdd66a
AM
78 }
79 /*
80 * UML2 lost message kind
81 */
82 if (fStartLifeline != null) {
cab6c8ff 83 return fStartLifeline.getY() + fStartLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence();
abbdd66a 84 }
73005152 85
abbdd66a
AM
86 /*
87 * UML2 found message kind
88 */
89 if (fEndLifeline != null) {
cab6c8ff 90 return fEndLifeline.getY() + fEndLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence();
73005152
BH
91 }
92 // return 0 by default
93 return 0;
94 }
95
96 @Override
97 public int getWidth() {
98 // Returns the exact width
99 return getWidth(false);
100 }
101
102 @Override
103 public int getHeight() {
104 return 0;
105 }
106
107 /**
108 * Returns the graph node x coordinate.<br>
109 * Depending on the quick parameter a approximative or exact value is return.<br>
110 * The approximative value does not take into account if both message ends are connected to a Lifeline Execution
111 * Occurrence.<br>
112 * Execution occurrence on a lifeline increase the vertical line width which represent the lifeline, this directly
113 * affect the message x coordinate and width.<br>
114 * <br>
115 * This method is typically used to faster execute none graphical operation like tooltip lookup.<br>
116 * <br>
abbdd66a 117 *
73005152
BH
118 * @param quick true to get an approximative value<br>
119 * false to get the exact x value<br>
120 * @return the graph node x coordinate
121 */
122 protected int getX(boolean quick) {
123 int x = 0;
124 int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
eb63f5ff
BH
125 if ((fStartLifeline != null) && (fEndLifeline != null)) {
126 x = fStartLifeline.getX() + Metrics.getLifelineWidth() / 2;
73005152 127 } else {
eb63f5ff
BH
128 if (fStartLifeline != null) {
129 x = fStartLifeline.getX() + Metrics.getLifelineWidth() / 2;
73005152
BH
130 }
131
eb63f5ff
BH
132 if (fEndLifeline != null) {
133 x = fEndLifeline.getX() - Metrics.LIFELINE_SPACING / 2;
73005152
BH
134 }
135 }
136
df0b8ff4 137 if (quick) {
73005152 138 return x;
df0b8ff4 139 }
73005152 140
eb63f5ff 141 if ((fStartLifeline != null) && (fEndLifeline != null) && (fStartLifeline.getX() > fEndLifeline.getX())) {
73005152
BH
142 activationWidth = -activationWidth;
143 }
144
cab6c8ff 145 if (isMessageStartInActivation(getEndOccurrence())) {
73005152
BH
146 x = x + activationWidth;
147 }
148
149 return x;
150 }
151
152 /**
153 * Returns the graph node width.<br>
154 * Depending on the quick parameter a approximative or exact value is returned.<br>
155 * The approximative value does not take into account if both message ends are connected to a Lifeline Execution
156 * Occurrence.<br>
157 * Execution occurrence on a lifeline increase the vertical line width which represent the lifeline, this directly
158 * affect the message x coordinate and width.<br>
159 * <br>
160 * This method is typically used to faster execute none graphical operation like tooltip lookup.<br>
161 * <br>
abbdd66a 162 *
73005152
BH
163 * @param quick true to get an approximative value<br>
164 * false to get the exact x value
165 * @return the graph node width
166 */
167 protected int getWidth(boolean quick) {
168 int width = 0;
169 int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
eb63f5ff 170 if ((fStartLifeline != null) && (fEndLifeline != null)) {
d66dc232 171 if (fStartLifeline.equals(fEndLifeline)) {
73005152 172 width = Metrics.INTERNAL_MESSAGE_WIDTH + Metrics.EXECUTION_OCCURRENCE_WIDTH;
df0b8ff4 173 } else {
eb63f5ff 174 width = fEndLifeline.getX() + Metrics.getLifelineWidth() / 2 - getX(true);
df0b8ff4 175 }
73005152 176 } else {
eb63f5ff 177 if (fStartLifeline != null) {
73005152
BH
178 width = Metrics.swimmingLaneWidth() / 2;
179 }
eb63f5ff 180 if (fEndLifeline != null) {
73005152
BH
181 width = Metrics.swimmingLaneWidth() / 2;
182 }
183 }
184
df0b8ff4 185 if (quick) {
73005152 186 return width;
df0b8ff4 187 }
73005152 188
eb63f5ff 189 if ((fStartLifeline != null) && (fEndLifeline != null) && (fStartLifeline.getX() > fEndLifeline.getX())) {
73005152
BH
190 activationWidth = -activationWidth;
191 }
192
cab6c8ff 193 if (isMessageStartInActivation(getEndOccurrence())) {
73005152 194 width = width - activationWidth;
df0b8ff4 195 }
73005152 196
cab6c8ff 197 if (isMessageEndInActivation(getEndOccurrence())) {
73005152 198 width = width - activationWidth;
df0b8ff4 199 }
73005152
BH
200
201 return width;
202 }
203
204 @Override
205 public boolean isVisible(int x, int y, int width, int height) {
206 // ***Common*** syncMessages visibility
207 // draw the message only if at least one end is visible
eb63f5ff 208 if (fEndLifeline != null && (fEndLifeline.isVisible(x, y, width, height)) || (fStartLifeline != null && fStartLifeline.isVisible(x, y, width, height))) {
73005152 209 return true;
df0b8ff4 210 }
73005152 211 // In this case it can be a message which cross the whole visible area
eb63f5ff
BH
212 else if (fEndLifeline != null && (!fEndLifeline.isVisible(x, y, width, height)) && (fStartLifeline != null && !fStartLifeline.isVisible(x, y, width, height))) {
213 if (fEndLifeline.getX() > x + width && fStartLifeline.getX() < x) {
73005152 214 return true;
eb63f5ff 215 } else if (fStartLifeline.getX() > x + width && fEndLifeline.getX() < x) {
73005152 216 return true;
df0b8ff4 217 }
73005152
BH
218 }
219 return false;
220 }
221
df0b8ff4
BH
222 /**
223 * Sets the visibility value.
abbdd66a 224 *
df0b8ff4
BH
225 * @param value The visibility to set.
226 */
73005152 227 public void setVisible(boolean value) {
eb63f5ff 228 fVisible = value;
73005152
BH
229 }
230
df0b8ff4 231 /**
abbdd66a 232 * @return the visibility value.
df0b8ff4 233 */
73005152 234 public boolean isVisible() {
eb63f5ff 235 return fVisible;
73005152
BH
236 }
237
238 /**
239 * Set the lifeline from which this message has been sent.
abbdd66a 240 *
73005152
BH
241 * @param lifeline - the message sender
242 */
243 public void setStartLifeline(Lifeline lifeline) {
eb63f5ff 244 fStartLifeline = lifeline;
73005152
BH
245 }
246
247 /**
248 * Returns the lifeline from which this message has been sent.
abbdd66a 249 *
73005152
BH
250 * @return the message sender
251 */
252 public Lifeline getStartLifeline() {
eb63f5ff 253 return fStartLifeline;
73005152
BH
254 }
255
256 /**
257 * Returns the lifeline which has received this message.
abbdd66a 258 *
73005152
BH
259 * @return the message receiver
260 */
261 public Lifeline getEndLifeline() {
eb63f5ff 262 return fEndLifeline;
73005152
BH
263 }
264
265 /**
266 * Set the lifeline which has receive this message.
abbdd66a 267 *
73005152
BH
268 * @param lifeline the message receiver
269 */
270 public void setEndLifeline(Lifeline lifeline) {
eb63f5ff 271 fEndLifeline = lifeline;
73005152
BH
272 }
273
274 /**
275 * Set the event occurrence when this message occurs.<br>
abbdd66a 276 *
73005152
BH
277 * @param occurrence the event occurrence to assign to this message.<br>
278 * @see Lifeline Lifeline for more event occurence details
279 */
280 protected void setEventOccurrence(int occurrence) {
cab6c8ff 281 setEndOccurrence(occurrence);
73005152
BH
282 }
283
284 /**
285 * Returns the event occurence when is message occurs.<br>
abbdd66a 286 *
73005152
BH
287 * @return the event occurrence assigned to this message.<br>
288 * @see Lifeline Lifeline for more event occurence details
289 */
290 public int getEventOccurrence() {
cab6c8ff 291 return getEndOccurrence();
73005152
BH
292 }
293
294 /**
295 * Determines if the given eventOccurence occurs on a executionOccurence owned by the sending lifeline.<br>
296 * WARNING: this method will return a valid result only for execution occurrences which are visible in the View.<br>
297 * As consequence this method is only used for drawing purpose, especially to determine the exact message x
298 * coordinate and width.<br>
abbdd66a 299 *
73005152
BH
300 * @see BaseMessage#getX(boolean)
301 * @param event the event occurrence to test
302 * @return true if occurs on a execution occurrence owned by the sending lifeine, false otherwise
303 */
304 protected boolean isMessageStartInActivation(int event) {
305 boolean inActivation = false;
eb63f5ff 306 if ((fStartLifeline != null) && (fStartLifeline.getExecutions() != null)) {
73005152
BH
307 // int acIndex=startLifeline.getExecOccurrenceDrawIndex();
308 // acIndex = first visible execution occurrence
309 // for drawing speed reason with only search on the visivle subset
310 int thisY = getY();
eb63f5ff
BH
311 for (int i = 0; i < fStartLifeline.getExecutions().size(); i++) {
312 BasicExecutionOccurrence toDraw = (BasicExecutionOccurrence) fStartLifeline.getExecutions().get(i);
cab6c8ff 313 if ((event >= toDraw.getStartOccurrence()) && (event <= toDraw.getEndOccurrence())) {
73005152 314 inActivation = true;
df0b8ff4 315 }
73005152
BH
316 // if we are outside the visible area we stop right now
317 // This works because execution occurrences are ordered along the Y axis
df0b8ff4 318 if (toDraw.getY() > thisY) {
73005152 319 break;
df0b8ff4 320 }
73005152
BH
321 }
322 }
323 return inActivation;
324 }
325
326 /**
327 * Determines if the given event occurrence occurs on a execution occurrence owned by the receiving lifeline.<br>
328 * WARNING: this method will return a valid result only for execution occurrences which are visible in the View.<br>
329 * As consequence this method is only used for drawing purpose, especially to determine the exact message x
330 * coordinate and width.<br>
abbdd66a 331 *
73005152
BH
332 * @see BaseMessage#getX(boolean)
333 * @param event the event occurrence to test
334 * @return true if occurs on a execution occurrence owned by the receiving lifeline, false otherwise
335 */
336 protected boolean isMessageEndInActivation(int event) {
337 boolean inActivation = false;
eb63f5ff 338 if ((fEndLifeline != null) && (fEndLifeline.getExecutions() != null)) {
73005152
BH
339 // acIndex = first visible execution occurrence
340 // for drawing speed reason with only search on the visivle subset
eb63f5ff
BH
341 for (int i = 0; i < fEndLifeline.getExecutions().size(); i++) {
342 BasicExecutionOccurrence toDraw = (BasicExecutionOccurrence) fEndLifeline.getExecutions().get(i);
cab6c8ff 343 if ((event >= toDraw.getStartOccurrence()) && (event <= toDraw.getEndOccurrence())) {
73005152 344 inActivation = true;
df0b8ff4 345 }
73005152
BH
346 // if we are outside the visible area we stop right now
347 // This works because execution occurrences are ordered along the Y axis
df0b8ff4 348 if (toDraw.getY() > getY()) {
73005152 349 break;
df0b8ff4 350 }
73005152
BH
351 }
352 }
353 return inActivation;
354 }
355
73005152 356 @Override
eb63f5ff 357 public boolean contains(int xValue, int yValue) {
73005152
BH
358 int x = getX();
359 int y = getY();
360 int width = getWidth();
361 int height = getHeight();
362
363 // Used to create a rectangle which contains the message label to allow selection when clicking the label
364 int tempHeight = Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth();
365
366 // Is it a self message?
d66dc232 367 if (fStartLifeline.equals(fEndLifeline)) {
73005152
BH
368 /*
369 * Rectangle.contains(x,y, width, height) does not works with negative height or width We check here if the
370 * rectangle width is negative.
371 */
372 if (getName().length() * Metrics.getAverageCharWidth() > Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2 + -Metrics.INTERNAL_MESSAGE_WIDTH) {
abbdd66a 373 if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH + 10, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2 + -Metrics.INTERNAL_MESSAGE_WIDTH, Metrics.getMessageFontHeigth(), xValue, yValue)) {
73005152 374 return true;
df0b8ff4 375 }
73005152 376 } else {
abbdd66a 377 if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH + 10, y, getName().length() * Metrics.getAverageCharWidth(), Metrics.getMessageFontHeigth(), xValue, yValue)) {
73005152 378 return true;
df0b8ff4 379 }
73005152
BH
380 }
381
382 // Test if the point is in part 1 of the self message
383 // see: "private void drawMessage (NGC context)" method for self message drawing schema
abbdd66a 384 if (GraphNode.contains(x, y - Metrics.MESSAGE_SELECTION_TOLERANCE / 2, Metrics.INTERNAL_MESSAGE_WIDTH / 2, Metrics.MESSAGE_SELECTION_TOLERANCE, xValue, yValue)) {
73005152 385 return true;
df0b8ff4 386 }
73005152
BH
387
388 // Test if the point is in part 3 of the self message
abbdd66a 389 if (GraphNode.contains(x + Metrics.INTERNAL_MESSAGE_WIDTH - Metrics.MESSAGE_SELECTION_TOLERANCE / 2, y, Metrics.MESSAGE_SELECTION_TOLERANCE, height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, xValue, yValue)) {
73005152 390 return true;
df0b8ff4 391 }
73005152
BH
392
393 // Test if the point is in part 5 of the self message
abbdd66a 394 if (GraphNode.contains(x, y + height - Metrics.MESSAGE_SELECTION_TOLERANCE / 2 + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, Metrics.INTERNAL_MESSAGE_WIDTH / 2, Metrics.MESSAGE_SELECTION_TOLERANCE, xValue, yValue)) {
73005152 395 return true;
df0b8ff4 396 }
73005152
BH
397
398 // false otherwise
399 return false;
400 }
abbdd66a 401 if (GraphNode.contains(x, y - tempHeight, width, tempHeight, xValue, yValue)) {
73005152 402 return true;
df0b8ff4 403 }
73005152
BH
404 // false otherwise
405 return false;
406 }
407
df0b8ff4
BH
408 /**
409 * Method to draw the message using the graphical context.
abbdd66a 410 *
df0b8ff4
BH
411 * @param context A graphical context to draw in.
412 */
73005152 413 protected void drawMessage(IGC context) {
cab6c8ff
BH
414 int fX = 0;
415 int fY = 0;
416 int fW = 0;
417 int fH = 0;
73005152 418
3145ec83 419 // temporary store the coordinates to avoid more methods calls
73005152
BH
420 int x = getX();
421 int y = getY();
422 int width = getWidth();
423 int height = getHeight();
424
3145ec83
BH
425 ISDPreferences pref = SDViewPref.getInstance();
426
73005152
BH
427 // UML2 found message (always drawn from left to right)
428 // or UML2 lost message (always drawn from left to right)
d66dc232 429 if ((fStartLifeline == null || fEndLifeline == null) && !fStartLifeline.equals(fEndLifeline)) {
73005152
BH
430 // Draw the message label above the message and centered
431 // The label is truncated if it cannot fit between the two message end
432 // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label
433 IColor temp = context.getForeground();
cab6c8ff 434 context.setForeground(pref.getFontColor(getColorPrefId()));
73005152
BH
435 context.drawTextTruncatedCentred(getName(), x, y - Metrics.getMessageFontHeigth() - 2 * Metrics.MESSAGES_NAME_SPACING, width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected());
436 context.setForeground(temp);
437 int margin = 0;
eb63f5ff 438 if (fEndLifeline == null) {
73005152 439 margin = Metrics.MESSAGE_CIRCLE_RAY;
df0b8ff4 440 }
73005152
BH
441
442 // Draw the message main line
443 context.drawLine(x, y, x + width, y + height);
444 // Draw the two little lines which make a arrow part of the message
83dcfe09
MK
445 Double xt = ARROW_HEAD_X;
446 Double yt = ARROW_HEAD_Y;
73005152
BH
447 if (context.getLineStyle() == context.getLineSolidStyle()) {
448 IColor backcolor = context.getBackground();
449 context.setBackground(context.getForeground());
450 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 };
451 context.fillPolygon(points);
452 context.drawPolygon(points);
453 context.setBackground(backcolor);
454 } else {
455 int currentStyle = context.getLineStyle();
456 int currentWidth = context.getLineWidth();
457 context.setLineWidth(currentWidth + 2);
458 context.setLineStyle(context.getLineSolidStyle());
459 context.drawLine(x + width - xt.intValue() - margin, y + height - yt.intValue(), x + width - margin, y + height);
460 context.drawLine(x + width - xt.intValue() - margin, y + height + yt.intValue(), x + width - margin, y + height);
461 context.setLineStyle(currentStyle);
462 context.setLineWidth(currentWidth);
463 }
464 IColor storedColor = context.getBackground();
465 context.setBackground(context.getForeground());
466
467 // Draw a circle at the message end (endLifeline side)
468 int ray = Metrics.MESSAGE_CIRCLE_RAY;
df0b8ff4 469 if (context.getLineWidth() != Metrics.NORMAL_LINE_WIDTH) {
73005152 470 ray = ray + Metrics.SELECTION_LINE_WIDTH - Metrics.NORMAL_LINE_WIDTH;
df0b8ff4 471 }
eb63f5ff 472 if (fStartLifeline == null) {
73005152 473 context.fillOval(x - ray, y - ray, ray * 2, ray * 2);
df0b8ff4 474 } else {
73005152 475 context.fillOval(x + width - ray, y + height - ray, ray * 2, ray * 2);
df0b8ff4 476 }
73005152 477 context.setBackground(storedColor);
cab6c8ff 478 context.setForeground(pref.getFontColor(getColorPrefId()));
73005152
BH
479 fX = x;
480 fY = y - yt.intValue();
481 fW = width;
482 fH = height + 2 * yt.intValue();
483 }
484 // it is self message (always drawn at the left side of the owning lifeLifeline)
d66dc232 485 else if (fStartLifeline != null && fEndLifeline != null && fStartLifeline.equals(fEndLifeline)) {
73005152
BH
486 /*
487 * Self syncMessages are drawn in 5 parts 1 -----------+ + 2 + | | | 3 | + 5 + 4 -----------+
488 */
489 int tempy = Metrics.INTERNAL_MESSAGE_WIDTH / 2;
df0b8ff4 490 if (Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT <= Metrics.INTERNAL_MESSAGE_WIDTH) {
73005152 491 tempy = Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT / 2;
df0b8ff4 492 }
73005152
BH
493
494 // Part 1
495 context.drawLine(x, y, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y);
496 // Part 3
497 context.drawLine(x + Metrics.INTERNAL_MESSAGE_WIDTH, y + tempy, x + Metrics.INTERNAL_MESSAGE_WIDTH, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - tempy);
498 // Part 5
499 context.drawLine(x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT);
500
83dcfe09
MK
501 Double xt = ARROW_HEAD_X;
502 Double yt = ARROW_HEAD_Y;
73005152
BH
503
504 fX = x;
505 fY = y;
506 fW = Metrics.INTERNAL_MESSAGE_WIDTH;
507 fH = height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT;
508
509 // Draw the two little lines which make a arrow part of the message
510 if (context.getLineStyle() == context.getLineSolidStyle()) {
511 IColor backcolor = context.getBackground();
512 context.setBackground(context.getForeground());
513 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(),
514 y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT };
515 context.fillPolygon(points);
516 context.drawPolygon(points);
517 context.setBackground(backcolor);
518 } else {
519 int currentStyle = context.getLineStyle();
520 int currentWidth = context.getLineWidth();
521 context.setLineWidth(currentWidth + 2);
522 context.setLineStyle(context.getLineSolidStyle());
523 context.drawLine(x + xt.intValue(), y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT + yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT);
524 context.drawLine(x + xt.intValue(), y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT - yt.intValue(), x, y + height + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT);
525 context.setLineStyle(currentStyle);
526 context.setLineWidth(currentWidth);
527 }
528
529 // Part 2
530 context.drawArc(x, y, Metrics.INTERNAL_MESSAGE_WIDTH, 2 * tempy, 0, 90);
531 // Part 4
532 context.drawArc(x, y + Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT, Metrics.INTERNAL_MESSAGE_WIDTH, -2 * tempy, 0, -90);
533
534 // Draw the message label above the message and centered
535 // The label is truncated if it cannot fit between the two message end
536 // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label
537
538 // the space available for the text is sorter if are drawing internal message on the last lifeline
cab6c8ff 539 context.setForeground(pref.getFontColor(getColorPrefId()));
eb63f5ff 540 if (fStartLifeline.getIndex() == fStartLifeline.getFrame().getHorizontalIndex()) {
73005152
BH
541 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
542 - Metrics.getMessageFontHeigth(), !isSelected());
df0b8ff4 543 } else {
73005152
BH
544 context.drawTextTruncated(getName(), x + width + Metrics.INTERNAL_MESSAGE_V_MARGIN / 2, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH,
545 +Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), !isSelected());
df0b8ff4 546 }
73005152
BH
547 }
548 // it is regular message
eb63f5ff 549 else if (fStartLifeline != null && fEndLifeline != null) {
73005152
BH
550 // Draw the message main line
551 context.drawLine(x, y, x + width, y + height);
552
eb63f5ff 553 int spaceBTWStartEnd = fEndLifeline.getX() - fStartLifeline.getX();
73005152
BH
554
555 double a = height;
556 double b = width;
557 double angle = Math.atan(a / b);
558 // Compute the coordinates of the two little lines which make the arrow part of the message
559 int sign = 1;
df0b8ff4 560 if (spaceBTWStartEnd < 0) {
73005152 561 sign = -1;
df0b8ff4 562 }
83dcfe09
MK
563 Double x1 = Double.valueOf(sign * Math.cos(angle - ARROW_ANGLE) * ARROW_LENGTH);
564 Double y1 = Double.valueOf(sign * Math.sin(angle - ARROW_ANGLE) * ARROW_LENGTH);
565 Double x2 = Double.valueOf(sign * Math.cos(angle + ARROW_ANGLE) * ARROW_LENGTH);
566 Double y2 = Double.valueOf(sign * Math.sin(angle + ARROW_ANGLE) * ARROW_LENGTH);
73005152
BH
567
568 fX = getX();
569 fY = y + height - y2.intValue();
570 fW = getWidth();
571 fH = y2.intValue() - y1.intValue() + 1;
572 if (fW < 0) {
573 fW = -fW;
574 fX = fX - fW;
575 }
576
577 if (fH < 0) {
578 fH = -fH;
579 fY = fY - fH;
580 }
581
582 // Draw the two little lines which make a arrow part of the message
583 if (context.getLineStyle() == context.getLineSolidStyle()) {
584 IColor backcolor = context.getBackground();
585 context.setBackground(context.getForeground());
586 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() };
587 context.fillPolygon(points);
588 context.drawPolygon(points);
589 context.setBackground(backcolor);
590 } else {
591 int currentStyle = context.getLineStyle();
592 int currentWidth = context.getLineWidth();
593 context.setLineWidth(currentWidth + 2);
594 context.setLineStyle(context.getLineSolidStyle());
595 context.drawLine(x + width - x1.intValue(), y + height - y1.intValue(), x + width, y + height);
596 context.drawLine(x + width - x2.intValue(), y + height - y2.intValue(), x + width, y + height);
597 context.setLineStyle(currentStyle);
598 context.setLineWidth(currentWidth);
599 }
600
601 // Draw the message label above the message and centered
602 // The label is truncated if it cannot fit between the two message end
603 // 2*Metrics.MESSAGES_NAME_SPACING = space above the label + space below the label
cab6c8ff 604 context.setForeground(pref.getFontColor(getColorPrefId()));
df0b8ff4 605 if (spaceBTWStartEnd > 0) {
73005152 606 context.drawTextTruncatedCentred(getName(), x, y + height / 2 - (2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()), width, 2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth(), !isSelected());
df0b8ff4 607 } else {
73005152 608 context.drawTextTruncatedCentred(getName(), x + width, y + height / 2 - (2 * Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()), -width, 2 * Metrics.MESSAGES_NAME_SPACING + +Metrics.getMessageFontHeigth(), !isSelected());
df0b8ff4 609 }
73005152
BH
610 }
611 }
abbdd66a 612
73005152
BH
613 @Override
614 public void draw(IGC context) {
df0b8ff4 615 if (!isVisible()) {
73005152 616 return;
df0b8ff4 617 }
abbdd66a 618
73005152
BH
619 // Draw it selected?*/
620 if (isSelected()) {
3145ec83 621 ISDPreferences pref = SDViewPref.getInstance();
73005152
BH
622 /*
623 * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection
624 * colors This create the highlight effect
625 */
3145ec83 626 context.setForeground(pref.getBackGroundColorSelection());
73005152
BH
627 context.setLineWidth(Metrics.SELECTION_LINE_WIDTH);
628 drawMessage(context);
3145ec83
BH
629 context.setBackground(pref.getBackGroundColorSelection());
630 context.setForeground(pref.getForeGroundColorSelection());
73005152
BH
631 // Second drawing is done after
632 }
633 context.setLineWidth(Metrics.NORMAL_LINE_WIDTH);
634 if (hasFocus()) {
635 context.setDrawTextWithFocusStyle(true);
636 }
637 drawMessage(context);
638 int oldStyle = context.getLineStyle();
639 if (hasFocus()) {
640 context.setDrawTextWithFocusStyle(false);
641 drawFocus(context);
642 }
643 // restore the context
644 context.setLineStyle(oldStyle);
645 }
646
647 /**
648 * Determine if two messages are identical. This default implementation considers that overlapping messages with
649 * same coordinates are identical.
abbdd66a 650 *
73005152
BH
651 * @param message - the message to compare with
652 * @return true if identical false otherwise
abbdd66a 653 *
2bdf0193 654 * @see org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode#isSameAs(org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode)
73005152
BH
655 */
656 @Override
657 public boolean isSameAs(GraphNode message) {
df0b8ff4 658 if (message == null) {
73005152 659 return false;
df0b8ff4
BH
660 }
661 if (!(message instanceof BaseMessage)) {
73005152 662 return super.isSameAs(message);
df0b8ff4 663 }
eb63f5ff 664 return ((getX() == message.getX()) && (getY() == message.getY()) && (getWidth() == message.getWidth()) && (getHeight() == message.getHeight()));
73005152
BH
665 }
666
df0b8ff4
BH
667 /**
668 * Method drawRot.
abbdd66a 669 *
df0b8ff4
BH
670 * @param x A x coordinate
671 * @param y A y coordinate
672 * @param w A width
673 * @param h A height
674 * @param context A graphical context
675 */
73005152
BH
676 public void drawRot(int x, int y, int w, int h, IGC context) {
677 double angleA = Math.atan2(getHeight(), getWidth());
678 double cosA = Math.cos(angleA);
679 double sinA = Math.sin(angleA);
680
681 int gx = getX();
682 int gy = getY();
683
eb63f5ff
BH
684 int localHeight = h;
685 localHeight = localHeight / 2;
73005152
BH
686
687 double cw = Math.sqrt(w * w + getHeight() * getHeight());
688
689 int x1 = Math.round((float) ((x - gx) * cosA - (y - gy) * sinA));
690 int y1 = Math.round((float) ((x - gx) * sinA + (y - gy) * cosA));
691
692 int x2 = Math.round((float) (cw * cosA - (y - gy) * sinA));
693 int y2 = Math.round((float) (cw * sinA + (y - gy) * cosA));
694
eb63f5ff
BH
695 int x3 = Math.round((float) (cw * cosA - (localHeight) * sinA));
696 int y3 = Math.round((float) (cw * sinA + (localHeight) * cosA));
73005152 697
eb63f5ff
BH
698 int x4 = Math.round((float) ((x - gx) * cosA - (localHeight) * sinA));
699 int y4 = Math.round((float) ((x - gx) * sinA + (localHeight) * cosA));
73005152
BH
700
701 int[] points = { x1 + getX(), y1 + getY(), x2 + getX(), y2 + getY(), x3 + getX(), y3 + getY(), x4 + getX(), y4 + getY() };
702 context.drawPolygon(points);
703 }
704
705 @Override
706 public void drawFocus(IGC context) {
3145ec83
BH
707
708 ISDPreferences pref = SDViewPref.getInstance();
709
d66dc232 710 if ((!fStartLifeline.equals(fEndLifeline)) && (getStartOccurrence() == getEndOccurrence())) {
73005152
BH
711 context.setLineStyle(context.getLineDotStyle());
712 context.setLineWidth(Metrics.NORMAL_LINE_WIDTH);
3145ec83
BH
713 context.setBackground(pref.getBackGroundColorSelection());
714 context.setForeground(pref.getForeGroundColorSelection());
73005152 715 context.drawFocus(getX(), getY() - 3, getWidth(), getHeight() + 6);
cab6c8ff 716 } else if ((fStartLifeline == fEndLifeline) && (getStartOccurrence() == getEndOccurrence())) {
73005152 717 context.drawFocus(getX(), getY() - 3, getWidth(), Metrics.SYNC_INTERNAL_MESSAGE_HEIGHT + 6);
d66dc232 718 } else if ((!fStartLifeline.equals(fEndLifeline)) && (getStartOccurrence() != getEndOccurrence())) {
73005152
BH
719 context.setLineStyle(context.getLineDotStyle());
720 context.setLineWidth(Metrics.NORMAL_LINE_WIDTH);
3145ec83
BH
721 context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE_HEADER));
722 context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE_HEADER));
73005152 723 drawRot(getX(), getY() - 5, getWidth(), 10, context);
df0b8ff4 724 } else {
73005152 725 super.drawFocus(context);
df0b8ff4 726 }
73005152
BH
727 }
728}
This page took 0.12992 seconds and 5 git commands to generate.