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