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(), 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(), 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(), m
);
352 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), 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(), m
);
369 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), 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
= fNodeList
.get(i
);
396 SDTimeEvent m2
= 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
]);
505 * @see org.eclipse.swt.widgets.Control#isFocusControl()
508 public boolean isFocusControl() {
509 Control
[] child
= getChildren();
510 for (int i
= 0; i
< child
.length
; i
++) {
511 if (child
[i
].isFocusControl()) {
514 checkFocusOnChilds(child
[i
]);
521 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseMoveEvent(org.eclipse.swt.events.MouseEvent)
524 protected void contentsMouseMoveEvent(MouseEvent event
) {
525 if (fTooltip
!= null) {
526 fTooltip
.hideToolTip();
528 super.contentsMouseMoveEvent(event
);
529 if (!isFocusControl() || getViewControl().isFocusControl()) {
530 Control
[] child
= getParent().getChildren();
531 for (int i
= 0; i
< child
.length
; i
++) {
532 if (child
[i
].isFocusControl()) {
542 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseHover(org.eclipse.swt.events.MouseEvent)
545 protected void contentsMouseHover(MouseEvent e
) {
546 if (fTooltip
== null) {
547 fTooltip
= new DrawableToolTip(this);
549 if (fFrame
!= null) {
551 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
552 SDTimeEvent m1
= fNodeList
.get(i
);
553 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
555 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
556 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
557 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
558 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
563 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
564 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
566 if (m1
.getGraphNode() instanceof AsyncMessage
) {
567 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
568 if (as
.getEndTime() == m1
.getTime()) {
569 y1
+= as
.getHeight();
572 if (m2
.getGraphNode() instanceof AsyncMessage
) {
573 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
574 if (as
.getEndTime() == m2
.getTime()) {
575 y2
+= as
.getHeight();
578 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
579 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
580 if (m1
.getEvent() == eo
.getEndOccurrence()) {
581 y1
+= eo
.getHeight();
584 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
586 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
587 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
588 y2
+= eo2
.getHeight();
592 int m1Y
= Math
.round(y1
* fZoomValue
);
593 int m2Y
= Math
.round(y2
* fZoomValue
);
594 if ((m1Y
< e
.y
) && (m2Y
>= e
.y
)) {
595 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
596 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
605 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseExit(org.eclipse.swt.events.MouseEvent)
608 protected void contentsMouseExit(MouseEvent e
) {
609 if (fTooltip
!= null) {
610 fTooltip
.hideToolTip();
616 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseUpEvent(org.eclipse.swt.events.MouseEvent)
619 protected void contentsMouseUpEvent(MouseEvent event
) {
620 selectTimeDelta(event
.y
, 0);
622 super.contentsMouseUpEvent(event
);
626 * Force the time compression bar to highlight the event occurrences between
627 * the two given messages. The event occurrences are highlighted on the
628 * first message's end lifeline
635 public void highlightRegion(BaseMessage mes1
, BaseMessage mes2
) {
636 BaseMessage localMes1
= mes1
;
637 BaseMessage localMes2
= mes2
;
639 if (fFrame
== null) {
642 if (!(localMes1
instanceof ITimeRange
)) {
645 if (!(localMes2
instanceof ITimeRange
)) {
648 ITimeRange t1
= (ITimeRange
) localMes1
;
649 ITimeRange t2
= (ITimeRange
) localMes2
;
651 ITmfTimestamp time1
= t1
.getStartTime();
652 ITmfTimestamp time2
= t2
.getStartTime();
653 int event1
= localMes1
.getEventOccurrence();
654 int event2
= localMes2
.getEventOccurrence();
656 if (localMes1
instanceof AsyncMessage
) {
657 AsyncMessage as
= (AsyncMessage
) localMes1
;
658 time1
= as
.getEndTime();
659 event1
= as
.getEndOccurrence();
661 if (localMes2
instanceof AsyncMessage
) {
662 AsyncMessage as
= (AsyncMessage
) localMes2
;
663 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
664 time1
= as
.getEndTime();
665 event1
= as
.getEndOccurrence();
667 time1
= as
.getStartTime();
668 event1
= as
.getStartOccurrence();
672 if (event1
> event2
) {
673 BaseMessage tempMes
= localMes2
;
674 localMes2
= localMes1
;
677 t1
= (ITimeRange
) localMes1
;
678 t2
= (ITimeRange
) localMes2
;
680 time1
= t1
.getStartTime();
681 time2
= t2
.getStartTime();
682 event1
= localMes1
.getEventOccurrence();
683 event2
= localMes2
.getEventOccurrence();
685 if (localMes1
instanceof AsyncMessage
) {
686 AsyncMessage as
= (AsyncMessage
) localMes1
;
687 time1
= as
.getEndTime();
688 event1
= as
.getEndOccurrence();
690 if (localMes2
instanceof AsyncMessage
) {
691 AsyncMessage as
= (AsyncMessage
) localMes2
;
692 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
693 time1
= as
.getEndTime();
694 event1
= as
.getEndOccurrence();
696 time1
= as
.getStartTime();
697 event1
= as
.getStartOccurrence();
702 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
703 double gr
= (minMaxdelta
.getValue()) / (double) 10;
705 ITmfTimestamp delta
= time2
.getDelta(time1
).getDelta(fMinTime
);
706 long absDelta
= Math
.abs(delta
.getValue());
710 colIndex
= Math
.round((float) (absDelta
/ gr
));
711 if (colIndex
>= fColors
.length
) {
712 colIndex
= fColors
.length
- 1;
713 } else if (colIndex
< 0) {
719 for (int j
= 0; j
< fListenerList
.size(); j
++) {
720 ITimeCompressionListener list
= fListenerList
.get(j
);
721 if (localMes1
.getEndLifeline() != null) {
722 list
.deltaSelected(localMes1
.getEndLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
723 } else if (localMes2
.getStartLifeline() != null) {
724 list
.deltaSelected(localMes2
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
726 list
.deltaSelected(localMes1
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
732 * Force the time compression bar to highlight the event occurrences between the two given messages. The event
733 * occurrences are highlighted on the first message's end lifeline
735 * @param mes1 the first message
736 * @param mes2 the second message
738 public void highlightRegionSync(final BaseMessage mes1
, final BaseMessage mes2
) {
739 getDisplay().syncExec(new Runnable() {
742 highlightRegion(mes1
, mes2
);
749 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#scrollBy(int, int)
752 public void scrollBy(int x
, int y
) {
756 * Sets the zoom value.
758 * @param value The zoom value to set.
760 public void setZoom(float value
) {
766 * Adds a listener to the time compression listener list to be notified about selected deltas.
768 * @param listener The listener to add
770 public void addTimeCompressionListener(ITimeCompressionListener listener
) {
771 if (!fListenerList
.contains(listener
)) {
772 fListenerList
.add(listener
);
777 * Removes a time compression listener.
779 * @param listener The listener to remove.
781 public void removeSelectionChangedListener(ITimeCompressionListener listener
) {
782 fListenerList
.remove(listener
);
787 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
790 public void widgetDisposed(DisposeEvent e
) {
791 if (fTooltip
!= null) {
794 super.removeDisposeListener(this);
795 for (int i
= 0; i
< fColors
.length
; i
++) {
796 fColors
[i
].dispose();
802 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#keyPressedEvent(org.eclipse.swt.events.KeyEvent)
805 protected void keyPressedEvent(KeyEvent event
) {
806 if (fTooltip
!= null) {
807 fTooltip
.hideToolTip();
809 if (!isFocusControl() || getViewControl().isFocusControl()) {
810 Control
[] child
= getParent().getChildren();
811 for (int i
= 0; i
< child
.length
; i
++) {
812 if (child
[i
].isFocusControl()) {
813 // getViewControl().setFocus();
821 if (fNextNodeY
== 0) {
824 if ((fFrame
!= null) && (fNextNodeY
== 0)) {
825 for (int i
= 0; i
< fNodeList
.size() - 1 && i
< 1; i
++) {
826 SDTimeEvent m1
= fNodeList
.get(i
);
827 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
828 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
829 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
830 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
831 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
836 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
837 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
838 if (m1
.getGraphNode() instanceof AsyncMessage
) {
839 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
840 if (as
.getEndTime() == m1
.getTime()) {
841 y1
+= as
.getHeight();
844 if (m2
.getGraphNode() instanceof AsyncMessage
) {
845 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
846 if (as
.getEndTime() == m2
.getTime()) {
847 y2
+= as
.getHeight();
850 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
851 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
852 if (m1
.getEvent() == eo
.getEndOccurrence()) {
853 y1
+= eo
.getHeight();
856 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
858 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
859 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
860 y2
+= eo2
.getHeight();
864 fPrevNodeY
= Math
.round(y1
* fZoomValue
);
865 fNextNodeY
= Math
.round(y2
* fZoomValue
);
869 if (fLifeline
!= null) {
870 for (int j
= 0; j
< fListenerList
.size(); j
++) {
871 ITimeCompressionListener list
= fListenerList
.get(j
);
872 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
876 if (event
.keyCode
== SWT
.ARROW_DOWN
) {
878 selectTimeDelta(fNextNodeY
+ 1, 1);
880 selectTimeDelta(fPrevNodeY
+ 1, 1);
883 } else if (event
.keyCode
== SWT
.ARROW_UP
) {
884 selectTimeDelta(fPrevNodeY
- 1, 2);
886 } else if (event
.keyCode
== SWT
.ARROW_RIGHT
) {
887 selectTimeDelta(fPrevNodeY
, 1);
890 super.keyPressedEvent(event
);
894 * Selects the time delta for given delta y coordinate and direction.
896 * @param dy The delta in y coordinate.
897 * @param direction 0 no direction, 1 = down, 2 = up
899 protected void selectTimeDelta(int dy
, int direction
) {
900 SDTimeEvent lastM1
= null;
901 SDTimeEvent lastM2
= null;
904 boolean done
= false;
905 if (fFrame
!= null) {
906 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
907 SDTimeEvent m1
= fNodeList
.get(i
);
908 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
909 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
910 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
911 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
912 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
917 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
918 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
919 if (m1
.getGraphNode() instanceof AsyncMessage
) {
920 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
921 if (as
.getEndTime() == m1
.getTime()) {
922 y1
+= as
.getHeight();
925 if (m2
.getGraphNode() instanceof AsyncMessage
) {
926 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
927 if (as
.getEndTime() == m2
.getTime()) {
928 y2
+= as
.getHeight();
931 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
932 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
933 if (m1
.getEvent() == eo
.getEndOccurrence()) {
934 y1
+= eo
.getHeight();
937 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
938 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
939 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
940 y2
+= eo2
.getHeight();
944 int m1Y
= Math
.round(y1
* fZoomValue
);
945 int m2Y
= Math
.round(y2
* fZoomValue
);
947 if ((m1Y
< dy
) && (m2Y
> dy
) || (!done
&& m2Y
> dy
&& direction
== 1 && lastM1
!= null) || (!done
&& m1Y
> dy
&& direction
== 2 && lastM1
!= null)) {
948 if (m1Y
> dy
&& direction
== 2) {
957 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
958 double gr
= (minMaxdelta
.getValue()) / (double) 10;
960 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
961 long absDelta
= Math
.abs(delta
.getValue());
965 colIndex
= Math
.round((float) (absDelta
/ gr
));
966 if (colIndex
>= fColors
.length
) {
967 colIndex
= fColors
.length
- 1;
968 } else if (colIndex
< 0) {
974 if (m1
.getGraphNode() instanceof BaseMessage
) {
975 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
976 if (mes1
.getEndLifeline() != null) {
977 fLifeline
= mes1
.getEndLifeline();
978 fLifelineStart
= m1
.getEvent();
979 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
980 fLifelineColor
= fColors
[colIndex
];
981 } else if (m2
.getGraphNode() instanceof BaseMessage
&& ((BaseMessage
) m2
.getGraphNode()).getStartLifeline() != null) {
982 fLifeline
= ((BaseMessage
) m2
.getGraphNode()).getStartLifeline();
983 fLifelineStart
= m1
.getEvent();
984 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
985 fLifelineColor
= fColors
[colIndex
];
987 fLifeline
= mes1
.getStartLifeline();
988 fLifelineStart
= m1
.getEvent();
989 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
990 fLifelineColor
= fColors
[colIndex
];
992 } else if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
993 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
994 ExecutionOccurrence eo
= (ExecutionOccurrence
) m2
.getGraphNode();
995 fLifeline
= eo
.getLifeline();
996 fLifelineStart
= m1
.getEvent();
997 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
998 fLifelineColor
= fColors
[colIndex
];
1000 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
1001 fLifeline
= eo
.getLifeline();
1002 fLifelineStart
= m1
.getEvent();
1003 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
1004 fLifelineColor
= fColors
[colIndex
];
1007 for (int j
= 0; j
< fListenerList
.size(); j
++) {
1008 ITimeCompressionListener list
= fListenerList
.get(j
);
1009 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
= fNodeList
.get(i
);
1033 SDTimeEvent m2
= 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
)) {