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