tmf: Update copyright headers in tmf.ui
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / uml2sd / core / BasicFrame.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.Iterator;
17 import java.util.List;
18
19 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
20 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
21 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC;
22 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.ISDPreferences;
23 import org.eclipse.linuxtools.tmf.ui.views.uml2sd.preferences.SDViewPref;
24
25 /**
26 * The Frame class is the base sequence diagram graph nodes container.<br>
27 * For instance, only one frame can be drawn in the View.<br>
28 * Lifelines, Messages and Stop which are supposed to represent a Sequence diagram are drawn in a Frame.<br>
29 * Only the graph node added to their representing list will be drawn.
30 *
31 * The lifelines are appended along the X axsis when added in a frame.<br>
32 * The syncMessages are ordered along the Y axsis depending on the event occurrence they are attached to.<br>
33 *
34 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.Lifeline Lifeline for more event occurence details
35 * @author sveyrier
36 * @version 1.0
37 */
38 public class BasicFrame extends GraphNode {
39
40 // ------------------------------------------------------------------------
41 // Attributes
42 // ------------------------------------------------------------------------
43
44 /**
45 * Contains the max elapsed time between two consecutive messages in the whole frame
46 */
47 protected ITmfTimestamp fMaxTime = new TmfTimestamp(0);
48 /**
49 * Contains the min elapsed time between two consecutive messages in the whole frame
50 */
51 protected ITmfTimestamp fMinTime = new TmfTimestamp(0);
52 /**
53 * Indicate if the min and max elapsed time between two consecutive messages in the whole frame need to be computed
54 */
55 protected boolean fComputeMinMax = true;
56 /**
57 * Store the preference set by the user regarding the external time. This flag is used determine if the min and max
58 * need to be recomputed in case this preference is changed.
59 */
60 protected boolean fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime();
61 /**
62 * The greater event occurrence created on graph nodes drawn in this Frame This directly impact the Frame height
63 */
64 protected int fVerticalIndex = 0;
65 /**
66 * The index along the x axis where the next lifeline will is drawn This directly impact the Frame width
67 */
68 protected int fHorizontalIndex = 0;
69 /**
70 * The time information flag.
71 */
72 protected boolean fHasTimeInfo = false;
73 /**
74 * The current Frame visible area - x coordinates
75 */
76 protected int fVisibleAreaX;
77 /**
78 * The current Frame visible area - y coordinates
79 */
80 protected int fVisibleAreaY;
81 /**
82 * The current Frame visible area - width
83 */
84 protected int fVisibleAreaWidth;
85 /**
86 * The current Frame visible area - height
87 */
88 protected int fVisibleAreaHeight;
89 /**
90 * The event occurrence spacing (-1 for none)
91 */
92 protected int fForceEventOccurrenceSpacing = -1;
93 /**
94 * Flag to indicate customized minumum and maximum.
95 */
96 protected boolean fCustomMinMax = false;
97 /**
98 * The minimum time between messages of the sequence diagram frame.
99 */
100 protected ITmfTimestamp fMinSDTime = new TmfTimestamp();
101 /**
102 * The maximum time between messages of the sequence diagram frame.
103 */
104 protected ITmfTimestamp fMaxSDTime = new TmfTimestamp();
105 /**
106 * Flag to indicate that initial minimum has to be computed.
107 */
108 protected boolean fInitSDMin = true;
109
110 // ------------------------------------------------------------------------
111 // Constructors
112 // ------------------------------------------------------------------------
113
114 /**
115 * Creates an empty frame.
116 */
117 public BasicFrame() {
118 Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing);
119 }
120
121 // ------------------------------------------------------------------------
122 // Methods
123 // ------------------------------------------------------------------------
124
125 /**
126 *
127 * Returns the greater event occurence known by the Frame
128 *
129 * @return the greater event occurrence
130 */
131 protected int getMaxEventOccurrence() {
132 return fVerticalIndex;
133 }
134
135 /**
136 * Set the greater event occurrence created in GraphNodes included in the frame
137 *
138 * @param eventOccurrence the new greater event occurrence
139 */
140 protected void setMaxEventOccurrence(int eventOccurrence) {
141 fVerticalIndex = eventOccurrence;
142 }
143
144 /**
145 * This method increase the lifeline place holder The return value is usually assign to a lifeline. This can be used
146 * to set the lifelines drawing order. Also, calling this method two times and assigning only the last given index
147 * to a lifeline will increase this lifeline draw spacing (2 times the default spacing) from the last added
148 * lifeline.
149 *
150 * @return a new lifeline index
151 */
152 protected int getNewHorizontalIndex() {
153 return ++fHorizontalIndex;
154 }
155
156 /**
157 * Returns the current horizontal index
158 *
159 * @return the current horizontal index
160 * @see Frame#getNewHorizontalIndex() for horizontal index description
161 */
162 protected int getHorizontalIndex() {
163 return fHorizontalIndex;
164 }
165
166 /*
167 * (non-Javadoc)
168 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#addNode(org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode)
169 */
170 @Override
171 public void addNode(GraphNode nodeToAdd) {
172 fComputeMinMax = true;
173 super.addNode(nodeToAdd);
174 }
175
176 /*
177 * (non-Javadoc)
178 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getX()
179 */
180 @Override
181 public int getX() {
182 return Metrics.FRAME_H_MARGIN;
183 }
184
185
186 /*
187 * (non-Javadoc)
188 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getY()
189 */
190 @Override
191 public int getY() {
192 return Metrics.FRAME_V_MARGIN;
193 }
194
195 /*
196 * (non-Javadoc)
197 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getWidth()
198 */
199 @Override
200 public int getWidth() {
201 if (fHorizontalIndex == 0) {
202 return 3 * Metrics.swimmingLaneWidth() + Metrics.LIFELINE_H_MAGIN * 2 - Metrics.FRAME_H_MARGIN - Metrics.LIFELINE_SPACING / 2;
203 }
204 return fHorizontalIndex * Metrics.swimmingLaneWidth() + Metrics.LIFELINE_H_MAGIN * 2 + 1 - Metrics.LIFELINE_SPACING;
205 }
206
207 /*
208 * (non-Javadoc)
209 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getHeight()
210 */
211 @Override
212 public int getHeight() {
213 // The Frame height depends on the maximum number of messages added to a lifeline
214 if (fVerticalIndex == 0) {
215 return 5 * (Metrics.getMessagesSpacing() + Metrics.getMessageFontHeigth()) + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getFrameFontHeigth() + Metrics.LIFELINE_VT_MAGIN + Metrics.LIFELINE_VB_MAGIN
216 + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getLifelineFontHeigth() * 2;
217 }
218 if (fForceEventOccurrenceSpacing >= 0) {
219 Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing);
220 }
221 return fVerticalIndex * (Metrics.getMessagesSpacing() + Metrics.getMessageFontHeigth()) + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getFrameFontHeigth() + Metrics.LIFELINE_VT_MAGIN + Metrics.LIFELINE_VB_MAGIN
222 + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getLifelineFontHeigth() * 2;
223 }
224
225 /**
226 * Returns the graph node which contains the point given in parameter for the given graph node list and starting the
227 * iteration at the given index<br>
228 * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.<br>
229 *
230 * @param x the x coordinate of the point to test
231 * @param y the y coordinate of the point to test
232 * @param list the list to search in
233 * @param fromIndex list browsing starting point
234 * @return the graph node containing the point given in parameter, null otherwise
235 *
236 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getNodeFromListAt(int, int, java.util.List, int)
237 */
238 @Override
239 protected GraphNode getNodeFromListAt(int x, int y, List<GraphNode> list, int fromIndex) {
240 if (list == null) {
241 return null;
242 }
243 for (int i = fromIndex; i < list.size(); i++) {
244 GraphNode node = list.get(i);
245 // only lifeline list is x ordered
246 // Stop browsing the list if the node is outside the visible area
247 // all others nodes will be not visible
248 if ((node instanceof Lifeline) && (node.getX() > fVisibleAreaX + fVisibleAreaWidth)) {
249 break;
250 }
251 if (node.getHeight() < 0) {
252 if (node.getY() + node.getHeight() > fVisibleAreaY + fVisibleAreaHeight) {
253 break;
254 }
255 } else {
256 if (node.getY() > fVisibleAreaY + fVisibleAreaHeight) {
257 break;
258 }
259 }
260 if (node.contains(x, y)) {
261 return node;
262 }
263 }
264 return null;
265 }
266
267 /**
268 * Draw the Frame rectangle
269 *
270 * @param context the context to draw to
271 */
272 protected void drawFrame(IGC context) {
273
274 ISDPreferences pref = SDViewPref.getInstance();
275
276 context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME));
277 context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME));
278
279 int x = getX();
280 int y = getY();
281 int w = getWidth();
282 int h = getHeight();
283
284 // Draw the frame main rectangle
285 context.fillRectangle(x, y, w, h);
286 context.drawRectangle(x, y, w, h);
287
288 context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME_NAME));
289 context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME_NAME));
290 context.setFont(pref.getFont(ISDPreferences.PREF_FRAME_NAME));
291
292 int nameWidth = context.textExtent(getName()) + 2 * Metrics.FRAME_NAME_V_MARGIN;
293 int nameHeight = Metrics.getFrameFontHeigth() + +Metrics.FRAME_NAME_H_MARGIN * 2;
294
295 // Draw the frame name area
296 if (nameWidth > w) {
297 nameWidth = w;
298 }
299
300 int[] points = { x, y, x + nameWidth, y, x + nameWidth, y - 11 + nameHeight, x - 11 + nameWidth, y + nameHeight, x, y + nameHeight, x, y + nameHeight };
301 context.fillPolygon(points);
302 context.drawPolygon(points);
303 context.drawLine(x, y, x, y + nameHeight);
304
305 context.setForeground(pref.getFontColor(ISDPreferences.PREF_FRAME_NAME));
306 context.drawTextTruncatedCentred(getName(), x, y, nameWidth - 11, nameHeight, false);
307
308 context.setBackground(pref.getBackGroundColor(ISDPreferences.PREF_FRAME));
309 context.setForeground(pref.getForeGroundColor(ISDPreferences.PREF_FRAME));
310 }
311
312 /*
313 * (non-Javadoc)
314 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC)
315 */
316 @Override
317 public void draw(IGC context) {
318 draw(context, true);
319 }
320
321 /**
322 * Draws the Frame on the given context.<br>
323 * This method start width GraphNodes ordering if needed.<br>
324 * After, depending on the visible area, only visible GraphNodes are drawn.<br>
325 *
326 * @param context the context to draw to
327 * @param drawFrame indicate if the frame rectangle need to be redrawn
328 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC)
329 */
330 protected void draw(IGC context, boolean drawFrame) {
331 fVisibleAreaHeight = context.getVisibleHeight();
332 fVisibleAreaWidth = context.getVisibleWidth();
333 fVisibleAreaX = context.getContentsX();
334 fVisibleAreaY = context.getContentsY();
335
336 if (fForceEventOccurrenceSpacing >= 0) {
337 Metrics.setForcedEventSpacing(fForceEventOccurrenceSpacing);
338 } else {
339 Metrics.setForcedEventSpacing(-1);
340 }
341
342 super.drawChildenNodes(context);
343 }
344
345 /**
346 * Sets the event occurrence spacing (-1 for none)
347 *
348 * @param space A spacing to set.
349 */
350 public void forceEventOccurrenceSpacing(int space) {
351 fForceEventOccurrenceSpacing = space;
352 }
353
354 /**
355 * Return the X coordinates of the frame visible area
356 *
357 * @return the X coordinates of the frame visible area
358 */
359 public int getVisibleAreaX() {
360 return fVisibleAreaX;
361 }
362
363 /**
364 * Return the frame visible area width
365 *
366 * @return the frame visible area width
367 */
368 public int getVisibleAreaWidth() {
369 return fVisibleAreaWidth;
370 }
371
372 /**
373 * Return the frame visible area height
374 *
375 * @return the frame visible area height
376 */
377 public int getVisibleAreaHeight() {
378 return fVisibleAreaHeight;
379 }
380
381 /**
382 * Return the X coordinates of the frame visible area
383 *
384 * @return the X coordinates of the frame visible area
385 */
386 public int getVisibleAreaY() {
387 return fVisibleAreaY;
388 }
389
390 /**
391 * Return the minimum time stored in the frame taking all GraphNodes into account
392 *
393 * @return the minimum GraphNode time
394 * @since 2.0
395 */
396 public ITmfTimestamp getMinTime() {
397 if (fLastExternalTimePref != SDViewPref.getInstance().excludeExternalTime()) {
398 fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime();
399 fComputeMinMax = true;
400 }
401 if ((fComputeMinMax) && (!fCustomMinMax)) {
402 computeMinMax();
403 fComputeMinMax = false;
404 }
405 return fMinTime;
406 }
407
408 /**
409 * Set the minimum timestamp of the frame.
410 *
411 * @param min
412 * The minimum timestamp
413 * @since 2.0
414 */
415 public void setMin(ITmfTimestamp min) {
416 fMinTime = min;
417 fCustomMinMax = true;
418 }
419
420 /**
421 * Set the maximum timestamp of the frame.
422 *
423 * @param max
424 * The maximum timestamp
425 * @since 2.0
426 */
427 public void setMax(ITmfTimestamp max) {
428 fMaxTime = max;
429 fCustomMinMax = true;
430 }
431
432 /**
433 * Reset min/max timestamp values to the default ones.
434 */
435 public void resetCustomMinMax() {
436 fCustomMinMax = false;
437 fComputeMinMax = true;
438 }
439
440 /**
441 * Return the maximum time stored in the frame taking all GraphNodes into account
442 *
443 * @return the maximum GraphNode time
444 * @since 2.0
445 */
446 public ITmfTimestamp getMaxTime() {
447 if (fLastExternalTimePref != SDViewPref.getInstance().excludeExternalTime()) {
448 fLastExternalTimePref = SDViewPref.getInstance().excludeExternalTime();
449 fComputeMinMax = true;
450 }
451 if (fComputeMinMax) {
452 computeMinMax();
453 fComputeMinMax = false;
454 }
455 return fMaxTime;
456 }
457
458 /**
459 * Computes the minimum and maximum time between consecutive messages within the frame.
460 */
461 protected void computeMaxMinTime() {
462 if (!fInitSDMin) {
463 return;
464 }
465
466 List<SDTimeEvent> timeArray = buildTimeArray();
467
468 if ((timeArray == null) || timeArray.isEmpty()) {
469 return;
470 }
471 for (int i = 0; i < timeArray.size(); i++) {
472 SDTimeEvent m = timeArray.get(i);
473
474 if (m.getTime().compareTo(fMaxSDTime, true) > 0) {
475 fMaxSDTime = m.getTime();
476 }
477
478 if ((m.getTime().compareTo(fMinSDTime, true) < 0) || fInitSDMin) {
479 fMinSDTime = m.getTime();
480 fInitSDMin = false;
481 }
482 }
483 }
484
485 /**
486 * Returns the minimum time between consecutive messages.
487 *
488 * @return the minimum time between consecutive messages
489 * @since 2.0
490 */
491 public ITmfTimestamp getSDMinTime() {
492 computeMaxMinTime();
493 return fMinSDTime;
494 }
495
496 /**
497 * Returns the maximum time between consecutive messages.
498 *
499 * @return the maximum time between consecutive messages
500 * @since 2.0
501 */
502 public ITmfTimestamp getSDMaxTime() {
503 computeMaxMinTime();
504 return fMaxSDTime;
505 }
506
507 /**
508 * Browse all the GraphNode to compute the min and max times store in the Frame
509 */
510 protected void computeMinMax() {
511 List<SDTimeEvent> timeArray = buildTimeArray();
512
513 if ((timeArray == null) || timeArray.isEmpty()) {
514 return;
515 }
516 for (int i = 0; i < timeArray.size() - 1; i++) {
517 SDTimeEvent m1 = timeArray.get(i);
518 SDTimeEvent m2 = timeArray.get(i + 1);
519
520 updateMinMax(m1, m2);
521 }
522 }
523
524 /**
525 * Updates the minimum and maximum time between consecutive message within the frame based on the given values.
526 *
527 * @param m1 A first SD time event.
528 * @param m2 A second SD time event.
529 */
530 protected void updateMinMax(SDTimeEvent m1, SDTimeEvent m2) {
531 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime());
532 if (fComputeMinMax) {
533 fMinTime = delta;
534 if (fMinTime.compareTo(TmfTimestamp.ZERO, false) < 0) {
535 fMinTime = new TmfTimestamp(0, m1.getTime().getScale(), m1.getTime().getPrecision());
536 }
537 fMaxTime = fMinTime;
538 fComputeMinMax = false;
539 }
540
541 if ((delta.compareTo(fMinTime, true) < 0) && (delta.compareTo(TmfTimestamp.ZERO, false) > 0)) {
542 fMinTime = delta;
543 }
544
545 if ((delta.compareTo(fMaxTime, true) > 0) && (delta.compareTo(TmfTimestamp.ZERO, false) > 0)) {
546 fMaxTime = delta;
547 }
548 }
549
550 /**
551 * Builds the time array based on the list of graph nodes.
552 *
553 * @return the time array else empty list.
554 */
555 protected List<SDTimeEvent> buildTimeArray() {
556 if (!fHasChilden) {
557 return new ArrayList<SDTimeEvent>();
558 }
559
560 Iterator<String> it = fForwardSort.keySet().iterator();
561 List<SDTimeEvent> timeArray = new ArrayList<SDTimeEvent>();
562 while (it.hasNext()) {
563 String nodeType = it.next();
564 List<GraphNode> list = fNodes.get(nodeType);
565 for (int i = 0; i < list.size(); i++) {
566 Object timedNode = list.get(i);
567 if ((timedNode instanceof ITimeRange) && ((ITimeRange) timedNode).hasTimeInfo()) {
568 int event = list.get(i).getStartOccurrence();
569 ITmfTimestamp time = ((ITimeRange) list.get(i)).getStartTime();
570 SDTimeEvent f = new SDTimeEvent(time, event, (ITimeRange) list.get(i));
571 timeArray.add(f);
572 if (event != list.get(i).getEndOccurrence()) {
573 event = ((AsyncMessage) list.get(i)).getEndOccurrence();
574 time = ((ITimeRange) list.get(i)).getEndTime();
575 f = new SDTimeEvent(time, event, (ITimeRange) list.get(i));
576 timeArray.add(f);
577 }
578 }
579 }
580 }
581 return timeArray;
582 }
583
584 /*
585 * (non-Javadoc)
586 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getArrayId()
587 */
588 @Override
589 public String getArrayId() {
590 return null;
591 }
592
593 /*
594 * (non-Javadoc)
595 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#contains(int, int)
596 */
597 @Override
598 public boolean contains(int x, int y) {
599 return false;
600 }
601 }
This page took 0.045497 seconds and 5 git commands to generate.