1 /*****************************************************************************
2 * Copyright (c) 2007, 2008 Intel Corporation.
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 * Intel Corporation - Initial API and implementation
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation
11 * Alvaro Sanchex-Leon - Udpated for TMF
13 * $Id: ThreadStatesCtrl.java,v 1.15 2008/07/11 13:49:01 aalexeev Exp $
14 *****************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.widgets
;
18 import java
.util
.ArrayList
;
19 import java
.util
.HashMap
;
20 import java
.util
.Iterator
;
21 import java
.util
.List
;
23 import java
.util
.Vector
;
25 import org
.eclipse
.jface
.viewers
.ISelection
;
26 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
27 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
28 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.Messages
;
29 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeAnalysisProvider
;
30 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITimeEvent
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.TimeEvent
;
33 import org
.eclipse
.osgi
.util
.NLS
;
34 import org
.eclipse
.swt
.SWT
;
35 import org
.eclipse
.swt
.events
.ControlEvent
;
36 import org
.eclipse
.swt
.events
.ControlListener
;
37 import org
.eclipse
.swt
.events
.FocusEvent
;
38 import org
.eclipse
.swt
.events
.FocusListener
;
39 import org
.eclipse
.swt
.events
.KeyEvent
;
40 import org
.eclipse
.swt
.events
.KeyListener
;
41 import org
.eclipse
.swt
.events
.MouseEvent
;
42 import org
.eclipse
.swt
.events
.MouseListener
;
43 import org
.eclipse
.swt
.events
.MouseMoveListener
;
44 import org
.eclipse
.swt
.events
.MouseTrackListener
;
45 import org
.eclipse
.swt
.events
.MouseWheelListener
;
46 import org
.eclipse
.swt
.events
.PaintEvent
;
47 import org
.eclipse
.swt
.events
.SelectionEvent
;
48 import org
.eclipse
.swt
.events
.SelectionListener
;
49 import org
.eclipse
.swt
.events
.TraverseEvent
;
50 import org
.eclipse
.swt
.events
.TraverseListener
;
51 import org
.eclipse
.swt
.graphics
.Cursor
;
52 import org
.eclipse
.swt
.graphics
.GC
;
53 import org
.eclipse
.swt
.graphics
.Image
;
54 import org
.eclipse
.swt
.graphics
.Point
;
55 import org
.eclipse
.swt
.graphics
.Rectangle
;
56 import org
.eclipse
.swt
.widgets
.Composite
;
57 import org
.eclipse
.swt
.widgets
.ScrollBar
;
63 public class TmfTimeStatesCtrl
extends TraceCtrl
implements FocusListener
,
64 KeyListener
, MouseMoveListener
, MouseListener
, MouseWheelListener
,
65 ControlListener
, SelectionListener
, MouseTrackListener
,
66 TraverseListener
, ISelectionProvider
{
68 public static final boolean DEFAULT_DRAW_THREAD_JOIN
= true;
69 public static final boolean DEFAULT_DRAW_THREAD_WAIT
= true;
70 public static final boolean DEFAULT_DRAW_THREAD_RELEASE
= true;
72 private final double zoomCoeff
= 1.5;
74 private ITimeDataProvider _timeProvider
;
75 private boolean _isInFocus
= false;
76 private boolean _isDragCursor3
= false;
77 private boolean _isWaitCursor
= true;
78 private boolean _mouseHover
= false;
79 private int _itemHeightDefault
= 18;
80 private int _itemHeight
= _itemHeightDefault
;
81 private int _topItem
= 0;
82 private int _dragState
= 0;
83 private int _hitIdx
= 0;
84 private int _dragX0
= 0;
85 private int _dragX
= 0;
86 private int _idealNameWidth
= 0;
88 private double _timeStep
= 0.001;
89 // private double _timeStep = 10000000;
90 private long _time0bak
;
91 private long _time1bak
;
92 private TmfTimeAnalysisProvider utilImpl
= null;
93 private ItemData _data
= null;
94 private List
<SelectionListener
> _selectionListeners
;
95 private List
<ISelectionChangedListener
> _selectionChangedListeners
= new ArrayList
<ISelectionChangedListener
>();
96 private Rectangle _rect0
= new Rectangle(0, 0, 0, 0);
97 private Rectangle _rect1
= new Rectangle(0, 0, 0, 0);
98 private Cursor _dragCursor3
;
99 private Cursor _WaitCursor
;
100 private boolean drawTracesInteraction
= false;
101 private boolean drawTraceJoins
= DEFAULT_DRAW_THREAD_JOIN
;
102 private boolean drawTraceWaits
= DEFAULT_DRAW_THREAD_WAIT
;
103 private boolean drawTraceReleases
= DEFAULT_DRAW_THREAD_RELEASE
;
105 // Vertical formatting formatting for the state control view
106 private boolean _visibleVerticalScroll
= true;
107 private int _borderWidth
= 0;
108 private int _headerHeight
= 0;
110 public TmfTimeStatesCtrl(Composite parent
, TraceColorScheme colors
,
111 TmfTimeAnalysisProvider rutilImp
) {
113 super(parent
, colors
, SWT
.NO_BACKGROUND
| SWT
.V_SCROLL
| SWT
.H_SCROLL
114 | SWT
.DOUBLE_BUFFERED
);
116 this.utilImpl
= rutilImp
;
117 _data
= new ItemData(utilImpl
);
119 addFocusListener(this);
120 addMouseListener(this);
121 addMouseMoveListener(this);
122 addMouseTrackListener(this);
123 addMouseWheelListener(this);
124 addTraverseListener(this);
125 addKeyListener(this);
126 addControlListener(this);
127 ScrollBar scrollVer
= getVerticalBar();
128 ScrollBar scrollHor
= getHorizontalBar();
129 if (scrollVer
!= null) {
130 scrollVer
.addSelectionListener(this);
131 scrollVer
.setVisible(_visibleVerticalScroll
);
134 if (scrollHor
!= null) {
135 scrollHor
.addSelectionListener(this);
138 _dragCursor3
= new Cursor(super.getDisplay(), SWT
.CURSOR_SIZEWE
);
139 _WaitCursor
= new Cursor(super.getDisplay(), SWT
.CURSOR_WAIT
);
143 public void dispose() {
145 _dragCursor3
.dispose();
146 _WaitCursor
.dispose();
149 public void setTimeProvider(ITimeDataProvider timeProvider
) {
150 _timeProvider
= timeProvider
;
155 public void addSelectionListener(SelectionListener listener
) {
156 if (listener
== null)
157 SWT
.error(SWT
.ERROR_NULL_ARGUMENT
);
158 if (null == _selectionListeners
)
159 _selectionListeners
= new ArrayList
<SelectionListener
>();
160 _selectionListeners
.add(listener
);
163 public void removeSelectionListener(SelectionListener listener
) {
164 if (null != _selectionListeners
)
165 _selectionListeners
.remove(listener
);
168 public void fireSelectionChanged() {
169 if (null != _selectionListeners
) {
170 Iterator
<SelectionListener
> it
= _selectionListeners
.iterator();
171 while (it
.hasNext()) {
172 SelectionListener listener
= it
.next();
173 listener
.widgetSelected(null);
178 public void fireDefaultSelection() {
179 if (null != _selectionListeners
) {
180 Iterator
<SelectionListener
> it
= _selectionListeners
.iterator();
181 while (it
.hasNext()) {
182 SelectionListener listener
= it
.next();
183 listener
.widgetDefaultSelected(null);
188 public Object
[] getTraces() {
189 return _data
.getTraces();
192 public boolean[] getTraceFilter() {
193 return _data
.getTraceFilter();
196 public void refreshData() {
202 public void refreshData(Object traces
[]) {
203 _data
.refreshData(traces
);
208 public void refreshPartial(ITmfTimeAnalysisEntry parent
, TimeEvent item
) {
209 _data
.refreshPartial(parent
, item
);
214 public void adjustScrolls() {
215 if (null == _timeProvider
) {
216 getVerticalBar().setValues(0, 1, 1, 1, 1, 1);
217 getHorizontalBar().setValues(0, 1, 1, 1, 1, 1);
220 int page
= countPerPage();
221 if (_topItem
+ page
> _data
._items
.length
)
222 _topItem
= _data
._items
.length
- page
;
225 getVerticalBar().setValues(_topItem
, 0, _data
._items
.length
, page
, 1,
227 long time0
= _timeProvider
.getTime0();
228 long time1
= _timeProvider
.getTime1();
229 long timeMin
= _timeProvider
.getMinTime();
230 long timeMax
= _timeProvider
.getMaxTime();
232 // int timePage = (int) ((time1 - time0) / _timeStep);
233 // int timePos = (int) (time0 / _timeStep);
234 // int minimum = (int) (timeMin / _timeStep);
235 // int maximum = (int) (timeMax / _timeStep);
237 long delta
= timeMax
- timeMin
;
241 // Trace.debug("time0 - time1 = " + (time0 - timeMin));
243 timePage
= (int) (((double) (time1
- time0
) / _timeStep
) / delta
);
244 timePos
= (int) (((double) (time0
- timeMin
) / _timeStep
) / delta
);
249 // Trace.debug("time0:" + time0 + " time1:" + time1 + " timeStep:"
250 // + _timeStep + " delta:" + delta);
251 // Trace.debug("selection:" + timePos + " min:" + minimum + " maximum:"
252 // + maximum + " Page:" + timePage);
253 getHorizontalBar().setValues(timePos
, minimum
, maximum
, timePage
, 1,
257 boolean ensureVisibleItem(int idx
, boolean redraw
) {
258 boolean changed
= false;
260 for (idx
= 0; idx
< _data
._items
.length
; idx
++) {
261 if (((Item
) _data
._items
[idx
])._selected
)
265 if (idx
>= _data
._items
.length
)
267 if (idx
< _topItem
) {
269 getVerticalBar().setSelection(_topItem
);
274 int page
= countPerPage();
275 if (idx
>= _topItem
+ page
) {
276 _topItem
= idx
- page
+ 1;
277 getVerticalBar().setSelection(_topItem
);
286 public ISelection
getSelection() {
287 PlainSelection sel
= new PlainSelection();
288 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
289 if (null != trace
&& null != _timeProvider
) {
290 long selectedTime
= _timeProvider
.getSelectedTime();
291 ITimeEvent event
= Utils
.findEvent(trace
, selectedTime
, 0);
300 public ISelection
getSelectionTrace() {
301 PlainSelection sel
= new PlainSelection();
302 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
309 public void selectTrace(int n
) {
310 if (n
!= 1 && n
!= -1)
312 boolean changed
= false;
313 int lastSelection
= -1;
314 for (int i
= 0; i
< _data
._items
.length
; i
++) {
315 Item item
= (Item
) _data
._items
[i
];
316 if (item
._selected
) {
318 if (1 == n
&& i
< _data
._items
.length
- 1) {
319 item
._selected
= false;
320 if (item
._hasChildren
)
321 _data
.expandItem(i
, true);
322 item
= (Item
) _data
._items
[i
+ 1];
323 if (item
._hasChildren
) {
324 _data
.expandItem(i
+ 1, true);
325 item
= (Item
) _data
._items
[i
+ 2];
327 item
._selected
= true;
329 } else if (-1 == n
&& i
> 0) {
331 Item prevItem
= (Item
) _data
._items
[i
];
332 if (prevItem
._hasChildren
) {
333 if (prevItem
._expanded
) {
336 prevItem
= (Item
) _data
._items
[i
];
339 if (!prevItem
._expanded
) {
340 int added
= _data
.expandItem(i
, true);
341 prevItem
= (Item
) _data
._items
[i
+ added
];
342 item
._selected
= false;
343 prevItem
._selected
= true;
347 item
._selected
= false;
348 prevItem
._selected
= true;
355 if (lastSelection
< 0 && _data
._items
.length
> 0) {
356 Item item
= (Item
) _data
._items
[0];
357 if (item
._hasChildren
) {
358 _data
.expandItem(0, true);
359 item
= (Item
) _data
._items
[1];
360 item
._selected
= true;
363 item
._selected
= true;
368 ensureVisibleItem(-1, false);
370 fireSelectionChanged();
374 public void selectEvent(int n
) {
375 if (null == _timeProvider
)
377 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
378 if (trace
== _timeProvider
)
380 long selectedTime
= _timeProvider
.getSelectedTime();
381 long endTime
= _timeProvider
.getEndTime();
382 ITimeEvent nextEvent
;
383 if (-1 == n
&& selectedTime
>= endTime
)
384 nextEvent
= Utils
.findEvent(trace
, selectedTime
, 0);
386 nextEvent
= Utils
.findEvent(trace
, selectedTime
, n
);
387 if (null == nextEvent
&& -1 == n
)
388 nextEvent
= Utils
.getFirstEvent(trace
);
389 if (null != nextEvent
) {
390 _timeProvider
.setSelectedTimeInt(nextEvent
.getTime(), true);
391 fireSelectionChanged();
393 _timeProvider
.setSelectedTimeInt(endTime
, true);
394 fireSelectionChanged();
398 public void selectNextEvent() {
402 public void selectPrevEvent() {
406 public void selectNextTrace() {
410 public void selectPrevTrace() {
414 public void zoomIn() {
415 long _time0
= _timeProvider
.getTime0();
416 long _time1
= _timeProvider
.getTime1();
417 long _range
= _time1
- _time0
;
418 long selTime
= _timeProvider
.getSelectedTime();
419 if (selTime
<= _time0
|| selTime
>= _time1
) {
420 selTime
= (_time0
+ _time1
) / 2;
422 long time0
= selTime
- (long) ((selTime
- _time0
) / zoomCoeff
);
423 long time1
= selTime
+ (long) ((_time1
- selTime
) / zoomCoeff
);
425 long inaccuracy
= (_timeProvider
.getMaxTime() - _timeProvider
429 // Trace.debug("selTime:" + selTime + " time0:" + time0 + " time1:"
430 // + time1 + " inaccuracy:" + inaccuracy);
432 if (inaccuracy
> 0 && inaccuracy
< 100) {
433 _timeProvider
.setStartFinishTime(_timeProvider
.getMinTime(),
434 _timeProvider
.getMaxTime());
438 long m
= _timeProvider
.getMinTimeInterval();
439 if ((time1
- time0
) < m
) {
440 time0
= selTime
- (long) ((selTime
- _time0
) * m
/ _range
);
444 _timeProvider
.setStartFinishTime(time0
, time1
);
447 public void zoomOut() {
448 long _time0
= _timeProvider
.getTime0();
449 long _time1
= _timeProvider
.getTime1();
450 long selTime
= _timeProvider
.getSelectedTime();
451 if (selTime
<= _time0
|| selTime
>= _time1
) {
452 selTime
= (_time0
+ _time1
) / 2;
454 long time0
= (long) (selTime
- (selTime
- _time0
) * zoomCoeff
);
455 long time1
= (long) (selTime
+ (_time1
- selTime
) * zoomCoeff
);
457 long inaccuracy
= (_timeProvider
.getMaxTime() - _timeProvider
460 if (inaccuracy
> 0 && inaccuracy
< 100) {
461 _timeProvider
.setStartFinishTime(_timeProvider
.getMinTime(),
462 _timeProvider
.getMaxTime());
466 _timeProvider
.setStartFinishTime(time0
, time1
);
469 public void groupTraces(boolean on
) {
470 _data
.groupTraces(on
);
475 public void toggleTraceInteractionDrawing() {
476 drawTracesInteraction
= !drawTracesInteraction
;
480 public void setTraceJoinDrawing(boolean on
) {
482 drawTracesInteraction
= true;
486 public void setTraceWaitDrawing(boolean on
) {
488 drawTracesInteraction
= true;
492 public void setTraceReleaseDrawing(boolean on
) {
493 drawTraceReleases
= on
;
494 drawTracesInteraction
= true;
498 public boolean getTracesInteractionDrawing() {
499 return drawTracesInteraction
;
502 public boolean getTraceJoinDrawing() {
503 return drawTraceJoins
;
506 public boolean getTraceWaitDrawing() {
507 return drawTraceWaits
;
510 public boolean getTraceReleaseDrawing() {
511 return drawTraceReleases
;
514 public ITmfTimeAnalysisEntry
getSelectedTrace() {
515 ITmfTimeAnalysisEntry trace
= null;
516 int idx
= getSelectedIndex();
517 if (idx
>= 0 && _data
._items
[idx
] instanceof TraceItem
)
518 trace
= ((TraceItem
) _data
._items
[idx
])._trace
;
522 public int getSelectedIndex() {
524 for (int i
= 0; i
< _data
._items
.length
; i
++) {
525 Item item
= (Item
) _data
._items
[i
];
526 if (item
._selected
) {
534 boolean toggle(int idx
) {
535 boolean toggled
= false;
536 if (idx
>= 0 && idx
< _data
._items
.length
) {
537 Item item
= (Item
) _data
._items
[idx
];
538 if (item
._hasChildren
) {
539 item
._expanded
= !item
._expanded
;
549 int hitTest(int x
, int y
) {
553 int idx
= y
/ _itemHeight
;
555 if (idx
< _data
._items
.length
)
560 int hitSplitTest(int x
, int y
) {
561 if (x
< 0 || y
< 0 || null == _timeProvider
)
565 int nameWidth
= _timeProvider
.getNameSpace();
566 if (x
> nameWidth
- w
&& x
< nameWidth
+ w
)
571 public Item
getItem(Point pt
) {
572 int idx
= hitTest(pt
.x
, pt
.y
);
573 return idx
>= 0 ?
(Item
) _data
._items
[idx
] : null;
576 long hitTimeTest(int x
, int y
) {
577 if (null == _timeProvider
)
580 Point size
= getCtrlSize();
581 long time0
= _timeProvider
.getTime0();
582 long time1
= _timeProvider
.getTime1();
583 int nameWidth
= _timeProvider
.getNameSpace();
585 if (x
>= 0 && size
.x
>= nameWidth
) {
586 hitTime
= time0
+ ((time1
- time0
) * x
) / (size
.x
- nameWidth
);
591 void selectItem(int idx
, boolean addSelection
) {
593 if (idx
>= 0 && idx
< _data
._items
.length
) {
594 Item item
= (Item
) _data
._items
[idx
];
595 item
._selected
= true;
598 for (int i
= 0; i
< _data
._items
.length
; i
++) {
599 Item item
= (Item
) _data
._items
[i
];
600 item
._selected
= i
== idx
;
603 boolean changed
= ensureVisibleItem(idx
, true);
608 public void selectItem(ITmfTimeAnalysisEntry trace
, boolean addSelection
) {
609 Integer idx
= _data
.findTraceItemIndex(trace
);
610 selectItem(idx
, addSelection
);
613 public int countPerPage() {
614 int height
= getCtrlSize().y
;
617 count
= height
/ _itemHeight
;
621 public int getTopIndex() {
623 if (_data
._items
.length
> 0)
628 public int getBottomIndex() {
629 int idx
= _data
._items
.length
- 1;
633 Point
getCtrlSize() {
634 Point size
= getSize();
635 size
.x
-= getVerticalBar().getSize().x
;
636 size
.y
-= getHorizontalBar().getSize().y
;
640 void getNameRect(Rectangle rect
, Rectangle bound
, int idx
, int nameWidth
) {
643 rect
.y
= bound
.y
+ idx
* _itemHeight
;
644 rect
.width
= nameWidth
;
645 rect
.height
= _itemHeight
;
648 void getStatesRect(Rectangle rect
, Rectangle bound
, int idx
, int nameWidth
) {
650 rect
.x
= bound
.x
+ nameWidth
;
651 rect
.y
= bound
.y
+ idx
* _itemHeight
;
652 rect
.width
= bound
.width
- rect
.x
;
653 rect
.height
= _itemHeight
;
656 // private int getTraceNumber(int tid) {
659 // Object[] items = _data._items;
660 // for (int i = _topItem; i < items.length; i++) {
661 // Item item = (Item) items[i];
662 // if ((item instanceof TraceItem)) {
663 // TsfTmTrace trace = ((TraceItem) item)._trace;
664 // if (trace != null && trace.getId() == tid) {
674 // private void drawArrow(GC gc, int x0, int y0, int x1, int y1, Color c) {
675 // gc.setForeground(c);
676 // gc.drawLine(x0, y0, x1, y1);
679 // gc.drawLine(x1 - 3, y1 - 3, x1, y1);
680 // gc.drawLine(x1 + 3, y1 - 3, x1, y1);
682 // gc.drawLine(x1 - 3, y1 + 3, x1, y1);
683 // gc.drawLine(x1 + 3, y1 + 3, x1, y1);
687 // TODO: CC: used in the removed functionality to draw thread interactions.
688 // private void drawTraceThreadEvent(Rectangle bound, TsfTmEvent e,
689 // TsfTmTrace trace, int nItem, int color, GC gc) {
690 // if (trace == null)
693 // int tid = trace.getId();
694 // if (tid < 0 || getTraceNumber(tid) == -1)
697 // int nameWidth = _timeProvider.getNameSpace();
699 // double time0 = _timeProvider.getTime0();
700 // double time1 = _timeProvider.getTime1();
701 // if (time0 == time1)
704 // int xr = bound.x + nameWidth;
705 // double K = (double) (bound.width - xr) / (time1 - time0);
707 // int x0 = xr + (int) ((e.getTime() - time0) * K);
711 // int x1 = xr + (int) ((trace.getStartTime() - time0) * K);
715 // int y0 = bound.y + (nItem - _topItem) * _itemHeight + 3
716 // + (_itemHeight - 6) / 2;
717 // int y1 = bound.y + (getTraceNumber(tid) - _topItem) * _itemHeight + 3
718 // + (_itemHeight - 6) / 2;
720 // drawArrow(gc, x0, y0, x1, y1, _colors.getColor(color));
723 public void drawTraceEvent(Rectangle bound
, ITimeEvent e
, int nItem
,
725 int nameWidth
= _timeProvider
.getNameSpace();
727 long time0
= _timeProvider
.getTime0();
728 long time1
= _timeProvider
.getTime1();
732 int xr
= bound
.x
+ nameWidth
;
733 double K
= (double) (bound
.width
- xr
) / (time1
- time0
);
735 int x0
= xr
+ (int) ((e
.getTime() - time0
) * K
);
739 int y0
= bound
.y
+ (nItem
- _topItem
) * _itemHeight
+ 3;
741 gc
.setBackground(_colors
.getColor(color
));
742 int c
[] = { x0
- 3, y0
- 3, x0
, y0
, x0
+ 3, y0
- 3 };
747 // private void drawExecEvent(Rectangle bound, TsfTmTraceExecEventImpl e,
748 // int nitem, int color, GC gc) {
749 // List runnings = e.getRunningEvents();
750 // if (runnings == null)
753 // int nameWidth = _timeProvider.getNameSpace();
755 // double time0 = _timeProvider.getTime0();
756 // double time1 = _timeProvider.getTime1();
757 // if (time0 == time1)
760 // int xr = bound.x + nameWidth;
761 // double K = (double) (bound.width - xr) / (time1 - time0);
763 // int x0 = xr + (int) ((e.getTime() - time0) * K);
767 // Iterator it = runnings.iterator();
768 // while (it.hasNext()) {
769 // TsfTmTraceRunningEventImpl re = (TsfTmTraceRunningEventImpl) it
771 // int tid = re.getThread().getId();
772 // if (tid < 0 || getThreadNumber(tid) == -1)
775 // int x1 = xr + (int) ((re.getTime() - time0) * K);
779 // int y0 = bound.y + (nitem - _topItem) * _itemHeight + 3
780 // + (_itemHeight - 6) / 2;
781 // int y1 = bound.y + (getThreadNumber(tid) - _topItem) * _itemHeight
782 // + 3 + (_itemHeight - 6) / 2;
784 // drawArrow(gc, x0, y0, x1, y1, _colors.getColor(color));
788 public void drawTraceInteractions(Rectangle bound
, GC gc
) {
789 // int nameWidth = _timeProvider.getNameSpace();
790 // Object[] items = _data._items;
792 // double time0 = _timeProvider.getTime0();
793 // double time1 = _timeProvider.getTime1();
795 // if (time0 == time1)
798 // int xr = bound.x + nameWidth;
799 // double K = (double) (bound.width - xr) / (time1 - time0);
801 // for (int i = 0; i < items.length; i++) {
802 // Item item = (Item) items[i];
803 // if (!(item instanceof TraceItem))
806 // TsfTmTrace trace = ((TraceItem) item)._trace;
807 // if (trace == null)
810 // List<TsfTmEvent> list = trace.getTraceEvents();
811 // Iterator<TsfTmEvent> it = list.iterator();
812 // while (it.hasNext()) {
813 // TsfTmEvent te = (TsfTmEvent) it.next();
814 // TODO: CC: Thread Interactions,
815 // This needs to be accessed externally via a specific
817 // if (te instanceof TsfTmTraceStartThreadEventImpl) {
818 // TsfTmTrace child = ((TsfTmTraceStartThreadEventImpl) te)
819 // .getStartedThread();
820 // drawThreadThreadEvent(bound, te, child, i,
821 // TraceColorScheme.TI_START_THREAD, gc);
822 // } else if (te instanceof TsfTmTraceHandoffLockEventImpl) {
823 // if (drawThreadReleases)
824 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
825 // TraceColorScheme.TI_HANDOFF_LOCK, gc);
826 // } else if (te instanceof TsfTmTraceNotifyAllEventImpl) {
827 // if (drawThreadWaits)
828 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
829 // TraceColorScheme.TI_NOTIFY_ALL, gc);
830 // } else if (te instanceof TsfTmTraceNotifyEventImpl) {
831 // if (drawThreadWaits)
832 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
833 // TraceColorScheme.TI_NOTIFY, gc);
834 // } else if (te instanceof
835 // TsfTmTraceDeadAndNotifyJoinedEventImpl) {
836 // if (drawThreadJoins)
837 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
838 // TraceColorScheme.TI_NOTIFY_JOINED, gc);
839 // } else if (te instanceof TsfTmTraceInterruptThreadEventImpl)
841 // if (drawThreadWaits)
842 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
843 // TraceColorScheme.TI_INTERRUPT, gc);
844 // } else if (te instanceof
845 // TsfTmTraceWaitTimeoutExceedEventImpl) {
846 // drawThreadEvent(bound, te, i,
847 // TraceColorScheme.TI_WAIT_EXCEEDED, gc);
854 void paint(Rectangle bound
, PaintEvent e
) {
855 // If no user preference defined for item height
856 if (_itemHeight
== _itemHeightDefault
) {
857 _itemHeight
= getFontHeight() + 6;
860 if (bound
.width
< 2 || bound
.height
< 2 || null == _timeProvider
)
865 int nameWidth
= _timeProvider
.getNameSpace();
866 long time0
= _timeProvider
.getTime0();
867 long time1
= _timeProvider
.getTime1();
868 long endTime
= _timeProvider
.getEndTime();
869 long selectedTime
= _timeProvider
.getSelectedTime();
871 Object
[] items
= _data
._items
;
872 for (int i
= _topItem
; i
< items
.length
; i
++) {
873 Item item
= (Item
) items
[i
];
874 getNameRect(_rect0
, bound
, i
, nameWidth
);
875 if (_rect0
.y
>= bound
.y
+ bound
.height
)
878 if (item
instanceof GroupItem
) {
879 getStatesRect(_rect1
, bound
, i
, nameWidth
);
880 _rect0
.width
+= _rect1
.width
;
881 drawName(item
, _rect0
, gc
);
883 drawName(item
, _rect0
, gc
);
885 getStatesRect(_rect0
, bound
, i
, nameWidth
);
886 drawItemDataDurations(item
, _rect0
, time0
, time1
, endTime
,
890 if (drawTracesInteraction
)
891 drawTraceInteractions(bound
, e
.gc
);
893 // fill free canvas area
895 _rect0
.y
+= _rect0
.height
;
896 _rect0
.width
= bound
.width
;
897 _rect0
.height
= bound
.y
+ bound
.height
- _rect0
.y
;
898 if (_rect0
.y
< bound
.y
+ bound
.height
) {
899 gc
.setBackground(_colors
.getColor(TraceColorScheme
.BACKGROUND
));
900 gc
.fillRectangle(_rect0
);
902 // draw drag line, no line if name space is 0.
903 if (3 == _dragState
) {
904 gc
.setForeground(_colors
.getColor(TraceColorScheme
.BLACK
));
905 gc
.drawLine(bound
.x
+ nameWidth
, bound
.y
, bound
.x
+ nameWidth
,
906 bound
.y
+ bound
.height
- 1);
907 } else if (0 == _dragState
&& _mouseHover
908 && _timeProvider
.getNameSpace() > 0) {
909 gc
.setForeground(_colors
.getColor(TraceColorScheme
.RED
));
910 gc
.drawLine(bound
.x
+ nameWidth
, bound
.y
, bound
.x
+ nameWidth
,
911 bound
.y
+ bound
.height
- 1);
915 void drawName(Item item
, Rectangle rect
, GC gc
) {
916 // No name to be drawn
917 if (_timeProvider
.getNameSpace() == 0)
919 boolean group
= item
instanceof GroupItem
;
921 int elemHeight
= rect
.height
/ 2;
922 int elemWidth
= elemHeight
;
923 String name
= item
._name
;
925 gc
.setBackground(_colors
926 .getBkColorGroup(item
._selected
, _isInFocus
));
927 gc
.fillRectangle(rect
);
928 if (item
._selected
&& _isInFocus
) {
929 gc
.setForeground(_colors
.getBkColor(item
._selected
, _isInFocus
,
931 gc
.drawRectangle(rect
.x
, rect
.y
, rect
.width
- 2,
934 gc
.setForeground(_colors
.getBkColor(false, false, false));
935 gc
.drawLine(rect
.x
, rect
.y
+ rect
.height
- 1, rect
.width
- 1,
936 rect
.y
+ rect
.height
- 1);
937 gc
.setForeground(_colors
.getFgColorGroup(false, false));
938 gc
.setBackground(_colors
.getBkColor(false, false, false));
939 Utils
.init(_rect1
, rect
);
941 _rect1
.y
+= (rect
.height
- elemHeight
) / 2;
942 _rect1
.width
= elemWidth
;
943 _rect1
.height
= elemHeight
;
944 // Get the icon rectangle in the group items
945 gc
.fillRectangle(_rect1
);
946 gc
.drawRectangle(_rect1
.x
, _rect1
.y
, _rect1
.width
- 1,
948 int p
= _rect1
.y
+ _rect1
.height
/ 2;
949 gc
.drawLine(_rect1
.x
+ 2, p
, _rect1
.x
+ _rect1
.width
- 3, p
);
950 if (!item
._expanded
) {
951 p
= _rect1
.x
+ _rect1
.width
/ 2;
952 gc
.drawLine(p
, _rect1
.y
+ 2, p
, _rect1
.y
+ _rect1
.height
- 3);
954 gc
.setForeground(_colors
955 .getFgColorGroup(item
._selected
, _isInFocus
));
958 gc
.setBackground(_colors
.getBkColor(item
._selected
, _isInFocus
,
960 gc
.setForeground(_colors
.getFgColor(item
._selected
, _isInFocus
));
961 gc
.fillRectangle(rect
);
962 Utils
.init(_rect1
, rect
);
965 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
966 Image img
= utilImpl
.getItemImage(trace
);
968 _rect1
.y
+= (rect
.height
- img
.getImageData().height
) / 2;
969 gc
.drawImage(img
, _rect1
.x
, _rect1
.y
);
971 elemWidth
= SMALL_ICON_SIZE
;
972 // cut long string with "..."
973 Point size
= gc
.stringExtent(name
);
974 if (_idealNameWidth
< size
.x
)
975 _idealNameWidth
= size
.x
;
976 int width
= rect
.width
- MARGIN
- MARGIN
- elemWidth
;
978 while (size
.x
> width
&& name
.length() > 1) {
980 name
= name
.substring(0, name
.length() - 1);
981 size
= gc
.stringExtent(name
+ "...");
987 Utils
.init(_rect1
, rect
);
988 int leftMargin
= MARGIN
+ elemWidth
;
989 _rect1
.x
+= leftMargin
;
990 _rect1
.width
-= leftMargin
;
993 if (_rect1
.width
> 0) {
995 textWidth
= Utils
.drawText(gc
, name
, _rect1
, true) + 8;
999 if (_rect1
.width
> 0 && !group
) {
1000 Utils
.init(_rect1
, rect
);
1001 _rect1
.x
+= leftMargin
+ textWidth
;
1002 _rect1
.width
-= textWidth
;
1003 gc
.setForeground(_colors
.getColor(TraceColorScheme
.MID_LINE
));
1004 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1005 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1007 // gc.drawLine(_rect1.x + _rect1.width - 1, _rect1.y, _rect1.x +
1008 // _rect1.width - 1, _rect1.y + _rect1.height);
1011 void drawItemData(Item item
, Rectangle rect
, long time0
, long time1
,
1012 long endTime
, long selectedTime
, GC gc
) {
1015 if (time1
<= time0
) {
1016 gc
.setBackground(_colors
.getBkColor(false, false, false));
1017 gc
.fillRectangle(rect
);
1021 Utils
.init(_rect1
, rect
);
1022 boolean selected
= item
._selected
;
1023 double K
= (double) rect
.width
/ (time1
- time0
);
1024 boolean group
= item
instanceof GroupItem
;
1027 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1028 // gc.fillRectangle(rect);
1029 } else if (item
instanceof TraceItem
) {
1030 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1033 List
<TimeEvent
> list
= trace
.getTraceEvents();
1034 // Iterator it = list.iterator();
1035 int count
= list
.size();
1036 ITimeEvent lastEvent
= null;
1038 ITimeEvent currEvent
= list
.get(0);
1039 ITimeEvent nextEvent
= null;
1040 long currEventTime
= currEvent
.getTime();
1041 long nextEventTime
= currEventTime
;
1042 x0
= rect
.x
+ (int) ((currEventTime
- time0
) * K
);
1043 int xEnd
= rect
.x
+ (int) ((time1
- time0
) * K
);
1050 fillSpace(rect
, gc
, selected
, _rect1
.x
, x0
, xEnd
);
1052 // draw event states
1053 while (x0
<= xEnd
&& null != currEvent
) {
1054 boolean stopped
= false;// currEvent instanceof
1055 // TsfTmTraceDeadEvent;
1057 nextEvent
= list
.get(idx
);
1058 nextEventTime
= nextEvent
.getTime();
1060 } else if (stopped
) {
1062 nextEventTime
= time1
;
1065 nextEventTime
= endTime
;
1067 x1
= rect
.x
+ (int) ((nextEventTime
- time0
) * K
);
1069 _rect1
.x
= x0
>= rect
.x ? x0
: rect
.x
;
1070 _rect1
.width
= (x1
<= xEnd ? x1
: xEnd
) - _rect1
.x
;
1071 boolean timeSelected
= currEventTime
<= selectedTime
1072 && selectedTime
< nextEventTime
;
1073 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1074 // + _rect1.y + "," + _rect1.height + ", "
1075 // + _rect1.width + "-->"
1076 // + ((int) _rect1.x + (int) _rect1.width));
1077 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1078 selected
, false, timeSelected
);
1080 lastEvent
= currEvent
;
1081 currEvent
= nextEvent
;
1082 currEventTime
= nextEventTime
;
1087 // fill space after last event
1088 int xEnd
= rect
.x
+ rect
.width
;
1090 _rect1
.x
= x0
>= rect
.x ? x0
: rect
.x
;
1091 _rect1
.width
= xEnd
- _rect1
.x
;
1092 gc
.setBackground(_colors
1093 .getBkColor(selected
, _isInFocus
, false));
1094 gc
.fillRectangle(_rect1
);
1096 gc
.setForeground(_colors
.getColor(utilImpl
1097 .getEventColorVal(lastEvent
)));
1098 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1099 int lw
= gc
.getLineWidth();
1101 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1102 gc
.setLineWidth(lw
);
1106 Utils
.init(_rect1
, rect
);
1107 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1109 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1111 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1113 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1114 y
= _rect1
.y
+ _rect1
.height
- 1;
1115 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1117 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1119 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1122 // draw selected time
1123 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1124 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1125 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1127 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1130 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1135 * Represent the event in series of bursts rather than sequence of states
1139 * - The container rectangle to be colored to different states
1141 * - Base time of all events
1143 * - End time of all events
1145 * @param selectedTime
1148 void drawItemDataBurst(Item item
, Rectangle rect
, long time0
, long time1
,
1149 long endTime
, long selectedTime
, GC gc
) {
1152 if (time1
<= time0
) {
1153 gc
.setBackground(_colors
.getBkColor(false, false, false));
1154 gc
.fillRectangle(rect
);
1158 // Initialize _rect1 to same values as enclosing rectangle rect
1159 Utils
.init(_rect1
, rect
);
1160 boolean selected
= item
._selected
;
1161 // K pixels per second
1162 double K
= (double) rect
.width
/ (time1
- time0
);
1163 // Trace.debug("Value of K: " + K + " width:" + rect.width + " time0: "
1164 // + time0 + " time1:" + time1 + " endTime: " + endTime);
1166 boolean group
= item
instanceof GroupItem
;
1169 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1170 // gc.fillRectangle(rect);
1171 // if (Trace.isDEBUG()) {
1172 // Trace.debug("Group");
1174 } else if (item
instanceof TraceItem
) {
1175 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1178 List
<TimeEvent
> list
= trace
.getTraceEvents();
1179 // Iterator it = list.iterator();
1180 int count
= list
.size();
1181 ITimeEvent lastEvent
= null;
1182 // Trace.debug("count is: " + count);
1184 ITimeEvent currEvent
= list
.get(0);
1185 ITimeEvent nextEvent
= null;
1186 long currEventTime
= currEvent
.getTime();
1187 long nextEventTime
= currEventTime
;
1188 // x0 - Points to the beginning of the event being drawn
1189 double step
= (double) ((currEventTime
- time0
) * K
);
1191 // xEnd - Points to the end of the events rectangle
1192 double xEnd
= rect
.x
+ (double) ((time1
- time0
) * K
);
1197 // Drawing rectangle is smaller than reserved space
1201 // Clean up to empty line to draw on top
1202 fillSpace(rect
, gc
, selected
, _rect1
.x
, xEnd
, xEnd
);
1203 // draw event states
1204 while (x0
<= xEnd
&& null != currEvent
) {
1205 boolean stopped
= false;// currEvent instanceof
1206 // TsfTmTraceDeadEvent;
1208 nextEvent
= list
.get(idx
);
1209 nextEventTime
= nextEvent
.getTime();
1211 } else if (stopped
) {
1213 nextEventTime
= time1
;
1216 nextEventTime
= endTime
;
1218 // .debug("nexEventTime is endTime: "
1219 // + nextEventTime);
1222 // Draw it as a burst, one unit of width.
1224 if (x1
>= rect
.x
&& x0
<= xEnd
) {
1225 // Fill with space until x0
1226 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1227 _rect1
.width
= (int) ((x1
<= xEnd ? x1
: xEnd
) - _rect1
.x
);
1228 boolean timeSelected
= currEventTime
<= selectedTime
1229 && selectedTime
< nextEventTime
;
1230 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1231 selected
, false, timeSelected
);
1232 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1233 // + _rect1.y + "," + _rect1.height + ", "
1234 // + _rect1.width + "-->"
1235 // + ((int) _rect1.x + (int) _rect1.width));
1236 // Advance rectangle to next start position and Fill
1237 // with space until next event
1238 _rect1
.x
+= _rect1
.width
;
1240 xNext
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1242 // Fill space till next event
1243 fillSpace(rect
, gc
, selected
, x0
, xNext
, xEnd
);
1245 lastEvent
= currEvent
;
1246 currEvent
= nextEvent
;
1247 currEventTime
= nextEventTime
;
1248 // Move x0 to the beginning of next event
1249 x0
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1250 // Trace.debug("rect.x: " + rect.x + " + " +
1251 // "(nextEvenTime: "
1252 // + nextEventTime + "- time0: " + time0 + ") * K: "
1253 // + K + " = " + x0);
1257 // fill space after last event
1258 int xEnd
= rect
.x
+ rect
.width
;
1260 // Trace.debug("Space after last event, x0: " + x0 + ", xEnd: "
1262 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1263 _rect1
.width
= xEnd
- _rect1
.x
;
1264 gc
.setBackground(_colors
1265 .getBkColor(selected
, _isInFocus
, false));
1266 gc
.fillRectangle(_rect1
);
1268 gc
.setForeground(_colors
.getColor(utilImpl
1269 .getEventColorVal(lastEvent
)));
1270 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1271 int lw
= gc
.getLineWidth();
1273 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1274 gc
.setLineWidth(lw
);
1278 Utils
.init(_rect1
, rect
);
1279 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1281 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1283 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1285 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1286 y
= _rect1
.y
+ _rect1
.height
- 1;
1287 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1289 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1291 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1294 // draw selected time
1295 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1296 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1297 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1299 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1302 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1307 * Represent the series of events with specified durations
1311 * - The container rectangle to be colored to different states
1313 * - Base time of all events - start of visible window
1315 * - End time of visible events - end time of visible window
1317 * - End time of all events - may not be visible in selected
1319 * @param selectedTime
1322 void drawItemDataDurations(Item item
, Rectangle rect
, long time0
,
1323 long time1
, long endTime
, long selectedTime
, GC gc
) {
1326 if (time1
<= time0
) {
1327 gc
.setBackground(_colors
.getBkColor(false, false, false));
1328 gc
.fillRectangle(rect
);
1332 // Initialize _rect1 to same values as enclosing rectangle rect
1333 Utils
.init(_rect1
, rect
);
1334 boolean selected
= item
._selected
;
1335 // K pixels per second
1336 double K
= (double) rect
.width
/ (time1
- time0
);
1337 // Trace.debug("Value of K: " + K + " width:" + rect.width + " time0: "
1338 // + time0 + " time1:" + time1 + " endTime: " + endTime);
1340 boolean group
= item
instanceof GroupItem
;
1343 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1344 // gc.fillRectangle(rect);
1345 // if (Trace.isDEBUG()) {
1346 // Trace.debug("\n\t\t\tGroup: " + ((GroupItem) item)._name);
1348 } else if (item
instanceof TraceItem
) {
1349 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1352 List
<TimeEvent
> list
= trace
.getTraceEvents();
1353 // Iterator it = list.iterator();
1354 int count
= list
.size();
1355 ITimeEvent lastEvent
= null;
1356 // if (Trace.isDEBUG()) {
1357 // Trace.debug("\n\t\t\tTrace: " + trace.getName()
1358 // + utilImpl.getTraceClassName(trace));
1360 // Trace.debug("count is: " + count);
1362 ITimeEvent currEvent
= list
.get(0);
1363 ITimeEvent nextEvent
= null;
1364 long currEventTime
= currEvent
.getTime();
1365 long currEventDuration
= currEvent
.getDuration();
1367 long nextEventTime
= currEventTime
;
1368 // x0 - Points to the beginning of the event being drawn
1369 double step
= (double) ((currEventTime
- time0
) * K
);
1371 // xEnd - Points to the end of the events rectangle
1372 double xEnd
= rect
.x
+ (double) ((time1
- time0
) * K
);
1377 // Drawing rectangle is smaller than reserved space
1381 // Clean up to empty line to draw on top
1382 fillSpace(rect
, gc
, selected
, _rect1
.x
, xEnd
, xEnd
);
1383 // draw event states
1384 while (x0
<= xEnd
&& null != currEvent
) {
1385 boolean stopped
= false;// currEvent instanceof
1386 // refresh current event duration as the loop moves
1387 currEventDuration
= currEvent
.getDuration();
1388 // TsfTmTraceDeadEvent;
1390 nextEvent
= list
.get(idx
);
1391 nextEventTime
= nextEvent
.getTime();
1393 } else if (stopped
) {
1395 nextEventTime
= time1
;
1398 nextEventTime
= endTime
;
1400 // .debug("nexEventTime is endTime: "
1401 // + nextEventTime);
1404 // Calculate position to next event
1405 xNext
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1407 // Calculate end position of current event
1408 if (currEventDuration
< 0) {
1409 x1
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1411 x1
= currEventDuration
== 0 ?
(x0
+ 2)
1412 : (x0
+ (double) ((currEventDuration
) * K
));
1415 // If event end position x1 further away than start position
1417 // next event, cut width till next event
1418 // Trace.debug("Next Event Pos: " + xNext
1419 // + " End Of Current at: " + x1 + " Event Duration: "
1420 // + currEventDuration);
1421 x1
= x1
> xNext ? xNext
: x1
;
1422 // if event end boundary is within time range
1423 if (x1
>= rect
.x
&& x0
<= xEnd
) {
1424 // Fill with space until x0
1425 x0
= (double) (x0
>= rect
.x ? x0
: rect
.x
);
1426 _rect1
.width
= (int) ((x1
<= xEnd ? x1
: xEnd
) - x0
);
1427 _rect1
.x
= (int) x0
;
1428 boolean timeSelected
= currEventTime
<= selectedTime
1429 && selectedTime
< nextEventTime
;
1430 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1431 selected
, false, timeSelected
);
1432 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1433 // + _rect1.y + "," + _rect1.height + ", "
1434 // + _rect1.width + "-->"
1435 // + ((int) _rect1.x + (int) _rect1.width));
1436 // Advance rectangle to next start position and Fill
1437 // with space until next event
1438 _rect1
.x
+= _rect1
.width
;
1442 // Fill space till next event
1443 fillSpace(rect
, gc
, selected
, x0
, xNext
, xEnd
);
1445 lastEvent
= currEvent
;
1446 currEvent
= nextEvent
;
1447 currEventTime
= nextEventTime
;
1448 // Move x0 to the beginning of next event
1449 x0
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1450 // Trace.debug("rect.x: " + rect.x + " + " +
1451 // "(nextEvenTime: "
1452 // + nextEventTime + "- time0: " + time0 + ") * K: "
1453 // + K + " = " + x0);
1457 // fill space after last event
1458 int xEnd
= rect
.x
+ rect
.width
;
1460 // Trace.debug("Space after last event, x0: " + x0 + ", xEnd: "
1462 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1463 _rect1
.width
= xEnd
- _rect1
.x
;
1464 gc
.setBackground(_colors
1465 .getBkColor(selected
, _isInFocus
, false));
1466 gc
.fillRectangle(_rect1
);
1468 gc
.setForeground(_colors
.getColor(utilImpl
1469 .getEventColorVal(lastEvent
)));
1470 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1471 int lw
= gc
.getLineWidth();
1473 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1474 gc
.setLineWidth(lw
);
1478 Utils
.init(_rect1
, rect
);
1479 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1481 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1483 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1485 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1486 y
= _rect1
.y
+ _rect1
.height
- 1;
1487 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1489 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1491 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1494 // draw selected time
1495 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1496 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1497 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1499 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1502 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1506 private void fillSpace(Rectangle rect
, GC gc
, boolean selected
, double x0
,
1507 double x1
, double xEnd
) {
1508 // fill space before first event
1509 if (x0
>= rect
.x
&& x0
< xEnd
) {
1510 // _rect1.width = (int) ((x1 <= xEnd ? x1 : xEnd) - x0);
1511 // Trace.debug("Drawing Space: " + _rect1.x + "," + _rect1.y + ","
1512 // + _rect1.height + ", " + _rect1.width + "--> "
1513 // + ((int) _rect1.x + (int) _rect1.width));
1515 // if (_rect1.width < 0) {
1516 // Trace.debug("Incorrect width:" + _rect1.width);
1518 gc
.setBackground(_colors
.getBkColor(selected
, _isInFocus
, false));
1519 gc
.fillRectangle(_rect1
);
1521 gc
.setForeground(_colors
.getColor(TraceColorScheme
.MID_LINE
));
1522 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1523 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1525 // Trace.debug("No space added since, x0 is out of range " + x0
1526 // + " rect.x: " + rect.x + " xEnd: " + xEnd);
1530 public void keyTraversed(TraverseEvent e
) {
1531 if ((e
.detail
== SWT
.TRAVERSE_TAB_NEXT
)
1532 || (e
.detail
== SWT
.TRAVERSE_TAB_PREVIOUS
))
1536 public void keyPressed(KeyEvent e
) {
1538 if (SWT
.HOME
== e
.keyCode
) {
1539 idx
= getTopIndex();
1540 } else if (SWT
.END
== e
.keyCode
) {
1541 idx
= getBottomIndex();
1542 } else if (SWT
.ARROW_DOWN
== e
.keyCode
) {
1543 idx
= getSelectedIndex();
1546 else if (idx
< _data
._items
.length
- 1)
1548 } else if (SWT
.ARROW_UP
== e
.keyCode
) {
1549 idx
= getSelectedIndex();
1554 } else if (SWT
.ARROW_LEFT
== e
.keyCode
) {
1556 } else if (SWT
.ARROW_RIGHT
== e
.keyCode
) {
1558 } else if (SWT
.PAGE_DOWN
== e
.keyCode
) {
1559 int page
= countPerPage();
1560 idx
= getSelectedIndex();
1564 if (idx
>= _data
._items
.length
)
1565 idx
= _data
._items
.length
- 1;
1566 } else if (SWT
.PAGE_UP
== e
.keyCode
) {
1567 int page
= countPerPage();
1568 idx
= getSelectedIndex();
1574 } else if (SWT
.CR
== e
.keyCode
) {
1575 idx
= getSelectedIndex();
1577 if (_data
._items
[idx
] instanceof TraceItem
)
1578 fireDefaultSelection();
1579 else if (_data
._items
[idx
] instanceof GroupItem
)
1585 selectItem(idx
, false);
1586 fireSelectionChanged();
1590 public void keyReleased(KeyEvent e
) {
1593 public void focusGained(FocusEvent e
) {
1598 public void focusLost(FocusEvent e
) {
1600 if (0 != _dragState
) {
1607 public boolean isInFocus() {
1611 public void mouseMove(MouseEvent e
) {
1612 if (null == _timeProvider
)
1614 Point size
= getCtrlSize();
1615 if (1 == _dragState
) {
1616 int nameWidth
= _timeProvider
.getNameSpace();
1617 int x
= e
.x
- nameWidth
;
1618 if (x
> 0 && size
.x
> nameWidth
&& _dragX
!= x
) {
1620 double K
= (double) (size
.x
- nameWidth
)
1621 / (_time1bak
- _time0bak
);
1622 long timeDelta
= (long) ((_dragX
- _dragX0
) / K
);
1623 long time1
= _time1bak
- timeDelta
;
1624 long maxTime
= _timeProvider
.getMaxTime();
1625 if (time1
> maxTime
)
1627 long time0
= time1
- (_time1bak
- _time0bak
);
1628 if (time0
< _timeProvider
.getMinTime()) {
1629 time0
= _timeProvider
.getMinTime();
1630 time1
= time0
+ (_time1bak
- _time0bak
);
1632 _timeProvider
.setStartFinishTime(time0
, time1
);
1634 } else if (3 == _dragState
) {
1636 _timeProvider
.setNameSpace(_hitIdx
+ _dragX
- _dragX0
);
1637 } else if (0 == _dragState
) {
1638 boolean mouseHover
= hitSplitTest(e
.x
, e
.y
) > 0;
1639 if (_mouseHover
!= mouseHover
)
1641 _mouseHover
= mouseHover
;
1643 updateCursor(e
.x
, e
.y
);
1646 public void mouseDoubleClick(MouseEvent e
) {
1647 if (null == _timeProvider
)
1649 if (1 == e
.button
) {
1650 int idx
= hitSplitTest(e
.x
, e
.y
);
1652 _timeProvider
.setNameSpace(_idealNameWidth
+ 3 * MARGIN
1656 idx
= hitTest(e
.x
, e
.y
);
1658 selectItem(idx
, false);
1659 if (_data
._items
[idx
] instanceof TraceItem
) {
1660 fireDefaultSelection();
1668 * If the x, y position is over the vertical split line (name to time
1669 * ranges), then change the cursor to a drag cursor to indicate the user the
1670 * possibility of resizing
1676 void updateCursor(int x
, int y
) {
1677 // if Wait cursor not active, check for the need to change to a drag
1679 if (_isWaitCursor
== false) {
1680 int idx
= hitSplitTest(x
, y
);
1681 // No dragcursor is name space is fixed to zero
1682 if (idx
> 0 && !_isDragCursor3
&& _timeProvider
.getNameSpace() > 0) {
1683 setCursor(_dragCursor3
);
1684 _isDragCursor3
= true;
1685 } else if (idx
<= 0 && _isDragCursor3
) {
1687 _isDragCursor3
= false;
1693 * Provide the possibilty to control the wait cursor externally e.g. data
1694 * requests in progress
1698 public void waitCursor(boolean waitInd
) {
1699 // Update cursor as indicated
1701 setCursor(_WaitCursor
);
1702 _isWaitCursor
= true;
1705 _isWaitCursor
= false;
1708 // Get ready for next mouse move
1709 _isDragCursor3
= false;
1712 public void mouseDown(MouseEvent e
) {
1713 if (null == _timeProvider
)
1716 if (1 == e
.button
) {
1717 int namewidth
= _timeProvider
.getNameSpace();
1718 if (namewidth
!= 0) {
1719 idx
= hitSplitTest(e
.x
, e
.y
);
1722 _dragX
= _dragX0
= e
.x
;
1723 _hitIdx
= _timeProvider
.getNameSpace();
1725 _time0bak
= _timeProvider
.getTime0();
1726 _time1bak
= _timeProvider
.getTime1();
1732 idx
= hitTest(e
.x
, e
.y
);
1734 if (_data
._items
[idx
] instanceof TraceItem
) {
1735 long hitTime
= hitTimeTest(e
.x
, e
.y
);
1737 _timeProvider
.setSelectedTimeInt(hitTime
, false);
1740 _dragX
= _dragX0
= e
.x
- _timeProvider
.getNameSpace();
1741 _time0bak
= _timeProvider
.getTime0();
1742 _time1bak
= _timeProvider
.getTime1();
1744 } else if (_data
._items
[idx
] instanceof GroupItem
) {
1748 selectItem(idx
, false);
1749 fireSelectionChanged();
1754 public void mouseUp(MouseEvent e
) {
1755 if (0 != _dragState
) {
1757 if (2 == _dragState
) {
1758 if (hitTest(e
.x
, e
.y
) == _hitIdx
)
1760 } else if (3 == _dragState
) {
1767 public void controlMoved(ControlEvent e
) {
1770 public void controlResized(ControlEvent e
) {
1774 public void widgetDefaultSelected(SelectionEvent e
) {
1777 public void widgetSelected(SelectionEvent e
) {
1778 if (e
.widget
== getVerticalBar()) {
1779 _topItem
= getVerticalBar().getSelection();
1783 } else if (e
.widget
== getHorizontalBar() && null != _timeProvider
) {
1784 int startTime
= getHorizontalBar().getSelection();
1785 long time0
= _timeProvider
.getTime0();
1786 long time1
= _timeProvider
.getTime1();
1787 long timeMin
= _timeProvider
.getMinTime();
1788 long timeMax
= _timeProvider
.getMaxTime();
1789 long delta
= timeMax
- timeMin
;
1791 long range
= time1
- time0
;
1792 // _timeRangeFixed = true;
1793 time0
= timeMin
+ (long) ((double) (startTime
* _timeStep
) * delta
);
1794 time1
= time0
+ range
;
1795 // Trace.debug("\nstartTime:" + startTime + " time0:" + time0
1796 // + " time1:" + time1 + " Delta:" + delta);
1797 _timeProvider
.setStartFinishTime(time0
, time1
);
1801 public void mouseEnter(MouseEvent e
) {
1804 public void mouseExit(MouseEvent e
) {
1806 _mouseHover
= false;
1811 public void mouseHover(MouseEvent e
) {
1814 public void mouseScrolled(MouseEvent e
) {
1817 } else if (e
.count
< 0) {
1822 public boolean isVisibleVerticalScroll() {
1823 return _visibleVerticalScroll
;
1826 public void setVisibleVerticalScroll(boolean visibleVerticalScroll
) {
1827 ScrollBar scrollVer
= getVerticalBar();
1828 if (scrollVer
!= null) {
1829 scrollVer
.setVisible(visibleVerticalScroll
);
1831 this._visibleVerticalScroll
= visibleVerticalScroll
;
1835 public int getBorderWidth() {
1836 return _borderWidth
;
1839 public void setBorderWidth(int borderWidth
) {
1840 this._borderWidth
= borderWidth
;
1843 public int getHeaderHeight() {
1844 return _headerHeight
;
1847 public void setHeaderHeight(int headerHeight
) {
1848 this._headerHeight
= headerHeight
;
1851 public int getItemHeight() {
1855 public void setItemHeight(int rowHeight
) {
1856 this._itemHeight
= rowHeight
;
1859 public Vector
<ITmfTimeAnalysisEntry
> getFilteredOut() {
1860 return _data
.getFilteredOut();
1864 public void addSelectionChangedListener(ISelectionChangedListener listener
) {
1865 if (listener
!= null) {
1866 if (!_selectionChangedListeners
.contains(listener
)) {
1867 _selectionChangedListeners
.add(listener
);
1873 public void removeSelectionChangedListener(
1874 ISelectionChangedListener listener
) {
1875 if (listener
!= null) {
1876 _selectionChangedListeners
.remove(listener
);
1881 public void setSelection(ISelection selection
) {
1882 if (selection
instanceof PlainSelection
) {
1883 PlainSelection sel
= (PlainSelection
) selection
;
1884 Object ob
= sel
.getFirstElement();
1885 if (ob
instanceof ITmfTimeAnalysisEntry
) {
1886 ITmfTimeAnalysisEntry trace
= (ITmfTimeAnalysisEntry
) ob
;
1887 selectItem(trace
, false);
1895 public boolean _expanded
;
1896 public boolean _selected
;
1897 public boolean _hasChildren
;
1898 public String _name
;
1905 public String
toString() {
1910 class TraceItem
extends Item
{
1911 public ITmfTimeAnalysisEntry _trace
;
1913 TraceItem(ITmfTimeAnalysisEntry trace
, String name
) {
1919 class GroupItem
extends Item
{
1920 public List
<ITmfTimeAnalysisEntry
> _traces
;
1922 GroupItem(String name
) {
1924 _traces
= new ArrayList
<ITmfTimeAnalysisEntry
>();
1925 _hasChildren
= true;
1928 void add(ITmfTimeAnalysisEntry trace
) {
1934 public Object
[] _items
= new Object
[0];
1935 private Object _traces
[] = new Object
[0];
1936 private boolean traceFilter
[] = new boolean[0];
1937 private Map
<String
, GroupItem
> _groupTable
= new HashMap
<String
, GroupItem
>();
1938 private boolean _flatList
= false;
1939 private TmfTimeAnalysisProvider utilsImp
;
1940 private Vector
<ITmfTimeAnalysisEntry
> filteredOut
= new Vector
<ITmfTimeAnalysisEntry
>();
1942 public ItemData(TmfTimeAnalysisProvider utils
) {
1943 this.utilsImp
= utils
;
1946 protected void groupTraces(boolean on
) {
1947 if (_flatList
== on
) {
1953 void clearGroups() {
1954 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
1955 while (it
.hasNext()) {
1956 GroupItem group
= it
.next();
1957 group
._traces
.clear();
1961 void deleteEmptyGroups() {
1962 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
1963 while (it
.hasNext()) {
1964 GroupItem group
= it
.next();
1965 if (group
._traces
.size() == 0)
1970 TraceItem
findTraceItem(ITmfTimeAnalysisEntry trace
) {
1974 int traceId
= trace
.getId();
1975 TraceItem traceItem
= null;
1977 for (int i
= 0; i
< _items
.length
; i
++) {
1978 Object item
= _items
[i
];
1979 if (item
instanceof TraceItem
) {
1980 TraceItem ti
= (TraceItem
) item
;
1981 if (ti
._trace
.getId() == traceId
) {
1991 Integer
findTraceItemIndex(ITmfTimeAnalysisEntry trace
) {
1995 int traceId
= trace
.getId();
1998 for (int i
= 0; i
< _items
.length
; i
++) {
2000 Object item
= _items
[i
];
2001 if (item
instanceof TraceItem
) {
2002 TraceItem ti
= (TraceItem
) item
;
2003 if (ti
._trace
.getId() == traceId
) {
2012 public void updateItems() {
2013 List
<Item
> itemList
= new ArrayList
<Item
>();
2016 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
2017 while (it
.hasNext()) {
2018 GroupItem group
= it
.next();
2020 itemList
.add(group
);
2022 if (_flatList
|| group
._expanded
) {
2023 Iterator
<ITmfTimeAnalysisEntry
> it2
= group
._traces
.iterator();
2024 while (it2
.hasNext()) {
2025 ITmfTimeAnalysisEntry trace
= it2
.next();
2026 TraceItem traceItem
= findTraceItem(trace
);
2027 name
= utilsImp
.composeTraceName(trace
, false);
2028 traceItem
= new TraceItem(trace
, name
);
2029 itemList
.add(traceItem
);
2033 _items
= itemList
.toArray();
2036 public int expandItem(int idx
, boolean expand
) {
2037 if (idx
< 0 || idx
>= _items
.length
)
2040 Item item
= (Item
) _items
[idx
];
2041 if (item
._hasChildren
&& !item
._expanded
) {
2042 item
._expanded
= expand
;
2043 ret
= _items
.length
;
2045 ret
= _items
.length
- ret
;
2050 public void refreshData(Object traces
[]) {
2051 if (traces
== null || traces
.length
== 0) {
2053 } else if (traceFilter
== null || traces
.length
!= traceFilter
.length
) {
2054 traceFilter
= new boolean[traces
.length
];
2055 java
.util
.Arrays
.fill(traceFilter
, true);
2063 * Allows to update the GUI from a stream of events handling addition one by
2064 * one over known TmfTaTrace parents.
2069 public void refreshPartial(ITmfTimeAnalysisEntry parent
, TimeEvent childItem
) {
2070 // Find the Trace item within the current list
2071 TraceItem item
= findTraceItem(parent
);
2073 // This method is not used (yet) so this code can be commented out for now
2074 // FIXME: Arrays.copyOf is a Java6 feature
2075 // if (item == null) {
2076 // // If the parent item is not found, make room for it in the current
2080 // if (_traces != null) {
2081 // length = _traces.length + 1;
2082 // traces = Arrays.copyOf(_traces, length);
2084 // traces = new Object[length];
2087 // // Add the new parent element to the end of the array.
2088 // traces[length - 1] = parent;
2090 // // update the filter array to accomodate a postion to the new
2092 // traceFilter = new boolean[traces.length];
2093 // java.util.Arrays.fill(traceFilter, true);
2095 // // rebuild internal data
2096 // _traces = traces;
2099 // // item must be there
2100 // item = findTraceItem(parent);
2103 ITmfTimeAnalysisEntry localTraceItem
= item
._trace
;
2104 // Local trace found
2105 Vector
<TimeEvent
> children
= localTraceItem
.getTraceEvents();
2106 TimeEvent lastChildIn
= children
.lastElement();
2107 long lastChildSTime
= lastChildIn
.getTime();
2108 long newChildSTime
= childItem
.getTime();
2109 if (newChildSTime
< lastChildSTime
) {
2110 // The children are expected to arrive sorted by time
2111 // since the new time is earlier than the last child
2112 // The infomation is being refreshed from start, remove all
2113 // children and start over
2117 children
.add(childItem
);
2121 public void refreshData() {
2123 filteredOut
.clear();
2124 String undef
= Messages
._UNDEFINED_GROUP
;
2125 List
<GroupItem
> groupList
= new ArrayList
<GroupItem
>();
2126 for (int i
= 0; i
< _traces
.length
; i
++) {
2127 ITmfTimeAnalysisEntry trace
= (ITmfTimeAnalysisEntry
) _traces
[i
];
2128 if (!traceFilter
[i
]) {
2129 filteredOut
.add(trace
);
2133 String groupName
= trace
.getGroupName();
2134 if (null == groupName
)
2137 GroupItem group
= _groupTable
.get(groupName
);
2138 if (null == group
) {
2139 group
= new GroupItem(NLS
.bind(Messages
._TRACE_GROUP_LABEL
,
2141 group
._expanded
= !groupName
.equalsIgnoreCase("system")
2142 && !groupName
.equalsIgnoreCase(undef
);
2143 _groupTable
.put(groupName
, group
);
2144 groupList
.add(group
);
2149 deleteEmptyGroups();
2153 public Object
[] getTraces() {
2157 public boolean[] getTraceFilter() {
2161 public Vector
<ITmfTimeAnalysisEntry
> getFilteredOut() {