Improve test cases, speed and accuracy.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / views / uml2sd / core / BasicFrame.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: BasicFrame.java,v 1.2 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.ArrayList;
16import java.util.Iterator;
17import java.util.List;
18
4df4581d 19import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
6c13869b 20import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
73005152
BH
21import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.IGC;
22import org.eclipse.linuxtools.tmf.ui.views.uml2sd.drawings.ISDPreferences;
23import 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 */
38public class BasicFrame extends GraphNode {
39
40 /**
41 * Contains the max elapsed time between two consecutive messages in the whole frame
42 */
4df4581d 43 protected ITmfTimestamp maxTime = new TmfTimestamp(0);
73005152
BH
44 /**
45 * Contains the min elapsed time between two consecutive messages in the whole frame
46 */
4df4581d 47 protected ITmfTimestamp minTime = new TmfTimestamp(0);
73005152
BH
48
49 /**
50 * Indicate if the min and max elapsed time between two consecutive messages in the whole frame need to be computed
51 */
52 protected boolean computeMinMax = true;
53
54 /**
55 * Store the preference set by the user regarding the external time. This flag is used determine if the min and max
56 * need to be recomputed in case this preference is changed.
57 */
58 protected boolean lastExternalTimePref = SDViewPref.getInstance().excludeExternalTime();
59
60 /**
61 * The greater event occurrence created on graph nodes drawn in this Frame This directly impact the Frame height
62 */
63 protected int verticalIndex = 0;
64
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 horizontalIndex = 0;
69
70 protected boolean timeInfo = false;
71
72 /**
73 * The current Frame visible area
74 */
75 protected int visibleAreaX;
76 protected int visibleAreaY;
77 protected int visibleAreaWidth;
78 protected int visibleAreaHeight;
79
e6ace8bb 80 static ISDPreferences userPref = null;
73005152
BH
81
82 protected int forceEventOccurrenceSpacing = -1;
83
84 protected boolean customMinMax = false;
85
4df4581d 86 protected ITmfTimestamp minSDTime = new TmfTimestamp();
87 protected ITmfTimestamp maxSDTime = new TmfTimestamp();
73005152
BH
88 protected boolean initSDMin = true;
89
90 /**
91 * Creates an empty frame.
92 */
93 public BasicFrame() {
94 Metrics.setForcedEventSpacing(forceEventOccurrenceSpacing);
95 }
96
97 /**
98 *
99 * Returns the greater event occurence known by the Frame
100 *
101 * @return the greater event occurrence
102 */
103 protected int getMaxEventOccurrence() {
104 return verticalIndex;
105 }
106
107 /**
108 * Set the greater event occurrence created in GraphNodes included in the frame
109 *
110 * @param eventOccurrence the new greater event occurrence
111 */
112 protected void setMaxEventOccurrence(int eventOccurrence) {
113 verticalIndex = eventOccurrence;
114 }
115
116 /**
117 * This method increase the lifeline place holder The return value is usually assign to a lifeline. This can be used
118 * to set the lifelines drawing order. Also, calling this method two times and assigning only the last given index
119 * to a lifeline will increase this lifeline draw spacing (2 times the default spacing) from the last added
120 * lifeline.
121 *
122 * @return a new lifeline index
123 */
124 protected int getNewHorizontalIndex() {
125 return ++horizontalIndex;
126 }
127
128 /**
129 * Returns the current horizontal index
130 *
131 * @return the current horizontal index
132 * @see Frame#getNewHorizontalIndex() for horizontal index description
133 */
134 protected int getHorizontalIndex() {
135 return horizontalIndex;
136 }
137
138 /**
139 * Add a GraphNode into the frame
140 *
141 * @param nodeToAdd the node to add
142 */
143 @Override
144 public void addNode(GraphNode nodeToAdd) {
145 computeMinMax = true;
146 super.addNode(nodeToAdd);
147 }
148
149 /**
150 * @return the frame x axis value in the containing view
151 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getX()
152 */
153 @Override
154 public int getX() {
155 return Metrics.FRAME_H_MARGIN;
156 }
157
158 /**
159 * @return the frame y axis value in the containing view
160 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getX()
161 */
162 @Override
163 public int getY() {
164 return Metrics.FRAME_V_MARGIN;
165 }
166
167 /**
168 * The frame width depends on the number of lifeline added in the frame
169 *
170 * @return the frame width
171 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getWidth()
172 */
173 @Override
174 public int getWidth() {
175 if (horizontalIndex == 0)
176 return 3 * Metrics.swimmingLaneWidth() + Metrics.LIFELINE_H_MAGIN * 2 - Metrics.FRAME_H_MARGIN - Metrics.LIFELINE_SPACING / 2;
177 else
178 return horizontalIndex * Metrics.swimmingLaneWidth() + Metrics.LIFELINE_H_MAGIN * 2 + 1 - Metrics.LIFELINE_SPACING;
179 }
180
181 /**
182 * The Frame height depends on the maximum number of messages added to a lifeline( Taking all lifelines into
183 * account)
184 *
185 * @return the frame height
186 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getHeight()
187 */
188 @Override
189 public int getHeight() {
190 if (verticalIndex == 0)
191 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
192 + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getLifelineFontHeigth() * 2;
193 if (forceEventOccurrenceSpacing >= 0)
194 Metrics.setForcedEventSpacing(forceEventOccurrenceSpacing);
195 return verticalIndex * (Metrics.getMessagesSpacing() + Metrics.getMessageFontHeigth()) + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getFrameFontHeigth() + Metrics.LIFELINE_VT_MAGIN + Metrics.LIFELINE_VB_MAGIN
196 + Metrics.LIFELINE_NAME_H_MARGIN + Metrics.FRAME_NAME_H_MARGIN + Metrics.getLifelineFontHeigth() * 2;
197 }
198
199 /**
200 * Returns the graph node which contains the point given in parameter for the given graph node list and starting the
201 * iteration at the given index<br>
202 * WARNING: Only graph nodes with smaller coordinates than the current visible area can be returned.<br>
203 *
204 * @param x the x coordinate of the point to test
205 * @param y the y coordinate of the point to test
206 * @param list the list to search in
207 * @param fromIndex list browsing starting point
208 * @return the graph node containing the point given in parameter, null otherwise
209 */
210 @Override
211 protected GraphNode getNodeFromListAt(int x, int y, List<GraphNode> list, int fromIndex) {
212 if (list == null)
213 return null;
214 for (int i = fromIndex; i < list.size(); i++) {
215 GraphNode node = (GraphNode) list.get(i);
216 // only lifeline list is x ordered
217 // Stop browsing the list if the node is outside the visible area
218 // all others nodes will be not visible
219 if ((node instanceof Lifeline) && (node.getX() > visibleAreaX + visibleAreaWidth))
220 break;
221 if (node.getHeight() < 0) {
222 if (node.getY() + node.getHeight() > visibleAreaY + visibleAreaHeight)
223 break;
224 } else {
225 if (node.getY() > visibleAreaY + visibleAreaHeight)
226 break;
227 }
228 if (node.contains(x, y))
229 return node;
230 }
231 return null;
232 }
233
234 /**
235 * Draw the Frame rectangle
236 *
237 * @param context the context to draw to
238 */
239 protected void drawFrame(IGC context) {
240 context.setBackground(Frame.getUserPref().getBackGroundColor(ISDPreferences.PREF_FRAME));
241 context.setForeground(Frame.getUserPref().getForeGroundColor(ISDPreferences.PREF_FRAME));
242
243 int x = getX();
244 int y = getY();
245 int w = getWidth();
246 int h = getHeight();
247
248 // Draw the frame main rectangle
249 context.fillRectangle(x, y, w, h);
250 context.drawRectangle(x, y, w, h);
251
252 context.setBackground(Frame.getUserPref().getBackGroundColor(ISDPreferences.PREF_FRAME_NAME));
253 context.setForeground(Frame.getUserPref().getForeGroundColor(ISDPreferences.PREF_FRAME_NAME));
254 context.setFont(Frame.getUserPref().getFont(ISDPreferences.PREF_FRAME_NAME));
255
256 int nameWidth = context.textExtent(getName()) + 2 * Metrics.FRAME_NAME_V_MARGIN;
257 int nameHeight = Metrics.getFrameFontHeigth() + +Metrics.FRAME_NAME_H_MARGIN * 2;
258
259 // Draw the frame name area
260 if (nameWidth > w)
261 nameWidth = w;
262
263 int[] points = { x, y, x + nameWidth, y, x + nameWidth, y - 11 + nameHeight, x - 11 + nameWidth, y + nameHeight, x, y + nameHeight, x, y + nameHeight };
264 context.fillPolygon(points);
265 context.drawPolygon(points);
266 context.drawLine(x, y, x, y + nameHeight);
267
268 context.setForeground(Frame.getUserPref().getFontColor(ISDPreferences.PREF_FRAME_NAME));
269 context.drawTextTruncatedCentred(getName(), x, y, nameWidth - 11, nameHeight, false);
270
271 context.setBackground(Frame.getUserPref().getBackGroundColor(ISDPreferences.PREF_FRAME));
272 context.setForeground(Frame.getUserPref().getForeGroundColor(ISDPreferences.PREF_FRAME));
273 }
274
275 /**
276 * Draws the Frame on the given context.<br>
277 * This method start width GraphNodes ordering if needed.<br>
278 * After, depending on the visible area, only visible GraphNodes are drawn.<br>
279 *
280 * @param context the context to draw to
281 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC)
282 */
283 @Override
284 public void draw(IGC context) {
285 draw(context, true);
286 }
287
288 /**
289 * Draws the Frame on the given context.<br>
290 * This method start width GraphNodes ordering if needed.<br>
291 * After, depending on the visible area, only visible GraphNodes are drawn.<br>
292 *
293 * @param context the context to draw to
294 * @param drawFrame indicate if the frame rectangle need to be redrawn
295 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#draw(IGC)
296 */
297 protected void draw(IGC context, boolean drawFrame) {
298 visibleAreaHeight = context.getVisibleHeight();
299 visibleAreaWidth = context.getVisibleWidth();
300 visibleAreaX = context.getContentsX();
301 visibleAreaY = context.getContentsY();
302
303 if (forceEventOccurrenceSpacing >= 0)
304 Metrics.setForcedEventSpacing(forceEventOccurrenceSpacing);
305 else
306 Metrics.setForcedEventSpacing(-1);
307 if (userPref == null)
308 return;
309 super.drawChildenNodes(context);
310 }
311
312 public static void setUserPref(ISDPreferences pref) {
313 userPref = pref;
314 }
315
316 public static ISDPreferences getUserPref() {
317 return userPref;
318 }
319
320 public void forceEventOccurrenceSpacing(int space) {
321 forceEventOccurrenceSpacing = space;
322 }
323
324 /**
325 * Return the X coordinates of the frame visible area
326 *
327 * @return the X coordinates of the frame visible area
328 */
329 public int getVisibleAreaX() {
330 return visibleAreaX;
331 }
332
333 /**
334 * Return the frame visible area width
335 *
336 * @return the frame visible area width
337 */
338 public int getVisibleAreaWidth() {
339 return visibleAreaWidth;
340 }
341
342 /**
343 * Return the frame visible area height
344 *
345 * @return the frame visible area height
346 */
347 public int getVisibleAreaHeight() {
348 return visibleAreaHeight;
349 }
350
351 /**
352 * Return the X coordinates of the frame visible area
353 *
354 * @return the X coordinates of the frame visible area
355 */
356 public int getVisibleAreaY() {
357 return visibleAreaY;
358 }
359
360 /**
361 * Return the minimum time stored in the frame taking all GraphNodes into account
362 *
363 * @return the minimum GraphNode time
364 */
4df4581d 365 public ITmfTimestamp getMinTime() {
73005152
BH
366 if (lastExternalTimePref != SDViewPref.getInstance().excludeExternalTime()) {
367 lastExternalTimePref = SDViewPref.getInstance().excludeExternalTime();
368 computeMinMax = true;
369 }
370 if ((computeMinMax) && (!customMinMax)) {
371 computeMinMax();
372 computeMinMax = false;
373 }
374 return minTime;
375 }
376
d7dbf09a 377 public void setMin(ITmfTimestamp min) {
73005152
BH
378 minTime = min;
379 customMinMax = true;
380 }
381
d7dbf09a 382 public void setMax(ITmfTimestamp max) {
73005152
BH
383 maxTime = max;
384 customMinMax = true;
385 }
386
387 public void resetCustomMinMax() {
388 customMinMax = false;
389 computeMinMax = true;
390 }
391
392 /**
393 * Return the maximum time stored in the frame taking all GraphNodes into account
394 *
395 * @return the maximum GraphNode time
396 */
4df4581d 397 public ITmfTimestamp getMaxTime() {
73005152
BH
398 if (lastExternalTimePref != SDViewPref.getInstance().excludeExternalTime()) {
399 lastExternalTimePref = SDViewPref.getInstance().excludeExternalTime();
400 computeMinMax = true;
401 }
402 if (computeMinMax) {
403 computeMinMax();
404 computeMinMax = false;
405 }
406 return maxTime;
407 }
408
409 protected void computeMaxMinTime() {
410 if (!initSDMin)
411 return;
412
413 List<SDTimeEvent> timeArray = buildTimeArray();
414 if (timeArray == null)
415 return;
416 for (int i = 0; i < timeArray.size(); i++) {
417 SDTimeEvent m = (SDTimeEvent) timeArray.get(i);
418
419 if (m.getTime().compareTo(maxSDTime, true) > 0) {
420 maxSDTime = m.getTime();
421 }
422
423 if ((m.getTime().compareTo(minSDTime, true) < 0) || (initSDMin == true)) {
424 minSDTime = m.getTime();
425 initSDMin = false;
426 }
427 }
428 }
429
4df4581d 430 public ITmfTimestamp getSDMinTime() {
73005152
BH
431 computeMaxMinTime();
432 return minSDTime;
433 }
434
4df4581d 435 public ITmfTimestamp getSDMaxTime() {
73005152
BH
436 computeMaxMinTime();
437 return maxSDTime;
438 }
439
440 /**
441 * Browse all the GraphNode to compute the min and max times store in the Frame
442 */
443 protected void computeMinMax() {
444 List<SDTimeEvent> timeArray = buildTimeArray();
445 if (timeArray == null)
446 return;
447 for (int i = 0; i < timeArray.size() - 1; i++) {
448 SDTimeEvent m1 = (SDTimeEvent) timeArray.get(i);
449 SDTimeEvent m2 = (SDTimeEvent) timeArray.get(i + 1);
450
451 updateMinMax(m1, m2);
452
453 }
454 }
455
456 protected void updateMinMax(SDTimeEvent m1, SDTimeEvent m2) {
4df4581d 457 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime());
73005152
BH
458 if (computeMinMax) {
459 minTime = delta.clone();
a4115405 460 if (minTime.compareTo(TmfTimestamp.ZERO, false) < 0) {
73005152
BH
461 minTime = new TmfTimestamp(0, m1.getTime().getScale(), m1.getTime().getPrecision());
462 }
463 maxTime = minTime.clone();
464 computeMinMax = false;
465 }
466
a4115405 467 if ((delta.compareTo(minTime, true) < 0) && (delta.compareTo(TmfTimestamp.ZERO, false) > 0)) {
73005152
BH
468 minTime = delta.clone();
469 }
470
a4115405 471 if ((delta.compareTo(maxTime, true) > 0) && (delta.compareTo(TmfTimestamp.ZERO, false) > 0)) {
73005152
BH
472 maxTime = delta.clone();
473 }
474 }
475
476 protected List<SDTimeEvent> buildTimeArray() {
477 if (!hasChilden)
478 return null;
479
480 Iterator<String> it = fSort.keySet().iterator();
481 List<SDTimeEvent> timeArray = new ArrayList<SDTimeEvent>();
482 while (it.hasNext()) {
483 String nodeType = it.next();
484 List<GraphNode> list = (List<GraphNode>) nodes.get(nodeType);
485 for (int i = 0; i < list.size(); i++) {
486 Object timedNode = list.get(i);
487 if ((timedNode instanceof ITimeRange) && ((ITimeRange) timedNode).hasTimeInfo()) {
488 int event = ((GraphNode) list.get(i)).getStartOccurrence();
4df4581d 489 ITmfTimestamp time = ((ITimeRange) list.get(i)).getStartTime();
73005152
BH
490 SDTimeEvent f = new SDTimeEvent(time, event, (ITimeRange) list.get(i));
491 timeArray.add(f);
492 if (event != ((GraphNode) list.get(i)).getEndOccurrence()) {
493 event = ((AsyncMessage) list.get(i)).getEndOccurrence();
494 time = ((ITimeRange) list.get(i)).getEndTime();
495 f = new SDTimeEvent(time, event, (ITimeRange) list.get(i));
496 timeArray.add(f);
497 }
498 }
499 }
500 }
501 return timeArray;
502 }
503
504 /*
505 * (non-Javadoc)
506 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#getArrayId()
507 */
508 @Override
509 public String getArrayId() {
510 return null;
511 }
512
513 /*
514 * (non-Javadoc)
515 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.core.GraphNode#contains(int, int)
516 */
517 @Override
518 public boolean contains(int x, int y) {
519 return false;
520 }
521}
This page took 0.077976 seconds and 5 git commands to generate.