1 /**********************************************************************
2 * Copyright (c) 2005, 2008 IBM Corporation and others.
3 * Copyright (c) 2011, 2012 Ericsson.
5 * All rights reserved. This program and the accompanying materials
6 * are made available under the terms of the Eclipse Public License v1.0
7 * which accompanies this distribution, and is available at
8 * http://www.eclipse.org/legal/epl-v10.html
11 * IBM - Initial API and implementation
12 * Bernd Hufmann - Updated for TMF
14 **********************************************************************/
15 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
;
17 import java
.util
.ArrayList
;
18 import java
.util
.Arrays
;
19 import java
.util
.List
;
21 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
22 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.AsyncMessage
;
25 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.AsyncMessageReturn
;
26 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.BaseMessage
;
27 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.ExecutionOccurrence
;
28 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Frame
;
29 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.GraphNode
;
30 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.ITimeRange
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Lifeline
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Metrics
;
33 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.SDTimeEvent
;
34 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.SyncMessage
;
35 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IColor
;
36 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.impl
.ColorImpl
;
37 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.preferences
.SDViewPref
;
38 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.util
.TimeEventComparator
;
39 import org
.eclipse
.swt
.SWT
;
40 import org
.eclipse
.swt
.accessibility
.ACC
;
41 import org
.eclipse
.swt
.accessibility
.Accessible
;
42 import org
.eclipse
.swt
.accessibility
.AccessibleAdapter
;
43 import org
.eclipse
.swt
.accessibility
.AccessibleControlAdapter
;
44 import org
.eclipse
.swt
.accessibility
.AccessibleControlEvent
;
45 import org
.eclipse
.swt
.accessibility
.AccessibleEvent
;
46 import org
.eclipse
.swt
.events
.DisposeEvent
;
47 import org
.eclipse
.swt
.events
.DisposeListener
;
48 import org
.eclipse
.swt
.events
.FocusEvent
;
49 import org
.eclipse
.swt
.events
.FocusListener
;
50 import org
.eclipse
.swt
.events
.KeyEvent
;
51 import org
.eclipse
.swt
.events
.MouseEvent
;
52 import org
.eclipse
.swt
.events
.TraverseEvent
;
53 import org
.eclipse
.swt
.events
.TraverseListener
;
54 import org
.eclipse
.swt
.graphics
.Color
;
55 import org
.eclipse
.swt
.graphics
.GC
;
56 import org
.eclipse
.swt
.graphics
.Image
;
57 import org
.eclipse
.swt
.widgets
.Composite
;
58 import org
.eclipse
.swt
.widgets
.Control
;
59 import org
.eclipse
.swt
.widgets
.Display
;
63 * The time compression bar implementation.
69 public class TimeCompressionBar
extends ScrollView
implements DisposeListener
{
71 // ------------------------------------------------------------------------
73 // ------------------------------------------------------------------------
78 protected List
<ITimeCompressionListener
> fListenerList
= null;
80 * The current frame displayed.
82 protected Frame fFrame
= null;
84 * List of time events.
86 protected List
<SDTimeEvent
> fNodeList
= null;
88 * The minimum time delta.
90 protected ITmfTimestamp fMinTime
= new TmfTimestamp();
92 * The maximum time delta.
94 protected ITmfTimestamp fMaxTime
= new TmfTimestamp();
96 * The current zoom value.
98 protected float fZoomValue
= 1;
100 * The tooltip to display.
102 protected DrawableToolTip fTooltip
= null;
104 * Array of colors for displaying wight of time deltas.
106 protected ColorImpl
[] fColors
;
108 * The accessible object reference.
110 protected Accessible fAccessible
= null;
112 * The focused widget reference.
114 protected int fFocusedWidget
= -1;
116 * The sequence diagram view reference.
118 protected SDView view
= null;
120 * The current lifeline.
122 protected Lifeline fLifeline
= null;
124 * The current start event value.
126 protected int fLifelineStart
= 0;
128 * The current number of events.
130 protected int fLifelineNumEvents
= 0;
132 * The Current color of range to display.
134 protected IColor fLifelineColor
= null;
136 * The next graph node y coordinate.
138 protected int fNextNodeY
= 0;
140 * The previous graph node y coordinate.
142 protected int fPrevNodeY
= 0;
144 // ------------------------------------------------------------------------
146 // ------------------------------------------------------------------------
148 * Standard constructor
150 * @param parent The parent composite
151 * @param s The style bits
153 public TimeCompressionBar(Composite parent
, int s
) {
154 super(parent
, s
| SWT
.NO_BACKGROUND
, false);
155 setVScrollBarMode(ScrollView
.ALWAYS_OFF
);
156 setHScrollBarMode(ScrollView
.ALWAYS_OFF
);
157 fListenerList
= new ArrayList
<ITimeCompressionListener
>();
158 fColors
= new ColorImpl
[10];
159 fColors
[0] = new ColorImpl(Display
.getDefault(), 255, 229, 229);
160 fColors
[1] = new ColorImpl(Display
.getDefault(), 255, 204, 204);
161 fColors
[2] = new ColorImpl(Display
.getDefault(), 255, 178, 178);
162 fColors
[3] = new ColorImpl(Display
.getDefault(), 255, 153, 153);
163 fColors
[4] = new ColorImpl(Display
.getDefault(), 255, 127, 127);
164 fColors
[5] = new ColorImpl(Display
.getDefault(), 255, 102, 102);
165 fColors
[6] = new ColorImpl(Display
.getDefault(), 255, 76, 76);
166 fColors
[7] = new ColorImpl(Display
.getDefault(), 255, 51, 51);
167 fColors
[8] = new ColorImpl(Display
.getDefault(), 255, 25, 25);
168 fColors
[9] = new ColorImpl(Display
.getDefault(), 255, 0, 0);
169 super.addDisposeListener(this);
171 fAccessible
= getViewControl().getAccessible();
173 fAccessible
.addAccessibleListener(new AccessibleAdapter() {
175 public void getName(AccessibleEvent e
) {
177 if (e
.childID
== 0) {
178 if (fTooltip
!= null) {
179 e
.result
= fTooltip
.getAccessibleText();
181 } else if (e
.childID
== 1) {
183 e
.result
= fTooltip
.getAccessibleText();
188 fAccessible
.addAccessibleControlListener(new AccessibleControlAdapter() {
191 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getFocus(org.eclipse.swt.accessibility.AccessibleControlEvent)
194 public void getFocus(AccessibleControlEvent e
) {
195 if (fFocusedWidget
== -1) {
196 e
.childID
= ACC
.CHILDID_SELF
;
199 e
.childID
= fFocusedWidget
;
205 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getRole(org.eclipse.swt.accessibility.AccessibleControlEvent)
208 public void getRole(AccessibleControlEvent e
) {
210 case ACC
.CHILDID_SELF
:
211 e
.detail
= ACC
.ROLE_CLIENT_AREA
;
214 e
.detail
= ACC
.ROLE_TOOLTIP
;
217 e
.detail
= ACC
.ROLE_LABEL
;
226 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getState(org.eclipse.swt.accessibility.AccessibleControlEvent)
229 public void getState(AccessibleControlEvent e
) {
230 e
.detail
= ACC
.STATE_FOCUSABLE
;
231 if (e
.childID
== ACC
.CHILDID_SELF
) {
232 e
.detail
|= ACC
.STATE_FOCUSED
;
234 e
.detail
|= ACC
.STATE_SELECTABLE
;
235 if (e
.childID
== fFocusedWidget
) {
236 e
.detail
|= ACC
.STATE_FOCUSED
| ACC
.STATE_SELECTED
| ACC
.STATE_CHECKED
;
242 getViewControl().addTraverseListener(new LocalTraverseListener());
244 addTraverseListener(new LocalTraverseListener());
246 getViewControl().addFocusListener(new FocusListener() {
250 * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
253 public void focusGained(FocusEvent e
) {
259 * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
262 public void focusLost(FocusEvent e
) {
268 // ------------------------------------------------------------------------
270 // ------------------------------------------------------------------------
273 * Sets the focus widget
275 * @param newFocusShape widget reference to set
277 void setFocus(int newFocusShape
) {
278 fFocusedWidget
= newFocusShape
;
279 if (fFocusedWidget
== -1) {
280 getViewControl().getAccessible().setFocus(ACC
.CHILDID_SELF
);
282 getViewControl().getAccessible().setFocus(fFocusedWidget
);
287 * Sets the current frame.
289 * @param theFrame The frame to set
291 public void setFrame(Frame theFrame
) {
293 fMinTime
= fFrame
.getMinTime();
294 fMaxTime
= fFrame
.getMaxTime();
299 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#drawContents(org.eclipse.swt.graphics.GC, int, int, int, int)
302 protected void drawContents(GC gc
, int clipx
, int clipy
, int clipw
, int cliph
) {
303 if (fFrame
== null) {
306 fNodeList
= new ArrayList
<SDTimeEvent
>();
307 int messageArraysStep
= 1;
309 if ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * fZoomValue
< Metrics
.MESSAGE_SIGNIFICANT_VSPACING
+ 1) {
310 messageArraysStep
= Math
.round(Metrics
.MESSAGE_SIGNIFICANT_VSPACING
+ 1 / ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * fZoomValue
));
313 int firstVisible
= fFrame
.getFirstVisibleSyncMessage();
314 if (firstVisible
> 0) {
315 firstVisible
= firstVisible
- 1;
317 for (int i
= firstVisible
; i
< fFrame
.syncMessageCount(); i
= i
+ messageArraysStep
) {
318 SyncMessage m
= fFrame
.getSyncMessage(i
);
319 if (m
.hasTimeInfo()) {
320 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getEventOccurrence(), (ITimeRange
) m
);
322 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
328 firstVisible
= fFrame
.getFirstVisibleSyncMessageReturn();
329 if (firstVisible
> 0) {
330 firstVisible
= firstVisible
- 1;
332 for (int i
= firstVisible
; i
< fFrame
.syncMessageReturnCount(); i
= i
+ messageArraysStep
) {
333 SyncMessage m
= fFrame
.getSyncMessageReturn(i
);
334 if (m
.hasTimeInfo()) {
335 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getEventOccurrence(), (ITimeRange
) m
);
337 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
343 firstVisible
= fFrame
.getFirstVisibleAsyncMessage();
344 if (firstVisible
> 0) {
345 firstVisible
= firstVisible
- 1;
347 for (int i
= firstVisible
; i
< fFrame
.asyncMessageCount(); i
= i
+ messageArraysStep
) {
348 AsyncMessage m
= fFrame
.getAsyncMessage(i
);
349 if (m
.hasTimeInfo()) {
350 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getStartOccurrence(), (ITimeRange
) m
);
352 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), (ITimeRange
) m
);
354 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
360 firstVisible
= fFrame
.getFirstVisibleAsyncMessageReturn();
361 if (firstVisible
> 0) {
362 firstVisible
= firstVisible
- 1;
364 for (int i
= firstVisible
; i
< fFrame
.asyncMessageReturnCount(); i
= i
+ messageArraysStep
) {
365 AsyncMessageReturn m
= fFrame
.getAsyncMessageReturn(i
);
366 if (m
.hasTimeInfo()) {
367 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getStartOccurrence(), (ITimeRange
) m
);
369 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), (ITimeRange
) m
);
371 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
377 List
<SDTimeEvent
> executionOccurrencesWithTime
= fFrame
.getExecutionOccurrencesWithTime();
378 if (executionOccurrencesWithTime
!= null) {
379 fNodeList
.addAll(executionOccurrencesWithTime
);
382 SDTimeEvent
[] temp
= fNodeList
.toArray(new SDTimeEvent
[fNodeList
.size()]);
383 Arrays
.sort(temp
, new TimeEventComparator());
384 fNodeList
= Arrays
.asList(temp
);
386 Image dbuffer
= null;
389 dbuffer
= new Image(getDisplay(), getClientArea().width
, getClientArea().height
);
390 } catch (Exception e
) {
391 Activator
.getDefault().logError("Error creating image", e
); //$NON-NLS-1$
393 gcim
= new GC(dbuffer
);
394 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
395 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
396 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
398 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
399 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
400 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
401 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
406 fMinTime
= fFrame
.getMinTime();
407 fMaxTime
= fFrame
.getMaxTime();
408 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
409 double gr
= (minMaxdelta
.getValue()) / (double) 10;
411 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
412 long absDelta
= Math
.abs(delta
.getValue());
416 int colIndex
= Math
.round((float) (absDelta
/ gr
));
417 if (colIndex
< fColors
.length
&& colIndex
> 0) {
418 color
= fColors
[colIndex
- 1];
419 } else if (colIndex
<= 0) {
422 color
= fColors
[fColors
.length
- 1];
428 if (color
.getColor() instanceof Color
) {
429 gcim
.setBackground((Color
) color
.getColor());
431 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
432 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
433 if (m1
.getGraphNode() instanceof AsyncMessage
) {
434 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
435 if (as
.getEndTime() == m1
.getTime()) {
436 y1
+= as
.getHeight();
439 if (m2
.getGraphNode() instanceof AsyncMessage
) {
440 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
441 if (as
.getEndTime() == m2
.getTime()) {
442 y2
+= as
.getHeight();
445 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
447 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
448 if (m1
.getEvent() == eo
.getEndOccurrence()) {
449 y1
+= eo
.getHeight();
452 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
454 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
455 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
456 y2
+= eo2
.getHeight();
461 gcim
.fillRectangle(contentsToViewX(0), contentsToViewY(Math
.round(y1
* fZoomValue
)), 10, Math
.round((y2
- y1
) * fZoomValue
) + 1);
462 if (messageArraysStep
== 1) {
463 Color backupColor
= gcim
.getForeground();
464 gcim
.setForeground(Display
.getDefault().getSystemColor(SWT
.COLOR_WHITE
));
465 gcim
.drawRectangle(contentsToViewX(0), contentsToViewY(Math
.round(y1
* fZoomValue
)), 9, Math
.round((y2
- y1
) * fZoomValue
));
466 gcim
.setForeground(backupColor
);
469 if (getViewControl().isFocusControl() || isFocusControl()) {
470 gcim
.drawFocus(contentsToViewX(0), contentsToViewY(Math
.round(fPrevNodeY
* fZoomValue
)), contentsToViewX(10), Math
.round((fNextNodeY
- fPrevNodeY
) * fZoomValue
));
473 gc
.drawImage(dbuffer
, 0, 0, getClientArea().width
, getClientArea().height
, 0, 0, getClientArea().width
, getClientArea().height
);
474 } catch (Exception e
) {
475 Activator
.getDefault().logError("Error drawing image", e
); //$NON-NLS-1$
478 if (dbuffer
!= null) {
485 * Checks for focus of children.
487 * @param children Control to check
488 * @return true if child is on focus else false
490 protected boolean checkFocusOnChilds(Control childs
) {
491 if (childs
instanceof Composite
) {
492 Control
[] child
= ((Composite
) childs
).getChildren();
493 for (int i
= 0; i
< child
.length
; i
++) {
494 if (child
[i
].isFocusControl()) {
497 checkFocusOnChilds(child
[i
]);
506 * @see org.eclipse.swt.widgets.Control#isFocusControl()
509 public boolean isFocusControl() {
510 Control
[] child
= getChildren();
511 for (int i
= 0; i
< child
.length
; i
++) {
512 if (child
[i
].isFocusControl()) {
515 checkFocusOnChilds(child
[i
]);
523 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseMoveEvent(org.eclipse.swt.events.MouseEvent)
526 protected void contentsMouseMoveEvent(MouseEvent event
) {
527 if (fTooltip
!= null) {
528 fTooltip
.hideToolTip();
530 super.contentsMouseMoveEvent(event
);
531 if (!isFocusControl() || getViewControl().isFocusControl()) {
532 Control
[] child
= getParent().getChildren();
533 for (int i
= 0; i
< child
.length
; i
++) {
534 if (child
[i
].isFocusControl()) {
544 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseHover(org.eclipse.swt.events.MouseEvent)
547 protected void contentsMouseHover(MouseEvent e
) {
548 if (fTooltip
== null) {
549 fTooltip
= new DrawableToolTip(this);
551 if (fFrame
!= null) {
553 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
554 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
555 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
557 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
558 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
559 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
560 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
565 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
566 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
568 if (m1
.getGraphNode() instanceof AsyncMessage
) {
569 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
570 if (as
.getEndTime() == m1
.getTime()) {
571 y1
+= as
.getHeight();
574 if (m2
.getGraphNode() instanceof AsyncMessage
) {
575 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
576 if (as
.getEndTime() == m2
.getTime()) {
577 y2
+= as
.getHeight();
580 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
581 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
582 if (m1
.getEvent() == eo
.getEndOccurrence()) {
583 y1
+= eo
.getHeight();
586 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
588 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
589 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
590 y2
+= eo2
.getHeight();
594 int m1Y
= Math
.round(y1
* fZoomValue
);
595 int m2Y
= Math
.round(y2
* fZoomValue
);
596 if ((m1Y
< e
.y
) && (m2Y
>= e
.y
)) {
597 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
598 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
607 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseExit(org.eclipse.swt.events.MouseEvent)
610 protected void contentsMouseExit(MouseEvent e
) {
611 if (fTooltip
!= null) {
612 fTooltip
.hideToolTip();
618 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseUpEvent(org.eclipse.swt.events.MouseEvent)
621 protected void contentsMouseUpEvent(MouseEvent event
) {
622 selectTimeDelta(event
.y
, 0);
624 super.contentsMouseUpEvent(event
);
628 * Force the time compression bar to highlight the event occurrences between the two given messages. The event
629 * occurrences are highlighted on the first message's end lifeline
631 * @param mes1 the first message
632 * @param localMes2 the second message
634 public void highlightRegion(BaseMessage mes1
, BaseMessage mes2
) {
635 BaseMessage localMes1
= mes1
;
636 BaseMessage localMes2
= mes2
;
638 if (fFrame
== null) {
641 if (!(localMes1
instanceof ITimeRange
)) {
644 if (!(localMes2
instanceof ITimeRange
)) {
647 ITimeRange t1
= (ITimeRange
) localMes1
;
648 ITimeRange t2
= (ITimeRange
) localMes2
;
650 ITmfTimestamp time1
= t1
.getStartTime();
651 ITmfTimestamp time2
= t2
.getStartTime();
652 int event1
= localMes1
.getEventOccurrence();
653 int event2
= localMes2
.getEventOccurrence();
655 if (localMes1
instanceof AsyncMessage
) {
656 AsyncMessage as
= (AsyncMessage
) localMes1
;
657 time1
= as
.getEndTime();
658 event1
= as
.getEndOccurrence();
660 if (localMes2
instanceof AsyncMessage
) {
661 AsyncMessage as
= (AsyncMessage
) localMes2
;
662 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
663 time1
= as
.getEndTime();
664 event1
= as
.getEndOccurrence();
666 time1
= as
.getStartTime();
667 event1
= as
.getStartOccurrence();
671 if (event1
> event2
) {
672 BaseMessage tempMes
= localMes2
;
673 localMes2
= localMes1
;
676 t1
= (ITimeRange
) localMes1
;
677 t2
= (ITimeRange
) localMes2
;
679 time1
= t1
.getStartTime();
680 time2
= t2
.getStartTime();
681 event1
= localMes1
.getEventOccurrence();
682 event2
= localMes2
.getEventOccurrence();
684 if (localMes1
instanceof AsyncMessage
) {
685 AsyncMessage as
= (AsyncMessage
) localMes1
;
686 time1
= as
.getEndTime();
687 event1
= as
.getEndOccurrence();
689 if (localMes2
instanceof AsyncMessage
) {
690 AsyncMessage as
= (AsyncMessage
) localMes2
;
691 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
692 time1
= as
.getEndTime();
693 event1
= as
.getEndOccurrence();
695 time1
= as
.getStartTime();
696 event1
= as
.getStartOccurrence();
701 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
702 double gr
= (minMaxdelta
.getValue()) / (double) 10;
704 ITmfTimestamp delta
= time2
.getDelta(time1
).getDelta(fMinTime
);
705 long absDelta
= Math
.abs(delta
.getValue());
709 colIndex
= Math
.round((float) (absDelta
/ gr
));
710 if (colIndex
>= fColors
.length
) {
711 colIndex
= fColors
.length
- 1;
712 } else if (colIndex
< 0) {
718 for (int j
= 0; j
< fListenerList
.size(); j
++) {
719 ITimeCompressionListener list
= (ITimeCompressionListener
) fListenerList
.get(j
);
720 if (localMes1
.getEndLifeline() != null) {
721 list
.deltaSelected(localMes1
.getEndLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
722 } else if (localMes2
.getStartLifeline() != null) {
723 list
.deltaSelected(localMes2
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
725 list
.deltaSelected(localMes1
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
731 * Force the time compression bar to highlight the event occurrences between the two given messages. The event
732 * occurrences are highlighted on the first message's end lifeline
734 * @param mes1 the first message
735 * @param mes2 the second message
737 public void highlightRegionSync(final BaseMessage mes1
, final BaseMessage mes2
) {
738 getDisplay().syncExec(new Runnable() {
741 highlightRegion(mes1
, mes2
);
748 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#scrollBy(int, int)
751 public void scrollBy(int x
, int y
) {
755 * Sets the zoom value.
757 * @param value The zoom value to set.
759 public void setZoom(float value
) {
765 * Adds a listener to the time compression listener list to be notified about selected deltas.
767 * @param listener The listener to add
769 public void addTimeCompressionListener(ITimeCompressionListener listener
) {
770 if (!fListenerList
.contains(listener
)) {
771 fListenerList
.add(listener
);
776 * Removes a time compression listener.
778 * @param listener The listener to remove.
780 public void removeSelectionChangedListener(ITimeCompressionListener listener
) {
781 fListenerList
.remove(listener
);
786 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
789 public void widgetDisposed(DisposeEvent e
) {
790 if (fTooltip
!= null) {
793 super.removeDisposeListener(this);
794 for (int i
= 0; i
< fColors
.length
; i
++) {
795 fColors
[i
].dispose();
801 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#keyPressedEvent(org.eclipse.swt.events.KeyEvent)
804 protected void keyPressedEvent(KeyEvent event
) {
805 if (fTooltip
!= null) {
806 fTooltip
.hideToolTip();
808 if (!isFocusControl() || getViewControl().isFocusControl()) {
809 Control
[] child
= getParent().getChildren();
810 for (int i
= 0; i
< child
.length
; i
++) {
811 if (child
[i
].isFocusControl()) {
812 // getViewControl().setFocus();
820 if (fNextNodeY
== 0) {
823 if ((fFrame
!= null) && (fNextNodeY
== 0)) {
824 for (int i
= 0; i
< fNodeList
.size() - 1 && i
< 1; i
++) {
825 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
826 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
827 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
828 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
829 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
830 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
835 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
836 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
837 if (m1
.getGraphNode() instanceof AsyncMessage
) {
838 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
839 if (as
.getEndTime() == m1
.getTime()) {
840 y1
+= as
.getHeight();
843 if (m2
.getGraphNode() instanceof AsyncMessage
) {
844 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
845 if (as
.getEndTime() == m2
.getTime()) {
846 y2
+= as
.getHeight();
849 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
850 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
851 if (m1
.getEvent() == eo
.getEndOccurrence()) {
852 y1
+= eo
.getHeight();
855 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
857 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
858 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
859 y2
+= eo2
.getHeight();
863 fPrevNodeY
= Math
.round(y1
* fZoomValue
);
864 fNextNodeY
= Math
.round(y2
* fZoomValue
);
868 if (fLifeline
!= null) {
869 for (int j
= 0; j
< fListenerList
.size(); j
++) {
870 ITimeCompressionListener list
= (ITimeCompressionListener
) fListenerList
.get(j
);
871 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
875 if (event
.keyCode
== SWT
.ARROW_DOWN
) {
877 selectTimeDelta(fNextNodeY
+ 1, 1);
879 selectTimeDelta(fPrevNodeY
+ 1, 1);
882 } else if (event
.keyCode
== SWT
.ARROW_UP
) {
883 selectTimeDelta(fPrevNodeY
- 1, 2);
885 } else if (event
.keyCode
== SWT
.ARROW_RIGHT
) {
886 selectTimeDelta(fPrevNodeY
, 1);
889 super.keyPressedEvent(event
);
893 * Selects the time delta for given delta y coordinate and direction.
895 * @param dy The delta in y coordinate.
896 * @param direction 0 no direction, 1 = down, 2 = up
898 protected void selectTimeDelta(int dy
, int direction
) {
899 SDTimeEvent lastM1
= null;
900 SDTimeEvent lastM2
= null;
903 boolean done
= false;
904 if (fFrame
!= null) {
905 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
906 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
907 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
908 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
909 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
910 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
911 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
916 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
917 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
918 if (m1
.getGraphNode() instanceof AsyncMessage
) {
919 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
920 if (as
.getEndTime() == m1
.getTime()) {
921 y1
+= as
.getHeight();
924 if (m2
.getGraphNode() instanceof AsyncMessage
) {
925 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
926 if (as
.getEndTime() == m2
.getTime()) {
927 y2
+= as
.getHeight();
930 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
931 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
932 if (m1
.getEvent() == eo
.getEndOccurrence()) {
933 y1
+= eo
.getHeight();
936 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
937 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
938 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
939 y2
+= eo2
.getHeight();
943 int m1Y
= Math
.round(y1
* fZoomValue
);
944 int m2Y
= Math
.round(y2
* fZoomValue
);
946 if ((m1Y
< dy
) && (m2Y
> dy
) || (!done
&& m2Y
> dy
&& direction
== 1 && lastM1
!= null) || (!done
&& m1Y
> dy
&& direction
== 2 && lastM1
!= null)) {
947 if (m1Y
> dy
&& direction
== 2) {
956 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
957 double gr
= (minMaxdelta
.getValue()) / (double) 10;
959 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
960 long absDelta
= Math
.abs(delta
.getValue());
964 colIndex
= Math
.round((float) (absDelta
/ gr
));
965 if (colIndex
>= fColors
.length
) {
966 colIndex
= fColors
.length
- 1;
967 } else if (colIndex
< 0) {
973 if (m1
.getGraphNode() instanceof BaseMessage
) {
974 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
975 if (mes1
.getEndLifeline() != null) {
976 fLifeline
= mes1
.getEndLifeline();
977 fLifelineStart
= m1
.getEvent();
978 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
979 fLifelineColor
= fColors
[colIndex
];
980 } else if (m2
.getGraphNode() instanceof BaseMessage
&& ((BaseMessage
) m2
.getGraphNode()).getStartLifeline() != null) {
981 fLifeline
= ((BaseMessage
) m2
.getGraphNode()).getStartLifeline();
982 fLifelineStart
= m1
.getEvent();
983 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
984 fLifelineColor
= fColors
[colIndex
];
986 fLifeline
= mes1
.getStartLifeline();
987 fLifelineStart
= m1
.getEvent();
988 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
989 fLifelineColor
= fColors
[colIndex
];
991 } else if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
992 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
993 ExecutionOccurrence eo
= (ExecutionOccurrence
) m2
.getGraphNode();
994 fLifeline
= eo
.getLifeline();
995 fLifelineStart
= m1
.getEvent();
996 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
997 fLifelineColor
= fColors
[colIndex
];
999 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
1000 fLifeline
= eo
.getLifeline();
1001 fLifelineStart
= m1
.getEvent();
1002 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
1003 fLifelineColor
= fColors
[colIndex
];
1006 for (int j
= 0; j
< fListenerList
.size(); j
++) {
1007 ITimeCompressionListener list
= (ITimeCompressionListener
) fListenerList
.get(j
);
1008 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
1022 * Creates a fake tool tip.
1024 protected void createFakeTooltip() {
1025 if (fTooltip
== null) {
1026 fTooltip
= new DrawableToolTip(this);
1029 if (fFrame
!= null) {
1031 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
1032 SDTimeEvent m1
= (SDTimeEvent
) fNodeList
.get(i
);
1033 SDTimeEvent m2
= (SDTimeEvent
) fNodeList
.get(i
+ 1);
1035 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
1036 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
1037 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
1038 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
1043 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
1044 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
1046 if (m1
.getGraphNode() instanceof AsyncMessage
) {
1047 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
1048 if (as
.getEndTime() == m1
.getTime()) {
1049 y1
+= as
.getHeight();
1052 if (m2
.getGraphNode() instanceof AsyncMessage
) {
1053 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
1054 if (as
.getEndTime() == m2
.getTime()) {
1055 y2
+= as
.getHeight();
1058 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
1059 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
1060 if (m1
.getEvent() == eo
.getEndOccurrence()) {
1061 y1
+= eo
.getHeight();
1064 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
1066 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
1067 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
1068 y2
+= eo2
.getHeight();
1072 int m1Y
= Math
.round(y1
* fZoomValue
);
1073 int m2Y
= Math
.round(y2
* fZoomValue
);
1074 if ((m1Y
< fPrevNodeY
+ 1) && (m2Y
>= fPrevNodeY
+ 1)) {
1075 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
1076 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
1077 fTooltip
.hideToolTip();
1084 * Traverse Listener implementation.
1086 protected static class LocalTraverseListener
implements TraverseListener
{
1090 * @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
1093 public void keyTraversed(TraverseEvent e
) {
1094 if ((e
.detail
== SWT
.TRAVERSE_TAB_NEXT
) || (e
.detail
== SWT
.TRAVERSE_TAB_PREVIOUS
)) {