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
1 /**********************************************************************
2 * Copyright (c) 2005, 2014 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.tracecompass.tmf.ui.views.uml2sd;
14
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.List;
18
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.accessibility.ACC;
21 import org.eclipse.swt.accessibility.Accessible;
22 import org.eclipse.swt.accessibility.AccessibleAdapter;
23 import org.eclipse.swt.accessibility.AccessibleControlAdapter;
24 import org.eclipse.swt.accessibility.AccessibleControlEvent;
25 import org.eclipse.swt.accessibility.AccessibleEvent;
26 import org.eclipse.swt.events.DisposeEvent;
27 import org.eclipse.swt.events.DisposeListener;
28 import org.eclipse.swt.events.FocusEvent;
29 import org.eclipse.swt.events.FocusListener;
30 import org.eclipse.swt.events.KeyEvent;
31 import org.eclipse.swt.events.MouseEvent;
32 import org.eclipse.swt.events.TraverseEvent;
33 import org.eclipse.swt.events.TraverseListener;
34 import org.eclipse.swt.graphics.Color;
35 import org.eclipse.swt.graphics.GC;
36 import org.eclipse.swt.graphics.Image;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Control;
39 import org.eclipse.swt.widgets.Display;
40 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
41 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
42 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestamp;
43 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessage;
44 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.AsyncMessageReturn;
45 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.BaseMessage;
46 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.ExecutionOccurrence;
47 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Frame;
48 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.GraphNode;
49 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.ITimeRange;
50 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Lifeline;
51 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.Metrics;
52 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SDTimeEvent;
53 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.core.SyncMessage;
54 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.IColor;
55 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.drawings.impl.ColorImpl;
56 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.preferences.SDViewPref;
57 import org.eclipse.tracecompass.tmf.ui.views.uml2sd.util.TimeEventComparator;
58
59 /**
60 * <p>
61 * The time compression bar implementation.
62 * </p>
63 *
64 * @version 1.0
65 * @author sveyrier
66 */
67 public class TimeCompressionBar extends ScrollView implements DisposeListener {
68
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
77 // ------------------------------------------------------------------------
78 // Attributes
79 // ------------------------------------------------------------------------
80
81 /**
82 * The listener list
83 */
84 private List<ITimeCompressionListener> fListenerList = null;
85 /**
86 * The current frame displayed.
87 */
88 private Frame fFrame = null;
89 /**
90 * List of time events.
91 */
92 private List<SDTimeEvent> fNodeList = null;
93 /**
94 * The minimum time delta.
95 */
96 private ITmfTimestamp fMinTime = TmfTimestamp.fromSeconds(0);
97 /**
98 * The maximum time delta.
99 */
100 private ITmfTimestamp fMaxTime = TmfTimestamp.fromSeconds(0);
101 /**
102 * The current zoom value.
103 */
104 private float fZoomValue = 1;
105 /**
106 * The tooltip to display.
107 */
108 private DrawableToolTip fTooltip = null;
109 /**
110 * Array of colors for displaying wight of time deltas.
111 */
112 private ColorImpl[] fColors;
113 /**
114 * The accessible object reference.
115 */
116 private Accessible fAccessible = null;
117 /**
118 * The focused widget reference.
119 */
120 private int fFocusedWidget = -1;
121 /**
122 * The current lifeline.
123 */
124 private Lifeline fLifeline = null;
125 /**
126 * The current start event value.
127 */
128 private int fLifelineStart = 0;
129 /**
130 * The current number of events.
131 */
132 private int fLifelineNumEvents = 0;
133 /**
134 * The Current color of range to display.
135 */
136 private IColor fLifelineColor = null;
137 /**
138 * The next graph node y coordinate.
139 */
140 private int fNextNodeY = 0;
141 /**
142 * The previous graph node y coordinate.
143 */
144 private int fPrevNodeY = 0;
145
146 // ------------------------------------------------------------------------
147 // Constructors
148 // ------------------------------------------------------------------------
149 /**
150 * Standard constructor
151 *
152 * @param parent
153 * The parent composite
154 * @param s
155 * The style bits
156 */
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);
161 fListenerList = new ArrayList<>();
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 }
169 super.addDisposeListener(this);
170
171 fAccessible = getViewControl().getAccessible();
172
173 fAccessible.addAccessibleListener(new AccessibleAdapter() {
174 @Override
175 public void getName(AccessibleEvent e) {
176 // Case toolTip
177 if (e.childID == 0) {
178 if (fTooltip != null) {
179 e.result = fTooltip.getAccessibleText();
180 }
181 } else if (e.childID == 1) {
182 createFakeTooltip();
183 e.result = fTooltip.getAccessibleText();
184 }
185 }
186 });
187
188 fAccessible.addAccessibleControlListener(new AccessibleControlAdapter() {
189 @Override
190 public void getFocus(AccessibleControlEvent e) {
191 if (fFocusedWidget == -1) {
192 e.childID = ACC.CHILDID_SELF;
193 }
194 else {
195 e.childID = fFocusedWidget;
196 }
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;
211 default:
212 break;
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;
223 if (e.childID == fFocusedWidget) {
224 e.detail |= ACC.STATE_FOCUSED | ACC.STATE_SELECTED | ACC.STATE_CHECKED;
225 }
226 }
227 }
228 });
229
230 getViewControl().addTraverseListener(new LocalTraverseListener());
231
232 addTraverseListener(new LocalTraverseListener());
233
234 getViewControl().addFocusListener(new FocusListener() {
235 @Override
236 public void focusGained(FocusEvent e) {
237 redraw();
238 }
239
240 @Override
241 public void focusLost(FocusEvent e) {
242 redraw();
243 }
244 });
245 }
246
247 // ------------------------------------------------------------------------
248 // Methods
249 // ------------------------------------------------------------------------
250
251 /**
252 * Sets the focus widget
253 *
254 * @param newFocusShape
255 * widget reference to set
256 */
257 void setFocus(int newFocusShape) {
258 fFocusedWidget = newFocusShape;
259 if (fFocusedWidget == -1) {
260 getViewControl().getAccessible().setFocus(ACC.CHILDID_SELF);
261 } else {
262 getViewControl().getAccessible().setFocus(fFocusedWidget);
263 }
264 }
265
266 /**
267 * Sets the current frame.
268 *
269 * @param theFrame
270 * The frame to set
271 */
272 public void setFrame(Frame theFrame) {
273 fFrame = theFrame;
274 fMinTime = fFrame.getMinTime();
275 fMaxTime = fFrame.getMaxTime();
276 }
277
278 @Override
279 protected void drawContents(GC gc, int clipx, int clipy, int clipw, int cliph) {
280 if (fFrame == null) {
281 return;
282 }
283 fNodeList = new ArrayList<>();
284 int messageArraysStep = 1;
285
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));
288 }
289
290 int firstVisible = fFrame.getFirstVisibleSyncMessage();
291 if (firstVisible > 0) {
292 firstVisible = firstVisible - 1;
293 }
294 for (int i = firstVisible; i < fFrame.syncMessageCount(); i = i + messageArraysStep) {
295 SyncMessage m = fFrame.getSyncMessage(i);
296 if (addMessageIfVisible(m)) {
297 break;
298 }
299 }
300
301 firstVisible = fFrame.getFirstVisibleSyncMessageReturn();
302 if (firstVisible > 0) {
303 firstVisible = firstVisible - 1;
304 }
305 for (int i = firstVisible; i < fFrame.syncMessageReturnCount(); i = i + messageArraysStep) {
306 SyncMessage m = fFrame.getSyncMessageReturn(i);
307 if (addMessageIfVisible(m)) {
308 break;
309 }
310 }
311
312 firstVisible = fFrame.getFirstVisibleAsyncMessage();
313 if (firstVisible > 0) {
314 firstVisible = firstVisible - 1;
315 }
316 for (int i = firstVisible; i < fFrame.asyncMessageCount(); i = i + messageArraysStep) {
317 BaseMessage m = fFrame.getAsyncMessage(i);
318 if (addMessageIfVisible(m)) {
319 break;
320 }
321 }
322
323 firstVisible = fFrame.getFirstVisibleAsyncMessageReturn();
324 if (firstVisible > 0) {
325 firstVisible = firstVisible - 1;
326 }
327 for (int i = firstVisible; i < fFrame.asyncMessageReturnCount(); i = i + messageArraysStep) {
328 AsyncMessageReturn m = fFrame.getAsyncMessageReturn(i);
329 if (addMessageIfVisible(m)) {
330 break;
331 }
332 }
333
334 List<SDTimeEvent> executionOccurrencesWithTime = fFrame.getExecutionOccurrencesWithTime();
335 if (executionOccurrencesWithTime != null) {
336 fNodeList.addAll(executionOccurrencesWithTime);
337 }
338
339 SDTimeEvent[] temp = fNodeList.toArray(new SDTimeEvent[fNodeList.size()]);
340 Arrays.sort(temp, new TimeEventComparator());
341 fNodeList = Arrays.asList(temp);
342
343 Image dbuffer = new Image(getDisplay(), getClientArea().width, getClientArea().height);
344 GC gcim = new GC(dbuffer);
345
346 for (int i = 0; i < fNodeList.size() - 1; i++) {
347 SDTimeEvent m1 = fNodeList.get(i);
348 SDTimeEvent m2 = fNodeList.get(i + 1);
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;
355 }
356 }
357
358 fMinTime = fFrame.getMinTime();
359 fMaxTime = fFrame.getMaxTime();
360 ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime);
361 double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS;
362
363 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(fMinTime);
364 long absDelta = Math.abs(delta.getValue());
365
366 ColorImpl color;
367 if (gr != 0) {
368 int colIndex = Math.round((float) (absDelta / gr));
369 if (colIndex < fColors.length && colIndex > 0) {
370 color = fColors[colIndex - 1];
371 } else if (colIndex <= 0) {
372 color = fColors[0];
373 } else {
374 color = fColors[fColors.length - 1];
375 }
376 } else {
377 color = fColors[0];
378 }
379
380 if (color.getColor() instanceof Color) {
381 gcim.setBackground((Color) color.getColor());
382 }
383 PairOfYs poy = adjustHeights(m1, m2);
384 int y1 = poy.getY1();
385 int y2 = poy.getY2();
386 gcim.fillRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * fZoomValue)), 10, Math.round((y2 - y1) * fZoomValue) + 1);
387 if (messageArraysStep == 1) {
388 Color backupColor = gcim.getForeground();
389 gcim.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_WHITE));
390 gcim.drawRectangle(contentsToViewX(0), contentsToViewY(Math.round(y1 * fZoomValue)), 9, Math.round((y2 - y1) * fZoomValue));
391 gcim.setForeground(backupColor);
392 }
393 }
394 if (getViewControl().isFocusControl() || isFocusControl()) {
395 gcim.drawFocus(contentsToViewX(0), contentsToViewY(Math.round(fPrevNodeY * fZoomValue)), contentsToViewX(10), Math.round((fNextNodeY - fPrevNodeY) * fZoomValue));
396 }
397 try {
398 gc.drawImage(dbuffer, 0, 0, getClientArea().width, getClientArea().height, 0, 0, getClientArea().width, getClientArea().height);
399 } catch (Exception e) {
400 Activator.getDefault().logError("Error drawing image", e); //$NON-NLS-1$
401 }
402 gcim.dispose();
403 dbuffer.dispose();
404 gc.dispose();
405 }
406
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
455 /**
456 * Checks for focus of children.
457 *
458 * @param children
459 * Control to check
460 * @return true if child is on focus else false
461 */
462 protected boolean checkFocusOnChilds(Control children) {
463 if (children instanceof Composite) {
464 Control[] child = ((Composite) children).getChildren();
465 for (int i = 0; i < child.length; i++) {
466 if (child[i].isFocusControl()) {
467 return true;
468 }
469 checkFocusOnChilds(child[i]);
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;
481 }
482 checkFocusOnChilds(child[i]);
483 }
484 return false;
485 }
486
487 @Override
488 protected void contentsMouseMoveEvent(MouseEvent event) {
489 if (fTooltip != null) {
490 fTooltip.hideToolTip();
491 }
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()) {
497 break;
498 }
499 }
500 }
501 setFocus(-1);
502 }
503
504 @Override
505 protected void contentsMouseHover(MouseEvent e) {
506 if (fTooltip == null) {
507 fTooltip = new DrawableToolTip(this);
508 }
509 if (fFrame != null) {
510 setFocus(0);
511 for (int i = 0; i < fNodeList.size() - 1; i++) {
512 SDTimeEvent m1 = fNodeList.get(i);
513 SDTimeEvent m2 = fNodeList.get(i + 1);
514
515 if (skipIfLifelineIsNull(m1, m2)) {
516 continue;
517 }
518 PairOfYs poy = adjustHeights(m1, m2);
519
520 int m1Y = Math.round(poy.getY1() * fZoomValue);
521 int m2Y = Math.round(poy.getY2() * fZoomValue);
522 if ((m1Y < e.y) && (m2Y >= e.y)) {
523 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime());
524 fTooltip.showToolTip(delta, fMinTime, fMaxTime);
525 }
526 }
527 }
528 setFocus(0);
529 }
530
531 @Override
532 protected void contentsMouseExit(MouseEvent e) {
533 if (fTooltip != null) {
534 fTooltip.hideToolTip();
535 }
536 }
537
538 @Override
539 protected void contentsMouseUpEvent(MouseEvent event) {
540 selectTimeDelta(event.y, 0);
541 setFocus();
542 super.contentsMouseUpEvent(event);
543 }
544
545 /**
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
549 *
550 * @param mes1
551 * the first message
552 * @param mes2
553 * the second message
554 */
555 public void highlightRegion(BaseMessage mes1, BaseMessage mes2) {
556 BaseMessage localMes1 = mes1;
557 BaseMessage localMes2 = mes2;
558
559 if (fFrame == null) {
560 return;
561 }
562 if (!(localMes1 instanceof ITimeRange)) {
563 return;
564 }
565 if (!(localMes2 instanceof ITimeRange)) {
566 return;
567 }
568 ITimeRange t1 = (ITimeRange) localMes1;
569 ITimeRange t2 = (ITimeRange) localMes2;
570
571 ITmfTimestamp time1 = t1.getStartTime();
572 ITmfTimestamp time2 = t2.getStartTime();
573 int event1 = localMes1.getEventOccurrence();
574 int event2 = localMes2.getEventOccurrence();
575
576 if (localMes1 instanceof AsyncMessage) {
577 AsyncMessage as = (AsyncMessage) localMes1;
578 time1 = as.getEndTime();
579 event1 = as.getEndOccurrence();
580 }
581 if (localMes2 instanceof AsyncMessage) {
582 AsyncMessage as = (AsyncMessage) localMes2;
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) {
593 BaseMessage tempMes = localMes2;
594 localMes2 = localMes1;
595 localMes1 = tempMes;
596
597 t1 = (ITimeRange) localMes1;
598 t2 = (ITimeRange) localMes2;
599
600 time1 = t1.getStartTime();
601 time2 = t2.getStartTime();
602 event1 = localMes1.getEventOccurrence();
603 event2 = localMes2.getEventOccurrence();
604
605 if (localMes1 instanceof AsyncMessage) {
606 AsyncMessage as = (AsyncMessage) localMes1;
607 time1 = as.getEndTime();
608 event1 = as.getEndOccurrence();
609 }
610 if (localMes2 instanceof AsyncMessage) {
611 AsyncMessage as = (AsyncMessage) localMes2;
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
622 ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime);
623 double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS;
624
625 ITmfTimestamp delta = time2.getDelta(time1).getDelta(fMinTime);
626 long absDelta = Math.abs(delta.getValue());
627
628 int colIndex = 0;
629 if (gr != 0) {
630 colIndex = Math.round((float) (absDelta / gr));
631 if (colIndex >= fColors.length) {
632 colIndex = fColors.length - 1;
633 } else if (colIndex < 0) {
634 colIndex = 0;
635 }
636 } else {
637 colIndex = 0;
638 }
639 for (int j = 0; j < fListenerList.size(); j++) {
640 ITimeCompressionListener list = fListenerList.get(j);
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]);
645 } else {
646 list.deltaSelected(localMes1.getStartLifeline(), event1, event2 - event1, fColors[colIndex]);
647 }
648 }
649 }
650
651 /**
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
655 *
656 * @param mes1
657 * the first message
658 * @param mes2
659 * the second message
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
674 /**
675 * Sets the zoom value.
676 *
677 * @param value
678 * The zoom value to set.
679 */
680 public void setZoom(float value) {
681 fZoomValue = value;
682 redraw();
683 }
684
685 /**
686 * Adds a listener to the time compression listener list to be notified
687 * about selected deltas.
688 *
689 * @param listener
690 * The listener to add
691 */
692 public void addTimeCompressionListener(ITimeCompressionListener listener) {
693 if (!fListenerList.contains(listener)) {
694 fListenerList.add(listener);
695 }
696 }
697
698 /**
699 * Removes a time compression listener.
700 *
701 * @param listener
702 * The listener to remove.
703 */
704 public void removeSelectionChangedListener(ITimeCompressionListener listener) {
705 fListenerList.remove(listener);
706 }
707
708 @Override
709 public void widgetDisposed(DisposeEvent e) {
710 if (fTooltip != null) {
711 fTooltip.dispose();
712 }
713 super.removeDisposeListener(this);
714 for (int i = 0; i < fColors.length; i++) {
715 fColors[i].dispose();
716 }
717 }
718
719 @Override
720 protected void keyPressedEvent(KeyEvent event) {
721 if (fTooltip != null) {
722 fTooltip.hideToolTip();
723 }
724 if (!isFocusControl() || getViewControl().isFocusControl()) {
725 Control[] child = getParent().getChildren();
726 for (int i = 0; i < child.length; i++) {
727 if (child[i].isFocusControl()) {
728 break;
729 }
730 }
731 }
732 setFocus(-1);
733
734 boolean top = false;
735 if (fNextNodeY == 0) {
736 top = true;
737 }
738 if ((fFrame != null) && (fNextNodeY == 0)) {
739 for (int i = 0; i < fNodeList.size() - 1 && i < 1; i++) {
740 SDTimeEvent m1 = fNodeList.get(i);
741 SDTimeEvent m2 = fNodeList.get(i + 1);
742 if (skipIfLifelineIsNull(m1, m2)) {
743 continue;
744 }
745
746 PairOfYs poy = adjustHeights(m1, m2);
747
748 fPrevNodeY = Math.round(poy.getY1() * fZoomValue);
749 fNextNodeY = Math.round(poy.getY2() * fZoomValue);
750 }
751 }
752
753 if (fLifeline != null) {
754 for (int j = 0; j < fListenerList.size(); j++) {
755 ITimeCompressionListener list = fListenerList.get(j);
756 list.deltaSelected(fLifeline, fLifelineStart, fLifelineNumEvents, fLifelineColor);
757 }
758 }
759
760 if (event.keyCode == SWT.ARROW_DOWN) {
761 if (!top) {
762 selectTimeDelta(fNextNodeY + 1, 1);
763 } else {
764 selectTimeDelta(fPrevNodeY + 1, 1);
765 }
766 setFocus(1);
767 } else if (event.keyCode == SWT.ARROW_UP) {
768 selectTimeDelta(fPrevNodeY - 1, 2);
769 setFocus(1);
770 } else if (event.keyCode == SWT.ARROW_RIGHT) {
771 selectTimeDelta(fPrevNodeY, 1);
772 setFocus(1);
773 }
774 super.keyPressedEvent(event);
775 }
776
777 /**
778 * Selects the time delta for given delta y coordinate and direction.
779 *
780 * @param dy
781 * The delta in y coordinate.
782 * @param direction
783 * 0 no direction, 1 = down, 2 = up
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;
791 if (fFrame != null) {
792 for (int i = 0; i < fNodeList.size() - 1; i++) {
793 SDTimeEvent m1 = fNodeList.get(i);
794 SDTimeEvent m2 = fNodeList.get(i + 1);
795 if (skipIfLifelineIsNull(m1, m2)) {
796 continue;
797 }
798
799 PairOfYs poy = adjustHeights(m1, m2);
800
801 int m1Y = Math.round(poy.getY1() * fZoomValue);
802 int m2Y = Math.round(poy.getY2() * fZoomValue);
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;
812 fPrevNodeY = m1Y;
813 fNextNodeY = m2Y;
814 ITmfTimestamp minMaxdelta = fMaxTime.getDelta(fMinTime);
815 double gr = (minMaxdelta.getValue()) / (double) NUMBER_STEPS;
816
817 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime()).getDelta(fMinTime);
818 long absDelta = Math.abs(delta.getValue());
819
820 int colIndex = 0;
821 if (gr != 0) {
822 colIndex = Math.round((float) (absDelta / gr));
823 if (colIndex >= fColors.length) {
824 colIndex = fColors.length - 1;
825 } else if (colIndex < 0) {
826 colIndex = 0;
827 }
828 } else {
829 colIndex = 0;
830 }
831 if (m1.getGraphNode() instanceof BaseMessage) {
832 BaseMessage mes1 = (BaseMessage) m1.getGraphNode();
833 if (mes1.getEndLifeline() != null) {
834 fLifeline = mes1.getEndLifeline();
835 fLifelineStart = m1.getEvent();
836 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
837 fLifelineColor = fColors[colIndex];
838 } else if (m2.getGraphNode() instanceof BaseMessage && ((BaseMessage) m2.getGraphNode()).getStartLifeline() != null) {
839 fLifeline = ((BaseMessage) m2.getGraphNode()).getStartLifeline();
840 fLifelineStart = m1.getEvent();
841 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
842 fLifelineColor = fColors[colIndex];
843 } else {
844 fLifeline = mes1.getStartLifeline();
845 fLifelineStart = m1.getEvent();
846 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
847 fLifelineColor = fColors[colIndex];
848 }
849 } else if (m1.getGraphNode() instanceof ExecutionOccurrence) {
850 if (m2.getGraphNode() instanceof ExecutionOccurrence) {
851 ExecutionOccurrence eo = (ExecutionOccurrence) m2.getGraphNode();
852 fLifeline = eo.getLifeline();
853 fLifelineStart = m1.getEvent();
854 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
855 fLifelineColor = fColors[colIndex];
856 } else {
857 ExecutionOccurrence eo = (ExecutionOccurrence) m1.getGraphNode();
858 fLifeline = eo.getLifeline();
859 fLifelineStart = m1.getEvent();
860 fLifelineNumEvents = m2.getEvent() - m1.getEvent();
861 fLifelineColor = fColors[colIndex];
862 }
863 }
864 for (int j = 0; j < fListenerList.size(); j++) {
865 ITimeCompressionListener list = fListenerList.get(j);
866 list.deltaSelected(fLifeline, fLifelineStart, fLifelineNumEvents, fLifelineColor);
867 }
868 break;
869 }
870 lastM1 = m1;
871 lastM2 = m2;
872 lastY1 = m1Y;
873 lastY2 = m2Y;
874 }
875 }
876 }
877
878 /**
879 * Creates a fake tool tip.
880 */
881 protected void createFakeTooltip() {
882 if (fTooltip == null) {
883 fTooltip = new DrawableToolTip(this);
884 }
885
886 if (fFrame != null) {
887 setFocus(0);
888 for (int i = 0; i < fNodeList.size() - 1; i++) {
889 SDTimeEvent m1 = fNodeList.get(i);
890 SDTimeEvent m2 = fNodeList.get(i + 1);
891 if (skipIfLifelineIsNull(m1, m2)) {
892 continue;
893 }
894 PairOfYs poy = adjustHeights(m1, m2);
895 int m1Y = Math.round(poy.getY1() * fZoomValue);
896 int m2Y = Math.round(poy.getY2() * fZoomValue);
897 if ((m1Y < fPrevNodeY + 1) && (m2Y >= fPrevNodeY + 1)) {
898 ITmfTimestamp delta = m2.getTime().getDelta(m1.getTime());
899 fTooltip.showToolTip(delta, fMinTime, fMaxTime);
900 fTooltip.hideToolTip();
901 }
902 }
903 }
904 }
905
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
948 /**
949 * Traverse Listener implementation.
950 */
951 protected static class LocalTraverseListener implements TraverseListener {
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 }
959 }
This page took 0.062464 seconds and 5 git commands to generate.