Remove all existing @since annotations
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / uml2sd / core / AsyncMessage.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
013a5f1c
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
BH
14
15import java.util.Comparator;
16
2bdf0193
AM
17import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
18import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
19import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IGC;
20import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.ISDPreferences;
21import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref;
22import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.SortAsyncForBackward;
23import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.SortAsyncMessageComparator;
73005152
BH
24
25/**
26 * A AsyncMessage is a asynchronous message which appear at two different event occurrences on each lifeline ends (sender
27 * and receiver).<br>
28 * <br>
29 * <br>
30 * Usage example:
013a5f1c 31 *
73005152
BH
32 * <pre>
33 * Frame frame;
34 * Lifeline lifeLine1;
35 * Lifeline lifeLine2;
013a5f1c 36 *
73005152
BH
37 * AsyncMessage message = new AsyncMessage();
38 * // Create a new event occurrence on each lifeline
39 * lifeline1.getNewOccurrenceIndex();
40 * lifeline2.getNewOccurrenceIndex();
41 * // Set the message sender and receiver
42 * message.setStartLifeline(lifeLine1);
43 * message.setEndLifline(lifeline2);
44 * message.setName(&quot;Message label&quot;);
45 * // add the message to the frame
46 * frame.addMessage(message);
47 * </pre>
013a5f1c 48 *
73005152 49 * @see Lifeline Lifeline for more event occurence details
013a5f1c 50 * @version 1.0
73005152 51 * @author sveyrier
73005152
BH
52 */
53public class AsyncMessage extends BaseMessage implements ITimeRange {
54
df0b8ff4
BH
55 // ------------------------------------------------------------------------
56 // Constants
57 // ------------------------------------------------------------------------
58 /**
59 * The grahNode ID constant
60 */
61 public static final String ASYNC_MESS_TAG = "AsyncMessage"; //$NON-NLS-1$
62
63 // ------------------------------------------------------------------------
64 // Attributes
65 // ------------------------------------------------------------------------
66 /**
67 * Flag whether message has time information or not.
68 */
cab6c8ff 69 private boolean fHasTime = false;
73005152
BH
70 /**
71 * The time when the message begin
72 */
cab6c8ff 73 private ITmfTimestamp fEndTime = new TmfTimestamp();
73005152
BH
74 /**
75 * The time when the message end
76 */
cab6c8ff 77 private ITmfTimestamp fStartTime = new TmfTimestamp();
73005152
BH
78 /**
79 * The associated message.
80 */
eb63f5ff 81 protected AsyncMessageReturn fMessageReturn = null;
73005152 82
df0b8ff4
BH
83 // ------------------------------------------------------------------------
84 // Constructors
85 // ------------------------------------------------------------------------
86 /**
87 * Default constructor
88 */
73005152 89 public AsyncMessage() {
cab6c8ff 90 setColorPrefId(ISDPreferences.PREF_ASYNC_MESS);
73005152
BH
91 }
92
df0b8ff4
BH
93 // ------------------------------------------------------------------------
94 // Methods
95 // ------------------------------------------------------------------------
11252342 96
73005152
BH
97 @Override
98 public int getX() {
99 int x = super.getX(true);
100 int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
cab6c8ff 101 if ((getStartLifeline() != null) && (getEndLifeline() != null) && (getStartLifeline().getX() > getEndLifeline().getX())) {
73005152
BH
102 activationWidth = -activationWidth;
103 }
104
cab6c8ff 105 if (isMessageStartInActivation(getStartOccurrence())) {
73005152
BH
106 x = x + activationWidth;
107 }
108 return x;
109 }
013a5f1c 110
73005152
BH
111 @Override
112 public int getY() {
cab6c8ff
BH
113 if ((getStartLifeline() != null) && (getEndLifeline() != null)) {
114 return getEndLifeline().getY() + getEndLifeline().getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getStartOccurrence();
73005152
BH
115 }
116 return super.getY();
117 }
118
119 @Override
120 public int getWidth() {
121 int width = super.getWidth(true);
122 int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
cab6c8ff 123 if ((getStartLifeline() != null) && (getEndLifeline() != null) && (getStartLifeline().getX() > getEndLifeline().getX())) {
73005152
BH
124 activationWidth = -activationWidth;
125 }
126
cab6c8ff 127 if (isMessageStartInActivation(getStartOccurrence())) {
73005152 128 width = width - activationWidth;
df0b8ff4 129 }
73005152 130
cab6c8ff 131 if (isMessageEndInActivation(getEndOccurrence())) {
73005152 132 width = width - activationWidth;
df0b8ff4 133 }
73005152
BH
134
135 return width;
136 }
137
138 @Override
139 public int getHeight() {
cab6c8ff
BH
140 if ((getStartLifeline() != null) && (getEndLifeline() != null)) {
141 return (getEndLifeline().getY() + getEndLifeline().getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * getEndOccurrence()) - getY();
73005152
BH
142 }
143 return super.getHeight();
144 }
145
146 /**
147 * Set the message return associated with this message.
013a5f1c 148 *
73005152
BH
149 * @param message the message return to associate
150 */
151 protected void setMessageReturn(AsyncMessageReturn message) {
eb63f5ff 152 fMessageReturn = message;
73005152
BH
153 }
154
155 /**
156 * Set the event occurrence attached to this message for its end lifeline
013a5f1c 157 *
73005152
BH
158 * @param occurrence the event occurrence to set
159 */
cab6c8ff 160 @Override
73005152 161 public void setEndOccurrence(int occurrence) {
cab6c8ff 162 super.setEndOccurrence(occurrence);
df0b8ff4 163 if (getStartLifeline() == null) {
cab6c8ff 164 setStartOccurrence(occurrence);
df0b8ff4 165 }
73005152
BH
166 informFrame(getEndLifeline(), occurrence);
167 }
168
df0b8ff4
BH
169 /**
170 * Informs the given lifeline about the maximum occurrence if applicable.
013a5f1c 171 *
df0b8ff4 172 * @param lifeLine
a0a88f65 173 * Concerned lifeline
df0b8ff4 174 * @param occurrence
a0a88f65 175 * Occurrence number
df0b8ff4 176 */
73005152 177 protected void informFrame(Lifeline lifeLine, int occurrence) {
df0b8ff4
BH
178 if ((lifeLine != null) && (lifeLine.getFrame() != null) && (lifeLine.getFrame().getMaxEventOccurrence() < occurrence)) {
179 lifeLine.getFrame().setMaxEventOccurrence(occurrence);
180 }
73005152
BH
181 }
182
183 /**
184 * Set the event occurrence attached to this message for its start lifeline
013a5f1c 185 *
73005152
BH
186 * @param occurrence the event occurrence to set
187 */
cab6c8ff 188 @Override
73005152 189 public void setStartOccurrence(int occurrence) {
cab6c8ff 190 super.setStartOccurrence(occurrence);
df0b8ff4 191 if (getEndLifeline() == null) {
cab6c8ff 192 setEndOccurrence(getStartOccurrence());
df0b8ff4 193 }
73005152
BH
194 informFrame(getStartLifeline(), occurrence);
195 }
196
197 /**
198 * Set the lifeLine which has sent the message.<br>
199 * A new EventOccurence will be create on this lifeLine.<br>
013a5f1c 200 *
73005152 201 * @param lifeline the message sender
73005152
BH
202 */
203 public void autoSetStartLifeline(Lifeline lifeline) {
204 lifeline.getNewEventOccurrence();
205 setStartLifeline(lifeline);
206 }
207
208 /**
209 * Set the lifeLine which has received the message.<br>
210 * A new EventOccurence will be create on this lifeLine.<br>
013a5f1c 211 *
73005152 212 * @param lifeline the message receiver
73005152
BH
213 */
214 public void autoSetEndLifeline(Lifeline lifeline) {
215 lifeline.getNewEventOccurrence();
216 setEndLifeline(lifeline);
217 }
218
73005152
BH
219 @Override
220 public void setStartLifeline(Lifeline lifeline) {
221 super.setStartLifeline(lifeline);
222 setStartOccurrence(getStartLifeline().getEventOccurrence());
df0b8ff4 223 if (getEndLifeline() == null) {
cab6c8ff 224 setEndOccurrence(getStartOccurrence());
df0b8ff4 225 }
73005152
BH
226 }
227
73005152
BH
228 @Override
229 public void setEndLifeline(Lifeline lifeline) {
230 super.setEndLifeline(lifeline);
231 setEventOccurrence(getEndLifeline().getEventOccurrence());
232 }
233
234 /**
235 * Returns true if the point C is on the segment defined with the point A and B
013a5f1c 236 *
73005152
BH
237 * @param xA point A x coordinate
238 * @param yA point A y coordinate
239 * @param xB point B x coordinate
240 * @param yB point B y coordinate
241 * @param xC point C x coordinate
242 * @param yC point C y coordinate
243 * @return Return true if the point C is on the segment defined with the point A and B, else otherwise
244 */
245 protected boolean isNearSegment(int xA, int yA, int xB, int yB, int xC, int yC) {
df0b8ff4 246 if ((xA > xB) && (xC > xA)) {
73005152 247 return false;
df0b8ff4
BH
248 }
249 if ((xA < xB) && (xC > xB)) {
73005152 250 return false;
df0b8ff4
BH
251 }
252 if ((xA < xB) && (xC < xA)) {
73005152 253 return false;
df0b8ff4
BH
254 }
255 if ((xA > xB) && (xC < xB)) {
73005152 256 return false;
df0b8ff4 257 }
73005152
BH
258 double distAB = Math.sqrt((xB - xA) * (xB - xA) + (yB - yA) * (yB - yA));
259 double scalar = ((xB - xA) * (xC - xA) + (yB - yA) * (yC - yA)) / distAB;
260 double distAC = Math.sqrt((xC - xA) * (xC - xA) + (yC - yA) * (yC - yA));
261 double distToSegment = Math.sqrt(Math.abs(distAC * distAC - scalar * scalar));
df0b8ff4 262 if (distToSegment <= Metrics.MESSAGE_SELECTION_TOLERANCE) {
73005152 263 return true;
df0b8ff4 264 }
73005152
BH
265 return false;
266 }
267
268 @Override
269 public boolean contains(int x, int y) {
270 // Is it a self message?
cab6c8ff 271 if (getStartLifeline() == getEndLifeline()) {
73005152
BH
272 return super.contains(x, y);
273 }
013a5f1c 274 if (isNearSegment(getX(), getY(), getX() + getWidth(), getY() + getHeight(), x, y)) {
73005152 275 return true;
013a5f1c 276 }
73005152
BH
277 int messageMaxWidth = Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH;
278 int nameWidth = getName().length() * Metrics.getAverageCharWidth();
279 if (getName().length() * Metrics.getAverageCharWidth() > messageMaxWidth) {
abbdd66a 280 if (GraphNode.contains(getX(), getY() - Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), messageMaxWidth, Metrics.getMessageFontHeigth(), x, y)) {
73005152 281 return true;
df0b8ff4 282 }
73005152 283 } else {
abbdd66a 284 if (GraphNode.contains(getX() + (messageMaxWidth - nameWidth) / 2, getY() + getHeight() / 2 - Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), nameWidth, Metrics.getMessageFontHeigth(), x, y)) {
73005152 285 return true;
df0b8ff4 286 }
73005152
BH
287 }
288 return false;
289 }
290
df0b8ff4
BH
291 /**
292 * Draws the asynchronous message using giving graphical context.
013a5f1c 293 *
df0b8ff4
BH
294 * @param context A graphical context to draw in.
295 */
73005152 296 protected void drawAsyncMessage(IGC context) {
cab6c8ff 297 if (getStartLifeline() != null && getEndLifeline() != null && getStartLifeline() == getEndLifeline() && (getStartOccurrence() != getEndOccurrence())) {
73005152
BH
298 int x = getX();
299 int y = getY();
300 int height = getHeight();
301 int tempx = 0;
cab6c8ff
BH
302 boolean startInActivation = isMessageStartInActivation(getStartOccurrence());
303 boolean endInActivation = isMessageEndInActivation(getEndOccurrence());
73005152 304
df0b8ff4 305 if (endInActivation && !startInActivation) {
73005152 306 tempx = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
df0b8ff4
BH
307 }
308 if (startInActivation && !endInActivation) {
73005152 309 tempx = -Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
df0b8ff4 310 }
73005152
BH
311
312 int tempy = Metrics.INTERNAL_MESSAGE_WIDTH / 2;
df0b8ff4 313 if (getHeight() <= Metrics.INTERNAL_MESSAGE_WIDTH) {
73005152 314 tempy = getHeight() / 2;
df0b8ff4 315 }
73005152
BH
316
317 context.drawLine(x, y, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y);
318 context.drawLine(x + Metrics.INTERNAL_MESSAGE_WIDTH, y + tempy, x + Metrics.INTERNAL_MESSAGE_WIDTH, y + height - tempy);
319 context.drawLine(x + tempx, y + height, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y + height);
320
eb63f5ff
BH
321 Double xt = Double.valueOf(Math.cos(0.75) * 7);
322 Double yt = Double.valueOf(Math.sin(0.75) * 7);
73005152
BH
323
324 context.drawLine(x + xt.intValue() + tempx, y + height + yt.intValue(), x + tempx, y + height);
325 context.drawArc(x, y, Metrics.INTERNAL_MESSAGE_WIDTH, 2 * tempy, 0, 90);
326 context.drawArc(x, y + height, Metrics.INTERNAL_MESSAGE_WIDTH, -2 * tempy, 0, -90);
327 context.drawLine(x + xt.intValue() + tempx, y + height - yt.intValue(), x + tempx, y + height);
328
329 context.drawTextTruncated(getName(), x + Metrics.INTERNAL_MESSAGE_WIDTH + Metrics.INTERNAL_MESSAGE_V_MARGIN, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH,
330 +Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), !isSelected());
df0b8ff4 331 } else {
73005152 332 super.draw(context);
df0b8ff4 333 }
73005152
BH
334 }
335
73005152
BH
336 @Override
337 public void draw(IGC context) {
df0b8ff4 338 if (!isVisible()) {
73005152 339 return;
df0b8ff4 340 }
3145ec83
BH
341
342 ISDPreferences pref = SDViewPref.getInstance();
343
73005152 344 // Draw it selected?
cab6c8ff 345 if (isSelected() && (getStartLifeline() != null && getEndLifeline() != null && getStartLifeline() == getEndLifeline() && (getStartOccurrence() != getEndOccurrence()))) {
73005152
BH
346 /*
347 * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection
348 * colors This create the highlight effect
349 */
3145ec83 350 context.setForeground(pref.getBackGroundColorSelection());
73005152
BH
351 context.setLineWidth(Metrics.SELECTION_LINE_WIDTH);
352 drawAsyncMessage(context);
3145ec83
BH
353 context.setBackground(pref.getBackGroundColorSelection());
354 context.setForeground(pref.getForeGroundColorSelection());
73005152
BH
355 // Second drawing is done after the else
356 } else {
cab6c8ff
BH
357 context.setBackground(pref.getBackGroundColor(getColorPrefId()));
358 context.setForeground(pref.getForeGroundColor(getColorPrefId()));
73005152
BH
359 }
360 if (hasFocus()) {
361 context.setDrawTextWithFocusStyle(true);
362 }
363 context.setLineWidth(Metrics.NORMAL_LINE_WIDTH);
364 drawAsyncMessage(context);
365 if (hasFocus()) {
366 context.setDrawTextWithFocusStyle(false);
367 }
368 }
369
370 /**
371 * Set the time when the message end
013a5f1c 372 *
73005152
BH
373 * @param time the time when the message end
374 */
4df4581d 375 public void setEndTime(ITmfTimestamp time) {
4593bd5b 376 fEndTime = time;
eb63f5ff 377 fHasTime = true;
df0b8ff4 378 if (getStartLifeline() != null && getStartLifeline().getFrame() != null) {
73005152 379 getStartLifeline().getFrame().setHasTimeInfo(true);
df0b8ff4 380 } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) {
73005152 381 getEndLifeline().getFrame().setHasTimeInfo(true);
df0b8ff4 382 }
73005152
BH
383 }
384
385 /**
386 * Set the time when the message start
013a5f1c 387 *
73005152
BH
388 * @param time the time when the message start
389 */
4df4581d 390 public void setStartTime(ITmfTimestamp time) {
4593bd5b 391 fStartTime = time;
eb63f5ff 392 fHasTime = true;
df0b8ff4 393 if (getStartLifeline() != null && getStartLifeline().getFrame() != null) {
73005152 394 getStartLifeline().getFrame().setHasTimeInfo(true);
df0b8ff4 395 } else if (getEndLifeline() != null && getEndLifeline().getFrame() != null) {
73005152 396 getEndLifeline().getFrame().setHasTimeInfo(true);
df0b8ff4 397 }
73005152
BH
398 }
399
73005152 400 @Override
4df4581d 401 public ITmfTimestamp getEndTime() {
eb63f5ff 402 return fEndTime;
73005152
BH
403 }
404
73005152 405 @Override
4df4581d 406 public ITmfTimestamp getStartTime() {
eb63f5ff 407 return fStartTime;
73005152
BH
408 }
409
410 @Override
411 public boolean hasTimeInfo() {
eb63f5ff 412 return fHasTime;
73005152
BH
413 }
414
cab6c8ff
BH
415 /**
416 * @return message return instance or null
cab6c8ff
BH
417 */
418 public AsyncMessageReturn getMessageReturn() {
419 return fMessageReturn;
420 }
421
73005152
BH
422 @Override
423 public boolean isVisible(int x, int y, int width, int height) {
424 int toDrawY = getY();
425 int toDrawHeight = getHeight();
df0b8ff4 426 if ((toDrawY > y + height + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()) && (toDrawY + toDrawHeight > y + height + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth())) {
73005152 427 return false;
df0b8ff4
BH
428 }
429 if (toDrawY < y && (toDrawY + toDrawHeight < y)) {
73005152 430 return false;
df0b8ff4 431 }
73005152
BH
432 return super.isVisible(x, y, width, height);
433 }
434
435 @Override
436 public Comparator<GraphNode> getComparator() {
437 return new SortAsyncMessageComparator();
438 }
439
440 @Override
441 public String getArrayId() {
442 return ASYNC_MESS_TAG;
443 }
444
445 @Override
446 public Comparator<GraphNode> getBackComparator() {
447 return new SortAsyncForBackward();
448 }
449
450 @Override
451 public boolean positiveDistanceToPoint(int x, int y) {
452 int mY = getY();
453 int mH = getHeight();
df0b8ff4 454 if ((mY > y) || (mY + mH > y)) {
73005152 455 return true;
df0b8ff4 456 }
73005152
BH
457 return false;
458 }
459}
This page took 0.091152 seconds and 5 git commands to generate.