1755eda41bc9cb5ecf63dc6a8fb5b2333e002dbe
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / uml2sd / core / Lifeline.java
1 /**********************************************************************
2 * Copyright (c) 2005, 2013 IBM Corporation, Ericsson
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 *
8 * Contributors:
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
11 **********************************************************************/
12
13 package org.eclipse.linuxtools.tmf.ui.views.uml2sd.core;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IColor;
19 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC;
20 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IImage;
21 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences;
22 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref;
23
24 /**
25 * Lifeline is the UML2 lifeline graphical representation.<br>
26 * Each lifeline owns a set of event occurrences. An event occurrence is the base element in UML2 to set an event in a
27 * sequence diagram.<br>
28 * Event occurrence define the drawing order of graph node along a lifeline. In this lifeline implementation, event
29 * occurrences are just integer index. The event occurrences with the same value on different lifelines will correspond
30 * the same y coordinate value.
31 *
32 * @version 1.0
33 * @author sveyrier
34 *
35 */
36 public class Lifeline extends GraphNode {
37 // ------------------------------------------------------------------------
38 // Constants
39 // ------------------------------------------------------------------------
40 /**
41 * The life line tag.
42 */
43 public static final String LIFELINE_TAG = "Lifeline"; //$NON-NLS-1$
44
45 // ------------------------------------------------------------------------
46 // Attribute
47 // ------------------------------------------------------------------------
48 /**
49 * The lifeline position in the containing frame
50 */
51 protected int fIndexInFrame = 0;
52 /**
53 * The frame where the lifeline is drawn
54 */
55 protected Frame fFrame = null;
56 /**
57 * The current event occurrence created in the lifeline
58 */
59 protected int fEventOccurrence = 0;
60 /**
61 * The lifeline category.
62 */
63 protected int fCategory = -1;
64 /**
65 * Flag whether lifeline has time information available or not
66 */
67 protected boolean fHasTimeInfo = false;
68
69 // ------------------------------------------------------------------------
70 // Constructors
71 // ------------------------------------------------------------------------
72 /**
73 * Default constructor
74 */
75 public Lifeline() {
76 fPrefId = ISDPreferences.PREF_LIFELINE;
77 }
78
79 // ------------------------------------------------------------------------
80 // Methods
81 // ------------------------------------------------------------------------
82
83 @Override
84 public int getX() {
85 return Metrics.FRAME_H_MARGIN + Metrics.LIFELINE_H_MAGIN + (fIndexInFrame - 1) * Metrics.swimmingLaneWidth();
86 }
87
88 @Override
89 public int getY() {
90 return 2 * Metrics.FRAME_NAME_H_MARGIN + Metrics.LIFELINE_VT_MAGIN / 2 + Metrics.getFrameFontHeigth() + Metrics.getLifelineHeaderFontHeigth() + Metrics.FRAME_V_MARGIN + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN;
91 }
92
93 @Override
94 public int getWidth() {
95 return Metrics.getLifelineWidth();
96 }
97
98 @Override
99 public int getHeight() {
100 // Set room for two text lines
101 return Metrics.getLifelineFontHeigth()/** 2 */
102 + 2 * Metrics.LIFELINE_NAME_H_MARGIN;
103 }
104
105 /**
106 * Set the lifeline category for this lifeline.
107 *
108 * @param arrayIndex the index of the category to use
109 * @see Frame#setLifelineCategories(LifelineCategories[])
110 */
111 public void setCategory(int arrayIndex) {
112 fCategory = arrayIndex;
113 }
114
115 /**
116 * Returns the tooltip text for the lifeline. It is the combination between the category name(if any) and the
117 * lifeline name
118 *
119 * @return the tooltip text
120 */
121 public String getToolTipText() {
122 if (fCategory >= 0) {
123 LifelineCategories[] categories = fFrame.getLifelineCategories();
124 if (fCategory < categories.length) {
125 return categories[fCategory].getName() + " " + getName(); //$NON-NLS-1$
126 }
127 }
128 return ""; //$NON-NLS-1$
129 }
130
131 /**
132 * Returns the index of the first visible Execution Occurrence in the execution occurrence array.<br>
133 * Execution Occurrences are Y ordered in this array
134 *
135 * @return the first visible Execution Occurrence
136 */
137 public int getExecOccurrenceDrawIndex() {
138 if (!fHasChilden) {
139 return 0;
140 }
141 if (fIndexes.get(BasicExecutionOccurrence.EXEC_OCC_TAG) != null) {
142 return fIndexes.get(BasicExecutionOccurrence.EXEC_OCC_TAG).intValue();
143 }
144 return 0;
145 }
146
147 /**
148 * Set the frame on which this lifeline must be drawn
149 *
150 * @param parentFrame
151 * Parent frame
152 */
153 protected void setFrame(Frame parentFrame) {
154 fFrame = parentFrame;
155 if (fHasTimeInfo) {
156 fFrame.setHasTimeInfo(true);
157 }
158 if (fFrame.getMaxEventOccurrence() < getEventOccurrence() + 1) {
159 fFrame.setMaxEventOccurrence(getEventOccurrence() + 1);
160 }
161 }
162
163 /**
164 * Returns the frame which this lifeline is drawn
165 *
166 * @return the Frame
167 */
168 protected Frame getFrame() {
169 return fFrame;
170 }
171
172 /**
173 * Set the lifeline position index in the containing frame
174 *
175 * @param index the lifeline X position
176 */
177 protected void setIndex(int index) {
178 fIndexInFrame = index;
179 }
180
181 /**
182 * Returns the lifeline position in de the containing frame
183 *
184 * @return the X position
185 */
186 public int getIndex() {
187 return fIndexInFrame;
188 }
189
190 /**
191 * Set the lifeline event occurrence to the value given in parameter This only change the current event occurrence,
192 * greater event created on this lifeline are still valid and usable. This also need to inform the frame of the
193 * operation mostly to store in the frame the greater event found in the diagram (used to determine the frame
194 * height)
195 *
196 * @param eventOcc the new current event occurrence
197 */
198 public void setCurrentEventOccurrence(int eventOcc) {
199 if ((fFrame != null) && (fFrame.getMaxEventOccurrence() < eventOcc)) {
200 fFrame.setMaxEventOccurrence(eventOcc);
201 }
202 fEventOccurrence = eventOcc;
203 }
204
205 /**
206 * Returns the last created event occurrence along the lifeline.
207 *
208 * @return the current event occurrence
209 */
210 public int getEventOccurrence() {
211 return fEventOccurrence;
212 }
213
214 /**
215 * Creates a new event occurrence along the lifeline.
216 *
217 * @return the new created event occurrence
218 */
219 public int getNewEventOccurrence() {
220 setCurrentEventOccurrence(fEventOccurrence + 1);
221 return fEventOccurrence;
222 }
223
224 /**
225 * Adds the execution occurrence given in parameter to the lifeline.<br>
226 * A Execution occurrence is never drawn in the frame instead it is added to a lifeline
227 *
228 * @param exec the execution occurrence to add
229 */
230 public void addExecution(BasicExecutionOccurrence exec) {
231 exec.setLifeline(this);
232 addNode(exec);
233 if ((fFrame != null) && (fFrame.getMaxEventOccurrence() < exec.fEndEventOccurrence)) {
234 fFrame.setMaxEventOccurrence(exec.fEndEventOccurrence);
235 }
236 }
237
238 /**
239 * Set whether lifeline has time information available or not.
240 * @param value The value to set
241 */
242 protected void setTimeInfo(boolean value) {
243 fHasTimeInfo = value;
244 if ((fFrame != null) && value) {
245 fFrame.setHasTimeInfo(value);
246 }
247 }
248
249 /**
250 * Returns true if at least one execution occurrence has time info.
251 *
252 * @return true if at least one execution occurrence has time info
253 */
254 public boolean hasTimeInfo() {
255 return fHasTimeInfo;
256 }
257
258 /**
259 * Returns the list of execution occurrence on this lifeline.
260 *
261 * @return the execution occurrence list
262 */
263 public List<GraphNode> getExecutions() {
264 if (fHasChilden) {
265 return fNodes.get(BasicExecutionOccurrence.EXEC_OCC_TAG);
266 }
267 return new ArrayList<GraphNode>();
268 }
269
270 @Override
271 public boolean contains(int xValue, int yValue) {
272 int x = getX();
273 int y = getY();
274 int width = getWidth();
275 int height = getHeight();
276
277 if (fFrame == null) {
278 return false;
279 }
280 if (GraphNode.contains(x, y, width, height, xValue, yValue)) {
281 return true;
282 }
283 if (GraphNode.contains(x + Metrics.getLifelineWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2, y + height, Metrics.EXECUTION_OCCURRENCE_WIDTH, (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fFrame.getMaxEventOccurrence()
284 + Metrics.LIFELINE_VB_MAGIN - 4, xValue, yValue)) {
285 return true;
286 }
287
288 height = Metrics.getLifelineFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN;
289 int hMargin = (Metrics.LIFELINE_VT_MAGIN - height) / 2;
290
291 if (hMargin >= 2) {
292 if (fFrame.getVisibleAreaY() < y - height - hMargin) {
293 if (GraphNode.contains(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height + 1, xValue, yValue)) {
294 return true;
295 }
296 } else {
297 if (GraphNode.contains(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height, xValue, yValue)) {
298 return true;
299 }
300 }
301 }
302 if (getNodeAt(xValue, yValue) != null) {
303 return true;
304 }
305 return false;
306 }
307
308 /**
309 * Returns the lifeline visibility for the given visible area
310 *
311 * @param vx The x coordinate of the visible area
312 * @param vy The y coordinate of the visible area
313 * @param vwidth The width of the visible area
314 * @param vheight The height of the visible area
315 * @return true if visible false otherwise
316 */
317 @Override
318 public boolean isVisible(int vx, int vy, int vwidth, int vheight) {
319 int x = getX();
320 int width = getWidth();
321 if (((x >= vx) && (x <= vx + vwidth)) || ((x + width >= vx) && (x <= vx))) {
322 return true;
323 }
324 return false;
325 }
326
327 /**
328 * Draws the name within the graphical context.
329 *
330 * @param context The graphical context.
331 */
332 protected void drawName(IGC context) {
333 ISDPreferences pref = SDViewPref.getInstance();
334
335 int x = getX();
336 int y = getY();
337 int height = Metrics.getLifelineHeaderFontHeigth() + 2 * Metrics.LIFELINE_HEARDER_TEXT_V_MARGIN;
338 int hMargin = Metrics.LIFELINE_VT_MAGIN / 4;// (Metrics.LIFELINE_NAME_H_MARGIN)/2;
339
340 context.setLineStyle(context.getLineSolidStyle());
341 context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE_HEADER));
342 context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE_HEADER));
343 context.setFont(pref.getFont(ISDPreferences.PREF_LIFELINE_HEADER));
344 if (hMargin >= 0) {
345 if (fFrame.getVisibleAreaY() < y - height - hMargin) {
346 context.fillRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height);
347 context.drawRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2, height);
348 context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE_HEADER));
349 context.drawTextTruncatedCentred(getName(), x + Metrics.LIFELINE_NAME_V_MARGIN - Metrics.LIFELINE_SPACING / 2 + 1, y - height - hMargin, Metrics.swimmingLaneWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN - 2, height, true);
350 } else {
351 context.fillRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height);
352 context.drawRectangle(x - Metrics.LIFELINE_SPACING / 2 + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2, height);
353 context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE_HEADER));
354 context.drawTextTruncatedCentred(getName(), x - Metrics.LIFELINE_SPACING / 2 + Metrics.LIFELINE_NAME_V_MARGIN + 1, fFrame.getVisibleAreaY(), Metrics.swimmingLaneWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN - 2, height, true);
355 }
356 }
357 }
358
359 /**
360 * Force the lifeline to be drawn at the given coordinate
361 *
362 * @param context - the context to draw into
363 * @param x - the x coordinate
364 * @param y - the y coordinate
365 */
366 public void draw(IGC context, int x, int y) {
367
368 ISDPreferences pref = SDViewPref.getInstance();
369
370 // Set the draw color depending if the lifeline must be selected or not
371 context.setLineWidth(Metrics.NORMAL_LINE_WIDTH);
372 if (isSelected()) {
373 if (pref.useGradienColor()) {
374 context.setGradientColor(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE));
375 }
376 context.setBackground(pref.getBackGroundColorSelection());
377 context.setForeground(pref.getForeGroundColorSelection());
378 } else {
379 if (pref.useGradienColor()) {
380 context.setGradientColor(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE));
381 context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME));
382 } else {
383 context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_LIFELINE));
384 }
385 context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_LIFELINE));
386 }
387 // Store the lifeline coordinates to save some calls
388 int width = getWidth();
389 int height = getHeight();
390
391 // Draw the rectangle which contain the lifeline name
392 if (pref.useGradienColor()) {
393 context.fillGradientRectangle(x, y, width, height / 2 - 7, true);
394 context.fillRectangle(x, y + height / 2 - 8, width, +height / 2 - 5);
395 context.fillGradientRectangle(x, y + height, width, -height / 2 + 6, true);
396 } else {
397 context.fillRectangle(x, y, width, height);
398 }
399 context.drawRectangle(x, y, width, height);
400
401 if (fCategory >= 0) {
402 LifelineCategories[] categories = fFrame.getLifelineCategories();
403 if (fCategory < categories.length) {
404 IImage image = categories[fCategory].getImage();
405 if (image != null) {
406 context.drawImage(image, x, y, width, height);
407 }
408 }
409 }
410
411 // Draw the lifeline label into the rectangle
412 // The label is truncated if it cannot fit
413 IColor temp = context.getForeground();
414 context.setFont(pref.getFont(ISDPreferences.PREF_LIFELINE));
415 context.setForeground(pref.getFontColor(ISDPreferences.PREF_LIFELINE));
416 context.drawTextTruncatedCentred(getName(), x + Metrics.LIFELINE_NAME_V_MARGIN, y, Metrics.getLifelineWidth() - 2 * Metrics.LIFELINE_NAME_V_MARGIN, height, true);
417
418 context.setLineStyle(context.getLineDashStyle());
419 context.setForeground(temp);
420 int oldStyle = context.getLineStyle();
421
422 // Now draw the lifeline vertical line
423 // this line height depends on a stop assignment
424 // if there is no stop the line is drawn to the bottom of the frame
425
426 // by default set the height to reach the frame bottom
427 int dashedLineEnd = y + height + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * fFrame.getMaxEventOccurrence() + Metrics.LIFELINE_VB_MAGIN;
428 /*
429 * if (stop != null) { dashedLineEnd = stop.getY(); }
430 */
431
432 if (isSelected()) {
433 context.setForeground(pref.getBackGroundColorSelection());
434 context.setLineWidth(5);
435 context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4);
436 context.setForeground(pref.getForeGroundColorSelection());
437 }
438
439 context.setLineWidth(Metrics.NORMAL_LINE_WIDTH);
440 context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4);
441 context.drawLine(x + Metrics.getLifelineWidth() / 2, y + height, x + Metrics.getLifelineWidth() / 2, dashedLineEnd - 4);
442 context.setLineStyle(oldStyle);
443
444 context.setLineStyle(context.getLineSolidStyle());
445
446 if (hasFocus()) {
447 drawFocus(context);
448 }
449
450 super.drawChildenNodes(context);
451 }
452
453 /**
454 * Draws the select execution occurrence region using the given color
455 *
456 * @param context the graphical context
457 * @param startEvent the region start
458 * @param nbEvent the region height
459 * @param color the color to use
460 */
461 public void highlightExecOccurrenceRegion(IGC context, int startEvent, int nbEvent, IColor color) {
462 IColor backupColor = context.getBackground();
463 context.setBackground(color);
464 int x = getX() + Metrics.getLifelineWidth() / 2 - Metrics.EXECUTION_OCCURRENCE_WIDTH / 2;
465 int y = getY() + getHeight() + (Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing()) * startEvent;
466 int width = Metrics.EXECUTION_OCCURRENCE_WIDTH;
467 int height = ((Metrics.getMessageFontHeigth() + Metrics.getMessagesSpacing())) * nbEvent;
468 context.fillRectangle(x, y, width, height);
469 context.setBackground(backupColor);
470 }
471
472 @Override
473 public void draw(IGC context) {
474 draw(context, getX(), getY());
475 }
476
477 @Override
478 public String getArrayId() {
479 return LIFELINE_TAG;
480 }
481
482 @Override
483 public boolean positiveDistanceToPoint(int x, int y) {
484 if (getX() > x - Metrics.swimmingLaneWidth()) {
485 return true;
486 }
487 return false;
488 }
489
490 @Override
491 public GraphNode getNodeAt(int x, int y) {
492 int vy = 0;
493 int vh = 0;
494 if (getFrame() != null) {
495 vy = getFrame().getVisibleAreaY();
496 vh = getFrame().getVisibleAreaHeight();
497 } else {
498 return null;
499 }
500 if (getExecutions() == null) {
501 return null;
502 }
503 for (int i = getExecOccurrenceDrawIndex(); i < getExecutions().size(); i++) {
504 GraphNode node = getExecutions().get(i);
505 if (node.getHeight() < 0) {
506 if (node.getY() + node.getHeight() > vy + vh) {
507 break;
508 }
509 } else {
510 if (node.getY() > vy + vh) {
511 break;
512 }
513 }
514 if (node.contains(x, y)) {
515 GraphNode internal = node.getNodeAt(x, y);
516 if (internal != null) {
517 return internal;
518 }
519 return node;
520 }
521 }
522 return null;
523 }
524 }
This page took 0.04209 seconds and 5 git commands to generate.