tmf.core: Introduce TmfTimestamp factory methods
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / views / uml2sd / TimeCompressionBar.java
CommitLineData
73005152 1/**********************************************************************
ed902a2b 2 * Copyright (c) 2005, 2014 IBM Corporation, Ericsson
73005152
BH
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
013a5f1c
AM
7 *
8 * Contributors:
c8422608
AM
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
73005152 11 **********************************************************************/
c8422608 12
2bdf0193 13package org.eclipse.tracecompass.tmf.ui.views.uml2sd;
73005152
BH
14
15import java.util.ArrayList;
16import java.util.Arrays;
17import java.util.List;
18
73005152
BH
19import org.eclipse.swt.SWT;
20import org.eclipse.swt.accessibility.ACC;
21import org.eclipse.swt.accessibility.Accessible;
22import org.eclipse.swt.accessibility.AccessibleAdapter;
23import org.eclipse.swt.accessibility.AccessibleControlAdapter;
24import org.eclipse.swt.accessibility.AccessibleControlEvent;
25import org.eclipse.swt.accessibility.AccessibleEvent;
26import org.eclipse.swt.events.DisposeEvent;
27import org.eclipse.swt.events.DisposeListener;
28import org.eclipse.swt.events.FocusEvent;
29import org.eclipse.swt.events.FocusListener;
30import org.eclipse.swt.events.KeyEvent;
31import org.eclipse.swt.events.MouseEvent;
32import org.eclipse.swt.events.TraverseEvent;
33import org.eclipse.swt.events.TraverseListener;
34import org.eclipse.swt.graphics.Color;
35import org.eclipse.swt.graphics.GC;
36import org.eclipse.swt.graphics.Image;
37import org.eclipse.swt.widgets.Composite;
38import org.eclipse.swt.widgets.Control;
39import org.eclipse.swt.widgets.Display;
2bdf0193
AM
40import org.eclipse.tracecompass.internal.tmf.ui.Activator;
41import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
42import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
43import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessage;
44import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessageReturn;
45import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.BaseMessage;
46import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.ExecutionOccurrence;
47import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Frame;
48import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode;
49import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.ITimeRange;
50import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline;
51import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Metrics;
52import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SDTimeEvent;
53import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage;
54import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor;
55import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl.ColorImpl;
56import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref;
57import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.TimeEventComparator;
73005152
BH
58
59/**
df0b8ff4
BH
60 * <p>
61 * The time compression bar implementation.
62 * </p>
013a5f1c 63 *
df0b8ff4 64 * @version 1.0
73005152 65 * @author sveyrier
73005152
BH
66 */
67public class TimeCompressionBar extends ScrollView implements DisposeListener {
68
f26e290b
BH
69 // ------------------------------------------------------------------------
70 // Constants
71 // ------------------------------------------------------------------------
72 private static final int BASE_RED_VALUE = 255;
73 private static final int BASE_GREEN_BLUE_VALUE = 225;
74 private static final int COLOR_STEP = 25;
75 private static final int NUMBER_STEPS = 10;
76
df0b8ff4
BH
77 // ------------------------------------------------------------------------
78 // Attributes
79 // ------------------------------------------------------------------------
80
73005152
BH
81 /**
82 * The listener list
83 */
cab6c8ff 84 private List<ITimeCompressionListener> fListenerList = null;
df0b8ff4
BH
85 /**
86 * The current frame displayed.
87 */
cab6c8ff 88 private Frame fFrame = null;
df0b8ff4
BH
89 /**
90 * List of time events.
91 */
cab6c8ff 92 private List<SDTimeEvent> fNodeList = null;
df0b8ff4
BH
93 /**
94 * The minimum time delta.
95 */
b2c971ec 96 private ITmfTimestamp fMinTime = TmfTimestamp.fromSeconds(0);
df0b8ff4
BH
97 /**
98 * The maximum time delta.
99 */
b2c971ec 100 private ITmfTimestamp fMaxTime = TmfTimestamp.fromSeconds(0);
df0b8ff4
BH
101 /**
102 * The current zoom value.
103 */
cab6c8ff 104 private float fZoomValue = 1;
df0b8ff4
BH
105 /**
106 * The tooltip to display.
107 */
cab6c8ff 108 private DrawableToolTip fTooltip = null;
df0b8ff4 109 /**
d3024bf7 110 * Array of colors for displaying wight of time deltas.
df0b8ff4 111 */
cab6c8ff 112 private ColorImpl[] fColors;
df0b8ff4
BH
113 /**
114 * The accessible object reference.
115 */
cab6c8ff 116 private Accessible fAccessible = null;
df0b8ff4
BH
117 /**
118 * The focused widget reference.
119 */
cab6c8ff 120 private int fFocusedWidget = -1;
df0b8ff4
BH
121 /**
122 * The current lifeline.
123 */
cab6c8ff 124 private Lifeline fLifeline = null;
df0b8ff4
BH
125 /**
126 * The current start event value.
127 */
cab6c8ff 128 private int fLifelineStart = 0;
df0b8ff4
BH
129 /**
130 * The current number of events.
131 */
cab6c8ff 132 private int fLifelineNumEvents = 0;
df0b8ff4 133 /**
013a5f1c 134 * The Current color of range to display.
df0b8ff4 135 */
cab6c8ff 136 private IColor fLifelineColor = null;
df0b8ff4 137 /**
d3024bf7 138 * The next graph node y coordinate.
df0b8ff4 139 */
cab6c8ff 140 private int fNextNodeY = 0;
df0b8ff4 141 /**
d3024bf7 142 * The previous graph node y coordinate.
df0b8ff4 143 */
cab6c8ff 144 private int fPrevNodeY = 0;
73005152 145
df0b8ff4
BH
146 // ------------------------------------------------------------------------
147 // Constructors
148 // ------------------------------------------------------------------------
149 /**
150 * Standard constructor
013a5f1c 151 *
d3024bf7
MK
152 * @param parent
153 * The parent composite
154 * @param s
155 * The style bits
df0b8ff4 156 */
73005152
BH
157 public TimeCompressionBar(Composite parent, int s) {
158 super(parent, s | SWT.NO_BACKGROUND, false);
159 setVScrollBarMode(ScrollView.ALWAYS_OFF);
160 setHScrollBarMode(ScrollView.ALWAYS_OFF);
507b1336 161 fListenerList = new ArrayList<>();
f26e290b
BH
162 fColors = new ColorImpl[NUMBER_STEPS];
163 int greenBlue = BASE_GREEN_BLUE_VALUE;
164 final int step = COLOR_STEP;
165 for (int i = 0; i < fColors.length; i++) {
166 fColors[i] = new ColorImpl(Display.getDefault(), BASE_RED_VALUE, greenBlue, greenBlue);
167 greenBlue -= step;
168 }
73005152
BH
169 super.addDisposeListener(this);
170
eb63f5ff 171 fAccessible = getViewControl().getAccessible();
73005152 172
eb63f5ff 173 fAccessible.addAccessibleListener(new AccessibleAdapter() {
73005152
BH
174 @Override
175 public void getName(AccessibleEvent e) {
73005152 176 // Case toolTip
eb63f5ff
BH
177 if (e.childID == 0) {
178 if (fTooltip != null) {
179 e.result = fTooltip.getAccessibleText();
df0b8ff4 180 }
73005152
BH
181 } else if (e.childID == 1) {
182 createFakeTooltip();
eb63f5ff 183 e.result = fTooltip.getAccessibleText();
73005152
BH
184 }
185 }
186 });
187
eb63f5ff 188 fAccessible.addAccessibleControlListener(new AccessibleControlAdapter() {
73005152
BH
189 @Override
190 public void getFocus(AccessibleControlEvent e) {
eb63f5ff 191 if (fFocusedWidget == -1) {
73005152 192 e.childID = ACC.CHILDID_SELF;
df0b8ff4
BH
193 }
194 else {
eb63f5ff 195 e.childID = fFocusedWidget;
df0b8ff4 196 }
73005152
BH
197 }
198
199 @Override
200 public void getRole(AccessibleControlEvent e) {
201 switch (e.childID) {
202 case ACC.CHILDID_SELF:
203 e.detail = ACC.ROLE_CLIENT_AREA;
204 break;
205 case 0:
206 e.detail = ACC.ROLE_TOOLTIP;
207 break;
208 case 1:
209 e.detail = ACC.ROLE_LABEL;
210 break;
eb63f5ff 211 default:
d3024bf7 212 break;
73005152
BH
213 }
214 }
215
216 @Override
217 public void getState(AccessibleControlEvent e) {
218 e.detail = ACC.STATE_FOCUSABLE;
219 if (e.childID == ACC.CHILDID_SELF) {
220 e.detail |= ACC.STATE_FOCUSED;
221 } else {
222 e.detail |= ACC.STATE_SELECTABLE;
eb63f5ff 223 if (e.childID == fFocusedWidget) {
73005152 224 e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED;
df0b8ff4 225 }
73005152
BH
226 }
227 }
228 });
229
3145ec83 230 getViewControl().addTraverseListener(new LocalTraverseListener());
73005152 231
3145ec83 232 addTraverseListener(new LocalTraverseListener());
73005152
BH
233
234 getViewControl().addFocusListener(new FocusListener() {
73005152
BH
235 @Override
236 public void focusGained(FocusEvent e) {
73005152
BH
237 redraw();
238 }
239
240 @Override
241 public void focusLost(FocusEvent e) {
242 redraw();
243 }
244 });
245 }
246
df0b8ff4
BH
247 // ------------------------------------------------------------------------
248 // Methods
249 // ------------------------------------------------------------------------
250
251 /**
252 * Sets the focus widget
013a5f1c 253 *
d3024bf7
MK
254 * @param newFocusShape
255 * widget reference to set
df0b8ff4 256 */
73005152 257 void setFocus(int newFocusShape) {
eb63f5ff
BH
258 fFocusedWidget = newFocusShape;
259 if (fFocusedWidget == -1) {
73005152
BH
260 getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF);
261 } else {
eb63f5ff 262 getViewControl().getAccessible().setFocus(fFocusedWidget);
73005152
BH
263 }
264 }
265
df0b8ff4
BH
266 /**
267 * Sets the current frame.
013a5f1c 268 *
d3024bf7
MK
269 * @param theFrame
270 * The frame to set
df0b8ff4 271 */
73005152 272 public void setFrame(Frame theFrame) {
eb63f5ff
BH
273 fFrame = theFrame;
274 fMinTime = fFrame.getMinTime();
275 fMaxTime = fFrame.getMaxTime();
73005152
BH
276 }
277
278 @Override
279 protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) {
eb63f5ff 280 if (fFrame == null) {
73005152 281 return;
df0b8ff4 282 }
507b1336 283 fNodeList = new ArrayList<>();
73005152
BH
284 int messageArraysStep = 1;
285
eb63f5ff
BH
286 if ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * fZoomValue < Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1) {
287 messageArraysStep = Math.round(Metrics.MESSAGE_SIGNIFICANT_VSPACING + 1 / ((Metrics.getMessageFontHeigth() + Metrics.MESSAGES_NAME_SPACING * 2) * fZoomValue));
df0b8ff4 288 }
73005152 289
eb63f5ff 290 int firstVisible = fFrame.getFirstVisibleSyncMessage();
df0b8ff4 291 if (firstVisible > 0) {
73005152 292 firstVisible = firstVisible - 1;
df0b8ff4 293 }
eb63f5ff
BH
294 for (int i = firstVisible; i < fFrame.syncMessageCount(); i = i + messageArraysStep) {
295 SyncMessage m = fFrame.getSyncMessage(i);
d3024bf7
MK
296 if (addMessageIfVisible(m)) {
297 break;
73005152
BH
298 }
299 }
300
eb63f5ff 301 firstVisible = fFrame.getFirstVisibleSyncMessageReturn();
df0b8ff4 302 if (firstVisible > 0) {
73005152 303 firstVisible = firstVisible - 1;
df0b8ff4 304 }
eb63f5ff
BH
305 for (int i = firstVisible; i < fFrame.syncMessageReturnCount(); i = i + messageArraysStep) {
306 SyncMessage m = fFrame.getSyncMessageReturn(i);
d3024bf7
MK
307 if (addMessageIfVisible(m)) {
308 break;
73005152
BH
309 }
310 }
311
eb63f5ff 312 firstVisible = fFrame.getFirstVisibleAsyncMessage();
df0b8ff4 313 if (firstVisible > 0) {
73005152 314 firstVisible = firstVisible - 1;
df0b8ff4 315 }
eb63f5ff 316 for (int i = firstVisible; i < fFrame.asyncMessageCount(); i = i + messageArraysStep) {
d3024bf7
MK
317 BaseMessage m = fFrame.getAsyncMessage(i);
318 if (addMessageIfVisible(m)) {
319 break;
73005152
BH
320 }
321 }
322
eb63f5ff 323 firstVisible = fFrame.getFirstVisibleAsyncMessageReturn();
df0b8ff4 324 if (firstVisible > 0) {
73005152 325 firstVisible = firstVisible - 1;
df0b8ff4 326 }
eb63f5ff
BH
327 for (int i = firstVisible; i < fFrame.asyncMessageReturnCount(); i = i + messageArraysStep) {
328 AsyncMessageReturn m = fFrame.getAsyncMessageReturn(i);
d3024bf7
MK
329 if (addMessageIfVisible(m)) {
330 break;
73005152
BH
331 }
332 }
333
eb63f5ff 334 List<SDTimeEvent> executionOccurrencesWithTime = fFrame.getExecutionOccurrencesWithTime();
73005152 335 if (executionOccurrencesWithTime != null) {
eb63f5ff 336 fNodeList.addAll(executionOccurrencesWithTime);
73005152
BH
337 }
338
eb63f5ff 339 SDTimeEvent[] temp = fNodeList.toArray(new SDTimeEvent[fNodeList.size()]);
73005152 340 Arrays.sort(temp, new TimeEventComparator());
eb63f5ff 341 fNodeList = Arrays.asList(temp);
73005152 342
95aee2a1
AM
343 Image dbuffer = new Image(getDisplay(), getClientArea().width, getClientArea().height);
344 GC gcim = new GC(dbuffer);
345
eb63f5ff 346 for (int i = 0; i < fNodeList.size() - 1; i++) {
abbdd66a
AM
347 SDTimeEvent m1 = fNodeList.get(i);
348 SDTimeEvent m2 = fNodeList.get(i + 1);
eb63f5ff
BH
349
350 if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) {
351 BaseMessage mes1 = (BaseMessage) m1.getGraphNode();
352 BaseMessage mes2 = (BaseMessage) m2.getGraphNode();
353 if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) {
354 continue;
73005152
BH
355 }
356 }
357
eb63f5ff
BH
358 fMinTime = fFrame.getMinTime();
359 fMaxTime = fFrame.getMaxTime();
360 ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime);
f26e290b 361 double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS;
73005152 362
eb63f5ff 363 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(fMinTime);
73005152 364 long absDelta = Math.abs(delta.getValue());
013a5f1c 365
73005152
BH
366 ColorImpl color;
367 if (gr != 0) {
368 int colIndex = Math.round((float) (absDelta / gr));
eb63f5ff
BH
369 if (colIndex < fColors.length && colIndex > 0) {
370 color = fColors[colIndex - 1];
df0b8ff4 371 } else if (colIndex <= 0) {
eb63f5ff 372 color = fColors[0];
df0b8ff4 373 } else {
eb63f5ff 374 color = fColors[fColors.length - 1];
df0b8ff4
BH
375 }
376 } else {
eb63f5ff 377 color = fColors[0];
df0b8ff4 378 }
73005152 379
df0b8ff4 380 if (color.getColor() instanceof Color) {
73005152 381 gcim.setBackground((Color) color.getColor());
df0b8ff4 382 }
d3024bf7
MK
383 PairOfYs poy = adjustHeights(m1, m2);
384 int y1 = poy.getY1();
385 int y2 = poy.getY2();
eb63f5ff 386 gcim.fillRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * fZoomValue)), 10, Math.round((y2 - y1) * fZoomValue) + 1);
73005152
BH
387 if (messageArraysStep == 1) {
388 Color backupColor = gcim.getForeground();
389 gcim.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
eb63f5ff 390 gcim.drawRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * fZoomValue)), 9, Math.round((y2 - y1) * fZoomValue));
73005152
BH
391 gcim.setForeground(backupColor);
392 }
393 }
394 if (getViewControl().isFocusControl() || isFocusControl()) {
eb63f5ff 395 gcim.drawFocus(contentsToViewX(0), contentsToViewY(Math.round(fPrevNodeY * fZoomValue)), contentsToViewX(10), Math.round((fNextNodeY - fPrevNodeY) * fZoomValue));
73005152
BH
396 }
397 try {
398 gc.drawImage(dbuffer, 0, 0, getClientArea().width, getClientArea().height, 0, 0, getClientArea().width, getClientArea().height);
399 } catch (Exception e) {
8fd82db5 400 Activator.getDefault().logError("Error drawing image", e); //$NON-NLS-1$
73005152
BH
401 }
402 gcim.dispose();
95aee2a1 403 dbuffer.dispose();
73005152
BH
404 gc.dispose();
405 }
406
d3024bf7
MK
407 private boolean addMessageIfVisible(BaseMessage m) {
408 if (m instanceof ITimeRange) {
409 ITimeRange timeRange = (ITimeRange) m;
410 if (timeRange.hasTimeInfo()) {
411 SDTimeEvent t = new SDTimeEvent(timeRange.getStartTime(), m.getStartOccurrence(), timeRange);
412 fNodeList.add(t);
413 if (m instanceof AsyncMessage) {
414 t = new SDTimeEvent(timeRange.getEndTime(), m.getEndOccurrence(), timeRange);
415 fNodeList.add(t);
416 }
417 return isNotVisible(m);
418 }
419 }
420 return false;
421 }
422
423 private boolean isNotVisible(BaseMessage m) {
424 return m.getY() * fZoomValue > getContentsY() + getVisibleHeight();
425 }
426
427 private static int addHeightIfAsynchronousMessage(SDTimeEvent timeEvent, int yPos) {
428 if (timeEvent.getGraphNode() instanceof AsyncMessage) {
429 AsyncMessage as = (AsyncMessage) timeEvent.getGraphNode();
430 if (as.getEndTime() == timeEvent.getTime()) {
431 return yPos + as.getHeight();
432 }
433 }
434 return yPos;
435 }
436
437 private static int addHeight(SDTimeEvent timeEvent, int yPos) {
438 ExecutionOccurrence eo = (ExecutionOccurrence) timeEvent.getGraphNode();
439 if (timeEvent.getEvent() == eo.getEndOccurrence()) {
440 return yPos + eo.getHeight();
441 }
442 return yPos;
443 }
444
445 private static int addHeightIfExecutionOccurence(SDTimeEvent timeWidget, int yPos) {
446 if (timeWidget.getGraphNode() instanceof ExecutionOccurrence) {
447 ExecutionOccurrence eo2 = (ExecutionOccurrence) timeWidget.getGraphNode();
448 if (timeWidget.getEvent() == eo2.getEndOccurrence()) {
449 return yPos + eo2.getHeight();
450 }
451 }
452 return yPos;
453 }
454
df0b8ff4
BH
455 /**
456 * Checks for focus of children.
013a5f1c 457 *
a0a88f65
AM
458 * @param children
459 * Control to check
df0b8ff4
BH
460 * @return true if child is on focus else false
461 */
a0a88f65
AM
462 protected boolean checkFocusOnChilds(Control children) {
463 if (children instanceof Composite) {
464 Control[] child = ((Composite) children).getChildren();
73005152
BH
465 for (int i = 0; i < child.length; i++) {
466 if (child[i].isFocusControl()) {
467 return true;
df0b8ff4 468 }
abbdd66a 469 checkFocusOnChilds(child[i]);
73005152
BH
470 }
471 }
472 return false;
473 }
474
475 @Override
476 public boolean isFocusControl() {
477 Control[] child = getChildren();
478 for (int i = 0; i < child.length; i++) {
479 if (child[i].isFocusControl()) {
480 return true;
df0b8ff4 481 }
abbdd66a 482 checkFocusOnChilds(child[i]);
73005152
BH
483 }
484 return false;
485 }
486
487 @Override
488 protected void contentsMouseMoveEvent(MouseEvent event) {
eb63f5ff
BH
489 if (fTooltip != null) {
490 fTooltip.hideToolTip();
df0b8ff4 491 }
73005152
BH
492 super.contentsMouseMoveEvent(event);
493 if (!isFocusControl() || getViewControl().isFocusControl()) {
494 Control[] child = getParent().getChildren();
495 for (int i = 0; i < child.length; i++) {
496 if (child[i].isFocusControl()) {
73005152
BH
497 break;
498 }
499 }
500 }
501 setFocus(-1);
502 }
503
504 @Override
505 protected void contentsMouseHover(MouseEvent e) {
eb63f5ff
BH
506 if (fTooltip == null) {
507 fTooltip = new DrawableToolTip(this);
73005152 508 }
eb63f5ff 509 if (fFrame != null) {
73005152 510 setFocus(0);
eb63f5ff 511 for (int i = 0; i < fNodeList.size() - 1; i++) {
abbdd66a
AM
512 SDTimeEvent m1 = fNodeList.get(i);
513 SDTimeEvent m2 = fNodeList.get(i + 1);
73005152 514
d3024bf7
MK
515 if (skipIfLifelineIsNull(m1, m2)) {
516 continue;
73005152 517 }
d3024bf7 518 PairOfYs poy = adjustHeights(m1, m2);
73005152 519
d3024bf7
MK
520 int m1Y = Math.round(poy.getY1() * fZoomValue);
521 int m2Y = Math.round(poy.getY2() * fZoomValue);
73005152 522 if ((m1Y < e.y) && (m2Y >= e.y)) {
df0b8ff4 523 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime());
eb63f5ff 524 fTooltip.showToolTip(delta, fMinTime, fMaxTime);
73005152
BH
525 }
526 }
527 }
528 setFocus(0);
529 }
530
531 @Override
532 protected void contentsMouseExit(MouseEvent e) {
013a5f1c 533 if (fTooltip != null) {
eb63f5ff 534 fTooltip.hideToolTip();
013a5f1c 535 }
73005152
BH
536 }
537
538 @Override
539 protected void contentsMouseUpEvent(MouseEvent event) {
540 selectTimeDelta(event.y, 0);
541 setFocus();
542 super.contentsMouseUpEvent(event);
543 }
544
545 /**
a55887ca
AM
546 * Force the time compression bar to highlight the event occurrences between
547 * the two given messages. The event occurrences are highlighted on the
548 * first message's end lifeline
013a5f1c 549 *
a55887ca
AM
550 * @param mes1
551 * the first message
552 * @param mes2
553 * the second message
73005152
BH
554 */
555 public void highlightRegion(BaseMessage mes1, BaseMessage mes2) {
013a5f1c 556 BaseMessage localMes1 = mes1;
eb63f5ff 557 BaseMessage localMes2 = mes2;
013a5f1c 558
eb63f5ff 559 if (fFrame == null) {
73005152 560 return;
df0b8ff4 561 }
eb63f5ff 562 if (!(localMes1 instanceof ITimeRange)) {
73005152 563 return;
df0b8ff4 564 }
eb63f5ff 565 if (!(localMes2 instanceof ITimeRange)) {
73005152 566 return;
df0b8ff4 567 }
eb63f5ff
BH
568 ITimeRange t1 = (ITimeRange) localMes1;
569 ITimeRange t2 = (ITimeRange) localMes2;
73005152 570
4df4581d 571 ITmfTimestamp time1 = t1.getStartTime();
572 ITmfTimestamp time2 = t2.getStartTime();
eb63f5ff
BH
573 int event1 = localMes1.getEventOccurrence();
574 int event2 = localMes2.getEventOccurrence();
73005152 575
eb63f5ff
BH
576 if (localMes1 instanceof AsyncMessage) {
577 AsyncMessage as = (AsyncMessage) localMes1;
73005152
BH
578 time1 = as.getEndTime();
579 event1 = as.getEndOccurrence();
580 }
eb63f5ff
BH
581 if (localMes2 instanceof AsyncMessage) {
582 AsyncMessage as = (AsyncMessage) localMes2;
73005152
BH
583 if (as.getEndOccurrence() > as.getStartOccurrence()) {
584 time1 = as.getEndTime();
585 event1 = as.getEndOccurrence();
586 } else {
587 time1 = as.getStartTime();
588 event1 = as.getStartOccurrence();
589 }
590 }
591
592 if (event1 > event2) {
eb63f5ff
BH
593 BaseMessage tempMes = localMes2;
594 localMes2 = localMes1;
595 localMes1 = tempMes;
73005152 596
eb63f5ff
BH
597 t1 = (ITimeRange) localMes1;
598 t2 = (ITimeRange) localMes2;
73005152
BH
599
600 time1 = t1.getStartTime();
601 time2 = t2.getStartTime();
eb63f5ff
BH
602 event1 = localMes1.getEventOccurrence();
603 event2 = localMes2.getEventOccurrence();
73005152 604
eb63f5ff
BH
605 if (localMes1 instanceof AsyncMessage) {
606 AsyncMessage as = (AsyncMessage) localMes1;
73005152
BH
607 time1 = as.getEndTime();
608 event1 = as.getEndOccurrence();
609 }
eb63f5ff
BH
610 if (localMes2 instanceof AsyncMessage) {
611 AsyncMessage as = (AsyncMessage) localMes2;
73005152
BH
612 if (as.getEndOccurrence() > as.getStartOccurrence()) {
613 time1 = as.getEndTime();
614 event1 = as.getEndOccurrence();
615 } else {
616 time1 = as.getStartTime();
617 event1 = as.getStartOccurrence();
618 }
619 }
620 }
621
eb63f5ff 622 ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime);
f26e290b 623 double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS;
73005152 624
eb63f5ff 625 ITmfTimestamp delta = time2.getDelta(time1).getDelta(fMinTime);
73005152
BH
626 long absDelta = Math.abs(delta.getValue());
627
628 int colIndex = 0;
629 if (gr != 0) {
630 colIndex = Math.round((float) (absDelta / gr));
eb63f5ff
BH
631 if (colIndex >= fColors.length) {
632 colIndex = fColors.length - 1;
df0b8ff4 633 } else if (colIndex < 0) {
73005152 634 colIndex = 0;
df0b8ff4
BH
635 }
636 } else {
73005152 637 colIndex = 0;
df0b8ff4 638 }
eb63f5ff 639 for (int j = 0; j < fListenerList.size(); j++) {
abbdd66a 640 ITimeCompressionListener list = fListenerList.get(j);
eb63f5ff
BH
641 if (localMes1.getEndLifeline() != null) {
642 list.deltaSelected(localMes1.getEndLifeline(), event1, event2 - event1, fColors[colIndex]);
643 } else if (localMes2.getStartLifeline() != null) {
644 list.deltaSelected(localMes2.getStartLifeline(), event1, event2 - event1, fColors[colIndex]);
df0b8ff4 645 } else {
eb63f5ff 646 list.deltaSelected(localMes1.getStartLifeline(), event1, event2 - event1, fColors[colIndex]);
df0b8ff4 647 }
73005152
BH
648 }
649 }
650
651 /**
d3024bf7
MK
652 * Force the time compression bar to highlight the event occurrences between
653 * the two given messages. The event occurrences are highlighted on the
654 * first message's end lifeline
013a5f1c 655 *
d3024bf7
MK
656 * @param mes1
657 * the first message
658 * @param mes2
659 * the second message
73005152
BH
660 */
661 public void highlightRegionSync(final BaseMessage mes1, final BaseMessage mes2) {
662 getDisplay().syncExec(new Runnable() {
663 @Override
664 public void run() {
665 highlightRegion(mes1, mes2);
666 }
667 });
668 }
669
670 @Override
671 public void scrollBy(int x, int y) {
672 }
673
df0b8ff4
BH
674 /**
675 * Sets the zoom value.
013a5f1c 676 *
d3024bf7
MK
677 * @param value
678 * The zoom value to set.
df0b8ff4 679 */
73005152 680 public void setZoom(float value) {
eb63f5ff 681 fZoomValue = value;
73005152
BH
682 redraw();
683 }
684
df0b8ff4 685 /**
d3024bf7
MK
686 * Adds a listener to the time compression listener list to be notified
687 * about selected deltas.
013a5f1c 688 *
d3024bf7
MK
689 * @param listener
690 * The listener to add
df0b8ff4 691 */
73005152 692 public void addTimeCompressionListener(ITimeCompressionListener listener) {
eb63f5ff
BH
693 if (!fListenerList.contains(listener)) {
694 fListenerList.add(listener);
df0b8ff4 695 }
73005152
BH
696 }
697
df0b8ff4
BH
698 /**
699 * Removes a time compression listener.
013a5f1c 700 *
d3024bf7
MK
701 * @param listener
702 * The listener to remove.
df0b8ff4 703 */
73005152 704 public void removeSelectionChangedListener(ITimeCompressionListener listener) {
eb63f5ff 705 fListenerList.remove(listener);
73005152
BH
706 }
707
708 @Override
709 public void widgetDisposed(DisposeEvent e) {
eb63f5ff
BH
710 if (fTooltip != null) {
711 fTooltip.dispose();
df0b8ff4 712 }
73005152 713 super.removeDisposeListener(this);
eb63f5ff
BH
714 for (int i = 0; i < fColors.length; i++) {
715 fColors[i].dispose();
df0b8ff4 716 }
73005152
BH
717 }
718
719 @Override
eb63f5ff
BH
720 protected void keyPressedEvent(KeyEvent event) {
721 if (fTooltip != null) {
722 fTooltip.hideToolTip();
df0b8ff4 723 }
73005152
BH
724 if (!isFocusControl() || getViewControl().isFocusControl()) {
725 Control[] child = getParent().getChildren();
726 for (int i = 0; i < child.length; i++) {
727 if (child[i].isFocusControl()) {
73005152
BH
728 break;
729 }
730 }
731 }
732 setFocus(-1);
733
734 boolean top = false;
eb63f5ff 735 if (fNextNodeY == 0) {
73005152 736 top = true;
df0b8ff4 737 }
eb63f5ff
BH
738 if ((fFrame != null) && (fNextNodeY == 0)) {
739 for (int i = 0; i < fNodeList.size() - 1 && i < 1; i++) {
abbdd66a
AM
740 SDTimeEvent m1 = fNodeList.get(i);
741 SDTimeEvent m2 = fNodeList.get(i + 1);
d3024bf7
MK
742 if (skipIfLifelineIsNull(m1, m2)) {
743 continue;
73005152 744 }
73005152 745
d3024bf7 746 PairOfYs poy = adjustHeights(m1, m2);
73005152 747
d3024bf7
MK
748 fPrevNodeY = Math.round(poy.getY1() * fZoomValue);
749 fNextNodeY = Math.round(poy.getY2() * fZoomValue);
73005152
BH
750 }
751 }
752
eb63f5ff
BH
753 if (fLifeline != null) {
754 for (int j = 0; j < fListenerList.size(); j++) {
abbdd66a 755 ITimeCompressionListener list = fListenerList.get(j);
eb63f5ff 756 list.deltaSelected(fLifeline, fLifelineStart, fLifelineNumEvents, fLifelineColor);
73005152 757 }
df0b8ff4 758 }
73005152 759
eb63f5ff 760 if (event.keyCode == SWT.ARROW_DOWN) {
df0b8ff4 761 if (!top) {
eb63f5ff 762 selectTimeDelta(fNextNodeY + 1, 1);
df0b8ff4 763 } else {
eb63f5ff 764 selectTimeDelta(fPrevNodeY + 1, 1);
df0b8ff4 765 }
73005152 766 setFocus(1);
eb63f5ff
BH
767 } else if (event.keyCode == SWT.ARROW_UP) {
768 selectTimeDelta(fPrevNodeY - 1, 2);
73005152 769 setFocus(1);
eb63f5ff
BH
770 } else if (event.keyCode == SWT.ARROW_RIGHT) {
771 selectTimeDelta(fPrevNodeY, 1);
73005152
BH
772 setFocus(1);
773 }
eb63f5ff 774 super.keyPressedEvent(event);
73005152
BH
775 }
776
73005152 777 /**
df0b8ff4 778 * Selects the time delta for given delta y coordinate and direction.
013a5f1c 779 *
d3024bf7
MK
780 * @param dy
781 * The delta in y coordinate.
782 * @param direction
783 * 0 no direction, 1 = down, 2 = up
73005152
BH
784 */
785 protected void selectTimeDelta(int dy, int direction) {
786 SDTimeEvent lastM1 = null;
787 SDTimeEvent lastM2 = null;
788 int lastY1 = 0;
789 int lastY2 = 0;
790 boolean done = false;
eb63f5ff
BH
791 if (fFrame != null) {
792 for (int i = 0; i < fNodeList.size() - 1; i++) {
abbdd66a
AM
793 SDTimeEvent m1 = fNodeList.get(i);
794 SDTimeEvent m2 = fNodeList.get(i + 1);
d3024bf7
MK
795 if (skipIfLifelineIsNull(m1, m2)) {
796 continue;
73005152
BH
797 }
798
d3024bf7 799 PairOfYs poy = adjustHeights(m1, m2);
73005152 800
d3024bf7
MK
801 int m1Y = Math.round(poy.getY1() * fZoomValue);
802 int m2Y = Math.round(poy.getY2() * fZoomValue);
73005152
BH
803
804 if ((m1Y < dy) && (m2Y > dy) || (!done && m2Y > dy && direction == 1 && lastM1 != null) || (!done && m1Y > dy && direction == 2 && lastM1 != null)) {
805 if (m1Y > dy && direction == 2) {
806 m1 = lastM1;
807 m2 = lastM2;
808 m1Y = lastY1;
809 m2Y = lastY2;
810 }
811 done = true;
eb63f5ff
BH
812 fPrevNodeY = m1Y;
813 fNextNodeY = m2Y;
814 ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime);
f26e290b 815 double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS;
73005152 816
eb63f5ff 817 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(fMinTime);
73005152
BH
818 long absDelta = Math.abs(delta.getValue());
819
820 int colIndex = 0;
821 if (gr != 0) {
822 colIndex = Math.round((float) (absDelta / gr));
eb63f5ff
BH
823 if (colIndex >= fColors.length) {
824 colIndex = fColors.length - 1;
df0b8ff4 825 } else if (colIndex < 0) {
73005152 826 colIndex = 0;
df0b8ff4
BH
827 }
828 } else {
73005152 829 colIndex = 0;
df0b8ff4 830 }
73005152
BH
831 if (m1.getGraphNode() instanceof BaseMessage) {
832 BaseMessage mes1 = (BaseMessage) m1.getGraphNode();
833 if (mes1.getEndLifeline() != null) {
eb63f5ff
BH
834 fLifeline = mes1.getEndLifeline();
835 fLifelineStart = m1.getEvent();
836 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
837 fLifelineColor = fColors[colIndex];
73005152 838 } else if (m2.getGraphNode() instanceof BaseMessage && ((BaseMessage) m2.getGraphNode()).getStartLifeline() != null) {
eb63f5ff
BH
839 fLifeline = ((BaseMessage) m2.getGraphNode()).getStartLifeline();
840 fLifelineStart = m1.getEvent();
841 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
842 fLifelineColor = fColors[colIndex];
73005152 843 } else {
eb63f5ff
BH
844 fLifeline = mes1.getStartLifeline();
845 fLifelineStart = m1.getEvent();
846 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
847 fLifelineColor = fColors[colIndex];
73005152
BH
848 }
849 } else if (m1.getGraphNode() instanceof ExecutionOccurrence) {
850 if (m2.getGraphNode() instanceof ExecutionOccurrence) {
851 ExecutionOccurrence eo = (ExecutionOccurrence) m2.getGraphNode();
eb63f5ff
BH
852 fLifeline = eo.getLifeline();
853 fLifelineStart = m1.getEvent();
854 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
855 fLifelineColor = fColors[colIndex];
73005152
BH
856 } else {
857 ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode();
eb63f5ff
BH
858 fLifeline = eo.getLifeline();
859 fLifelineStart = m1.getEvent();
860 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
861 fLifelineColor = fColors[colIndex];
73005152
BH
862 }
863 }
eb63f5ff 864 for (int j = 0; j < fListenerList.size(); j++) {
abbdd66a 865 ITimeCompressionListener list = fListenerList.get(j);
eb63f5ff 866 list.deltaSelected(fLifeline, fLifelineStart, fLifelineNumEvents, fLifelineColor);
73005152
BH
867 }
868 break;
73005152 869 }
abbdd66a
AM
870 lastM1 = m1;
871 lastM2 = m2;
872 lastY1 = m1Y;
873 lastY2 = m2Y;
73005152
BH
874 }
875 }
876 }
877
df0b8ff4 878 /**
013a5f1c 879 * Creates a fake tool tip.
df0b8ff4 880 */
73005152 881 protected void createFakeTooltip() {
eb63f5ff
BH
882 if (fTooltip == null) {
883 fTooltip = new DrawableToolTip(this);
73005152 884 }
df0b8ff4 885
eb63f5ff 886 if (fFrame != null) {
73005152 887 setFocus(0);
eb63f5ff 888 for (int i = 0; i < fNodeList.size() - 1; i++) {
abbdd66a
AM
889 SDTimeEvent m1 = fNodeList.get(i);
890 SDTimeEvent m2 = fNodeList.get(i + 1);
d3024bf7
MK
891 if (skipIfLifelineIsNull(m1, m2)) {
892 continue;
73005152 893 }
d3024bf7
MK
894 PairOfYs poy = adjustHeights(m1, m2);
895 int m1Y = Math.round(poy.getY1() * fZoomValue);
896 int m2Y = Math.round(poy.getY2() * fZoomValue);
eb63f5ff 897 if ((m1Y < fPrevNodeY + 1) && (m2Y >= fPrevNodeY + 1)) {
df0b8ff4 898 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime());
eb63f5ff
BH
899 fTooltip.showToolTip(delta, fMinTime, fMaxTime);
900 fTooltip.hideToolTip();
73005152
BH
901 }
902 }
903 }
904 }
013a5f1c 905
d3024bf7
MK
906 private static PairOfYs adjustHeights(SDTimeEvent m1, SDTimeEvent m2) {
907 int y1 = ((GraphNode) m1.getGraphNode()).getY();
908 int y2 = ((GraphNode) m2.getGraphNode()).getY();
909
910 y1 = addHeightIfAsynchronousMessage(m1, y1);
911 y2 = addHeightIfAsynchronousMessage(m2, y2);
912 if (m1.getGraphNode() instanceof ExecutionOccurrence) {
913 y1 = addHeight(m1, y1);
914 y2 = addHeightIfExecutionOccurence(m2, y2);
915 }
916 return new PairOfYs(y1, y2);
917 }
918
919 private static class PairOfYs {
920 private final int fY1, fY2;
921
922 public PairOfYs(int y1, int y2) {
923 fY1 = y1;
924 fY2 = y2;
925 }
926
927 public int getY1() {
928 return fY1;
929 }
930
931 public int getY2() {
932 return fY2;
933 }
934
935 }
936
937 private static boolean skipIfLifelineIsNull(SDTimeEvent m1, SDTimeEvent m2) {
938 if ((SDViewPref.getInstance().excludeExternalTime()) && ((m1.getGraphNode() instanceof BaseMessage) && (m2.getGraphNode() instanceof BaseMessage))) {
939 BaseMessage mes1 = (BaseMessage) m1.getGraphNode();
940 BaseMessage mes2 = (BaseMessage) m2.getGraphNode();
941 if ((mes2.getStartLifeline() == null) || (mes1.getEndLifeline() == null)) {
942 return true;
943 }
944 }
945 return false;
946 }
947
3145ec83
BH
948 /**
949 * Traverse Listener implementation.
950 */
951 protected static class LocalTraverseListener implements TraverseListener {
3145ec83
BH
952 @Override
953 public void keyTraversed(TraverseEvent e) {
954 if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS)) {
955 e.doit = true;
956 }
957 }
958 }
73005152 959}
This page took 0.25416 seconds and 5 git commands to generate.