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