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
.timestamp
.ITmfTimestamp
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.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.
489 * @return true if child is on focus else false
491 protected boolean checkFocusOnChilds(Control children
) {
492 if (children
instanceof Composite
) {
493 Control
[] child
= ((Composite
) children
).getChildren();
494 for (int i
= 0; i
< child
.length
; i
++) {
495 if (child
[i
].isFocusControl()) {
498 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
]);
522 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseMoveEvent(org.eclipse.swt.events.MouseEvent)
525 protected void contentsMouseMoveEvent(MouseEvent event
) {
526 if (fTooltip
!= null) {
527 fTooltip
.hideToolTip();
529 super.contentsMouseMoveEvent(event
);
530 if (!isFocusControl() || getViewControl().isFocusControl()) {
531 Control
[] child
= getParent().getChildren();
532 for (int i
= 0; i
< child
.length
; i
++) {
533 if (child
[i
].isFocusControl()) {
543 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseHover(org.eclipse.swt.events.MouseEvent)
546 protected void contentsMouseHover(MouseEvent e
) {
547 if (fTooltip
== null) {
548 fTooltip
= new DrawableToolTip(this);
550 if (fFrame
!= null) {
552 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
553 SDTimeEvent m1
= fNodeList
.get(i
);
554 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
556 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
557 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
558 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
559 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
564 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
565 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
567 if (m1
.getGraphNode() instanceof AsyncMessage
) {
568 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
569 if (as
.getEndTime() == m1
.getTime()) {
570 y1
+= as
.getHeight();
573 if (m2
.getGraphNode() instanceof AsyncMessage
) {
574 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
575 if (as
.getEndTime() == m2
.getTime()) {
576 y2
+= as
.getHeight();
579 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
580 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
581 if (m1
.getEvent() == eo
.getEndOccurrence()) {
582 y1
+= eo
.getHeight();
585 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
587 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
588 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
589 y2
+= eo2
.getHeight();
593 int m1Y
= Math
.round(y1
* fZoomValue
);
594 int m2Y
= Math
.round(y2
* fZoomValue
);
595 if ((m1Y
< e
.y
) && (m2Y
>= e
.y
)) {
596 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
597 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
606 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseExit(org.eclipse.swt.events.MouseEvent)
609 protected void contentsMouseExit(MouseEvent e
) {
610 if (fTooltip
!= null) {
611 fTooltip
.hideToolTip();
617 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseUpEvent(org.eclipse.swt.events.MouseEvent)
620 protected void contentsMouseUpEvent(MouseEvent event
) {
621 selectTimeDelta(event
.y
, 0);
623 super.contentsMouseUpEvent(event
);
627 * Force the time compression bar to highlight the event occurrences between
628 * the two given messages. The event occurrences are highlighted on the
629 * first message's end lifeline
636 public void highlightRegion(BaseMessage mes1
, BaseMessage mes2
) {
637 BaseMessage localMes1
= mes1
;
638 BaseMessage localMes2
= mes2
;
640 if (fFrame
== null) {
643 if (!(localMes1
instanceof ITimeRange
)) {
646 if (!(localMes2
instanceof ITimeRange
)) {
649 ITimeRange t1
= (ITimeRange
) localMes1
;
650 ITimeRange t2
= (ITimeRange
) localMes2
;
652 ITmfTimestamp time1
= t1
.getStartTime();
653 ITmfTimestamp time2
= t2
.getStartTime();
654 int event1
= localMes1
.getEventOccurrence();
655 int event2
= localMes2
.getEventOccurrence();
657 if (localMes1
instanceof AsyncMessage
) {
658 AsyncMessage as
= (AsyncMessage
) localMes1
;
659 time1
= as
.getEndTime();
660 event1
= as
.getEndOccurrence();
662 if (localMes2
instanceof AsyncMessage
) {
663 AsyncMessage as
= (AsyncMessage
) localMes2
;
664 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
665 time1
= as
.getEndTime();
666 event1
= as
.getEndOccurrence();
668 time1
= as
.getStartTime();
669 event1
= as
.getStartOccurrence();
673 if (event1
> event2
) {
674 BaseMessage tempMes
= localMes2
;
675 localMes2
= localMes1
;
678 t1
= (ITimeRange
) localMes1
;
679 t2
= (ITimeRange
) localMes2
;
681 time1
= t1
.getStartTime();
682 time2
= t2
.getStartTime();
683 event1
= localMes1
.getEventOccurrence();
684 event2
= localMes2
.getEventOccurrence();
686 if (localMes1
instanceof AsyncMessage
) {
687 AsyncMessage as
= (AsyncMessage
) localMes1
;
688 time1
= as
.getEndTime();
689 event1
= as
.getEndOccurrence();
691 if (localMes2
instanceof AsyncMessage
) {
692 AsyncMessage as
= (AsyncMessage
) localMes2
;
693 if (as
.getEndOccurrence() > as
.getStartOccurrence()) {
694 time1
= as
.getEndTime();
695 event1
= as
.getEndOccurrence();
697 time1
= as
.getStartTime();
698 event1
= as
.getStartOccurrence();
703 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
704 double gr
= (minMaxdelta
.getValue()) / (double) 10;
706 ITmfTimestamp delta
= time2
.getDelta(time1
).getDelta(fMinTime
);
707 long absDelta
= Math
.abs(delta
.getValue());
711 colIndex
= Math
.round((float) (absDelta
/ gr
));
712 if (colIndex
>= fColors
.length
) {
713 colIndex
= fColors
.length
- 1;
714 } else if (colIndex
< 0) {
720 for (int j
= 0; j
< fListenerList
.size(); j
++) {
721 ITimeCompressionListener list
= fListenerList
.get(j
);
722 if (localMes1
.getEndLifeline() != null) {
723 list
.deltaSelected(localMes1
.getEndLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
724 } else if (localMes2
.getStartLifeline() != null) {
725 list
.deltaSelected(localMes2
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
727 list
.deltaSelected(localMes1
.getStartLifeline(), event1
, event2
- event1
, fColors
[colIndex
]);
733 * Force the time compression bar to highlight the event occurrences between the two given messages. The event
734 * occurrences are highlighted on the first message's end lifeline
736 * @param mes1 the first message
737 * @param mes2 the second message
739 public void highlightRegionSync(final BaseMessage mes1
, final BaseMessage mes2
) {
740 getDisplay().syncExec(new Runnable() {
743 highlightRegion(mes1
, mes2
);
750 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#scrollBy(int, int)
753 public void scrollBy(int x
, int y
) {
757 * Sets the zoom value.
759 * @param value The zoom value to set.
761 public void setZoom(float value
) {
767 * Adds a listener to the time compression listener list to be notified about selected deltas.
769 * @param listener The listener to add
771 public void addTimeCompressionListener(ITimeCompressionListener listener
) {
772 if (!fListenerList
.contains(listener
)) {
773 fListenerList
.add(listener
);
778 * Removes a time compression listener.
780 * @param listener The listener to remove.
782 public void removeSelectionChangedListener(ITimeCompressionListener listener
) {
783 fListenerList
.remove(listener
);
788 * @see org.eclipse.swt.events.DisposeListener#widgetDisposed(org.eclipse.swt.events.DisposeEvent)
791 public void widgetDisposed(DisposeEvent e
) {
792 if (fTooltip
!= null) {
795 super.removeDisposeListener(this);
796 for (int i
= 0; i
< fColors
.length
; i
++) {
797 fColors
[i
].dispose();
803 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#keyPressedEvent(org.eclipse.swt.events.KeyEvent)
806 protected void keyPressedEvent(KeyEvent event
) {
807 if (fTooltip
!= null) {
808 fTooltip
.hideToolTip();
810 if (!isFocusControl() || getViewControl().isFocusControl()) {
811 Control
[] child
= getParent().getChildren();
812 for (int i
= 0; i
< child
.length
; i
++) {
813 if (child
[i
].isFocusControl()) {
814 // getViewControl().setFocus();
822 if (fNextNodeY
== 0) {
825 if ((fFrame
!= null) && (fNextNodeY
== 0)) {
826 for (int i
= 0; i
< fNodeList
.size() - 1 && i
< 1; i
++) {
827 SDTimeEvent m1
= fNodeList
.get(i
);
828 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
829 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
830 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
831 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
832 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
837 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
838 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
839 if (m1
.getGraphNode() instanceof AsyncMessage
) {
840 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
841 if (as
.getEndTime() == m1
.getTime()) {
842 y1
+= as
.getHeight();
845 if (m2
.getGraphNode() instanceof AsyncMessage
) {
846 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
847 if (as
.getEndTime() == m2
.getTime()) {
848 y2
+= as
.getHeight();
851 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
852 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
853 if (m1
.getEvent() == eo
.getEndOccurrence()) {
854 y1
+= eo
.getHeight();
857 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
859 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
860 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
861 y2
+= eo2
.getHeight();
865 fPrevNodeY
= Math
.round(y1
* fZoomValue
);
866 fNextNodeY
= Math
.round(y2
* fZoomValue
);
870 if (fLifeline
!= null) {
871 for (int j
= 0; j
< fListenerList
.size(); j
++) {
872 ITimeCompressionListener list
= fListenerList
.get(j
);
873 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
877 if (event
.keyCode
== SWT
.ARROW_DOWN
) {
879 selectTimeDelta(fNextNodeY
+ 1, 1);
881 selectTimeDelta(fPrevNodeY
+ 1, 1);
884 } else if (event
.keyCode
== SWT
.ARROW_UP
) {
885 selectTimeDelta(fPrevNodeY
- 1, 2);
887 } else if (event
.keyCode
== SWT
.ARROW_RIGHT
) {
888 selectTimeDelta(fPrevNodeY
, 1);
891 super.keyPressedEvent(event
);
895 * Selects the time delta for given delta y coordinate and direction.
897 * @param dy The delta in y coordinate.
898 * @param direction 0 no direction, 1 = down, 2 = up
900 protected void selectTimeDelta(int dy
, int direction
) {
901 SDTimeEvent lastM1
= null;
902 SDTimeEvent lastM2
= null;
905 boolean done
= false;
906 if (fFrame
!= null) {
907 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
908 SDTimeEvent m1
= fNodeList
.get(i
);
909 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
910 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
911 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
912 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
913 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
918 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
919 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
920 if (m1
.getGraphNode() instanceof AsyncMessage
) {
921 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
922 if (as
.getEndTime() == m1
.getTime()) {
923 y1
+= as
.getHeight();
926 if (m2
.getGraphNode() instanceof AsyncMessage
) {
927 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
928 if (as
.getEndTime() == m2
.getTime()) {
929 y2
+= as
.getHeight();
932 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
933 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
934 if (m1
.getEvent() == eo
.getEndOccurrence()) {
935 y1
+= eo
.getHeight();
938 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
939 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
940 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
941 y2
+= eo2
.getHeight();
945 int m1Y
= Math
.round(y1
* fZoomValue
);
946 int m2Y
= Math
.round(y2
* fZoomValue
);
948 if ((m1Y
< dy
) && (m2Y
> dy
) || (!done
&& m2Y
> dy
&& direction
== 1 && lastM1
!= null) || (!done
&& m1Y
> dy
&& direction
== 2 && lastM1
!= null)) {
949 if (m1Y
> dy
&& direction
== 2) {
958 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
959 double gr
= (minMaxdelta
.getValue()) / (double) 10;
961 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
962 long absDelta
= Math
.abs(delta
.getValue());
966 colIndex
= Math
.round((float) (absDelta
/ gr
));
967 if (colIndex
>= fColors
.length
) {
968 colIndex
= fColors
.length
- 1;
969 } else if (colIndex
< 0) {
975 if (m1
.getGraphNode() instanceof BaseMessage
) {
976 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
977 if (mes1
.getEndLifeline() != null) {
978 fLifeline
= mes1
.getEndLifeline();
979 fLifelineStart
= m1
.getEvent();
980 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
981 fLifelineColor
= fColors
[colIndex
];
982 } else if (m2
.getGraphNode() instanceof BaseMessage
&& ((BaseMessage
) m2
.getGraphNode()).getStartLifeline() != null) {
983 fLifeline
= ((BaseMessage
) m2
.getGraphNode()).getStartLifeline();
984 fLifelineStart
= m1
.getEvent();
985 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
986 fLifelineColor
= fColors
[colIndex
];
988 fLifeline
= mes1
.getStartLifeline();
989 fLifelineStart
= m1
.getEvent();
990 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
991 fLifelineColor
= fColors
[colIndex
];
993 } else if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
994 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
995 ExecutionOccurrence eo
= (ExecutionOccurrence
) m2
.getGraphNode();
996 fLifeline
= eo
.getLifeline();
997 fLifelineStart
= m1
.getEvent();
998 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
999 fLifelineColor
= fColors
[colIndex
];
1001 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
1002 fLifeline
= eo
.getLifeline();
1003 fLifelineStart
= m1
.getEvent();
1004 fLifelineNumEvents
= m2
.getEvent() - m1
.getEvent();
1005 fLifelineColor
= fColors
[colIndex
];
1008 for (int j
= 0; j
< fListenerList
.size(); j
++) {
1009 ITimeCompressionListener list
= fListenerList
.get(j
);
1010 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
1023 * Creates a fake tool tip.
1025 protected void createFakeTooltip() {
1026 if (fTooltip
== null) {
1027 fTooltip
= new DrawableToolTip(this);
1030 if (fFrame
!= null) {
1032 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
1033 SDTimeEvent m1
= fNodeList
.get(i
);
1034 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
1036 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
1037 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
1038 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
1039 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
1044 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
1045 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
1047 if (m1
.getGraphNode() instanceof AsyncMessage
) {
1048 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
1049 if (as
.getEndTime() == m1
.getTime()) {
1050 y1
+= as
.getHeight();
1053 if (m2
.getGraphNode() instanceof AsyncMessage
) {
1054 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
1055 if (as
.getEndTime() == m2
.getTime()) {
1056 y2
+= as
.getHeight();
1059 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
1060 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
1061 if (m1
.getEvent() == eo
.getEndOccurrence()) {
1062 y1
+= eo
.getHeight();
1065 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
1067 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
1068 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
1069 y2
+= eo2
.getHeight();
1073 int m1Y
= Math
.round(y1
* fZoomValue
);
1074 int m2Y
= Math
.round(y2
* fZoomValue
);
1075 if ((m1Y
< fPrevNodeY
+ 1) && (m2Y
>= fPrevNodeY
+ 1)) {
1076 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
1077 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
1078 fTooltip
.hideToolTip();
1085 * Traverse Listener implementation.
1087 protected static class LocalTraverseListener
implements TraverseListener
{
1091 * @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
1094 public void keyTraversed(TraverseEvent e
) {
1095 if ((e
.detail
== SWT
.TRAVERSE_TAB_NEXT
) || (e
.detail
== SWT
.TRAVERSE_TAB_PREVIOUS
)) {