Integrate the TmfEvent+ITmfTimestamp API
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / uml2sd / core / AsyncMessage.java
CommitLineData
73005152
BH
1/**********************************************************************
2 * Copyright (c) 2005, 2008, 2011 IBM Corporation and others.
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
7 * $Id: AsyncMessage.java,v 1.3 2008/01/24 02:28:49 apnan Exp $
8 *
9 * Contributors:
10 * IBM - Initial API and implementation
11 * Bernd Hufmann - Updated for TMF
12 **********************************************************************/
13package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core;
14
15import java.util.Comparator;
16
4df4581d 17import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
6c13869b 18import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
73005152
BH
19import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC;
20import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.ISDPreferences;
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:
30 *
31 * <pre>
32 * Frame frame;
33 * Lifeline lifeLine1;
34 * Lifeline lifeLine2;
35 *
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>
47 *
48 * @see Lifeline Lifeline for more event occurence details
49 * @author sveyrier
50 *
51 */
52public class AsyncMessage extends BaseMessage implements ITimeRange {
53
54 protected boolean hasTime = false;
55 /**
56 * The time when the message begin
57 */
4df4581d 58 protected ITmfTimestamp endTime = new TmfTimestamp();
73005152
BH
59
60 /**
61 * The time when the message end
62 */
4df4581d 63 protected ITmfTimestamp startTime = new TmfTimestamp();
73005152
BH
64
65 /**
66 * The associated message.
67 */
68 protected AsyncMessageReturn messageReturn = null;
69
70 public static final String ASYNC_MESS_TAG = "AsyncMessage"; //$NON-NLS-1$
71
72 public AsyncMessage() {
73 prefId = ISDPreferences.PREF_ASYNC_MESS;
74 }
75
76 @Override
77 public int getX() {
78 int x = super.getX(true);
79 int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
80 if ((startLifeline != null) && (endLifeline != null) && (startLifeline.getX() > endLifeline.getX())) {
81 activationWidth = -activationWidth;
82 }
83
84 if (isMessageStartInActivation(startEventOccurrence)) {
85 x = x + activationWidth;
86 }
87 return x;
88 }
89
90 @Override
91 public int getY() {
92 if ((startLifeline != null) && (endLifeline != null)) {
93 return endLifeline.getY() + endLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * startEventOccurrence;
94 }
95 return super.getY();
96 }
97
98 @Override
99 public int getWidth() {
100 int width = super.getWidth(true);
101 int activationWidth = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
102 if ((startLifeline != null) && (endLifeline != null) && (startLifeline.getX() > endLifeline.getX())) {
103 activationWidth = -activationWidth;
104 }
105
106 if (isMessageStartInActivation(startEventOccurrence))
107 width = width - activationWidth;
108
109 if (isMessageEndInActivation(endEventOccurrence))
110 width = width - activationWidth;
111
112 return width;
113 }
114
115 @Override
116 public int getHeight() {
117 if ((startLifeline != null) && (endLifeline != null)) {
118 return (endLifeline.getY() + endLifeline.getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * endEventOccurrence) - getY();
119 }
120 return super.getHeight();
121 }
122
123 /**
124 * Set the message return associated with this message.
125 *
126 * @param message the message return to associate
127 */
128 protected void setMessageReturn(AsyncMessageReturn message) {
129 messageReturn = message;
130 }
131
132 /**
133 * Set the event occurrence attached to this message for its end lifeline
134 *
135 * @param occurrence the event occurrence to set
136 */
137 public void setEndOccurrence(int occurrence) {
138 endEventOccurrence = occurrence;
139 if (getStartLifeline() == null)
140 startEventOccurrence = occurrence;
141 informFrame(getEndLifeline(), occurrence);
142 }
143
144 protected void informFrame(Lifeline lifeLine, int occurrence) {
145 if ((lifeLine != null) && (lifeLine.getFrame() != null))
146 if (lifeLine.getFrame().getMaxEventOccurrence() < occurrence)
147 lifeLine.getFrame().setMaxEventOccurrence(occurrence);
148 }
149
150 /**
151 * Set the event occurrence attached to this message for its start lifeline
152 *
153 * @param occurrence the event occurrence to set
154 */
155 public void setStartOccurrence(int occurrence) {
156 startEventOccurrence = occurrence;
157 if (getEndLifeline() == null)
158 endEventOccurrence = startEventOccurrence;
159 informFrame(getStartLifeline(), occurrence);
160 }
161
162 /**
163 * Set the lifeLine which has sent the message.<br>
164 * A new EventOccurence will be create on this lifeLine.<br>
165 *
166 * @param lifeline the message sender
167 * @param autoCreateEvent if true, create an eventOccurence lifeline given in parameter
168 */
169 public void autoSetStartLifeline(Lifeline lifeline) {
170 lifeline.getNewEventOccurrence();
171 setStartLifeline(lifeline);
172 }
173
174 /**
175 * Set the lifeLine which has received the message.<br>
176 * A new EventOccurence will be create on this lifeLine.<br>
177 *
178 * @param lifeline the message receiver
179 * @param autoCreateEvent if true, create an eventOccurence lifeline given in parameter
180 */
181 public void autoSetEndLifeline(Lifeline lifeline) {
182 lifeline.getNewEventOccurrence();
183 setEndLifeline(lifeline);
184 }
185
186 /**
187 * Set the lifeLine which has sent the message.<br>
188 *
189 * @param lifeline the message sender
190 */
191 @Override
192 public void setStartLifeline(Lifeline lifeline) {
193 super.setStartLifeline(lifeline);
194 setStartOccurrence(getStartLifeline().getEventOccurrence());
195 if (getEndLifeline() == null)
196 endEventOccurrence = startEventOccurrence;
197 }
198
199 /**
200 * Set the lifeLine which has received the message.<br>
201 *
202 * @param lifeline the message receiver
203 */
204 @Override
205 public void setEndLifeline(Lifeline lifeline) {
206 super.setEndLifeline(lifeline);
207 setEventOccurrence(getEndLifeline().getEventOccurrence());
208 }
209
210 /**
211 * Returns true if the point C is on the segment defined with the point A and B
212 *
213 * @param xA point A x coordinate
214 * @param yA point A y coordinate
215 * @param xB point B x coordinate
216 * @param yB point B y coordinate
217 * @param xC point C x coordinate
218 * @param yC point C y coordinate
219 * @return Return true if the point C is on the segment defined with the point A and B, else otherwise
220 */
221 protected boolean isNearSegment(int xA, int yA, int xB, int yB, int xC, int yC) {
222 if ((xA > xB) && (xC > xA))
223 return false;
224 if ((xA < xB) && (xC > xB))
225 return false;
226 if ((xA < xB) && (xC < xA))
227 return false;
228 if ((xA > xB) && (xC < xB))
229 return false;
230 double distAB = Math.sqrt((xB - xA) * (xB - xA) + (yB - yA) * (yB - yA));
231 double scalar = ((xB - xA) * (xC - xA) + (yB - yA) * (yC - yA)) / distAB;
232 double distAC = Math.sqrt((xC - xA) * (xC - xA) + (yC - yA) * (yC - yA));
233 double distToSegment = Math.sqrt(Math.abs(distAC * distAC - scalar * scalar));
234 if (distToSegment <= Metrics.MESSAGE_SELECTION_TOLERANCE)
235 return true;
236 return false;
237 }
238
239 @Override
240 public boolean contains(int x, int y) {
241 // Is it a self message?
242 if (startLifeline == endLifeline) {
243 return super.contains(x, y);
244 }
245 if (isNearSegment(getX(), getY(), getX() + getWidth(), getY() + getHeight(), x, y))
246 return true;
247 int messageMaxWidth = Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH;
248 int nameWidth = getName().length() * Metrics.getAverageCharWidth();
249 if (getName().length() * Metrics.getAverageCharWidth() > messageMaxWidth) {
250 if (Frame.contains(getX(), getY() - Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), messageMaxWidth, Metrics.getMessageFontHeigth(), x, y))
251 return true;
252 } else {
253 if (Frame.contains(getX() + (messageMaxWidth - nameWidth) / 2, getY() + getHeight() / 2 - Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), nameWidth, Metrics.getMessageFontHeigth(), x, y))
254 return true;
255 }
256 return false;
257 }
258
259 protected void drawAsyncMessage(IGC context) {
260 if (startLifeline != null && endLifeline != null && startLifeline == endLifeline && (startEventOccurrence != endEventOccurrence)) {
261 int x = getX();
262 int y = getY();
263 int height = getHeight();
264 int tempx = 0;
265 boolean startInActivation = isMessageStartInActivation(startEventOccurrence);
266 boolean endInActivation = isMessageEndInActivation(endEventOccurrence);
267
268 if (endInActivation && !startInActivation)
269 tempx = Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
270 if (startInActivation && !endInActivation)
271 tempx = -Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
272
273 int tempy = Metrics.INTERNAL_MESSAGE_WIDTH / 2;
274 if (getHeight() <= Metrics.INTERNAL_MESSAGE_WIDTH)
275 tempy = getHeight() / 2;
276
277 context.drawLine(x, y, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y);
278 context.drawLine(x + Metrics.INTERNAL_MESSAGE_WIDTH, y + tempy, x + Metrics.INTERNAL_MESSAGE_WIDTH, y + height - tempy);
279 context.drawLine(x + tempx, y + height, x + Metrics.INTERNAL_MESSAGE_WIDTH / 2, y + height);
280
281 Double xt = new Double(Math.cos(0.75) * 7);
282 Double yt = new Double(Math.sin(0.75) * 7);
283
284 context.drawLine(x + xt.intValue() + tempx, y + height + yt.intValue(), x + tempx, y + height);
285 context.drawArc(x, y, Metrics.INTERNAL_MESSAGE_WIDTH, 2 * tempy, 0, 90);
286 context.drawArc(x, y + height, Metrics.INTERNAL_MESSAGE_WIDTH, -2 * tempy, 0, -90);
287 context.drawLine(x + xt.intValue() + tempx, y + height - yt.intValue(), x + tempx, y + height);
288
289 context.drawTextTruncated(getName(), x + Metrics.INTERNAL_MESSAGE_WIDTH + Metrics.INTERNAL_MESSAGE_V_MARGIN, y, Metrics.swimmingLaneWidth() - Metrics.EXECUTION_OCCURRENCE_WIDTH + -Metrics.INTERNAL_MESSAGE_WIDTH,
290 +Metrics.MESSAGES_NAME_SPACING - Metrics.getMessageFontHeigth(), !isSelected());
291 } else
292 super.draw(context);
293 }
294
295 /**
296 * Draws the asynchronous message in the given GC
297 */
298 @Override
299 public void draw(IGC context) {
300 if (!isVisible())
301 return;
302 // Draw it selected?
303 if (isSelected() && (startLifeline != null && endLifeline != null && startLifeline == endLifeline && (startEventOccurrence != endEventOccurrence))) {
304 /*
305 * Draw it twice First time, bigger inverting selection colors Second time, regular drawing using selection
306 * colors This create the highlight effect
307 */
308 context.setForeground(Frame.getUserPref().getBackGroundColorSelection());
309 context.setLineWidth(Metrics.SELECTION_LINE_WIDTH);
310 drawAsyncMessage(context);
311 context.setBackground(Frame.getUserPref().getBackGroundColorSelection());
312 context.setForeground(Frame.getUserPref().getForeGroundColorSelection());
313 // Second drawing is done after the else
314 } else {
315 context.setBackground(Frame.getUserPref().getBackGroundColor(prefId));
316 context.setForeground(Frame.getUserPref().getForeGroundColor(prefId));
317 }
318 if (hasFocus()) {
319 context.setDrawTextWithFocusStyle(true);
320 }
321 context.setLineWidth(Metrics.NORMAL_LINE_WIDTH);
322 drawAsyncMessage(context);
323 if (hasFocus()) {
324 context.setDrawTextWithFocusStyle(false);
325 }
326 }
327
328 /**
329 * Set the time when the message end
330 *
331 * @param time the time when the message end
332 */
4df4581d 333 public void setEndTime(ITmfTimestamp time) {
73005152
BH
334 endTime = time.clone();
335 hasTime = true;
336 if (getStartLifeline() != null && getStartLifeline().getFrame() != null)
337 getStartLifeline().getFrame().setHasTimeInfo(true);
338 else if (getEndLifeline() != null && getEndLifeline().getFrame() != null)
339 getEndLifeline().getFrame().setHasTimeInfo(true);
340 }
341
342 /**
343 * Set the time when the message start
344 *
345 * @param time the time when the message start
346 */
4df4581d 347 public void setStartTime(ITmfTimestamp time) {
73005152
BH
348 startTime = time.clone();
349 hasTime = true;
350 if (getStartLifeline() != null && getStartLifeline().getFrame() != null)
351 getStartLifeline().getFrame().setHasTimeInfo(true);
352 else if (getEndLifeline() != null && getEndLifeline().getFrame() != null)
353 getEndLifeline().getFrame().setHasTimeInfo(true);
354 }
355
356 /**
357 * Returns the time when the message begin
358 *
359 * @return the time
360 */
361 @Override
4df4581d 362 public ITmfTimestamp getEndTime() {
73005152
BH
363 return endTime;
364 }
365
366 /**
367 * Returns the time when the message end
368 *
369 * @return the time
370 */
371 @Override
4df4581d 372 public ITmfTimestamp getStartTime() {
73005152
BH
373 return startTime;
374 }
375
376 @Override
377 public boolean hasTimeInfo() {
378 return hasTime;
379 }
380
381 @Override
382 public boolean isVisible(int x, int y, int width, int height) {
383 int toDrawY = getY();
384 int toDrawHeight = getHeight();
385 if ((toDrawY > y + height + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()) && (toDrawY + toDrawHeight > y + height + Metrics.MESSAGES_NAME_SPACING + Metrics.getMessageFontHeigth()))
386 return false;
387 if (toDrawY < y && (toDrawY + toDrawHeight < y))
388 return false;
389 return super.isVisible(x, y, width, height);
390 }
391
392 @Override
393 public Comparator<GraphNode> getComparator() {
394 return new SortAsyncMessageComparator();
395 }
396
397 @Override
398 public String getArrayId() {
399 return ASYNC_MESS_TAG;
400 }
401
402 @Override
403 public Comparator<GraphNode> getBackComparator() {
404 return new SortAsyncForBackward();
405 }
406
407 @Override
408 public boolean positiveDistanceToPoint(int x, int y) {
409 int mY = getY();
410 int mH = getHeight();
411 if ((mY > y) || (mY + mH > y))
412 return true;
413 return false;
414 }
415}
This page took 0.039369 seconds and 5 git commands to generate.