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