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
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
11 **********************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
;
15 import java
.util
.ArrayList
;
16 import java
.util
.Arrays
;
17 import java
.util
.List
;
19 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
20 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
21 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimestamp
;
22 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.AsyncMessage
;
23 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.AsyncMessageReturn
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.BaseMessage
;
25 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.ExecutionOccurrence
;
26 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Frame
;
27 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.GraphNode
;
28 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.ITimeRange
;
29 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Lifeline
;
30 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Metrics
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.SDTimeEvent
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.SyncMessage
;
33 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IColor
;
34 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.impl
.ColorImpl
;
35 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.preferences
.SDViewPref
;
36 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.util
.TimeEventComparator
;
37 import org
.eclipse
.swt
.SWT
;
38 import org
.eclipse
.swt
.accessibility
.ACC
;
39 import org
.eclipse
.swt
.accessibility
.Accessible
;
40 import org
.eclipse
.swt
.accessibility
.AccessibleAdapter
;
41 import org
.eclipse
.swt
.accessibility
.AccessibleControlAdapter
;
42 import org
.eclipse
.swt
.accessibility
.AccessibleControlEvent
;
43 import org
.eclipse
.swt
.accessibility
.AccessibleEvent
;
44 import org
.eclipse
.swt
.events
.DisposeEvent
;
45 import org
.eclipse
.swt
.events
.DisposeListener
;
46 import org
.eclipse
.swt
.events
.FocusEvent
;
47 import org
.eclipse
.swt
.events
.FocusListener
;
48 import org
.eclipse
.swt
.events
.KeyEvent
;
49 import org
.eclipse
.swt
.events
.MouseEvent
;
50 import org
.eclipse
.swt
.events
.TraverseEvent
;
51 import org
.eclipse
.swt
.events
.TraverseListener
;
52 import org
.eclipse
.swt
.graphics
.Color
;
53 import org
.eclipse
.swt
.graphics
.GC
;
54 import org
.eclipse
.swt
.graphics
.Image
;
55 import org
.eclipse
.swt
.widgets
.Composite
;
56 import org
.eclipse
.swt
.widgets
.Control
;
57 import org
.eclipse
.swt
.widgets
.Display
;
61 * The time compression bar implementation.
67 public class TimeCompressionBar
extends ScrollView
implements DisposeListener
{
69 // ------------------------------------------------------------------------
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;
77 // ------------------------------------------------------------------------
79 // ------------------------------------------------------------------------
84 private List
<ITimeCompressionListener
> fListenerList
= null;
86 * The current frame displayed.
88 private Frame fFrame
= null;
90 * List of time events.
92 private List
<SDTimeEvent
> fNodeList
= null;
94 * The minimum time delta.
96 private ITmfTimestamp fMinTime
= new TmfTimestamp();
98 * The maximum time delta.
100 private ITmfTimestamp fMaxTime
= new TmfTimestamp();
102 * The current zoom value.
104 private float fZoomValue
= 1;
106 * The tooltip to display.
108 private DrawableToolTip fTooltip
= null;
110 * Array of colors for displaying wight of time deltas.
112 private ColorImpl
[] fColors
;
114 * The accessible object reference.
116 private Accessible fAccessible
= null;
118 * The focused widget reference.
120 private int fFocusedWidget
= -1;
122 * The current lifeline.
124 private Lifeline fLifeline
= null;
126 * The current start event value.
128 private int fLifelineStart
= 0;
130 * The current number of events.
132 private int fLifelineNumEvents
= 0;
134 * The Current color of range to display.
136 private IColor fLifelineColor
= null;
138 * The next graph node y coordinate.
140 private int fNextNodeY
= 0;
142 * The previous graph node y coordinate.
144 private int fPrevNodeY
= 0;
146 // ------------------------------------------------------------------------
148 // ------------------------------------------------------------------------
150 * Standard constructor
152 * @param parent The parent composite
153 * @param s The style bits
155 public TimeCompressionBar(Composite parent
, int s
) {
156 super(parent
, s
| SWT
.NO_BACKGROUND
, false);
157 setVScrollBarMode(ScrollView
.ALWAYS_OFF
);
158 setHScrollBarMode(ScrollView
.ALWAYS_OFF
);
159 fListenerList
= new ArrayList
<>();
160 fColors
= new ColorImpl
[NUMBER_STEPS
];
161 int greenBlue
= BASE_GREEN_BLUE_VALUE
;
162 final int step
= COLOR_STEP
;
163 for (int i
= 0; i
< fColors
.length
; i
++) {
164 fColors
[i
] = new ColorImpl(Display
.getDefault(), BASE_RED_VALUE
, greenBlue
, greenBlue
);
167 super.addDisposeListener(this);
169 fAccessible
= getViewControl().getAccessible();
171 fAccessible
.addAccessibleListener(new AccessibleAdapter() {
173 public void getName(AccessibleEvent e
) {
175 if (e
.childID
== 0) {
176 if (fTooltip
!= null) {
177 e
.result
= fTooltip
.getAccessibleText();
179 } else if (e
.childID
== 1) {
181 e
.result
= fTooltip
.getAccessibleText();
186 fAccessible
.addAccessibleControlListener(new AccessibleControlAdapter() {
188 public void getFocus(AccessibleControlEvent e
) {
189 if (fFocusedWidget
== -1) {
190 e
.childID
= ACC
.CHILDID_SELF
;
193 e
.childID
= fFocusedWidget
;
198 public void getRole(AccessibleControlEvent e
) {
200 case ACC
.CHILDID_SELF
:
201 e
.detail
= ACC
.ROLE_CLIENT_AREA
;
204 e
.detail
= ACC
.ROLE_TOOLTIP
;
207 e
.detail
= ACC
.ROLE_LABEL
;
215 public void getState(AccessibleControlEvent e
) {
216 e
.detail
= ACC
.STATE_FOCUSABLE
;
217 if (e
.childID
== ACC
.CHILDID_SELF
) {
218 e
.detail
|= ACC
.STATE_FOCUSED
;
220 e
.detail
|= ACC
.STATE_SELECTABLE
;
221 if (e
.childID
== fFocusedWidget
) {
222 e
.detail
|= ACC
.STATE_FOCUSED
| ACC
.STATE_SELECTED
| ACC
.STATE_CHECKED
;
228 getViewControl().addTraverseListener(new LocalTraverseListener());
230 addTraverseListener(new LocalTraverseListener());
232 getViewControl().addFocusListener(new FocusListener() {
234 public void focusGained(FocusEvent e
) {
239 public void focusLost(FocusEvent e
) {
245 // ------------------------------------------------------------------------
247 // ------------------------------------------------------------------------
250 * Sets the focus widget
252 * @param newFocusShape widget reference to set
254 void setFocus(int newFocusShape
) {
255 fFocusedWidget
= newFocusShape
;
256 if (fFocusedWidget
== -1) {
257 getViewControl().getAccessible().setFocus(ACC
.CHILDID_SELF
);
259 getViewControl().getAccessible().setFocus(fFocusedWidget
);
264 * Sets the current frame.
266 * @param theFrame The frame to set
268 public void setFrame(Frame theFrame
) {
270 fMinTime
= fFrame
.getMinTime();
271 fMaxTime
= fFrame
.getMaxTime();
275 protected void drawContents(GC gc
, int clipx
, int clipy
, int clipw
, int cliph
) {
276 if (fFrame
== null) {
279 fNodeList
= new ArrayList
<>();
280 int messageArraysStep
= 1;
282 if ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * fZoomValue
< Metrics
.MESSAGE_SIGNIFICANT_VSPACING
+ 1) {
283 messageArraysStep
= Math
.round(Metrics
.MESSAGE_SIGNIFICANT_VSPACING
+ 1 / ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * fZoomValue
));
286 int firstVisible
= fFrame
.getFirstVisibleSyncMessage();
287 if (firstVisible
> 0) {
288 firstVisible
= firstVisible
- 1;
290 for (int i
= firstVisible
; i
< fFrame
.syncMessageCount(); i
= i
+ messageArraysStep
) {
291 SyncMessage m
= fFrame
.getSyncMessage(i
);
292 if (m
.hasTimeInfo()) {
293 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getEventOccurrence(), m
);
295 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
301 firstVisible
= fFrame
.getFirstVisibleSyncMessageReturn();
302 if (firstVisible
> 0) {
303 firstVisible
= firstVisible
- 1;
305 for (int i
= firstVisible
; i
< fFrame
.syncMessageReturnCount(); i
= i
+ messageArraysStep
) {
306 SyncMessage m
= fFrame
.getSyncMessageReturn(i
);
307 if (m
.hasTimeInfo()) {
308 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getEventOccurrence(), m
);
310 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
316 firstVisible
= fFrame
.getFirstVisibleAsyncMessage();
317 if (firstVisible
> 0) {
318 firstVisible
= firstVisible
- 1;
320 for (int i
= firstVisible
; i
< fFrame
.asyncMessageCount(); i
= i
+ messageArraysStep
) {
321 AsyncMessage m
= fFrame
.getAsyncMessage(i
);
322 if (m
.hasTimeInfo()) {
323 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getStartOccurrence(), m
);
325 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), m
);
327 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
333 firstVisible
= fFrame
.getFirstVisibleAsyncMessageReturn();
334 if (firstVisible
> 0) {
335 firstVisible
= firstVisible
- 1;
337 for (int i
= firstVisible
; i
< fFrame
.asyncMessageReturnCount(); i
= i
+ messageArraysStep
) {
338 AsyncMessageReturn m
= fFrame
.getAsyncMessageReturn(i
);
339 if (m
.hasTimeInfo()) {
340 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getStartOccurrence(), m
);
342 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), m
);
344 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
350 List
<SDTimeEvent
> executionOccurrencesWithTime
= fFrame
.getExecutionOccurrencesWithTime();
351 if (executionOccurrencesWithTime
!= null) {
352 fNodeList
.addAll(executionOccurrencesWithTime
);
355 SDTimeEvent
[] temp
= fNodeList
.toArray(new SDTimeEvent
[fNodeList
.size()]);
356 Arrays
.sort(temp
, new TimeEventComparator());
357 fNodeList
= Arrays
.asList(temp
);
359 Image dbuffer
= new Image(getDisplay(), getClientArea().width
, getClientArea().height
);
360 GC gcim
= new GC(dbuffer
);
362 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
363 SDTimeEvent m1
= fNodeList
.get(i
);
364 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
366 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
367 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
368 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
369 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
374 fMinTime
= fFrame
.getMinTime();
375 fMaxTime
= fFrame
.getMaxTime();
376 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
377 double gr
= (minMaxdelta
.getValue()) / (double) NUMBER_STEPS
;
379 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
380 long absDelta
= Math
.abs(delta
.getValue());
384 int colIndex
= Math
.round((float) (absDelta
/ gr
));
385 if (colIndex
< fColors
.length
&& colIndex
> 0) {
386 color
= fColors
[colIndex
- 1];
387 } else if (colIndex
<= 0) {
390 color
= fColors
[fColors
.length
- 1];
396 if (color
.getColor() instanceof Color
) {
397 gcim
.setBackground((Color
) color
.getColor());
399 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
400 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
401 if (m1
.getGraphNode() instanceof AsyncMessage
) {
402 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
403 if (as
.getEndTime() == m1
.getTime()) {
404 y1
+= as
.getHeight();
407 if (m2
.getGraphNode() instanceof AsyncMessage
) {
408 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
409 if (as
.getEndTime() == m2
.getTime()) {
410 y2
+= as
.getHeight();
413 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
415 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
416 if (m1
.getEvent() == eo
.getEndOccurrence()) {
417 y1
+= eo
.getHeight();
420 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
422 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
423 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
424 y2
+= eo2
.getHeight();
429 gcim
.fillRectangle(contentsToViewX(0), contentsToViewY(Math
.round(y1
* fZoomValue
)), 10, Math
.round((y2
- y1
) * fZoomValue
) + 1);
430 if (messageArraysStep
== 1) {
431 Color backupColor
= gcim
.getForeground();
432 gcim
.setForeground(Display
.getDefault().getSystemColor(SWT
.COLOR_WHITE
));
433 gcim
.drawRectangle(contentsToViewX(0), contentsToViewY(Math
.round(y1
* fZoomValue
)), 9, Math
.round((y2
- y1
) * fZoomValue
));
434 gcim
.setForeground(backupColor
);
437 if (getViewControl().isFocusControl() || isFocusControl()) {
438 gcim
.drawFocus(contentsToViewX(0), contentsToViewY(Math
.round(fPrevNodeY
* fZoomValue
)), contentsToViewX(10), Math
.round((fNextNodeY
- fPrevNodeY
) * fZoomValue
));
441 gc
.drawImage(dbuffer
, 0, 0, getClientArea().width
, getClientArea().height
, 0, 0, getClientArea().width
, getClientArea().height
);
442 } catch (Exception e
) {
443 Activator
.getDefault().logError("Error drawing image", e
); //$NON-NLS-1$
451 * Checks for focus of children.
455 * @return true if child is on focus else false
457 protected boolean checkFocusOnChilds(Control children
) {
458 if (children
instanceof Composite
) {
459 Control
[] child
= ((Composite
) children
).getChildren();
460 for (int i
= 0; i
< child
.length
; i
++) {
461 if (child
[i
].isFocusControl()) {
464 checkFocusOnChilds(child
[i
]);
471 public boolean isFocusControl() {
472 Control
[] child
= getChildren();
473 for (int i
= 0; i
< child
.length
; i
++) {
474 if (child
[i
].isFocusControl()) {
477 checkFocusOnChilds(child
[i
]);
483 protected void contentsMouseMoveEvent(MouseEvent event
) {
484 if (fTooltip
!= null) {
485 fTooltip
.hideToolTip();
487 super.contentsMouseMoveEvent(event
);
488 if (!isFocusControl() || getViewControl().isFocusControl()) {
489 Control
[] child
= getParent().getChildren();
490 for (int i
= 0; i
< child
.length
; i
++) {
491 if (child
[i
].isFocusControl()) {
500 protected void contentsMouseHover(MouseEvent e
) {
501 if (fTooltip
== null) {
502 fTooltip
= new DrawableToolTip(this);
504 if (fFrame
!= null) {
506 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
507 SDTimeEvent m1
= fNodeList
.get(i
);
508 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
510 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
511 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
512 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
513 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
518 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
519 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
521 if (m1
.getGraphNode() instanceof AsyncMessage
) {
522 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
523 if (as
.getEndTime() == m1
.getTime()) {
524 y1
+= as
.getHeight();
527 if (m2
.getGraphNode() instanceof AsyncMessage
) {
528 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
529 if (as
.getEndTime() == m2
.getTime()) {
530 y2
+= as
.getHeight();
533 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
534 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
535 if (m1
.getEvent() == eo
.getEndOccurrence()) {
536 y1
+= eo
.getHeight();
539 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
541 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
542 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
543 y2
+= eo2
.getHeight();
547 int m1Y
= Math
.round(y1
* fZoomValue
);
548 int m2Y
= Math
.round(y2
* fZoomValue
);
549 if ((m1Y
< e
.y
) && (m2Y
>= e
.y
)) {
550 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
551 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
559 protected void contentsMouseExit(MouseEvent e
) {
560 if (fTooltip
!= null) {
561 fTooltip
.hideToolTip();
566 protected void contentsMouseUpEvent(MouseEvent event
) {
567 selectTimeDelta(event
.y
, 0);
569 super.contentsMouseUpEvent(event
);
573 * Force the time compression bar to highlight the event occurrences between
574 * the two given messages. The event occurrences are highlighted on the
575 * first message's end lifeline
582 public void highlightRegion(BaseMessage mes1
, BaseMessage mes2
) {
583 BaseMessage localMes1
= mes1
;
584 BaseMessage localMes2
= mes2
;
586 if (fFrame
== null) {
589 if (!(localMes1
instanceof ITimeRange
)) {
592 if (!(localMes2
instanceof ITimeRange
)) {
595 ITimeRange t1
= (ITimeRange
) localMes1
;
596 ITimeRange t2
= (ITimeRange
) localMes2
;
598 ITmfTimestamp time1
= t1
.getStartTime();
599 ITmfTimestamp time2
= t2
.getStartTime();
600 int event1
= localMes1
.getEventOccurrence();
601 int event2
= localMes2
.getEventOccurrence();
603 if (localMes1
instanceof AsyncMessage
) {
604 AsyncMessage as
= (AsyncMessage
) localMes1
;
605 time1
= as
.getEndTime();
606 event1
= as
.getEndOccurrence();
608 if (localMes2
instanceof AsyncMessage
) {
609 AsyncMessage as
= (AsyncMessage
) localMes2
;
610 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
611 time1
= as
.getEndTime();
612 event1
= as
.getEndOccurrence();
614 time1
= as
.getStartTime();
615 event1
= as
.getStartOccurrence();
619 if (event1
> event2
) {
620 BaseMessage tempMes
= localMes2
;
621 localMes2
= localMes1
;
624 t1
= (ITimeRange
) localMes1
;
625 t2
= (ITimeRange
) localMes2
;
627 time1
= t1
.getStartTime();
628 time2
= t2
.getStartTime();
629 event1
= localMes1
.getEventOccurrence();
630 event2
= localMes2
.getEventOccurrence();
632 if (localMes1
instanceof AsyncMessage
) {
633 AsyncMessage as
= (AsyncMessage
) localMes1
;
634 time1
= as
.getEndTime();
635 event1
= as
.getEndOccurrence();
637 if (localMes2
instanceof AsyncMessage
) {
638 AsyncMessage as
= (AsyncMessage
) localMes2
;
639 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
640 time1
= as
.getEndTime();
641 event1
= as
.getEndOccurrence();
643 time1
= as
.getStartTime();
644 event1
= as
.getStartOccurrence();
649 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
650 double gr
= (minMaxdelta
.getValue()) / (double) NUMBER_STEPS
;
652 ITmfTimestamp delta
= time2
.getDelta(time1
).getDelta(fMinTime
);
653 long absDelta
= Math
.abs(delta
.getValue());
657 colIndex
= Math
.round((float) (absDelta
/ gr
));
658 if (colIndex
>= fColors
.length
) {
659 colIndex
= fColors
.length
- 1;
660 } else if (colIndex
< 0) {
666 for (int j
= 0; j
< fListenerList
.size(); j
++) {
667 ITimeCompressionListener list
= fListenerList
.get(j
);
668 if (localMes1
.getEndLifeline() != null) {
669 list
.deltaSelected(localMes1
.getEndLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
670 } else if (localMes2
.getStartLifeline() != null) {
671 list
.deltaSelected(localMes2
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
673 list
.deltaSelected(localMes1
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
679 * Force the time compression bar to highlight the event occurrences between the two given messages. The event
680 * occurrences are highlighted on the first message's end lifeline
682 * @param mes1 the first message
683 * @param mes2 the second message
685 public void highlightRegionSync(final BaseMessage mes1
, final BaseMessage mes2
) {
686 getDisplay().syncExec(new Runnable() {
689 highlightRegion(mes1
, mes2
);
695 public void scrollBy(int x
, int y
) {
699 * Sets the zoom value.
701 * @param value The zoom value to set.
703 public void setZoom(float value
) {
709 * Adds a listener to the time compression listener list to be notified about selected deltas.
711 * @param listener The listener to add
713 public void addTimeCompressionListener(ITimeCompressionListener listener
) {
714 if (!fListenerList
.contains(listener
)) {
715 fListenerList
.add(listener
);
720 * Removes a time compression listener.
722 * @param listener The listener to remove.
724 public void removeSelectionChangedListener(ITimeCompressionListener listener
) {
725 fListenerList
.remove(listener
);
729 public void widgetDisposed(DisposeEvent e
) {
730 if (fTooltip
!= null) {
733 super.removeDisposeListener(this);
734 for (int i
= 0; i
< fColors
.length
; i
++) {
735 fColors
[i
].dispose();
740 protected void keyPressedEvent(KeyEvent event
) {
741 if (fTooltip
!= null) {
742 fTooltip
.hideToolTip();
744 if (!isFocusControl() || getViewControl().isFocusControl()) {
745 Control
[] child
= getParent().getChildren();
746 for (int i
= 0; i
< child
.length
; i
++) {
747 if (child
[i
].isFocusControl()) {
755 if (fNextNodeY
== 0) {
758 if ((fFrame
!= null) && (fNextNodeY
== 0)) {
759 for (int i
= 0; i
< fNodeList
.size() - 1 && i
< 1; i
++) {
760 SDTimeEvent m1
= fNodeList
.get(i
);
761 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
762 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
763 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
764 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
765 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
770 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
771 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
772 if (m1
.getGraphNode() instanceof AsyncMessage
) {
773 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
774 if (as
.getEndTime() == m1
.getTime()) {
775 y1
+= as
.getHeight();
778 if (m2
.getGraphNode() instanceof AsyncMessage
) {
779 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
780 if (as
.getEndTime() == m2
.getTime()) {
781 y2
+= as
.getHeight();
784 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
785 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
786 if (m1
.getEvent() == eo
.getEndOccurrence()) {
787 y1
+= eo
.getHeight();
790 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
792 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
793 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
794 y2
+= eo2
.getHeight();
798 fPrevNodeY
= Math
.round(y1
* fZoomValue
);
799 fNextNodeY
= Math
.round(y2
* fZoomValue
);
803 if (fLifeline
!= null) {
804 for (int j
= 0; j
< fListenerList
.size(); j
++) {
805 ITimeCompressionListener list
= fListenerList
.get(j
);
806 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
810 if (event
.keyCode
== SWT
.ARROW_DOWN
) {
812 selectTimeDelta(fNextNodeY
+ 1, 1);
814 selectTimeDelta(fPrevNodeY
+ 1, 1);
817 } else if (event
.keyCode
== SWT
.ARROW_UP
) {
818 selectTimeDelta(fPrevNodeY
- 1, 2);
820 } else if (event
.keyCode
== SWT
.ARROW_RIGHT
) {
821 selectTimeDelta(fPrevNodeY
, 1);
824 super.keyPressedEvent(event
);
828 * Selects the time delta for given delta y coordinate and direction.
830 * @param dy The delta in y coordinate.
831 * @param direction 0 no direction, 1 = down, 2 = up
833 protected void selectTimeDelta(int dy
, int direction
) {
834 SDTimeEvent lastM1
= null;
835 SDTimeEvent lastM2
= null;
838 boolean done
= false;
839 if (fFrame
!= null) {
840 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
841 SDTimeEvent m1
= fNodeList
.get(i
);
842 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
843 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
844 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
845 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
846 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
851 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
852 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
853 if (m1
.getGraphNode() instanceof AsyncMessage
) {
854 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
855 if (as
.getEndTime() == m1
.getTime()) {
856 y1
+= as
.getHeight();
859 if (m2
.getGraphNode() instanceof AsyncMessage
) {
860 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
861 if (as
.getEndTime() == m2
.getTime()) {
862 y2
+= as
.getHeight();
865 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
866 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
867 if (m1
.getEvent() == eo
.getEndOccurrence()) {
868 y1
+= eo
.getHeight();
871 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
872 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
873 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
874 y2
+= eo2
.getHeight();
878 int m1Y
= Math
.round(y1
* fZoomValue
);
879 int m2Y
= Math
.round(y2
* fZoomValue
);
881 if ((m1Y
< dy
) && (m2Y
> dy
) || (!done
&& m2Y
> dy
&& direction
== 1 && lastM1
!= null) || (!done
&& m1Y
> dy
&& direction
== 2 && lastM1
!= null)) {
882 if (m1Y
> dy
&& direction
== 2) {
891 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
892 double gr
= (minMaxdelta
.getValue()) / (double) NUMBER_STEPS
;
894 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
895 long absDelta
= Math
.abs(delta
.getValue());
899 colIndex
= Math
.round((float) (absDelta
/ gr
));
900 if (colIndex
>= fColors
.length
) {
901 colIndex
= fColors
.length
- 1;
902 } else if (colIndex
< 0) {
908 if (m1
.getGraphNode() instanceof BaseMessage
) {
909 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
910 if (mes1
.getEndLifeline() != null) {
911 fLifeline
= mes1
.getEndLifeline();
912 fLifelineStart
= m1
.getEvent();
913 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
914 fLifelineColor
= fColors
[colIndex
];
915 } else if (m2
.getGraphNode() instanceof BaseMessage
&& ((BaseMessage
) m2
.getGraphNode()).getStartLifeline() != null) {
916 fLifeline
= ((BaseMessage
) m2
.getGraphNode()).getStartLifeline();
917 fLifelineStart
= m1
.getEvent();
918 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
919 fLifelineColor
= fColors
[colIndex
];
921 fLifeline
= mes1
.getStartLifeline();
922 fLifelineStart
= m1
.getEvent();
923 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
924 fLifelineColor
= fColors
[colIndex
];
926 } else if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
927 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
928 ExecutionOccurrence eo
= (ExecutionOccurrence
) m2
.getGraphNode();
929 fLifeline
= eo
.getLifeline();
930 fLifelineStart
= m1
.getEvent();
931 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
932 fLifelineColor
= fColors
[colIndex
];
934 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
935 fLifeline
= eo
.getLifeline();
936 fLifelineStart
= m1
.getEvent();
937 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
938 fLifelineColor
= fColors
[colIndex
];
941 for (int j
= 0; j
< fListenerList
.size(); j
++) {
942 ITimeCompressionListener list
= fListenerList
.get(j
);
943 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
956 * Creates a fake tool tip.
958 protected void createFakeTooltip() {
959 if (fTooltip
== null) {
960 fTooltip
= new DrawableToolTip(this);
963 if (fFrame
!= null) {
965 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
966 SDTimeEvent m1
= fNodeList
.get(i
);
967 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
969 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
970 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
971 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
972 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
977 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
978 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
980 if (m1
.getGraphNode() instanceof AsyncMessage
) {
981 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
982 if (as
.getEndTime() == m1
.getTime()) {
983 y1
+= as
.getHeight();
986 if (m2
.getGraphNode() instanceof AsyncMessage
) {
987 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
988 if (as
.getEndTime() == m2
.getTime()) {
989 y2
+= as
.getHeight();
992 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
993 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
994 if (m1
.getEvent() == eo
.getEndOccurrence()) {
995 y1
+= eo
.getHeight();
998 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
1000 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
1001 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
1002 y2
+= eo2
.getHeight();
1006 int m1Y
= Math
.round(y1
* fZoomValue
);
1007 int m2Y
= Math
.round(y2
* fZoomValue
);
1008 if ((m1Y
< fPrevNodeY
+ 1) && (m2Y
>= fPrevNodeY
+ 1)) {
1009 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
1010 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
1011 fTooltip
.hideToolTip();
1018 * Traverse Listener implementation.
1020 protected static class LocalTraverseListener
implements TraverseListener
{
1022 public void keyTraversed(TraverseEvent e
) {
1023 if ((e
.detail
== SWT
.TRAVERSE_TAB_NEXT
) || (e
.detail
== SWT
.TRAVERSE_TAB_PREVIOUS
)) {