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
.Arrays
;
20 import java
.util
.HashMap
;
21 import java
.util
.Iterator
;
22 import java
.util
.List
;
24 import java
.util
.Vector
;
26 import org
.eclipse
.jface
.viewers
.ISelection
;
27 import org
.eclipse
.jface
.viewers
.ISelectionChangedListener
;
28 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
29 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.Messages
;
30 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.TmfTimeAnalysisProvider
;
31 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITimeEvent
;
32 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.ITmfTimeAnalysisEntry
;
33 import org
.eclipse
.linuxtools
.tmf
.ui
.viewers
.timeAnalysis
.model
.TimeEvent
;
34 import org
.eclipse
.osgi
.util
.NLS
;
35 import org
.eclipse
.swt
.SWT
;
36 import org
.eclipse
.swt
.events
.ControlEvent
;
37 import org
.eclipse
.swt
.events
.ControlListener
;
38 import org
.eclipse
.swt
.events
.FocusEvent
;
39 import org
.eclipse
.swt
.events
.FocusListener
;
40 import org
.eclipse
.swt
.events
.KeyEvent
;
41 import org
.eclipse
.swt
.events
.KeyListener
;
42 import org
.eclipse
.swt
.events
.MouseEvent
;
43 import org
.eclipse
.swt
.events
.MouseListener
;
44 import org
.eclipse
.swt
.events
.MouseMoveListener
;
45 import org
.eclipse
.swt
.events
.MouseTrackListener
;
46 import org
.eclipse
.swt
.events
.MouseWheelListener
;
47 import org
.eclipse
.swt
.events
.PaintEvent
;
48 import org
.eclipse
.swt
.events
.SelectionEvent
;
49 import org
.eclipse
.swt
.events
.SelectionListener
;
50 import org
.eclipse
.swt
.events
.TraverseEvent
;
51 import org
.eclipse
.swt
.events
.TraverseListener
;
52 import org
.eclipse
.swt
.graphics
.Cursor
;
53 import org
.eclipse
.swt
.graphics
.GC
;
54 import org
.eclipse
.swt
.graphics
.Image
;
55 import org
.eclipse
.swt
.graphics
.Point
;
56 import org
.eclipse
.swt
.graphics
.Rectangle
;
57 import org
.eclipse
.swt
.widgets
.Composite
;
58 import org
.eclipse
.swt
.widgets
.ScrollBar
;
64 public class TmfTimeStatesCtrl
extends TraceCtrl
implements FocusListener
,
65 KeyListener
, MouseMoveListener
, MouseListener
, MouseWheelListener
,
66 ControlListener
, SelectionListener
, MouseTrackListener
,
67 TraverseListener
, ISelectionProvider
{
69 public static final boolean DEFAULT_DRAW_THREAD_JOIN
= true;
70 public static final boolean DEFAULT_DRAW_THREAD_WAIT
= true;
71 public static final boolean DEFAULT_DRAW_THREAD_RELEASE
= true;
73 private final double zoomCoeff
= 1.5;
75 private ITimeDataProvider _timeProvider
;
76 private boolean _isInFocus
= false;
77 private boolean _isDragCursor3
= false;
78 private boolean _isWaitCursor
= true;
79 private boolean _mouseHover
= false;
80 private int _itemHeightDefault
= 18;
81 private int _itemHeight
= _itemHeightDefault
;
82 private int _topItem
= 0;
83 private int _dragState
= 0;
84 private int _hitIdx
= 0;
85 private int _dragX0
= 0;
86 private int _dragX
= 0;
87 private int _idealNameWidth
= 0;
89 private double _timeStep
= 0.001;
90 // private double _timeStep = 10000000;
91 private long _time0bak
;
92 private long _time1bak
;
93 private TmfTimeAnalysisProvider utilImpl
= null;
94 private ItemData _data
= null;
95 private List
<SelectionListener
> _selectionListeners
;
96 private List
<ISelectionChangedListener
> _selectionChangedListeners
= new ArrayList
<ISelectionChangedListener
>();
97 private Rectangle _rect0
= new Rectangle(0, 0, 0, 0);
98 private Rectangle _rect1
= new Rectangle(0, 0, 0, 0);
99 private Cursor _dragCursor3
;
100 private Cursor _WaitCursor
;
101 private boolean drawTracesInteraction
= false;
102 private boolean drawTraceJoins
= DEFAULT_DRAW_THREAD_JOIN
;
103 private boolean drawTraceWaits
= DEFAULT_DRAW_THREAD_WAIT
;
104 private boolean drawTraceReleases
= DEFAULT_DRAW_THREAD_RELEASE
;
106 // Vertical formatting formatting for the state control view
107 private boolean _visibleVerticalScroll
= true;
108 private int _borderWidth
= 0;
109 private int _headerHeight
= 0;
111 public TmfTimeStatesCtrl(Composite parent
, TraceColorScheme colors
,
112 TmfTimeAnalysisProvider rutilImp
) {
114 super(parent
, colors
, SWT
.NO_BACKGROUND
| SWT
.V_SCROLL
| SWT
.H_SCROLL
115 | SWT
.DOUBLE_BUFFERED
);
117 this.utilImpl
= rutilImp
;
118 _data
= new ItemData(utilImpl
);
120 addFocusListener(this);
121 addMouseListener(this);
122 addMouseMoveListener(this);
123 addMouseTrackListener(this);
124 addMouseWheelListener(this);
125 addTraverseListener(this);
126 addKeyListener(this);
127 addControlListener(this);
128 ScrollBar scrollVer
= getVerticalBar();
129 ScrollBar scrollHor
= getHorizontalBar();
130 if (scrollVer
!= null) {
131 scrollVer
.addSelectionListener(this);
132 scrollVer
.setVisible(_visibleVerticalScroll
);
135 if (scrollHor
!= null) {
136 scrollHor
.addSelectionListener(this);
139 _dragCursor3
= new Cursor(super.getDisplay(), SWT
.CURSOR_SIZEWE
);
140 _WaitCursor
= new Cursor(super.getDisplay(), SWT
.CURSOR_WAIT
);
144 public void dispose() {
146 _dragCursor3
.dispose();
147 _WaitCursor
.dispose();
150 public void setTimeProvider(ITimeDataProvider timeProvider
) {
151 _timeProvider
= timeProvider
;
156 public void addSelectionListener(SelectionListener listener
) {
157 if (listener
== null)
158 SWT
.error(SWT
.ERROR_NULL_ARGUMENT
);
159 if (null == _selectionListeners
)
160 _selectionListeners
= new ArrayList
<SelectionListener
>();
161 _selectionListeners
.add(listener
);
164 public void removeSelectionListener(SelectionListener listener
) {
165 if (null != _selectionListeners
)
166 _selectionListeners
.remove(listener
);
169 public void fireSelectionChanged() {
170 if (null != _selectionListeners
) {
171 Iterator
<SelectionListener
> it
= _selectionListeners
.iterator();
172 while (it
.hasNext()) {
173 SelectionListener listener
= it
.next();
174 listener
.widgetSelected(null);
179 public void fireDefaultSelection() {
180 if (null != _selectionListeners
) {
181 Iterator
<SelectionListener
> it
= _selectionListeners
.iterator();
182 while (it
.hasNext()) {
183 SelectionListener listener
= it
.next();
184 listener
.widgetDefaultSelected(null);
189 public Object
[] getTraces() {
190 return _data
.getTraces();
193 public boolean[] getTraceFilter() {
194 return _data
.getTraceFilter();
197 public void refreshData() {
203 public void refreshData(Object traces
[]) {
204 _data
.refreshData(traces
);
209 public void refreshPartial(ITmfTimeAnalysisEntry parent
, TimeEvent item
) {
210 _data
.refreshPartial(parent
, item
);
215 public void adjustScrolls() {
216 if (null == _timeProvider
) {
217 getVerticalBar().setValues(0, 1, 1, 1, 1, 1);
218 getHorizontalBar().setValues(0, 1, 1, 1, 1, 1);
221 int page
= countPerPage();
222 if (_topItem
+ page
> _data
._items
.length
)
223 _topItem
= _data
._items
.length
- page
;
226 getVerticalBar().setValues(_topItem
, 0, _data
._items
.length
, page
, 1,
228 long time0
= _timeProvider
.getTime0();
229 long time1
= _timeProvider
.getTime1();
230 long timeMin
= _timeProvider
.getMinTime();
231 long timeMax
= _timeProvider
.getMaxTime();
233 // int timePage = (int) ((time1 - time0) / _timeStep);
234 // int timePos = (int) (time0 / _timeStep);
235 // int minimum = (int) (timeMin / _timeStep);
236 // int maximum = (int) (timeMax / _timeStep);
238 long delta
= timeMax
- timeMin
;
242 // Trace.debug("time0 - time1 = " + (time0 - timeMin));
244 timePage
= (int) (((double) (time1
- time0
) / _timeStep
) / delta
);
245 timePos
= (int) (((double) (time0
- timeMin
) / _timeStep
) / delta
);
250 // Trace.debug("time0:" + time0 + " time1:" + time1 + " timeStep:"
251 // + _timeStep + " delta:" + delta);
252 // Trace.debug("selection:" + timePos + " min:" + minimum + " maximum:"
253 // + maximum + " Page:" + timePage);
254 getHorizontalBar().setValues(timePos
, minimum
, maximum
, timePage
, 1,
258 boolean ensureVisibleItem(int idx
, boolean redraw
) {
259 boolean changed
= false;
261 for (idx
= 0; idx
< _data
._items
.length
; idx
++) {
262 if (((Item
) _data
._items
[idx
])._selected
)
266 if (idx
>= _data
._items
.length
)
268 if (idx
< _topItem
) {
270 getVerticalBar().setSelection(_topItem
);
275 int page
= countPerPage();
276 if (idx
>= _topItem
+ page
) {
277 _topItem
= idx
- page
+ 1;
278 getVerticalBar().setSelection(_topItem
);
287 public ISelection
getSelection() {
288 PlainSelection sel
= new PlainSelection();
289 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
290 if (null != trace
&& null != _timeProvider
) {
291 long selectedTime
= _timeProvider
.getSelectedTime();
292 ITimeEvent event
= Utils
.findEvent(trace
, selectedTime
, 0);
301 public ISelection
getSelectionTrace() {
302 PlainSelection sel
= new PlainSelection();
303 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
310 public void selectTrace(int n
) {
311 if (n
!= 1 && n
!= -1)
313 boolean changed
= false;
314 int lastSelection
= -1;
315 for (int i
= 0; i
< _data
._items
.length
; i
++) {
316 Item item
= (Item
) _data
._items
[i
];
317 if (item
._selected
) {
319 if (1 == n
&& i
< _data
._items
.length
- 1) {
320 item
._selected
= false;
321 if (item
._hasChildren
)
322 _data
.expandItem(i
, true);
323 item
= (Item
) _data
._items
[i
+ 1];
324 if (item
._hasChildren
) {
325 _data
.expandItem(i
+ 1, true);
326 item
= (Item
) _data
._items
[i
+ 2];
328 item
._selected
= true;
330 } else if (-1 == n
&& i
> 0) {
332 Item prevItem
= (Item
) _data
._items
[i
];
333 if (prevItem
._hasChildren
) {
334 if (prevItem
._expanded
) {
337 prevItem
= (Item
) _data
._items
[i
];
340 if (!prevItem
._expanded
) {
341 int added
= _data
.expandItem(i
, true);
342 prevItem
= (Item
) _data
._items
[i
+ added
];
343 item
._selected
= false;
344 prevItem
._selected
= true;
348 item
._selected
= false;
349 prevItem
._selected
= true;
356 if (lastSelection
< 0 && _data
._items
.length
> 0) {
357 Item item
= (Item
) _data
._items
[0];
358 if (item
._hasChildren
) {
359 _data
.expandItem(0, true);
360 item
= (Item
) _data
._items
[1];
361 item
._selected
= true;
364 item
._selected
= true;
369 ensureVisibleItem(-1, false);
371 fireSelectionChanged();
375 public void selectEvent(int n
) {
376 if (null == _timeProvider
)
378 ITmfTimeAnalysisEntry trace
= getSelectedTrace();
379 if (trace
== _timeProvider
)
381 long selectedTime
= _timeProvider
.getSelectedTime();
382 long endTime
= _timeProvider
.getEndTime();
383 ITimeEvent nextEvent
;
384 if (-1 == n
&& selectedTime
>= endTime
)
385 nextEvent
= Utils
.findEvent(trace
, selectedTime
, 0);
387 nextEvent
= Utils
.findEvent(trace
, selectedTime
, n
);
388 if (null == nextEvent
&& -1 == n
)
389 nextEvent
= Utils
.getFirstEvent(trace
);
390 if (null != nextEvent
) {
391 _timeProvider
.setSelectedTimeInt(nextEvent
.getTime(), true);
392 fireSelectionChanged();
394 _timeProvider
.setSelectedTimeInt(endTime
, true);
395 fireSelectionChanged();
399 public void selectNextEvent() {
403 public void selectPrevEvent() {
407 public void selectNextTrace() {
411 public void selectPrevTrace() {
415 public void zoomIn() {
416 long _time0
= _timeProvider
.getTime0();
417 long _time1
= _timeProvider
.getTime1();
418 long _range
= _time1
- _time0
;
419 long selTime
= _timeProvider
.getSelectedTime();
420 if (selTime
<= _time0
|| selTime
>= _time1
) {
421 selTime
= (_time0
+ _time1
) / 2;
423 long time0
= selTime
- (long) ((selTime
- _time0
) / zoomCoeff
);
424 long time1
= selTime
+ (long) ((_time1
- selTime
) / zoomCoeff
);
426 long inaccuracy
= (_timeProvider
.getMaxTime() - _timeProvider
430 // Trace.debug("selTime:" + selTime + " time0:" + time0 + " time1:"
431 // + time1 + " inaccuracy:" + inaccuracy);
433 if (inaccuracy
> 0 && inaccuracy
< 100) {
434 _timeProvider
.setStartFinishTime(_timeProvider
.getMinTime(),
435 _timeProvider
.getMaxTime());
439 long m
= _timeProvider
.getMinTimeInterval();
440 if ((time1
- time0
) < m
) {
441 time0
= selTime
- (long) ((selTime
- _time0
) * m
/ _range
);
445 _timeProvider
.setStartFinishTime(time0
, time1
);
448 public void zoomOut() {
449 long _time0
= _timeProvider
.getTime0();
450 long _time1
= _timeProvider
.getTime1();
451 long selTime
= _timeProvider
.getSelectedTime();
452 if (selTime
<= _time0
|| selTime
>= _time1
) {
453 selTime
= (_time0
+ _time1
) / 2;
455 long time0
= (long) (selTime
- (selTime
- _time0
) * zoomCoeff
);
456 long time1
= (long) (selTime
+ (_time1
- selTime
) * zoomCoeff
);
458 long inaccuracy
= (_timeProvider
.getMaxTime() - _timeProvider
461 if (inaccuracy
> 0 && inaccuracy
< 100) {
462 _timeProvider
.setStartFinishTime(_timeProvider
.getMinTime(),
463 _timeProvider
.getMaxTime());
467 _timeProvider
.setStartFinishTime(time0
, time1
);
470 public void groupTraces(boolean on
) {
471 _data
.groupTraces(on
);
476 public void toggleTraceInteractionDrawing() {
477 drawTracesInteraction
= !drawTracesInteraction
;
481 public void setTraceJoinDrawing(boolean on
) {
483 drawTracesInteraction
= true;
487 public void setTraceWaitDrawing(boolean on
) {
489 drawTracesInteraction
= true;
493 public void setTraceReleaseDrawing(boolean on
) {
494 drawTraceReleases
= on
;
495 drawTracesInteraction
= true;
499 public boolean getTracesInteractionDrawing() {
500 return drawTracesInteraction
;
503 public boolean getTraceJoinDrawing() {
504 return drawTraceJoins
;
507 public boolean getTraceWaitDrawing() {
508 return drawTraceWaits
;
511 public boolean getTraceReleaseDrawing() {
512 return drawTraceReleases
;
515 public ITmfTimeAnalysisEntry
getSelectedTrace() {
516 ITmfTimeAnalysisEntry trace
= null;
517 int idx
= getSelectedIndex();
518 if (idx
>= 0 && _data
._items
[idx
] instanceof TraceItem
)
519 trace
= ((TraceItem
) _data
._items
[idx
])._trace
;
523 public int getSelectedIndex() {
525 for (int i
= 0; i
< _data
._items
.length
; i
++) {
526 Item item
= (Item
) _data
._items
[i
];
527 if (item
._selected
) {
535 boolean toggle(int idx
) {
536 boolean toggled
= false;
537 if (idx
>= 0 && idx
< _data
._items
.length
) {
538 Item item
= (Item
) _data
._items
[idx
];
539 if (item
._hasChildren
) {
540 item
._expanded
= !item
._expanded
;
550 int hitTest(int x
, int y
) {
554 int idx
= y
/ _itemHeight
;
556 if (idx
< _data
._items
.length
)
561 int hitSplitTest(int x
, int y
) {
562 if (x
< 0 || y
< 0 || null == _timeProvider
)
566 int nameWidth
= _timeProvider
.getNameSpace();
567 if (x
> nameWidth
- w
&& x
< nameWidth
+ w
)
572 public Item
getItem(Point pt
) {
573 int idx
= hitTest(pt
.x
, pt
.y
);
574 return idx
>= 0 ?
(Item
) _data
._items
[idx
] : null;
577 long hitTimeTest(int x
, int y
) {
578 if (null == _timeProvider
)
581 Point size
= getCtrlSize();
582 long time0
= _timeProvider
.getTime0();
583 long time1
= _timeProvider
.getTime1();
584 int nameWidth
= _timeProvider
.getNameSpace();
586 if (x
>= 0 && size
.x
>= nameWidth
) {
587 hitTime
= time0
+ ((time1
- time0
) * x
) / (size
.x
- nameWidth
);
592 void selectItem(int idx
, boolean addSelection
) {
594 if (idx
>= 0 && idx
< _data
._items
.length
) {
595 Item item
= (Item
) _data
._items
[idx
];
596 item
._selected
= true;
599 for (int i
= 0; i
< _data
._items
.length
; i
++) {
600 Item item
= (Item
) _data
._items
[i
];
601 item
._selected
= i
== idx
;
604 boolean changed
= ensureVisibleItem(idx
, true);
609 public void selectItem(ITmfTimeAnalysisEntry trace
, boolean addSelection
) {
610 Integer idx
= _data
.findTraceItemIndex(trace
);
611 selectItem(idx
, addSelection
);
614 public int countPerPage() {
615 int height
= getCtrlSize().y
;
618 count
= height
/ _itemHeight
;
622 public int getTopIndex() {
624 if (_data
._items
.length
> 0)
629 public int getBottomIndex() {
630 int idx
= _data
._items
.length
- 1;
634 Point
getCtrlSize() {
635 Point size
= getSize();
636 size
.x
-= getVerticalBar().getSize().x
;
637 size
.y
-= getHorizontalBar().getSize().y
;
641 void getNameRect(Rectangle rect
, Rectangle bound
, int idx
, int nameWidth
) {
644 rect
.y
= bound
.y
+ idx
* _itemHeight
;
645 rect
.width
= nameWidth
;
646 rect
.height
= _itemHeight
;
649 void getStatesRect(Rectangle rect
, Rectangle bound
, int idx
, int nameWidth
) {
651 rect
.x
= bound
.x
+ nameWidth
;
652 rect
.y
= bound
.y
+ idx
* _itemHeight
;
653 rect
.width
= bound
.width
- rect
.x
;
654 rect
.height
= _itemHeight
;
657 // private int getTraceNumber(int tid) {
660 // Object[] items = _data._items;
661 // for (int i = _topItem; i < items.length; i++) {
662 // Item item = (Item) items[i];
663 // if ((item instanceof TraceItem)) {
664 // TsfTmTrace trace = ((TraceItem) item)._trace;
665 // if (trace != null && trace.getId() == tid) {
675 // private void drawArrow(GC gc, int x0, int y0, int x1, int y1, Color c) {
676 // gc.setForeground(c);
677 // gc.drawLine(x0, y0, x1, y1);
680 // gc.drawLine(x1 - 3, y1 - 3, x1, y1);
681 // gc.drawLine(x1 + 3, y1 - 3, x1, y1);
683 // gc.drawLine(x1 - 3, y1 + 3, x1, y1);
684 // gc.drawLine(x1 + 3, y1 + 3, x1, y1);
688 // TODO: CC: used in the removed functionality to draw thread interactions.
689 // private void drawTraceThreadEvent(Rectangle bound, TsfTmEvent e,
690 // TsfTmTrace trace, int nItem, int color, GC gc) {
691 // if (trace == null)
694 // int tid = trace.getId();
695 // if (tid < 0 || getTraceNumber(tid) == -1)
698 // int nameWidth = _timeProvider.getNameSpace();
700 // double time0 = _timeProvider.getTime0();
701 // double time1 = _timeProvider.getTime1();
702 // if (time0 == time1)
705 // int xr = bound.x + nameWidth;
706 // double K = (double) (bound.width - xr) / (time1 - time0);
708 // int x0 = xr + (int) ((e.getTime() - time0) * K);
712 // int x1 = xr + (int) ((trace.getStartTime() - time0) * K);
716 // int y0 = bound.y + (nItem - _topItem) * _itemHeight + 3
717 // + (_itemHeight - 6) / 2;
718 // int y1 = bound.y + (getTraceNumber(tid) - _topItem) * _itemHeight + 3
719 // + (_itemHeight - 6) / 2;
721 // drawArrow(gc, x0, y0, x1, y1, _colors.getColor(color));
724 public void drawTraceEvent(Rectangle bound
, ITimeEvent e
, int nItem
,
726 int nameWidth
= _timeProvider
.getNameSpace();
728 long time0
= _timeProvider
.getTime0();
729 long time1
= _timeProvider
.getTime1();
733 int xr
= bound
.x
+ nameWidth
;
734 double K
= (double) (bound
.width
- xr
) / (time1
- time0
);
736 int x0
= xr
+ (int) ((e
.getTime() - time0
) * K
);
740 int y0
= bound
.y
+ (nItem
- _topItem
) * _itemHeight
+ 3;
742 gc
.setBackground(_colors
.getColor(color
));
743 int c
[] = { x0
- 3, y0
- 3, x0
, y0
, x0
+ 3, y0
- 3 };
748 // private void drawExecEvent(Rectangle bound, TsfTmTraceExecEventImpl e,
749 // int nitem, int color, GC gc) {
750 // List runnings = e.getRunningEvents();
751 // if (runnings == null)
754 // int nameWidth = _timeProvider.getNameSpace();
756 // double time0 = _timeProvider.getTime0();
757 // double time1 = _timeProvider.getTime1();
758 // if (time0 == time1)
761 // int xr = bound.x + nameWidth;
762 // double K = (double) (bound.width - xr) / (time1 - time0);
764 // int x0 = xr + (int) ((e.getTime() - time0) * K);
768 // Iterator it = runnings.iterator();
769 // while (it.hasNext()) {
770 // TsfTmTraceRunningEventImpl re = (TsfTmTraceRunningEventImpl) it
772 // int tid = re.getThread().getId();
773 // if (tid < 0 || getThreadNumber(tid) == -1)
776 // int x1 = xr + (int) ((re.getTime() - time0) * K);
780 // int y0 = bound.y + (nitem - _topItem) * _itemHeight + 3
781 // + (_itemHeight - 6) / 2;
782 // int y1 = bound.y + (getThreadNumber(tid) - _topItem) * _itemHeight
783 // + 3 + (_itemHeight - 6) / 2;
785 // drawArrow(gc, x0, y0, x1, y1, _colors.getColor(color));
789 public void drawTraceInteractions(Rectangle bound
, GC gc
) {
790 // int nameWidth = _timeProvider.getNameSpace();
791 // Object[] items = _data._items;
793 // double time0 = _timeProvider.getTime0();
794 // double time1 = _timeProvider.getTime1();
796 // if (time0 == time1)
799 // int xr = bound.x + nameWidth;
800 // double K = (double) (bound.width - xr) / (time1 - time0);
802 // for (int i = 0; i < items.length; i++) {
803 // Item item = (Item) items[i];
804 // if (!(item instanceof TraceItem))
807 // TsfTmTrace trace = ((TraceItem) item)._trace;
808 // if (trace == null)
811 // List<TsfTmEvent> list = trace.getTraceEvents();
812 // Iterator<TsfTmEvent> it = list.iterator();
813 // while (it.hasNext()) {
814 // TsfTmEvent te = (TsfTmEvent) it.next();
815 // TODO: CC: Thread Interactions,
816 // This needs to be accessed externally via a specific
818 // if (te instanceof TsfTmTraceStartThreadEventImpl) {
819 // TsfTmTrace child = ((TsfTmTraceStartThreadEventImpl) te)
820 // .getStartedThread();
821 // drawThreadThreadEvent(bound, te, child, i,
822 // TraceColorScheme.TI_START_THREAD, gc);
823 // } else if (te instanceof TsfTmTraceHandoffLockEventImpl) {
824 // if (drawThreadReleases)
825 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
826 // TraceColorScheme.TI_HANDOFF_LOCK, gc);
827 // } else if (te instanceof TsfTmTraceNotifyAllEventImpl) {
828 // if (drawThreadWaits)
829 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
830 // TraceColorScheme.TI_NOTIFY_ALL, gc);
831 // } else if (te instanceof TsfTmTraceNotifyEventImpl) {
832 // if (drawThreadWaits)
833 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
834 // TraceColorScheme.TI_NOTIFY, gc);
835 // } else if (te instanceof
836 // TsfTmTraceDeadAndNotifyJoinedEventImpl) {
837 // if (drawThreadJoins)
838 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
839 // TraceColorScheme.TI_NOTIFY_JOINED, gc);
840 // } else if (te instanceof TsfTmTraceInterruptThreadEventImpl)
842 // if (drawThreadWaits)
843 // drawExecEvent(bound, (TsfTmTraceExecEventImpl) te, i,
844 // TraceColorScheme.TI_INTERRUPT, gc);
845 // } else if (te instanceof
846 // TsfTmTraceWaitTimeoutExceedEventImpl) {
847 // drawThreadEvent(bound, te, i,
848 // TraceColorScheme.TI_WAIT_EXCEEDED, gc);
855 void paint(Rectangle bound
, PaintEvent e
) {
856 // If no user preference defined for item height
857 if (_itemHeight
== _itemHeightDefault
) {
858 _itemHeight
= getFontHeight() + 6;
861 if (bound
.width
< 2 || bound
.height
< 2 || null == _timeProvider
)
866 int nameWidth
= _timeProvider
.getNameSpace();
867 long time0
= _timeProvider
.getTime0();
868 long time1
= _timeProvider
.getTime1();
869 long endTime
= _timeProvider
.getEndTime();
870 long selectedTime
= _timeProvider
.getSelectedTime();
872 Object
[] items
= _data
._items
;
873 for (int i
= _topItem
; i
< items
.length
; i
++) {
874 Item item
= (Item
) items
[i
];
875 getNameRect(_rect0
, bound
, i
, nameWidth
);
876 if (_rect0
.y
>= bound
.y
+ bound
.height
)
879 if (item
instanceof GroupItem
) {
880 getStatesRect(_rect1
, bound
, i
, nameWidth
);
881 _rect0
.width
+= _rect1
.width
;
882 drawName(item
, _rect0
, gc
);
884 drawName(item
, _rect0
, gc
);
886 getStatesRect(_rect0
, bound
, i
, nameWidth
);
887 drawItemDataDurations(item
, _rect0
, time0
, time1
, endTime
,
891 if (drawTracesInteraction
)
892 drawTraceInteractions(bound
, e
.gc
);
894 // fill free canvas area
896 _rect0
.y
+= _rect0
.height
;
897 _rect0
.width
= bound
.width
;
898 _rect0
.height
= bound
.y
+ bound
.height
- _rect0
.y
;
899 if (_rect0
.y
< bound
.y
+ bound
.height
) {
900 gc
.setBackground(_colors
.getColor(TraceColorScheme
.BACKGROUND
));
901 gc
.fillRectangle(_rect0
);
903 // draw drag line, no line if name space is 0.
904 if (3 == _dragState
) {
905 gc
.setForeground(_colors
.getColor(TraceColorScheme
.BLACK
));
906 gc
.drawLine(bound
.x
+ nameWidth
, bound
.y
, bound
.x
+ nameWidth
,
907 bound
.y
+ bound
.height
- 1);
908 } else if (0 == _dragState
&& _mouseHover
909 && _timeProvider
.getNameSpace() > 0) {
910 gc
.setForeground(_colors
.getColor(TraceColorScheme
.RED
));
911 gc
.drawLine(bound
.x
+ nameWidth
, bound
.y
, bound
.x
+ nameWidth
,
912 bound
.y
+ bound
.height
- 1);
916 void drawName(Item item
, Rectangle rect
, GC gc
) {
917 // No name to be drawn
918 if (_timeProvider
.getNameSpace() == 0)
920 boolean group
= item
instanceof GroupItem
;
922 int elemHeight
= rect
.height
/ 2;
923 int elemWidth
= elemHeight
;
924 String name
= item
._name
;
926 gc
.setBackground(_colors
927 .getBkColorGroup(item
._selected
, _isInFocus
));
928 gc
.fillRectangle(rect
);
929 if (item
._selected
&& _isInFocus
) {
930 gc
.setForeground(_colors
.getBkColor(item
._selected
, _isInFocus
,
932 gc
.drawRectangle(rect
.x
, rect
.y
, rect
.width
- 2,
935 gc
.setForeground(_colors
.getBkColor(false, false, false));
936 gc
.drawLine(rect
.x
, rect
.y
+ rect
.height
- 1, rect
.width
- 1,
937 rect
.y
+ rect
.height
- 1);
938 gc
.setForeground(_colors
.getFgColorGroup(false, false));
939 gc
.setBackground(_colors
.getBkColor(false, false, false));
940 Utils
.init(_rect1
, rect
);
942 _rect1
.y
+= (rect
.height
- elemHeight
) / 2;
943 _rect1
.width
= elemWidth
;
944 _rect1
.height
= elemHeight
;
945 // Get the icon rectangle in the group items
946 gc
.fillRectangle(_rect1
);
947 gc
.drawRectangle(_rect1
.x
, _rect1
.y
, _rect1
.width
- 1,
949 int p
= _rect1
.y
+ _rect1
.height
/ 2;
950 gc
.drawLine(_rect1
.x
+ 2, p
, _rect1
.x
+ _rect1
.width
- 3, p
);
951 if (!item
._expanded
) {
952 p
= _rect1
.x
+ _rect1
.width
/ 2;
953 gc
.drawLine(p
, _rect1
.y
+ 2, p
, _rect1
.y
+ _rect1
.height
- 3);
955 gc
.setForeground(_colors
956 .getFgColorGroup(item
._selected
, _isInFocus
));
959 gc
.setBackground(_colors
.getBkColor(item
._selected
, _isInFocus
,
961 gc
.setForeground(_colors
.getFgColor(item
._selected
, _isInFocus
));
962 gc
.fillRectangle(rect
);
963 Utils
.init(_rect1
, rect
);
966 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
967 Image img
= utilImpl
.getItemImage(trace
);
969 _rect1
.y
+= (rect
.height
- img
.getImageData().height
) / 2;
970 gc
.drawImage(img
, _rect1
.x
, _rect1
.y
);
972 elemWidth
= SMALL_ICON_SIZE
;
973 // cut long string with "..."
974 Point size
= gc
.stringExtent(name
);
975 if (_idealNameWidth
< size
.x
)
976 _idealNameWidth
= size
.x
;
977 int width
= rect
.width
- MARGIN
- MARGIN
- elemWidth
;
979 while (size
.x
> width
&& name
.length() > 1) {
981 name
= name
.substring(0, name
.length() - 1);
982 size
= gc
.stringExtent(name
+ "...");
988 Utils
.init(_rect1
, rect
);
989 int leftMargin
= MARGIN
+ elemWidth
;
990 _rect1
.x
+= leftMargin
;
991 _rect1
.width
-= leftMargin
;
994 if (_rect1
.width
> 0) {
996 textWidth
= Utils
.drawText(gc
, name
, _rect1
, true) + 8;
1000 if (_rect1
.width
> 0 && !group
) {
1001 Utils
.init(_rect1
, rect
);
1002 _rect1
.x
+= leftMargin
+ textWidth
;
1003 _rect1
.width
-= textWidth
;
1004 gc
.setForeground(_colors
.getColor(TraceColorScheme
.MID_LINE
));
1005 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1006 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1008 // gc.drawLine(_rect1.x + _rect1.width - 1, _rect1.y, _rect1.x +
1009 // _rect1.width - 1, _rect1.y + _rect1.height);
1012 void drawItemData(Item item
, Rectangle rect
, long time0
, long time1
,
1013 long endTime
, long selectedTime
, GC gc
) {
1016 if (time1
<= time0
) {
1017 gc
.setBackground(_colors
.getBkColor(false, false, false));
1018 gc
.fillRectangle(rect
);
1022 Utils
.init(_rect1
, rect
);
1023 boolean selected
= item
._selected
;
1024 double K
= (double) rect
.width
/ (time1
- time0
);
1025 boolean group
= item
instanceof GroupItem
;
1028 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1029 // gc.fillRectangle(rect);
1030 } else if (item
instanceof TraceItem
) {
1031 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1034 List
<TimeEvent
> list
= trace
.getTraceEvents();
1035 // Iterator it = list.iterator();
1036 int count
= list
.size();
1037 ITimeEvent lastEvent
= null;
1039 ITimeEvent currEvent
= list
.get(0);
1040 ITimeEvent nextEvent
= null;
1041 long currEventTime
= currEvent
.getTime();
1042 long nextEventTime
= currEventTime
;
1043 x0
= rect
.x
+ (int) ((currEventTime
- time0
) * K
);
1044 int xEnd
= rect
.x
+ (int) ((time1
- time0
) * K
);
1051 fillSpace(rect
, gc
, selected
, _rect1
.x
, x0
, xEnd
);
1053 // draw event states
1054 while (x0
<= xEnd
&& null != currEvent
) {
1055 boolean stopped
= false;// currEvent instanceof
1056 // TsfTmTraceDeadEvent;
1058 nextEvent
= list
.get(idx
);
1059 nextEventTime
= nextEvent
.getTime();
1061 } else if (stopped
) {
1063 nextEventTime
= time1
;
1066 nextEventTime
= endTime
;
1068 x1
= rect
.x
+ (int) ((nextEventTime
- time0
) * K
);
1070 _rect1
.x
= x0
>= rect
.x ? x0
: rect
.x
;
1071 _rect1
.width
= (x1
<= xEnd ? x1
: xEnd
) - _rect1
.x
;
1072 boolean timeSelected
= currEventTime
<= selectedTime
1073 && selectedTime
< nextEventTime
;
1074 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1075 // + _rect1.y + "," + _rect1.height + ", "
1076 // + _rect1.width + "-->"
1077 // + ((int) _rect1.x + (int) _rect1.width));
1078 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1079 selected
, false, timeSelected
);
1081 lastEvent
= currEvent
;
1082 currEvent
= nextEvent
;
1083 currEventTime
= nextEventTime
;
1088 // fill space after last event
1089 int xEnd
= rect
.x
+ rect
.width
;
1091 _rect1
.x
= x0
>= rect
.x ? x0
: rect
.x
;
1092 _rect1
.width
= xEnd
- _rect1
.x
;
1093 gc
.setBackground(_colors
1094 .getBkColor(selected
, _isInFocus
, false));
1095 gc
.fillRectangle(_rect1
);
1097 gc
.setForeground(_colors
.getColor(utilImpl
1098 .getEventColorVal(lastEvent
)));
1099 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1100 int lw
= gc
.getLineWidth();
1102 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1103 gc
.setLineWidth(lw
);
1107 Utils
.init(_rect1
, rect
);
1108 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1110 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1112 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1114 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1115 y
= _rect1
.y
+ _rect1
.height
- 1;
1116 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1118 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1120 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1123 // draw selected time
1124 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1125 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1126 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1128 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1131 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1136 * Represent the event in series of bursts rather than sequence of states
1140 * - The container rectangle to be colored to different states
1142 * - Base time of all events
1144 * - End time of all events
1146 * @param selectedTime
1149 void drawItemDataBurst(Item item
, Rectangle rect
, long time0
, long time1
,
1150 long endTime
, long selectedTime
, GC gc
) {
1153 if (time1
<= time0
) {
1154 gc
.setBackground(_colors
.getBkColor(false, false, false));
1155 gc
.fillRectangle(rect
);
1159 // Initialize _rect1 to same values as enclosing rectangle rect
1160 Utils
.init(_rect1
, rect
);
1161 boolean selected
= item
._selected
;
1162 // K pixels per second
1163 double K
= (double) rect
.width
/ (time1
- time0
);
1164 // Trace.debug("Value of K: " + K + " width:" + rect.width + " time0: "
1165 // + time0 + " time1:" + time1 + " endTime: " + endTime);
1167 boolean group
= item
instanceof GroupItem
;
1170 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1171 // gc.fillRectangle(rect);
1172 // if (Trace.isDEBUG()) {
1173 // Trace.debug("Group");
1175 } else if (item
instanceof TraceItem
) {
1176 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1179 List
<TimeEvent
> list
= trace
.getTraceEvents();
1180 // Iterator it = list.iterator();
1181 int count
= list
.size();
1182 ITimeEvent lastEvent
= null;
1183 // Trace.debug("count is: " + count);
1185 ITimeEvent currEvent
= list
.get(0);
1186 ITimeEvent nextEvent
= null;
1187 long currEventTime
= currEvent
.getTime();
1188 long nextEventTime
= currEventTime
;
1189 // x0 - Points to the beginning of the event being drawn
1190 double step
= (double) ((currEventTime
- time0
) * K
);
1192 // xEnd - Points to the end of the events rectangle
1193 double xEnd
= rect
.x
+ (double) ((time1
- time0
) * K
);
1198 // Drawing rectangle is smaller than reserved space
1202 // Clean up to empty line to draw on top
1203 fillSpace(rect
, gc
, selected
, _rect1
.x
, xEnd
, xEnd
);
1204 // draw event states
1205 while (x0
<= xEnd
&& null != currEvent
) {
1206 boolean stopped
= false;// currEvent instanceof
1207 // TsfTmTraceDeadEvent;
1209 nextEvent
= list
.get(idx
);
1210 nextEventTime
= nextEvent
.getTime();
1212 } else if (stopped
) {
1214 nextEventTime
= time1
;
1217 nextEventTime
= endTime
;
1219 // .debug("nexEventTime is endTime: "
1220 // + nextEventTime);
1223 // Draw it as a burst, one unit of width.
1225 if (x1
>= rect
.x
&& x0
<= xEnd
) {
1226 // Fill with space until x0
1227 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1228 _rect1
.width
= (int) ((x1
<= xEnd ? x1
: xEnd
) - _rect1
.x
);
1229 boolean timeSelected
= currEventTime
<= selectedTime
1230 && selectedTime
< nextEventTime
;
1231 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1232 selected
, false, timeSelected
);
1233 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1234 // + _rect1.y + "," + _rect1.height + ", "
1235 // + _rect1.width + "-->"
1236 // + ((int) _rect1.x + (int) _rect1.width));
1237 // Advance rectangle to next start position and Fill
1238 // with space until next event
1239 _rect1
.x
+= _rect1
.width
;
1241 xNext
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1243 // Fill space till next event
1244 fillSpace(rect
, gc
, selected
, x0
, xNext
, xEnd
);
1246 lastEvent
= currEvent
;
1247 currEvent
= nextEvent
;
1248 currEventTime
= nextEventTime
;
1249 // Move x0 to the beginning of next event
1250 x0
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1251 // Trace.debug("rect.x: " + rect.x + " + " +
1252 // "(nextEvenTime: "
1253 // + nextEventTime + "- time0: " + time0 + ") * K: "
1254 // + K + " = " + x0);
1258 // fill space after last event
1259 int xEnd
= rect
.x
+ rect
.width
;
1261 // Trace.debug("Space after last event, x0: " + x0 + ", xEnd: "
1263 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1264 _rect1
.width
= xEnd
- _rect1
.x
;
1265 gc
.setBackground(_colors
1266 .getBkColor(selected
, _isInFocus
, false));
1267 gc
.fillRectangle(_rect1
);
1269 gc
.setForeground(_colors
.getColor(utilImpl
1270 .getEventColorVal(lastEvent
)));
1271 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1272 int lw
= gc
.getLineWidth();
1274 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1275 gc
.setLineWidth(lw
);
1279 Utils
.init(_rect1
, rect
);
1280 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1282 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1284 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1286 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1287 y
= _rect1
.y
+ _rect1
.height
- 1;
1288 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1290 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1292 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1295 // draw selected time
1296 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1297 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1298 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1300 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1303 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1308 * Represent the series of events with specified durations
1312 * - The container rectangle to be colored to different states
1314 * - Base time of all events - start of visible window
1316 * - End time of visible events - end time of visible window
1318 * - End time of all events - may not be visible in selected
1320 * @param selectedTime
1323 void drawItemDataDurations(Item item
, Rectangle rect
, long time0
,
1324 long time1
, long endTime
, long selectedTime
, GC gc
) {
1327 if (time1
<= time0
) {
1328 gc
.setBackground(_colors
.getBkColor(false, false, false));
1329 gc
.fillRectangle(rect
);
1333 // Initialize _rect1 to same values as enclosing rectangle rect
1334 Utils
.init(_rect1
, rect
);
1335 boolean selected
= item
._selected
;
1336 // K pixels per second
1337 double K
= (double) rect
.width
/ (time1
- time0
);
1338 // Trace.debug("Value of K: " + K + " width:" + rect.width + " time0: "
1339 // + time0 + " time1:" + time1 + " endTime: " + endTime);
1341 boolean group
= item
instanceof GroupItem
;
1344 // gc.setBackground(_colors.getBkColorGroup(selected, _isInFocus));
1345 // gc.fillRectangle(rect);
1346 // if (Trace.isDEBUG()) {
1347 // Trace.debug("\n\t\t\tGroup: " + ((GroupItem) item)._name);
1349 } else if (item
instanceof TraceItem
) {
1350 ITmfTimeAnalysisEntry trace
= ((TraceItem
) item
)._trace
;
1353 List
<TimeEvent
> list
= trace
.getTraceEvents();
1354 // Iterator it = list.iterator();
1355 int count
= list
.size();
1356 ITimeEvent lastEvent
= null;
1357 // if (Trace.isDEBUG()) {
1358 // Trace.debug("\n\t\t\tTrace: " + trace.getName()
1359 // + utilImpl.getTraceClassName(trace));
1361 // Trace.debug("count is: " + count);
1363 ITimeEvent currEvent
= list
.get(0);
1364 ITimeEvent nextEvent
= null;
1365 long currEventTime
= currEvent
.getTime();
1366 long currEventDuration
= currEvent
.getDuration();
1368 long nextEventTime
= currEventTime
;
1369 // x0 - Points to the beginning of the event being drawn
1370 double step
= (double) ((currEventTime
- time0
) * K
);
1372 // xEnd - Points to the end of the events rectangle
1373 double xEnd
= rect
.x
+ (double) ((time1
- time0
) * K
);
1378 // Drawing rectangle is smaller than reserved space
1382 // Clean up to empty line to draw on top
1383 fillSpace(rect
, gc
, selected
, _rect1
.x
, xEnd
, xEnd
);
1384 // draw event states
1385 while (x0
<= xEnd
&& null != currEvent
) {
1386 boolean stopped
= false;// currEvent instanceof
1387 // refresh current event duration as the loop moves
1388 currEventDuration
= currEvent
.getDuration();
1389 // TsfTmTraceDeadEvent;
1391 nextEvent
= list
.get(idx
);
1392 nextEventTime
= nextEvent
.getTime();
1394 } else if (stopped
) {
1396 nextEventTime
= time1
;
1399 nextEventTime
= endTime
;
1401 // .debug("nexEventTime is endTime: "
1402 // + nextEventTime);
1405 // Calculate position to next event
1406 xNext
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1408 // Calculate end position of current event
1409 if (currEventDuration
< 0) {
1410 x1
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1412 x1
= currEventDuration
== 0 ?
(x0
+ 2)
1413 : (x0
+ (double) ((currEventDuration
) * K
));
1416 // If event end position x1 further away than start position
1418 // next event, cut width till next event
1419 // Trace.debug("Next Event Pos: " + xNext
1420 // + " End Of Current at: " + x1 + " Event Duration: "
1421 // + currEventDuration);
1422 x1
= x1
> xNext ? xNext
: x1
;
1423 // if event end boundary is within time range
1424 if (x1
>= rect
.x
&& x0
<= xEnd
) {
1425 // Fill with space until x0
1426 x0
= (double) (x0
>= rect
.x ? x0
: rect
.x
);
1427 _rect1
.width
= (int) ((x1
<= xEnd ? x1
: xEnd
) - x0
);
1428 _rect1
.x
= (int) x0
;
1429 boolean timeSelected
= currEventTime
<= selectedTime
1430 && selectedTime
< nextEventTime
;
1431 utilImpl
.drawState(_colors
, currEvent
, _rect1
, gc
,
1432 selected
, false, timeSelected
);
1433 // Trace.debug("Drawing rectangle: " + _rect1.x + ","
1434 // + _rect1.y + "," + _rect1.height + ", "
1435 // + _rect1.width + "-->"
1436 // + ((int) _rect1.x + (int) _rect1.width));
1437 // Advance rectangle to next start position and Fill
1438 // with space until next event
1439 _rect1
.x
+= _rect1
.width
;
1443 // Fill space till next event
1444 fillSpace(rect
, gc
, selected
, x0
, xNext
, xEnd
);
1446 lastEvent
= currEvent
;
1447 currEvent
= nextEvent
;
1448 currEventTime
= nextEventTime
;
1449 // Move x0 to the beginning of next event
1450 x0
= rect
.x
+ (double) ((nextEventTime
- time0
) * K
);
1451 // Trace.debug("rect.x: " + rect.x + " + " +
1452 // "(nextEvenTime: "
1453 // + nextEventTime + "- time0: " + time0 + ") * K: "
1454 // + K + " = " + x0);
1458 // fill space after last event
1459 int xEnd
= rect
.x
+ rect
.width
;
1461 // Trace.debug("Space after last event, x0: " + x0 + ", xEnd: "
1463 _rect1
.x
= (int) (x0
>= rect
.x ? x0
: rect
.x
);
1464 _rect1
.width
= xEnd
- _rect1
.x
;
1465 gc
.setBackground(_colors
1466 .getBkColor(selected
, _isInFocus
, false));
1467 gc
.fillRectangle(_rect1
);
1469 gc
.setForeground(_colors
.getColor(utilImpl
1470 .getEventColorVal(lastEvent
)));
1471 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1472 int lw
= gc
.getLineWidth();
1474 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1475 gc
.setLineWidth(lw
);
1479 Utils
.init(_rect1
, rect
);
1480 gc
.setForeground(_colors
.getBkColor(selected
, _isInFocus
, false));
1482 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1484 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1486 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1487 y
= _rect1
.y
+ _rect1
.height
- 1;
1488 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1490 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1492 gc
.drawLine(_rect1
.x
, y
, _rect1
.x
+ _rect1
.width
, y
);
1495 // draw selected time
1496 int x
= rect
.x
+ (int) ((selectedTime
- time0
) * K
);
1497 if (x
>= rect
.x
&& x
< rect
.x
+ rect
.width
) {
1498 gc
.setForeground(_colors
.getColor(TraceColorScheme
.SELECTED_TIME
));
1500 gc
.drawLine(x
, rect
.y
+ rect
.height
- 1, x
, rect
.y
1503 gc
.drawLine(x
, rect
.y
, x
, rect
.y
+ rect
.height
);
1507 private void fillSpace(Rectangle rect
, GC gc
, boolean selected
, double x0
,
1508 double x1
, double xEnd
) {
1509 // fill space before first event
1510 if (x0
>= rect
.x
&& x0
< xEnd
) {
1511 // _rect1.width = (int) ((x1 <= xEnd ? x1 : xEnd) - x0);
1512 // Trace.debug("Drawing Space: " + _rect1.x + "," + _rect1.y + ","
1513 // + _rect1.height + ", " + _rect1.width + "--> "
1514 // + ((int) _rect1.x + (int) _rect1.width));
1516 // if (_rect1.width < 0) {
1517 // Trace.debug("Incorrect width:" + _rect1.width);
1519 gc
.setBackground(_colors
.getBkColor(selected
, _isInFocus
, false));
1520 gc
.fillRectangle(_rect1
);
1522 gc
.setForeground(_colors
.getColor(TraceColorScheme
.MID_LINE
));
1523 int midy
= _rect1
.y
+ _rect1
.height
/ 2;
1524 gc
.drawLine(_rect1
.x
, midy
, _rect1
.x
+ _rect1
.width
, midy
);
1526 // Trace.debug("No space added since, x0 is out of range " + x0
1527 // + " rect.x: " + rect.x + " xEnd: " + xEnd);
1531 public void keyTraversed(TraverseEvent e
) {
1532 if ((e
.detail
== SWT
.TRAVERSE_TAB_NEXT
)
1533 || (e
.detail
== SWT
.TRAVERSE_TAB_PREVIOUS
))
1537 public void keyPressed(KeyEvent e
) {
1539 if (SWT
.HOME
== e
.keyCode
) {
1540 idx
= getTopIndex();
1541 } else if (SWT
.END
== e
.keyCode
) {
1542 idx
= getBottomIndex();
1543 } else if (SWT
.ARROW_DOWN
== e
.keyCode
) {
1544 idx
= getSelectedIndex();
1547 else if (idx
< _data
._items
.length
- 1)
1549 } else if (SWT
.ARROW_UP
== e
.keyCode
) {
1550 idx
= getSelectedIndex();
1555 } else if (SWT
.ARROW_LEFT
== e
.keyCode
) {
1557 } else if (SWT
.ARROW_RIGHT
== e
.keyCode
) {
1559 } else if (SWT
.PAGE_DOWN
== e
.keyCode
) {
1560 int page
= countPerPage();
1561 idx
= getSelectedIndex();
1565 if (idx
>= _data
._items
.length
)
1566 idx
= _data
._items
.length
- 1;
1567 } else if (SWT
.PAGE_UP
== e
.keyCode
) {
1568 int page
= countPerPage();
1569 idx
= getSelectedIndex();
1575 } else if (SWT
.CR
== e
.keyCode
) {
1576 idx
= getSelectedIndex();
1578 if (_data
._items
[idx
] instanceof TraceItem
)
1579 fireDefaultSelection();
1580 else if (_data
._items
[idx
] instanceof GroupItem
)
1586 selectItem(idx
, false);
1587 fireSelectionChanged();
1591 public void keyReleased(KeyEvent e
) {
1594 public void focusGained(FocusEvent e
) {
1599 public void focusLost(FocusEvent e
) {
1601 if (0 != _dragState
) {
1608 public boolean isInFocus() {
1612 public void mouseMove(MouseEvent e
) {
1613 if (null == _timeProvider
)
1615 Point size
= getCtrlSize();
1616 if (1 == _dragState
) {
1617 int nameWidth
= _timeProvider
.getNameSpace();
1618 int x
= e
.x
- nameWidth
;
1619 if (x
> 0 && size
.x
> nameWidth
&& _dragX
!= x
) {
1621 double K
= (double) (size
.x
- nameWidth
)
1622 / (_time1bak
- _time0bak
);
1623 long timeDelta
= (long) ((_dragX
- _dragX0
) / K
);
1624 long time1
= _time1bak
- timeDelta
;
1625 long maxTime
= _timeProvider
.getMaxTime();
1626 if (time1
> maxTime
)
1628 long time0
= time1
- (_time1bak
- _time0bak
);
1629 if (time0
< _timeProvider
.getMinTime()) {
1630 time0
= _timeProvider
.getMinTime();
1631 time1
= time0
+ (_time1bak
- _time0bak
);
1633 _timeProvider
.setStartFinishTime(time0
, time1
);
1635 } else if (3 == _dragState
) {
1637 _timeProvider
.setNameSpace(_hitIdx
+ _dragX
- _dragX0
);
1638 } else if (0 == _dragState
) {
1639 boolean mouseHover
= hitSplitTest(e
.x
, e
.y
) > 0;
1640 if (_mouseHover
!= mouseHover
)
1642 _mouseHover
= mouseHover
;
1644 updateCursor(e
.x
, e
.y
);
1647 public void mouseDoubleClick(MouseEvent e
) {
1648 if (null == _timeProvider
)
1650 if (1 == e
.button
) {
1651 int idx
= hitSplitTest(e
.x
, e
.y
);
1653 _timeProvider
.setNameSpace(_idealNameWidth
+ 3 * MARGIN
1657 idx
= hitTest(e
.x
, e
.y
);
1659 selectItem(idx
, false);
1660 if (_data
._items
[idx
] instanceof TraceItem
) {
1661 fireDefaultSelection();
1669 * If the x, y position is over the vertical split line (name to time
1670 * ranges), then change the cursor to a drag cursor to indicate the user the
1671 * possibility of resizing
1677 void updateCursor(int x
, int y
) {
1678 // if Wait cursor not active, check for the need to change to a drag
1680 if (_isWaitCursor
== false) {
1681 int idx
= hitSplitTest(x
, y
);
1682 // No dragcursor is name space is fixed to zero
1683 if (idx
> 0 && !_isDragCursor3
&& _timeProvider
.getNameSpace() > 0) {
1684 setCursor(_dragCursor3
);
1685 _isDragCursor3
= true;
1686 } else if (idx
<= 0 && _isDragCursor3
) {
1688 _isDragCursor3
= false;
1694 * Provide the possibilty to control the wait cursor externally e.g. data
1695 * requests in progress
1699 public void waitCursor(boolean waitInd
) {
1700 // Update cursor as indicated
1702 setCursor(_WaitCursor
);
1703 _isWaitCursor
= true;
1706 _isWaitCursor
= false;
1709 // Get ready for next mouse move
1710 _isDragCursor3
= false;
1713 public void mouseDown(MouseEvent e
) {
1714 if (null == _timeProvider
)
1717 if (1 == e
.button
) {
1718 int namewidth
= _timeProvider
.getNameSpace();
1719 if (namewidth
!= 0) {
1720 idx
= hitSplitTest(e
.x
, e
.y
);
1723 _dragX
= _dragX0
= e
.x
;
1724 _hitIdx
= _timeProvider
.getNameSpace();
1726 _time0bak
= _timeProvider
.getTime0();
1727 _time1bak
= _timeProvider
.getTime1();
1733 idx
= hitTest(e
.x
, e
.y
);
1735 if (_data
._items
[idx
] instanceof TraceItem
) {
1736 long hitTime
= hitTimeTest(e
.x
, e
.y
);
1738 _timeProvider
.setSelectedTimeInt(hitTime
, false);
1741 _dragX
= _dragX0
= e
.x
- _timeProvider
.getNameSpace();
1742 _time0bak
= _timeProvider
.getTime0();
1743 _time1bak
= _timeProvider
.getTime1();
1745 } else if (_data
._items
[idx
] instanceof GroupItem
) {
1749 selectItem(idx
, false);
1750 fireSelectionChanged();
1755 public void mouseUp(MouseEvent e
) {
1756 if (0 != _dragState
) {
1758 if (2 == _dragState
) {
1759 if (hitTest(e
.x
, e
.y
) == _hitIdx
)
1761 } else if (3 == _dragState
) {
1768 public void controlMoved(ControlEvent e
) {
1771 public void controlResized(ControlEvent e
) {
1775 public void widgetDefaultSelected(SelectionEvent e
) {
1778 public void widgetSelected(SelectionEvent e
) {
1779 if (e
.widget
== getVerticalBar()) {
1780 _topItem
= getVerticalBar().getSelection();
1784 } else if (e
.widget
== getHorizontalBar() && null != _timeProvider
) {
1785 int startTime
= getHorizontalBar().getSelection();
1786 long time0
= _timeProvider
.getTime0();
1787 long time1
= _timeProvider
.getTime1();
1788 long timeMin
= _timeProvider
.getMinTime();
1789 long timeMax
= _timeProvider
.getMaxTime();
1790 long delta
= timeMax
- timeMin
;
1792 long range
= time1
- time0
;
1793 // _timeRangeFixed = true;
1794 time0
= timeMin
+ (long) ((double) (startTime
* _timeStep
) * delta
);
1795 time1
= time0
+ range
;
1796 // Trace.debug("\nstartTime:" + startTime + " time0:" + time0
1797 // + " time1:" + time1 + " Delta:" + delta);
1798 _timeProvider
.setStartFinishTime(time0
, time1
);
1802 public void mouseEnter(MouseEvent e
) {
1805 public void mouseExit(MouseEvent e
) {
1807 _mouseHover
= false;
1812 public void mouseHover(MouseEvent e
) {
1815 public void mouseScrolled(MouseEvent e
) {
1818 } else if (e
.count
< 0) {
1823 public boolean isVisibleVerticalScroll() {
1824 return _visibleVerticalScroll
;
1827 public void setVisibleVerticalScroll(boolean visibleVerticalScroll
) {
1828 ScrollBar scrollVer
= getVerticalBar();
1829 if (scrollVer
!= null) {
1830 scrollVer
.setVisible(visibleVerticalScroll
);
1832 this._visibleVerticalScroll
= visibleVerticalScroll
;
1836 public int getBorderWidth() {
1837 return _borderWidth
;
1840 public void setBorderWidth(int borderWidth
) {
1841 this._borderWidth
= borderWidth
;
1844 public int getHeaderHeight() {
1845 return _headerHeight
;
1848 public void setHeaderHeight(int headerHeight
) {
1849 this._headerHeight
= headerHeight
;
1852 public int getItemHeight() {
1856 public void setItemHeight(int rowHeight
) {
1857 this._itemHeight
= rowHeight
;
1860 public Vector
<ITmfTimeAnalysisEntry
> getFilteredOut() {
1861 return _data
.getFilteredOut();
1865 public void addSelectionChangedListener(ISelectionChangedListener listener
) {
1866 if (listener
!= null) {
1867 if (!_selectionChangedListeners
.contains(listener
)) {
1868 _selectionChangedListeners
.add(listener
);
1874 public void removeSelectionChangedListener(
1875 ISelectionChangedListener listener
) {
1876 if (listener
!= null) {
1877 _selectionChangedListeners
.remove(listener
);
1882 public void setSelection(ISelection selection
) {
1883 if (selection
instanceof PlainSelection
) {
1884 PlainSelection sel
= (PlainSelection
) selection
;
1885 Object ob
= sel
.getFirstElement();
1886 if (ob
instanceof ITmfTimeAnalysisEntry
) {
1887 ITmfTimeAnalysisEntry trace
= (ITmfTimeAnalysisEntry
) ob
;
1888 selectItem(trace
, false);
1896 public boolean _expanded
;
1897 public boolean _selected
;
1898 public boolean _hasChildren
;
1899 public String _name
;
1906 public String
toString() {
1911 class TraceItem
extends Item
{
1912 public ITmfTimeAnalysisEntry _trace
;
1914 TraceItem(ITmfTimeAnalysisEntry trace
, String name
) {
1920 class GroupItem
extends Item
{
1921 public List
<ITmfTimeAnalysisEntry
> _traces
;
1923 GroupItem(String name
) {
1925 _traces
= new ArrayList
<ITmfTimeAnalysisEntry
>();
1926 _hasChildren
= true;
1929 void add(ITmfTimeAnalysisEntry trace
) {
1935 public Object
[] _items
= new Object
[0];
1936 private Object _traces
[] = new Object
[0];
1937 private boolean traceFilter
[] = new boolean[0];
1938 private Map
<String
, GroupItem
> _groupTable
= new HashMap
<String
, GroupItem
>();
1939 private boolean _flatList
= false;
1940 private TmfTimeAnalysisProvider utilsImp
;
1941 private Vector
<ITmfTimeAnalysisEntry
> filteredOut
= new Vector
<ITmfTimeAnalysisEntry
>();
1943 public ItemData(TmfTimeAnalysisProvider utils
) {
1944 this.utilsImp
= utils
;
1947 protected void groupTraces(boolean on
) {
1948 if (_flatList
== on
) {
1954 void clearGroups() {
1955 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
1956 while (it
.hasNext()) {
1957 GroupItem group
= it
.next();
1958 group
._traces
.clear();
1962 void deleteEmptyGroups() {
1963 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
1964 while (it
.hasNext()) {
1965 GroupItem group
= it
.next();
1966 if (group
._traces
.size() == 0)
1971 TraceItem
findTraceItem(ITmfTimeAnalysisEntry trace
) {
1975 int traceId
= trace
.getId();
1976 TraceItem traceItem
= null;
1978 for (int i
= 0; i
< _items
.length
; i
++) {
1979 Object item
= _items
[i
];
1980 if (item
instanceof TraceItem
) {
1981 TraceItem ti
= (TraceItem
) item
;
1982 if (ti
._trace
.getId() == traceId
) {
1992 Integer
findTraceItemIndex(ITmfTimeAnalysisEntry trace
) {
1996 int traceId
= trace
.getId();
1999 for (int i
= 0; i
< _items
.length
; i
++) {
2001 Object item
= _items
[i
];
2002 if (item
instanceof TraceItem
) {
2003 TraceItem ti
= (TraceItem
) item
;
2004 if (ti
._trace
.getId() == traceId
) {
2013 public void updateItems() {
2014 List
<Item
> itemList
= new ArrayList
<Item
>();
2017 Iterator
<GroupItem
> it
= _groupTable
.values().iterator();
2018 while (it
.hasNext()) {
2019 GroupItem group
= it
.next();
2021 itemList
.add(group
);
2023 if (_flatList
|| group
._expanded
) {
2024 Iterator
<ITmfTimeAnalysisEntry
> it2
= group
._traces
.iterator();
2025 while (it2
.hasNext()) {
2026 ITmfTimeAnalysisEntry trace
= it2
.next();
2027 TraceItem traceItem
= findTraceItem(trace
);
2028 name
= utilsImp
.composeTraceName(trace
, false);
2029 traceItem
= new TraceItem(trace
, name
);
2030 itemList
.add(traceItem
);
2034 _items
= itemList
.toArray();
2037 public int expandItem(int idx
, boolean expand
) {
2038 if (idx
< 0 || idx
>= _items
.length
)
2041 Item item
= (Item
) _items
[idx
];
2042 if (item
._hasChildren
&& !item
._expanded
) {
2043 item
._expanded
= expand
;
2044 ret
= _items
.length
;
2046 ret
= _items
.length
- ret
;
2051 public void refreshData(Object traces
[]) {
2052 if (traces
== null || traces
.length
== 0) {
2054 } else if (traceFilter
== null || traces
.length
!= traceFilter
.length
) {
2055 traceFilter
= new boolean[traces
.length
];
2056 java
.util
.Arrays
.fill(traceFilter
, true);
2064 * Allows to update the GUI from a stream of events handling addition one by
2065 * one over known TmfTaTrace parents.
2070 public void refreshPartial(ITmfTimeAnalysisEntry parent
, TimeEvent childItem
) {
2071 // Find the Trace item within the current list
2072 TraceItem item
= findTraceItem(parent
);
2075 // If the parent item is not found, make room for it in the current
2079 if (_traces
!= null) {
2080 length
= _traces
.length
+ 1;
2081 traces
= Arrays
.copyOf(_traces
, length
);
2083 traces
= new Object
[length
];
2086 // Add the new parent element to the end of the array.
2087 traces
[length
- 1] = parent
;
2089 // update the filter array to accomodate a postion to the new
2091 traceFilter
= new boolean[traces
.length
];
2092 java
.util
.Arrays
.fill(traceFilter
, true);
2094 // rebuild internal data
2098 // item must be there
2099 item
= findTraceItem(parent
);
2102 ITmfTimeAnalysisEntry localTraceItem
= item
._trace
;
2103 // Local trace found
2104 Vector
<TimeEvent
> children
= localTraceItem
.getTraceEvents();
2105 TimeEvent lastChildIn
= children
.lastElement();
2106 long lastChildSTime
= lastChildIn
.getTime();
2107 long newChildSTime
= childItem
.getTime();
2108 if (newChildSTime
< lastChildSTime
) {
2109 // The children are expected to arrive sorted by time
2110 // since the new time is earlier than the last child
2111 // The infomation is being refreshed from start, remove all
2112 // children and start over
2116 children
.add(childItem
);
2120 public void refreshData() {
2122 filteredOut
.clear();
2123 String undef
= Messages
._UNDEFINED_GROUP
;
2124 List
<GroupItem
> groupList
= new ArrayList
<GroupItem
>();
2125 for (int i
= 0; i
< _traces
.length
; i
++) {
2126 ITmfTimeAnalysisEntry trace
= (ITmfTimeAnalysisEntry
) _traces
[i
];
2127 if (!traceFilter
[i
]) {
2128 filteredOut
.add(trace
);
2132 String groupName
= trace
.getGroupName();
2133 if (null == groupName
)
2136 GroupItem group
= _groupTable
.get(groupName
);
2137 if (null == group
) {
2138 group
= new GroupItem(NLS
.bind(Messages
._TRACE_GROUP_LABEL
,
2140 group
._expanded
= !groupName
.equalsIgnoreCase("system")
2141 && !groupName
.equalsIgnoreCase(undef
);
2142 _groupTable
.put(groupName
, group
);
2143 groupList
.add(group
);
2148 deleteEmptyGroups();
2152 public Object
[] getTraces() {
2156 public boolean[] getTraceFilter() {
2160 public Vector
<ITmfTimeAnalysisEntry
> getFilteredOut() {