1 /**********************************************************************
2 * Copyright (c) 2005, 2013 IBM Corporation, Ericsson
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM - Initial API and implementation
10 * Bernd Hufmann - Updated for TMF
11 **********************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
;
15 import java
.util
.ArrayList
;
16 import java
.util
.Arrays
;
17 import java
.util
.List
;
19 import org
.eclipse
.linuxtools
.internal
.tmf
.ui
.Activator
;
20 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.ITmfTimestamp
;
21 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimestamp
;
22 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.AsyncMessage
;
23 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.AsyncMessageReturn
;
24 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.BaseMessage
;
25 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.ExecutionOccurrence
;
26 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Frame
;
27 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.GraphNode
;
28 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.ITimeRange
;
29 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Lifeline
;
30 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.Metrics
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.SDTimeEvent
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.core
.SyncMessage
;
33 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.IColor
;
34 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.drawings
.impl
.ColorImpl
;
35 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.preferences
.SDViewPref
;
36 import org
.eclipse
.linuxtools
.tmf
.ui
.views
.uml2sd
.util
.TimeEventComparator
;
37 import org
.eclipse
.swt
.SWT
;
38 import org
.eclipse
.swt
.accessibility
.ACC
;
39 import org
.eclipse
.swt
.accessibility
.Accessible
;
40 import org
.eclipse
.swt
.accessibility
.AccessibleAdapter
;
41 import org
.eclipse
.swt
.accessibility
.AccessibleControlAdapter
;
42 import org
.eclipse
.swt
.accessibility
.AccessibleControlEvent
;
43 import org
.eclipse
.swt
.accessibility
.AccessibleEvent
;
44 import org
.eclipse
.swt
.events
.DisposeEvent
;
45 import org
.eclipse
.swt
.events
.DisposeListener
;
46 import org
.eclipse
.swt
.events
.FocusEvent
;
47 import org
.eclipse
.swt
.events
.FocusListener
;
48 import org
.eclipse
.swt
.events
.KeyEvent
;
49 import org
.eclipse
.swt
.events
.MouseEvent
;
50 import org
.eclipse
.swt
.events
.TraverseEvent
;
51 import org
.eclipse
.swt
.events
.TraverseListener
;
52 import org
.eclipse
.swt
.graphics
.Color
;
53 import org
.eclipse
.swt
.graphics
.GC
;
54 import org
.eclipse
.swt
.graphics
.Image
;
55 import org
.eclipse
.swt
.widgets
.Composite
;
56 import org
.eclipse
.swt
.widgets
.Control
;
57 import org
.eclipse
.swt
.widgets
.Display
;
61 * The time compression bar implementation.
67 public class TimeCompressionBar
extends ScrollView
implements DisposeListener
{
69 // ------------------------------------------------------------------------
71 // ------------------------------------------------------------------------
76 protected List
<ITimeCompressionListener
> fListenerList
= null;
78 * The current frame displayed.
80 protected Frame fFrame
= null;
82 * List of time events.
84 protected List
<SDTimeEvent
> fNodeList
= null;
86 * The minimum time delta.
88 protected ITmfTimestamp fMinTime
= new TmfTimestamp();
90 * The maximum time delta.
92 protected ITmfTimestamp fMaxTime
= new TmfTimestamp();
94 * The current zoom value.
96 protected float fZoomValue
= 1;
98 * The tooltip to display.
100 protected DrawableToolTip fTooltip
= null;
102 * Array of colors for displaying wight of time deltas.
104 protected ColorImpl
[] fColors
;
106 * The accessible object reference.
108 protected Accessible fAccessible
= null;
110 * The focused widget reference.
112 protected int fFocusedWidget
= -1;
114 * The sequence diagram view reference.
116 protected SDView view
= null;
118 * The current lifeline.
120 protected Lifeline fLifeline
= null;
122 * The current start event value.
124 protected int fLifelineStart
= 0;
126 * The current number of events.
128 protected int fLifelineNumEvents
= 0;
130 * The Current color of range to display.
132 protected IColor fLifelineColor
= null;
134 * The next graph node y coordinate.
136 protected int fNextNodeY
= 0;
138 * The previous graph node y coordinate.
140 protected int fPrevNodeY
= 0;
142 // ------------------------------------------------------------------------
144 // ------------------------------------------------------------------------
146 * Standard constructor
148 * @param parent The parent composite
149 * @param s The style bits
151 public TimeCompressionBar(Composite parent
, int s
) {
152 super(parent
, s
| SWT
.NO_BACKGROUND
, false);
153 setVScrollBarMode(ScrollView
.ALWAYS_OFF
);
154 setHScrollBarMode(ScrollView
.ALWAYS_OFF
);
155 fListenerList
= new ArrayList
<ITimeCompressionListener
>();
156 fColors
= new ColorImpl
[10];
157 fColors
[0] = new ColorImpl(Display
.getDefault(), 255, 229, 229);
158 fColors
[1] = new ColorImpl(Display
.getDefault(), 255, 204, 204);
159 fColors
[2] = new ColorImpl(Display
.getDefault(), 255, 178, 178);
160 fColors
[3] = new ColorImpl(Display
.getDefault(), 255, 153, 153);
161 fColors
[4] = new ColorImpl(Display
.getDefault(), 255, 127, 127);
162 fColors
[5] = new ColorImpl(Display
.getDefault(), 255, 102, 102);
163 fColors
[6] = new ColorImpl(Display
.getDefault(), 255, 76, 76);
164 fColors
[7] = new ColorImpl(Display
.getDefault(), 255, 51, 51);
165 fColors
[8] = new ColorImpl(Display
.getDefault(), 255, 25, 25);
166 fColors
[9] = new ColorImpl(Display
.getDefault(), 255, 0, 0);
167 super.addDisposeListener(this);
169 fAccessible
= getViewControl().getAccessible();
171 fAccessible
.addAccessibleListener(new AccessibleAdapter() {
173 public void getName(AccessibleEvent e
) {
175 if (e
.childID
== 0) {
176 if (fTooltip
!= null) {
177 e
.result
= fTooltip
.getAccessibleText();
179 } else if (e
.childID
== 1) {
181 e
.result
= fTooltip
.getAccessibleText();
186 fAccessible
.addAccessibleControlListener(new AccessibleControlAdapter() {
189 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getFocus(org.eclipse.swt.accessibility.AccessibleControlEvent)
192 public void getFocus(AccessibleControlEvent e
) {
193 if (fFocusedWidget
== -1) {
194 e
.childID
= ACC
.CHILDID_SELF
;
197 e
.childID
= fFocusedWidget
;
203 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getRole(org.eclipse.swt.accessibility.AccessibleControlEvent)
206 public void getRole(AccessibleControlEvent e
) {
208 case ACC
.CHILDID_SELF
:
209 e
.detail
= ACC
.ROLE_CLIENT_AREA
;
212 e
.detail
= ACC
.ROLE_TOOLTIP
;
215 e
.detail
= ACC
.ROLE_LABEL
;
224 * @see org.eclipse.swt.accessibility.AccessibleControlAdapter#getState(org.eclipse.swt.accessibility.AccessibleControlEvent)
227 public void getState(AccessibleControlEvent e
) {
228 e
.detail
= ACC
.STATE_FOCUSABLE
;
229 if (e
.childID
== ACC
.CHILDID_SELF
) {
230 e
.detail
|= ACC
.STATE_FOCUSED
;
232 e
.detail
|= ACC
.STATE_SELECTABLE
;
233 if (e
.childID
== fFocusedWidget
) {
234 e
.detail
|= ACC
.STATE_FOCUSED
| ACC
.STATE_SELECTED
| ACC
.STATE_CHECKED
;
240 getViewControl().addTraverseListener(new LocalTraverseListener());
242 addTraverseListener(new LocalTraverseListener());
244 getViewControl().addFocusListener(new FocusListener() {
248 * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
251 public void focusGained(FocusEvent e
) {
257 * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
260 public void focusLost(FocusEvent e
) {
266 // ------------------------------------------------------------------------
268 // ------------------------------------------------------------------------
271 * Sets the focus widget
273 * @param newFocusShape widget reference to set
275 void setFocus(int newFocusShape
) {
276 fFocusedWidget
= newFocusShape
;
277 if (fFocusedWidget
== -1) {
278 getViewControl().getAccessible().setFocus(ACC
.CHILDID_SELF
);
280 getViewControl().getAccessible().setFocus(fFocusedWidget
);
285 * Sets the current frame.
287 * @param theFrame The frame to set
289 public void setFrame(Frame theFrame
) {
291 fMinTime
= fFrame
.getMinTime();
292 fMaxTime
= fFrame
.getMaxTime();
297 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#drawContents(org.eclipse.swt.graphics.GC, int, int, int, int)
300 protected void drawContents(GC gc
, int clipx
, int clipy
, int clipw
, int cliph
) {
301 if (fFrame
== null) {
304 fNodeList
= new ArrayList
<SDTimeEvent
>();
305 int messageArraysStep
= 1;
307 if ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * fZoomValue
< Metrics
.MESSAGE_SIGNIFICANT_VSPACING
+ 1) {
308 messageArraysStep
= Math
.round(Metrics
.MESSAGE_SIGNIFICANT_VSPACING
+ 1 / ((Metrics
.getMessageFontHeigth() + Metrics
.MESSAGES_NAME_SPACING
* 2) * fZoomValue
));
311 int firstVisible
= fFrame
.getFirstVisibleSyncMessage();
312 if (firstVisible
> 0) {
313 firstVisible
= firstVisible
- 1;
315 for (int i
= firstVisible
; i
< fFrame
.syncMessageCount(); i
= i
+ messageArraysStep
) {
316 SyncMessage m
= fFrame
.getSyncMessage(i
);
317 if (m
.hasTimeInfo()) {
318 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getEventOccurrence(), m
);
320 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
326 firstVisible
= fFrame
.getFirstVisibleSyncMessageReturn();
327 if (firstVisible
> 0) {
328 firstVisible
= firstVisible
- 1;
330 for (int i
= firstVisible
; i
< fFrame
.syncMessageReturnCount(); i
= i
+ messageArraysStep
) {
331 SyncMessage m
= fFrame
.getSyncMessageReturn(i
);
332 if (m
.hasTimeInfo()) {
333 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getEventOccurrence(), m
);
335 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
341 firstVisible
= fFrame
.getFirstVisibleAsyncMessage();
342 if (firstVisible
> 0) {
343 firstVisible
= firstVisible
- 1;
345 for (int i
= firstVisible
; i
< fFrame
.asyncMessageCount(); i
= i
+ messageArraysStep
) {
346 AsyncMessage m
= fFrame
.getAsyncMessage(i
);
347 if (m
.hasTimeInfo()) {
348 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getStartOccurrence(), m
);
350 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), m
);
352 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
358 firstVisible
= fFrame
.getFirstVisibleAsyncMessageReturn();
359 if (firstVisible
> 0) {
360 firstVisible
= firstVisible
- 1;
362 for (int i
= firstVisible
; i
< fFrame
.asyncMessageReturnCount(); i
= i
+ messageArraysStep
) {
363 AsyncMessageReturn m
= fFrame
.getAsyncMessageReturn(i
);
364 if (m
.hasTimeInfo()) {
365 SDTimeEvent t
= new SDTimeEvent(m
.getStartTime(), m
.getStartOccurrence(), m
);
367 t
= new SDTimeEvent(m
.getEndTime(), m
.getEndOccurrence(), m
);
369 if (m
.getY() * fZoomValue
> getContentsY() + getVisibleHeight()) {
375 List
<SDTimeEvent
> executionOccurrencesWithTime
= fFrame
.getExecutionOccurrencesWithTime();
376 if (executionOccurrencesWithTime
!= null) {
377 fNodeList
.addAll(executionOccurrencesWithTime
);
380 SDTimeEvent
[] temp
= fNodeList
.toArray(new SDTimeEvent
[fNodeList
.size()]);
381 Arrays
.sort(temp
, new TimeEventComparator());
382 fNodeList
= Arrays
.asList(temp
);
384 Image dbuffer
= null;
387 dbuffer
= new Image(getDisplay(), getClientArea().width
, getClientArea().height
);
388 } catch (Exception e
) {
389 Activator
.getDefault().logError("Error creating image", e
); //$NON-NLS-1$
391 gcim
= new GC(dbuffer
);
392 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
393 SDTimeEvent m1
= fNodeList
.get(i
);
394 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
396 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
397 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
398 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
399 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
404 fMinTime
= fFrame
.getMinTime();
405 fMaxTime
= fFrame
.getMaxTime();
406 ITmfTimestamp minMaxdelta
= fMaxTime
.getDelta(fMinTime
);
407 double gr
= (minMaxdelta
.getValue()) / (double) 10;
409 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime()).getDelta(fMinTime
);
410 long absDelta
= Math
.abs(delta
.getValue());
414 int colIndex
= Math
.round((float) (absDelta
/ gr
));
415 if (colIndex
< fColors
.length
&& colIndex
> 0) {
416 color
= fColors
[colIndex
- 1];
417 } else if (colIndex
<= 0) {
420 color
= fColors
[fColors
.length
- 1];
426 if (color
.getColor() instanceof Color
) {
427 gcim
.setBackground((Color
) color
.getColor());
429 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
430 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
431 if (m1
.getGraphNode() instanceof AsyncMessage
) {
432 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
433 if (as
.getEndTime() == m1
.getTime()) {
434 y1
+= as
.getHeight();
437 if (m2
.getGraphNode() instanceof AsyncMessage
) {
438 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
439 if (as
.getEndTime() == m2
.getTime()) {
440 y2
+= as
.getHeight();
443 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
445 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
446 if (m1
.getEvent() == eo
.getEndOccurrence()) {
447 y1
+= eo
.getHeight();
450 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
452 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
453 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
454 y2
+= eo2
.getHeight();
459 gcim
.fillRectangle(contentsToViewX(0), contentsToViewY(Math
.round(y1
* fZoomValue
)), 10, Math
.round((y2
- y1
) * fZoomValue
) + 1);
460 if (messageArraysStep
== 1) {
461 Color backupColor
= gcim
.getForeground();
462 gcim
.setForeground(Display
.getDefault().getSystemColor(SWT
.COLOR_WHITE
));
463 gcim
.drawRectangle(contentsToViewX(0), contentsToViewY(Math
.round(y1
* fZoomValue
)), 9, Math
.round((y2
- y1
) * fZoomValue
));
464 gcim
.setForeground(backupColor
);
467 if (getViewControl().isFocusControl() || isFocusControl()) {
468 gcim
.drawFocus(contentsToViewX(0), contentsToViewY(Math
.round(fPrevNodeY
* fZoomValue
)), contentsToViewX(10), Math
.round((fNextNodeY
- fPrevNodeY
) * fZoomValue
));
471 gc
.drawImage(dbuffer
, 0, 0, getClientArea().width
, getClientArea().height
, 0, 0, getClientArea().width
, getClientArea().height
);
472 } catch (Exception e
) {
473 Activator
.getDefault().logError("Error drawing image", e
); //$NON-NLS-1$
476 if (dbuffer
!= null) {
483 * Checks for focus of children.
487 * @return true if child is on focus else false
489 protected boolean checkFocusOnChilds(Control children
) {
490 if (children
instanceof Composite
) {
491 Control
[] child
= ((Composite
) children
).getChildren();
492 for (int i
= 0; i
< child
.length
; i
++) {
493 if (child
[i
].isFocusControl()) {
496 checkFocusOnChilds(child
[i
]);
504 * @see org.eclipse.swt.widgets.Control#isFocusControl()
507 public boolean isFocusControl() {
508 Control
[] child
= getChildren();
509 for (int i
= 0; i
< child
.length
; i
++) {
510 if (child
[i
].isFocusControl()) {
513 checkFocusOnChilds(child
[i
]);
520 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseMoveEvent(org.eclipse.swt.events.MouseEvent)
523 protected void contentsMouseMoveEvent(MouseEvent event
) {
524 if (fTooltip
!= null) {
525 fTooltip
.hideToolTip();
527 super.contentsMouseMoveEvent(event
);
528 if (!isFocusControl() || getViewControl().isFocusControl()) {
529 Control
[] child
= getParent().getChildren();
530 for (int i
= 0; i
< child
.length
; i
++) {
531 if (child
[i
].isFocusControl()) {
541 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseHover(org.eclipse.swt.events.MouseEvent)
544 protected void contentsMouseHover(MouseEvent e
) {
545 if (fTooltip
== null) {
546 fTooltip
= new DrawableToolTip(this);
548 if (fFrame
!= null) {
550 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
551 SDTimeEvent m1
= fNodeList
.get(i
);
552 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
554 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
555 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
556 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
557 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
562 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
563 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
565 if (m1
.getGraphNode() instanceof AsyncMessage
) {
566 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
567 if (as
.getEndTime() == m1
.getTime()) {
568 y1
+= as
.getHeight();
571 if (m2
.getGraphNode() instanceof AsyncMessage
) {
572 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
573 if (as
.getEndTime() == m2
.getTime()) {
574 y2
+= as
.getHeight();
577 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
578 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
579 if (m1
.getEvent() == eo
.getEndOccurrence()) {
580 y1
+= eo
.getHeight();
583 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
585 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
586 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
587 y2
+= eo2
.getHeight();
591 int m1Y
= Math
.round(y1
* fZoomValue
);
592 int m2Y
= Math
.round(y2
* fZoomValue
);
593 if ((m1Y
< e
.y
) && (m2Y
>= e
.y
)) {
594 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
595 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
604 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseExit(org.eclipse.swt.events.MouseEvent)
607 protected void contentsMouseExit(MouseEvent e
) {
608 if (fTooltip
!= null) {
609 fTooltip
.hideToolTip();
615 * @see org.eclipse.linuxtools.tmf.ui.views.uml2sd.ScrollView#contentsMouseUpEvent(org.eclipse.swt.events.MouseEvent)
618 protected void contentsMouseUpEvent(MouseEvent event
) {
619 selectTimeDelta(event
.y
, 0);
621 super.contentsMouseUpEvent(event
);
625 * Force the time compression bar to highlight the event occurrences between
626 * the two given messages. The event occurrences are highlighted on the
627 * first message's end lifeline
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
= 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
= fNodeList
.get(i
);
826 SDTimeEvent m2
= 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
= 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
= fNodeList
.get(i
);
907 SDTimeEvent m2
= 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
= fListenerList
.get(j
);
1008 list
.deltaSelected(fLifeline
, fLifelineStart
, fLifelineNumEvents
, fLifelineColor
);
1021 * Creates a fake tool tip.
1023 protected void createFakeTooltip() {
1024 if (fTooltip
== null) {
1025 fTooltip
= new DrawableToolTip(this);
1028 if (fFrame
!= null) {
1030 for (int i
= 0; i
< fNodeList
.size() - 1; i
++) {
1031 SDTimeEvent m1
= fNodeList
.get(i
);
1032 SDTimeEvent m2
= fNodeList
.get(i
+ 1);
1034 if ((SDViewPref
.getInstance().excludeExternalTime()) && ((m1
.getGraphNode() instanceof BaseMessage
) && (m2
.getGraphNode() instanceof BaseMessage
))) {
1035 BaseMessage mes1
= (BaseMessage
) m1
.getGraphNode();
1036 BaseMessage mes2
= (BaseMessage
) m2
.getGraphNode();
1037 if ((mes2
.getStartLifeline() == null) || (mes1
.getEndLifeline() == null)) {
1042 int y1
= ((GraphNode
) m1
.getGraphNode()).getY();
1043 int y2
= ((GraphNode
) m2
.getGraphNode()).getY();
1045 if (m1
.getGraphNode() instanceof AsyncMessage
) {
1046 AsyncMessage as
= (AsyncMessage
) m1
.getGraphNode();
1047 if (as
.getEndTime() == m1
.getTime()) {
1048 y1
+= as
.getHeight();
1051 if (m2
.getGraphNode() instanceof AsyncMessage
) {
1052 AsyncMessage as
= (AsyncMessage
) m2
.getGraphNode();
1053 if (as
.getEndTime() == m2
.getTime()) {
1054 y2
+= as
.getHeight();
1057 if (m1
.getGraphNode() instanceof ExecutionOccurrence
) {
1058 ExecutionOccurrence eo
= (ExecutionOccurrence
) m1
.getGraphNode();
1059 if (m1
.getEvent() == eo
.getEndOccurrence()) {
1060 y1
+= eo
.getHeight();
1063 if (m2
.getGraphNode() instanceof ExecutionOccurrence
) {
1065 ExecutionOccurrence eo2
= (ExecutionOccurrence
) m2
.getGraphNode();
1066 if (m2
.getEvent() == eo2
.getEndOccurrence()) {
1067 y2
+= eo2
.getHeight();
1071 int m1Y
= Math
.round(y1
* fZoomValue
);
1072 int m2Y
= Math
.round(y2
* fZoomValue
);
1073 if ((m1Y
< fPrevNodeY
+ 1) && (m2Y
>= fPrevNodeY
+ 1)) {
1074 ITmfTimestamp delta
= m2
.getTime().getDelta(m1
.getTime());
1075 fTooltip
.showToolTip(delta
, fMinTime
, fMaxTime
);
1076 fTooltip
.hideToolTip();
1083 * Traverse Listener implementation.
1085 protected static class LocalTraverseListener
implements TraverseListener
{
1089 * @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent)
1092 public void keyTraversed(TraverseEvent e
) {
1093 if ((e
.detail
== SWT
.TRAVERSE_TAB_NEXT
) || (e
.detail
== SWT
.TRAVERSE_TAB_PREVIOUS
)) {