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