Bug 378401: Implementation of time graph widget.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / widgets / timegraph / widgets / TimeGraphControl.java
CommitLineData
fb5cad3d
PT
1/*****************************************************************************\r
2 * Copyright (c) 2007, 2008 Intel Corporation, 2009, 2010, 2011, 2012 Ericsson.\r
3 * All rights reserved. This program and the accompanying materials\r
4 * are made available under the terms of the Eclipse Public License v1.0\r
5 * which accompanies this distribution, and is available at\r
6 * http://www.eclipse.org/legal/epl-v10.html\r
7 *\r
8 * Contributors:\r
9 * Intel Corporation - Initial API and implementation\r
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation\r
11 * Alvaro Sanchez-Leon - Updated for TMF\r
12 * Patrick Tasse - Refactoring\r
13 *\r
14 *****************************************************************************/\r
15\r
16package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets;\r
17\r
18import java.util.ArrayList;\r
19import java.util.Iterator;\r
20import java.util.List;\r
21import java.util.Vector;\r
22\r
b83af2c3
PT
23import org.eclipse.jface.resource.JFaceResources;\r
24import org.eclipse.jface.resource.LocalResourceManager;\r
fb5cad3d
PT
25import org.eclipse.jface.viewers.ISelection;\r
26import org.eclipse.jface.viewers.ISelectionChangedListener;\r
27import org.eclipse.jface.viewers.ISelectionProvider;\r
b83af2c3 28import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider;\r
fb5cad3d 29import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphTreeListener;\r
b83af2c3 30import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.StateItem;\r
fb5cad3d
PT
31import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTreeExpansionEvent;\r
32import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent;\r
33import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;\r
34import org.eclipse.swt.SWT;\r
35import org.eclipse.swt.events.ControlEvent;\r
36import org.eclipse.swt.events.ControlListener;\r
37import org.eclipse.swt.events.FocusEvent;\r
38import org.eclipse.swt.events.FocusListener;\r
39import org.eclipse.swt.events.KeyEvent;\r
40import org.eclipse.swt.events.KeyListener;\r
41import org.eclipse.swt.events.MouseEvent;\r
42import org.eclipse.swt.events.MouseListener;\r
43import org.eclipse.swt.events.MouseMoveListener;\r
44import org.eclipse.swt.events.MouseTrackListener;\r
45import org.eclipse.swt.events.MouseWheelListener;\r
46import org.eclipse.swt.events.PaintEvent;\r
47import org.eclipse.swt.events.SelectionEvent;\r
48import org.eclipse.swt.events.SelectionListener;\r
49import org.eclipse.swt.events.TraverseEvent;\r
50import org.eclipse.swt.events.TraverseListener;\r
b83af2c3 51import org.eclipse.swt.graphics.Color;\r
fb5cad3d
PT
52import org.eclipse.swt.graphics.Cursor;\r
53import org.eclipse.swt.graphics.GC;\r
54import org.eclipse.swt.graphics.Image;\r
55import org.eclipse.swt.graphics.Point;\r
56import org.eclipse.swt.graphics.Rectangle;\r
57import org.eclipse.swt.widgets.Composite;\r
b83af2c3 58import org.eclipse.swt.widgets.Display;\r
fb5cad3d
PT
59import org.eclipse.swt.widgets.Event;\r
60import org.eclipse.swt.widgets.Listener;\r
61import org.eclipse.swt.widgets.ScrollBar;\r
62\r
63public class TimeGraphControl extends TimeGraphBaseControl implements FocusListener, KeyListener, MouseMoveListener, MouseListener, MouseWheelListener, ControlListener, SelectionListener, MouseTrackListener, TraverseListener, ISelectionProvider {\r
64\r
65 private static final int DRAG_NONE = 0;\r
66 private static final int DRAG_TRACE_ITEM = 1;\r
67 private static final int DRAG_SPLIT_LINE = 2;\r
68 public static final boolean DEFAULT_DRAW_THREAD_JOIN = true;\r
69 public static final boolean DEFAULT_DRAW_THREAD_WAIT = true;\r
70 public static final boolean DEFAULT_DRAW_THREAD_RELEASE = true;\r
71 public static final int H_SCROLLBAR_MAX = Integer.MAX_VALUE - 1;\r
b83af2c3 72 private static final int CUSTOM_ITEM_HEIGHT = -1; // get item height from provider\r
fb5cad3d
PT
73\r
74 private static final double zoomCoeff = 1.5;\r
75\r
76 private ITimeDataProvider _timeProvider;\r
77 private boolean _isInFocus = false;\r
78 private boolean _isDragCursor3 = false;\r
79 private boolean _isWaitCursor = true;\r
80 private boolean _mouseOverSplitLine = false;\r
b83af2c3 81 private int _itemHeight = CUSTOM_ITEM_HEIGHT;\r
fb5cad3d
PT
82 private int _minimumItemWidth = 0;\r
83 private int _topIndex = 0;\r
84 private int _dragState = DRAG_NONE;\r
85 private int _dragX0 = 0;\r
86 private int _dragX = 0;\r
87 private int _idealNameSpace = 0;\r
88 // private double _timeStep = 10000000;\r
89 private long _time0bak;\r
90 private long _time1bak;\r
b83af2c3 91 private ITimeGraphPresentationProvider fTimeGraphProvider = null;\r
fb5cad3d
PT
92 private ItemData _data = null;\r
93 private List<SelectionListener> _selectionListeners;\r
94 private List<ISelectionChangedListener> _selectionChangedListeners = new ArrayList<ISelectionChangedListener>();\r
95 private List<ITimeGraphTreeListener> _treeListeners = new ArrayList<ITimeGraphTreeListener>();\r
96 private Cursor _dragCursor3;\r
97 private Cursor _WaitCursor;\r
98\r
99 // Vertical formatting formatting for the state control view\r
100 private boolean _visibleVerticalScroll = true;\r
101 private int _borderWidth = 0;\r
102 private int _headerHeight = 0;\r
103\r
104 private Listener mouseScrollFilterListener;\r
105\r
b83af2c3
PT
106 protected LocalResourceManager fResourceManager = new LocalResourceManager(JFaceResources.getResources());\r
107 protected Color[] fEventColorMap = null;\r
108\r
0c779b95
PT
109 private MouseScrollNotifier fMouseScrollNotifier;\r
110 private Object fMouseScrollNotifierLock = new Object();\r
111 private class MouseScrollNotifier extends Thread {\r
112 private final static long DELAY = 400L;\r
113 private final static long POLLING_INTERVAL = 10L;\r
114 private long fLastScrollTime = Long.MAX_VALUE;\r
115\r
116 @Override\r
117 public void run() {\r
118 while ((System.currentTimeMillis() - fLastScrollTime) < DELAY) {\r
119 try {\r
120 Thread.sleep(POLLING_INTERVAL);\r
121 } catch (Exception e) {\r
122 return;\r
123 }\r
124 }\r
125 if (!isInterrupted()) {\r
126 Display.getDefault().asyncExec(new Runnable() {\r
127 @Override\r
128 public void run() {\r
129 if (isDisposed()) {\r
130 return;\r
131 }\r
132 _timeProvider.notifyStartFinishTime();\r
133 }\r
134 });\r
135 }\r
136 synchronized (fMouseScrollNotifierLock) {\r
137 fMouseScrollNotifier = null;\r
138 }\r
139 }\r
140\r
141 public void mouseScrolled() {\r
142 fLastScrollTime = System.currentTimeMillis();\r
143 }\r
144 }\r
145\r
fb5cad3d
PT
146 public TimeGraphControl(Composite parent, TimeGraphColorScheme colors) {\r
147\r
148 super(parent, colors, SWT.NO_BACKGROUND | SWT.H_SCROLL | SWT.DOUBLE_BUFFERED);\r
149\r
150 _data = new ItemData();\r
151\r
152 addFocusListener(this);\r
153 addMouseListener(this);\r
154 addMouseMoveListener(this);\r
155 addMouseTrackListener(this);\r
156 addMouseWheelListener(this);\r
157 addTraverseListener(this);\r
158 addKeyListener(this);\r
159 addControlListener(this);\r
160 ScrollBar scrollHor = getHorizontalBar();\r
161\r
162 if (scrollHor != null) {\r
163 scrollHor.addSelectionListener(this);\r
164 }\r
165\r
166 _dragCursor3 = new Cursor(super.getDisplay(), SWT.CURSOR_SIZEWE);\r
167 _WaitCursor = new Cursor(super.getDisplay(), SWT.CURSOR_WAIT);\r
168 }\r
169\r
170 @Override\r
171 public void dispose() {\r
172 super.dispose();\r
173 _dragCursor3.dispose();\r
174 _WaitCursor.dispose();\r
b83af2c3 175 fResourceManager.dispose();\r
fb5cad3d
PT
176 }\r
177\r
178 /**\r
179 * Sets the timegraph provider used by this timegraph viewer.\r
180 * \r
181 * @param timeGraphProvider the timegraph provider\r
182 */\r
b83af2c3 183 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) {\r
fb5cad3d 184 fTimeGraphProvider = timeGraphProvider;\r
b83af2c3 185 _data.provider = timeGraphProvider;\r
b83af2c3 186\r
e9f70626
PT
187 if (fEventColorMap != null) {\r
188 for (Color color : fEventColorMap) {\r
189 fResourceManager.destroyColor(color.getRGB());\r
190 }\r
191 }\r
b83af2c3
PT
192 StateItem[] stateItems = fTimeGraphProvider.getStateTable();\r
193 if (stateItems != null) {\r
194 fEventColorMap = new Color[stateItems.length];\r
195 for (int i = 0; i < stateItems.length; i++) {\r
196 fEventColorMap[i] = fResourceManager.createColor(stateItems[i].getStateColor());\r
197 }\r
198 } else {\r
199 fEventColorMap = new Color[] { };\r
200 }\r
fb5cad3d
PT
201 }\r
202\r
203 public void setTimeProvider(ITimeDataProvider timeProvider) {\r
204 _timeProvider = timeProvider;\r
205 adjustScrolls();\r
206 redraw();\r
207 }\r
208\r
209 public void addSelectionListener(SelectionListener listener) {\r
210 if (listener == null)\r
211 SWT.error(SWT.ERROR_NULL_ARGUMENT);\r
212 if (null == _selectionListeners)\r
213 _selectionListeners = new ArrayList<SelectionListener>();\r
214 _selectionListeners.add(listener);\r
215 }\r
216\r
217 public void removeSelectionListener(SelectionListener listener) {\r
218 if (null != _selectionListeners)\r
219 _selectionListeners.remove(listener);\r
220 }\r
221\r
222 public void fireSelectionChanged() {\r
223 if (null != _selectionListeners) {\r
224 Iterator<SelectionListener> it = _selectionListeners.iterator();\r
225 while (it.hasNext()) {\r
226 SelectionListener listener = it.next();\r
227 listener.widgetSelected(null);\r
228 }\r
229 }\r
230 }\r
231\r
232 public void fireDefaultSelection() {\r
233 if (null != _selectionListeners) {\r
234 Iterator<SelectionListener> it = _selectionListeners.iterator();\r
235 while (it.hasNext()) {\r
236 SelectionListener listener = it.next();\r
237 listener.widgetDefaultSelected(null);\r
238 }\r
239 }\r
240 }\r
241\r
b83af2c3 242 public ITimeGraphEntry[] getTraces() {\r
fb5cad3d
PT
243 return _data.getTraces();\r
244 }\r
245\r
246 public boolean[] getTraceFilter() {\r
247 return _data.getTraceFilter();\r
248 }\r
249\r
250 public void refreshData() {\r
251 _data.refreshData();\r
252 adjustScrolls();\r
253 redraw();\r
254 }\r
255\r
256 public void refreshData(ITimeGraphEntry traces[]) {\r
257 _data.refreshData(traces);\r
258 adjustScrolls();\r
259 redraw();\r
260 }\r
261\r
262 public void adjustScrolls() {\r
263 if (null == _timeProvider) {\r
264 getHorizontalBar().setValues(0, 1, 1, 1, 1, 1);\r
265 return;\r
266 }\r
267\r
268 // HORIZONTAL BAR\r
269 // Visible window\r
270 long time0 = _timeProvider.getTime0();\r
271 long time1 = _timeProvider.getTime1();\r
272 // Time boundaries\r
273 long timeMin = _timeProvider.getMinTime();\r
274 long timeMax = _timeProvider.getMaxTime();\r
275\r
276 long delta = timeMax - timeMin;\r
277\r
278 int timePos = 0;\r
279 int thumb = H_SCROLLBAR_MAX;\r
280\r
281 if (delta != 0) {\r
282 // Thumb size (page size)\r
283 thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta)));\r
284 // At the beginning of visible window\r
285 timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta));\r
286 }\r
287\r
288 // position, minimum, maximum, thumb size, increment (half page)t, page\r
289 // increment size (full page)\r
290 getHorizontalBar().setValues(timePos, 0, H_SCROLLBAR_MAX, thumb, Math.max(1, thumb / 2), Math.max(2, thumb));\r
291 }\r
292\r
293 boolean ensureVisibleItem(int idx, boolean redraw) {\r
294 boolean changed = false;\r
295 if (idx < 0) {\r
296 for (idx = 0; idx < _data._expandedItems.length; idx++) {\r
297 if (((TimeGraphItem) _data._expandedItems[idx])._selected)\r
298 break;\r
299 }\r
300 }\r
301 if (idx >= _data._expandedItems.length)\r
302 return changed;\r
303 if (idx < _topIndex) {\r
b83af2c3 304 setTopIndex(idx);\r
fb5cad3d
PT
305 //FIXME:getVerticalBar().setSelection(_topItem);\r
306 if (redraw)\r
307 redraw();\r
308 changed = true;\r
309 } else {\r
310 int page = countPerPage();\r
311 if (idx >= _topIndex + page) {\r
b83af2c3 312 setTopIndex(idx - page + 1);\r
fb5cad3d
PT
313 //FIXME:getVerticalBar().setSelection(_topItem);\r
314 if (redraw)\r
315 redraw();\r
316 changed = true;\r
317 }\r
318 }\r
319 return changed;\r
320 }\r
321\r
322 public void setTopIndex(int idx) {\r
323 idx = Math.min(idx, _data._expandedItems.length - countPerPage());\r
324 idx = Math.max(0, idx);\r
325 _topIndex = idx;\r
326 redraw();\r
327 }\r
328\r
329 public void setExpandedState(ITimeGraphEntry entry, boolean expanded) {\r
330 TimeGraphItem item = _data.findItem(entry);\r
331 if (item != null && item._expanded != expanded) {\r
332 item._expanded = expanded;\r
333 _data.updateExpandedItems();\r
334 redraw();\r
335 }\r
336 }\r
337\r
338 public void addTreeListener (ITimeGraphTreeListener listener) {\r
339 if (!_treeListeners.contains(listener)) {\r
340 _treeListeners.add(listener);\r
341 }\r
342 }\r
343\r
344 public void removeTreeListener (ITimeGraphTreeListener listener) {\r
345 if (_treeListeners.contains(listener)) {\r
346 _treeListeners.remove(listener);\r
347 }\r
348 }\r
349\r
350 public void fireTreeEvent(ITimeGraphEntry entry, boolean expanded) {\r
351 TimeGraphTreeExpansionEvent event = new TimeGraphTreeExpansionEvent(this, entry);\r
352 for (ITimeGraphTreeListener listener : _treeListeners) {\r
353 if (expanded) {\r
354 listener.treeExpanded(event);\r
355 } else {\r
356 listener.treeCollapsed(event);\r
357 }\r
358 }\r
359 }\r
360\r
361 @Override\r
362 public ISelection getSelection() {\r
363 TimeGraphSelection sel = new TimeGraphSelection();\r
364 ITimeGraphEntry trace = getSelectedTrace();\r
365 if (null != trace && null != _timeProvider) {\r
366 long selectedTime = _timeProvider.getSelectedTime();\r
367 ITimeEvent event = Utils.findEvent(trace, selectedTime, 0);\r
368 if (event != null)\r
369 sel.add(event);\r
370 else\r
371 sel.add(trace);\r
372 }\r
373 return sel;\r
374 }\r
375\r
376 public ISelection getSelectionTrace() {\r
377 TimeGraphSelection sel = new TimeGraphSelection();\r
378 ITimeGraphEntry trace = getSelectedTrace();\r
379 if (null != trace) {\r
380 sel.add(trace);\r
381 }\r
382 return sel;\r
383 }\r
384\r
3ac6ad1a
BH
385 \r
386 // TODO select implementation for selectTrace\r
387// public void selectTrace(int n) {\r
388// if (n != 1 && n != -1)\r
389// return;\r
390// boolean changed = false;\r
391// int lastSelection = -1;\r
392// for (int i = 0; i < _data._expandedItems.length; i++) {\r
393// TimeGraphItem item = (TimeGraphItem) _data._expandedItems[i];\r
394// if (item._selected) {\r
395// lastSelection = i;\r
396// if (1 == n && i < _data._expandedItems.length - 1) {\r
397// item._selected = false;\r
398// if (item._hasChildren) {\r
399// _data.expandItem(i);\r
400// fireTreeEvent(item._trace, item._expanded);\r
401// }\r
402// item = (TimeGraphItem) _data._expandedItems[i + 1];\r
403// if (item._hasChildren) {\r
404// _data.expandItem(i + 1);\r
405// fireTreeEvent(item._trace, item._expanded);\r
406// item = (TimeGraphItem) _data._expandedItems[i + 2];\r
407// }\r
408// item._selected = true;\r
409// changed = true;\r
410// } else if (-1 == n && i > 0) {\r
411// i--;\r
412// TimeGraphItem prevItem = (TimeGraphItem) _data._expandedItems[i];\r
413// if (prevItem._hasChildren) {\r
414// if (prevItem._expanded) {\r
415// if (i > 0) {\r
416// i--;\r
417// prevItem = (TimeGraphItem) _data._expandedItems[i];\r
418// }\r
419// }\r
420// if (!prevItem._expanded) {\r
421// _data.expandItem(i);\r
422// fireTreeEvent(prevItem._trace, prevItem._expanded);\r
423// prevItem = (TimeGraphItem) _data._expandedItems[i + prevItem.children.size()];\r
424// item._selected = false;\r
425// prevItem._selected = true;\r
426// changed = true;\r
427// }\r
428// } else {\r
429// item._selected = false;\r
430// prevItem._selected = true;\r
431// changed = true;\r
432// }\r
433// }\r
434// break;\r
435// }\r
436// }\r
437// if (lastSelection < 0 && _data._expandedItems.length > 0) {\r
438// TimeGraphItem item = (TimeGraphItem) _data._expandedItems[0];\r
439// if (item._hasChildren) {\r
440// _data.expandItem(0);\r
441// fireTreeEvent(item._trace, item._expanded);\r
442// item = (TimeGraphItem) _data._expandedItems[1];\r
443// item._selected = true;\r
444// changed = true;\r
445// } else {\r
446// item._selected = true;\r
447// changed = true;\r
448// }\r
449// }\r
450// if (changed) {\r
451// ensureVisibleItem(-1, false);\r
452// redraw();\r
453// fireSelectionChanged();\r
454// }\r
455// }\r
456\r
fb5cad3d 457 public void selectTrace(int n) {\r
3ac6ad1a 458 if ((n != 1) && (n != -1)) {\r
fb5cad3d 459 return;\r
3ac6ad1a
BH
460 }\r
461\r
fb5cad3d
PT
462 boolean changed = false;\r
463 int lastSelection = -1;\r
464 for (int i = 0; i < _data._expandedItems.length; i++) {\r
465 TimeGraphItem item = (TimeGraphItem) _data._expandedItems[i];\r
466 if (item._selected) {\r
467 lastSelection = i;\r
3ac6ad1a 468 if ((1 == n) && (i < _data._expandedItems.length - 1)) {\r
fb5cad3d 469 item._selected = false;\r
fb5cad3d 470 item = (TimeGraphItem) _data._expandedItems[i + 1];\r
fb5cad3d
PT
471 item._selected = true;\r
472 changed = true;\r
3ac6ad1a
BH
473 } else if ((-1 == n) && (i > 0)) {\r
474 item._selected = false;\r
475 item = (TimeGraphItem) _data._expandedItems[i - 1];\r
476 item._selected = true;\r
477 changed = true;\r
fb5cad3d
PT
478 }\r
479 break;\r
480 }\r
481 }\r
3ac6ad1a 482\r
fb5cad3d
PT
483 if (lastSelection < 0 && _data._expandedItems.length > 0) {\r
484 TimeGraphItem item = (TimeGraphItem) _data._expandedItems[0];\r
3ac6ad1a
BH
485 item._selected = true;\r
486 changed = true;\r
fb5cad3d 487 }\r
3ac6ad1a 488\r
fb5cad3d
PT
489 if (changed) {\r
490 ensureVisibleItem(-1, false);\r
491 redraw();\r
492 fireSelectionChanged();\r
493 }\r
494 }\r
3ac6ad1a 495 \r
fb5cad3d
PT
496 public void selectEvent(int n) {\r
497 if (null == _timeProvider)\r
498 return;\r
499 ITimeGraphEntry trace = getSelectedTrace();\r
500 if (trace == null)\r
501 return;\r
502 long selectedTime = _timeProvider.getSelectedTime();\r
503 long endTime = _timeProvider.getEndTime();\r
504 ITimeEvent nextEvent;\r
505 if (-1 == n && selectedTime > endTime)\r
506 nextEvent = Utils.findEvent(trace, selectedTime, 0);\r
507 else\r
508 nextEvent = Utils.findEvent(trace, selectedTime, n);\r
509 if (null == nextEvent && -1 == n)\r
510 nextEvent = Utils.getFirstEvent(trace);\r
511 if (null != nextEvent) {\r
512 long nextTime = nextEvent.getTime();\r
513 // If last event detected e.g. going back or not moving to a next\r
514 // event\r
515 if (nextTime <= selectedTime && n == 1) {\r
516 // Select to the end of this last event\r
517 nextTime = nextEvent.getTime() + nextEvent.getDuration();\r
518 // but not beyond the end of the trace\r
519 if (nextTime > endTime) {\r
520 nextTime = endTime;\r
521 }\r
522 }\r
3ac6ad1a 523 _timeProvider.setSelectedTimeNotify(nextTime, true);\r
fb5cad3d
PT
524 fireSelectionChanged();\r
525 } else if (1 == n) {\r
3ac6ad1a 526 _timeProvider.setSelectedTimeNotify(endTime, true);\r
fb5cad3d
PT
527 fireSelectionChanged();\r
528 }\r
529 }\r
530\r
531 public void selectNextEvent() {\r
532 selectEvent(1);\r
533 // Notify if visible time window has been adjusted\r
534 _timeProvider.setStartFinishTimeNotify(_timeProvider.getTime0(), _timeProvider.getTime1());\r
535 }\r
536\r
537 public void selectPrevEvent() {\r
538 selectEvent(-1);\r
539 // Notify if visible time window has been adjusted\r
540 _timeProvider.setStartFinishTimeNotify(_timeProvider.getTime0(), _timeProvider.getTime1());\r
541 }\r
542\r
543 public void selectNextTrace() {\r
544 selectTrace(1);\r
545 }\r
546\r
547 public void selectPrevTrace() {\r
548 selectTrace(-1);\r
549 }\r
550\r
551 /**\r
e9f70626 552 * Zoom based on mouse cursor location with mouse scrolling\r
fb5cad3d 553 * \r
e9f70626 554 * @param zoomIn true to zoom in, false to zoom out\r
fb5cad3d
PT
555 */\r
556 public void zoom(boolean zoomIn) {\r
557 int globalX = getDisplay().getCursorLocation().x;\r
558 Point p = toControl(globalX, 0);\r
559 int nameSpace = _timeProvider.getNameSpace();\r
560 int timeSpace = _timeProvider.getTimeSpace();\r
561 int xPos = Math.max(nameSpace, Math.min(nameSpace + timeSpace, p.x));\r
562 long time0 = _timeProvider.getTime0();\r
563 long time1 = _timeProvider.getTime1();\r
564 long interval = time1 - time0;\r
565 if (interval == 0) {\r
566 interval = 1;\r
567 } // to allow getting out of single point interval\r
568 long newInterval;\r
569 if (zoomIn) {\r
570 newInterval = Math.max(Math.round((double) interval * 0.8), _timeProvider.getMinTimeInterval());\r
571 } else {\r
572 newInterval = (long) Math.ceil((double) interval * 1.25);\r
573 }\r
574 long center = time0 + Math.round(((double) (xPos - nameSpace) / timeSpace * interval));\r
575 long newTime0 = center - Math.round((double) newInterval * (center - time0) / interval);\r
576 long newTime1 = newTime0 + newInterval;\r
577 _timeProvider.setStartFinishTime(newTime0, newTime1);\r
0c779b95
PT
578 synchronized (fMouseScrollNotifierLock) {\r
579 if (fMouseScrollNotifier == null) {\r
580 fMouseScrollNotifier = new MouseScrollNotifier();\r
581 fMouseScrollNotifier.start();\r
582 }\r
583 fMouseScrollNotifier.mouseScrolled();\r
584 }\r
fb5cad3d
PT
585 }\r
586\r
587 /**\r
588 * zoom in using single click\r
589 */\r
590 public void zoomIn() {\r
591 long _time0 = _timeProvider.getTime0();\r
592 long _time1 = _timeProvider.getTime1();\r
593 long _range = _time1 - _time0;\r
594 long selTime = _timeProvider.getSelectedTime();\r
595 if (selTime <= _time0 || selTime >= _time1) {\r
596 selTime = (_time0 + _time1) / 2;\r
597 }\r
598 long time0 = selTime - (long) ((selTime - _time0) / zoomCoeff);\r
599 long time1 = selTime + (long) ((_time1 - selTime) / zoomCoeff);\r
600\r
601 long inaccuracy = (_timeProvider.getMaxTime() - _timeProvider.getMinTime()) - (time1 - time0);\r
602\r
603 // Trace.debug("selTime:" + selTime + " time0:" + time0 + " time1:"\r
604 // + time1 + " inaccuracy:" + inaccuracy);\r
605\r
606 if (inaccuracy > 0 && inaccuracy < 100) {\r
607 _timeProvider.setStartFinishTimeNotify(_timeProvider.getMinTime(), _timeProvider.getMaxTime());\r
608 return;\r
609 }\r
610\r
611 long m = _timeProvider.getMinTimeInterval();\r
612 if ((time1 - time0) < m) {\r
613 time0 = selTime - (long) ((selTime - _time0) * m / _range);\r
614 time1 = time0 + m;\r
615 }\r
616\r
617 _timeProvider.setStartFinishTimeNotify(time0, time1);\r
618 }\r
619\r
620 /**\r
621 * zoom out using single click\r
622 */\r
623 public void zoomOut() {\r
624 long _time0 = _timeProvider.getTime0();\r
625 long _time1 = _timeProvider.getTime1();\r
626 long selTime = _timeProvider.getSelectedTime();\r
627 if (selTime <= _time0 || selTime >= _time1) {\r
628 selTime = (_time0 + _time1) / 2;\r
629 }\r
630 long time0 = (long) (selTime - (selTime - _time0) * zoomCoeff);\r
631 long time1 = (long) (selTime + (_time1 - selTime) * zoomCoeff);\r
632\r
633 long inaccuracy = (_timeProvider.getMaxTime() - _timeProvider.getMinTime()) - (time1 - time0);\r
634 if (inaccuracy > 0 && inaccuracy < 100) {\r
635 _timeProvider.setStartFinishTimeNotify(_timeProvider.getMinTime(), _timeProvider.getMaxTime());\r
636 return;\r
637 }\r
638\r
639 _timeProvider.setStartFinishTimeNotify(time0, time1);\r
640 }\r
641\r
642 public ITimeGraphEntry getSelectedTrace() {\r
643 ITimeGraphEntry trace = null;\r
644 int idx = getSelectedIndex();\r
645 if (idx >= 0)\r
646 trace = _data._expandedItems[idx]._trace;\r
647 return trace;\r
648 }\r
649\r
650 public int getSelectedIndex() {\r
651 int idx = -1;\r
652 for (int i = 0; i < _data._expandedItems.length; i++) {\r
653 TimeGraphItem item = (TimeGraphItem) _data._expandedItems[i];\r
654 if (item._selected) {\r
655 idx = i;\r
656 break;\r
657 }\r
658 }\r
659 return idx;\r
660 }\r
661\r
662 boolean toggle(int idx) {\r
663 boolean toggled = false;\r
664 if (idx >= 0 && idx < _data._expandedItems.length) {\r
665 TimeGraphItem item = (TimeGraphItem) _data._expandedItems[idx];\r
666 if (item._hasChildren) {\r
667 item._expanded = !item._expanded;\r
668 _data.updateExpandedItems();\r
669 adjustScrolls();\r
670 redraw();\r
671 toggled = true;\r
672 fireTreeEvent(item._trace, item._expanded);\r
673 }\r
674 }\r
675 return toggled;\r
676 }\r
677\r
678 int getItemIndexAtY(int y) {\r
679 if (y < 0) {\r
680 return -1;\r
681 }\r
b83af2c3
PT
682 if (_itemHeight == CUSTOM_ITEM_HEIGHT) {\r
683 int ySum = 0;\r
684 for (int idx = _topIndex; idx < _data._expandedItems.length; idx++) {\r
685 ySum += _data._expandedItems[idx].itemHeight;\r
686 if (y < ySum) {\r
687 return idx;\r
688 }\r
689 }\r
690 return -1;\r
691 }\r
fb5cad3d
PT
692 int idx = y / _itemHeight;\r
693 idx += _topIndex;\r
694 if (idx < _data._expandedItems.length) {\r
695 return idx;\r
696 }\r
697 return -1;\r
698 }\r
699\r
700 boolean isOverSplitLine(int x) {\r
701 if (x < 0 || null == _timeProvider)\r
702 return false;\r
703 int w = 4;\r
704 int nameWidth = _timeProvider.getNameSpace();\r
705 if (x > nameWidth - w && x < nameWidth + w) {\r
706 return true;\r
707 } else {\r
708 return false;\r
709 }\r
710 }\r
711\r
712 TimeGraphItem getItem(Point pt) {\r
713 int idx = getItemIndexAtY(pt.y);\r
714 return idx >= 0 ? (TimeGraphItem) _data._expandedItems[idx] : null;\r
715 }\r
716\r
717 long getTimeAtX(int x) {\r
718 if (null == _timeProvider)\r
719 return -1;\r
720 long hitTime = -1;\r
721 Point size = getCtrlSize();\r
722 long time0 = _timeProvider.getTime0();\r
723 long time1 = _timeProvider.getTime1();\r
724 int nameWidth = _timeProvider.getNameSpace();\r
725 x -= nameWidth;\r
1571f4e4 726 int timeWidth = size.x - nameWidth - RIGHT_MARGIN;\r
fb5cad3d 727 if (x >= 0 && size.x >= nameWidth) {\r
1571f4e4 728 if (time1 - time0 > timeWidth) {\r
fb5cad3d 729 // get the last possible time represented by the pixel position\r
1571f4e4
PT
730 // by taking the time of the next pixel position minus 1 nanosecond\r
731 hitTime = time0 + (long) ((time1 - time0) * ((double) (x + 1) / timeWidth)) - 1;\r
fb5cad3d 732 } else {\r
1571f4e4 733 hitTime = time0 + Math.round((time1 - time0) * ((double) x / timeWidth));\r
fb5cad3d
PT
734 }\r
735 }\r
736 return hitTime;\r
737 }\r
738\r
739 void selectItem(int idx, boolean addSelection) {\r
740 boolean changed = false;\r
741 if (addSelection) {\r
742 if (idx >= 0 && idx < _data._expandedItems.length) {\r
743 TimeGraphItem item = (TimeGraphItem) _data._expandedItems[idx];\r
744 changed = (item._selected == false);\r
745 item._selected = true;\r
746 }\r
747 } else {\r
748 for (int i = 0; i < _data._expandedItems.length; i++) {\r
749 TimeGraphItem item = (TimeGraphItem) _data._expandedItems[i];\r
750 if ((i == idx && !item._selected) || (idx == -1 && item._selected)) {\r
751 changed = true;\r
752 }\r
753 item._selected = i == idx;\r
754 }\r
755 }\r
756 changed |= ensureVisibleItem(idx, true);\r
757 if (changed)\r
758 redraw();\r
759 }\r
760\r
761 public void selectItem(ITimeGraphEntry trace, boolean addSelection) {\r
762 int idx = _data.findItemIndex(trace);\r
763 selectItem(idx, addSelection);\r
764 }\r
765\r
766 public int countPerPage() {\r
767 int height = getCtrlSize().y;\r
768 int count = 0;\r
b83af2c3
PT
769 if (_itemHeight == CUSTOM_ITEM_HEIGHT) {\r
770 int ySum = 0;\r
771 for (int idx = _topIndex; idx < _data._expandedItems.length; idx++) {\r
772 ySum += _data._expandedItems[idx].itemHeight;\r
773 if (ySum >= height) {\r
774 return count;\r
775 }\r
776 count++;\r
777 }\r
778 for (int idx = _topIndex - 1; idx >= 0; idx--) {\r
779 ySum += _data._expandedItems[idx].itemHeight;\r
780 if (ySum >= height) {\r
781 return count;\r
782 }\r
783 count++;\r
784 }\r
785 return count;\r
786 }\r
787 if (height > 0) {\r
fb5cad3d 788 count = height / _itemHeight;\r
b83af2c3 789 }\r
fb5cad3d
PT
790 return count;\r
791 }\r
792\r
793 public int getTopIndex() {\r
794 return _topIndex;\r
795 }\r
796\r
797 public int getExpandedElementCount() {\r
798 return _data._expandedItems.length;\r
799 }\r
800\r
549f3c43
PT
801 public ITimeGraphEntry[] getExpandedElements() {\r
802 ArrayList<ITimeGraphEntry> elements = new ArrayList<ITimeGraphEntry>();\r
803 for (TimeGraphItem item : _data._expandedItems) {\r
804 elements.add(item._trace);\r
805 }\r
806 return elements.toArray(new ITimeGraphEntry[0]);\r
807 }\r
808\r
fb5cad3d
PT
809 Point getCtrlSize() {\r
810 Point size = getSize();\r
811 if (getHorizontalBar().isVisible()) {\r
812 size.y -= getHorizontalBar().getSize().y;\r
813 }\r
814 return size;\r
815 }\r
816\r
817 Rectangle getNameRect(Rectangle bound, int idx, int nameWidth) {\r
fb5cad3d 818 int x = bound.x;\r
b83af2c3 819 int y = bound.y + (idx - _topIndex) * _itemHeight;\r
fb5cad3d
PT
820 int width = nameWidth;\r
821 int height = _itemHeight;\r
b83af2c3
PT
822 if (_itemHeight == CUSTOM_ITEM_HEIGHT) {\r
823 int ySum = 0;\r
824 for (int i = _topIndex; i < idx; i++) {\r
825 ySum += _data._expandedItems[i].itemHeight;\r
826 }\r
827 y = bound.y + ySum;\r
828 height = _data._expandedItems[idx].itemHeight;\r
829 }\r
fb5cad3d
PT
830 return new Rectangle(x, y, width, height);\r
831 }\r
832\r
833 Rectangle getStatesRect(Rectangle bound, int idx, int nameWidth) {\r
fb5cad3d 834 int x = bound.x + nameWidth;\r
b83af2c3 835 int y = bound.y + (idx - _topIndex) * _itemHeight;\r
fb5cad3d
PT
836 int width = bound.width - x;\r
837 int height = _itemHeight;\r
b83af2c3
PT
838 if (_itemHeight == CUSTOM_ITEM_HEIGHT) {\r
839 int ySum = 0;\r
840 for (int i = _topIndex; i < idx; i++) {\r
841 ySum += _data._expandedItems[i].itemHeight;\r
842 }\r
843 y = bound.y + ySum;\r
844 height = _data._expandedItems[idx].itemHeight;\r
845 }\r
fb5cad3d
PT
846 return new Rectangle(x, y, width, height);\r
847 }\r
848\r
fb5cad3d
PT
849 @Override\r
850 void paint(Rectangle bounds, PaintEvent e) {\r
851 GC gc = e.gc;\r
852 gc.setBackground(_colors.getColor(TimeGraphColorScheme.BACKGROUND));\r
853 drawBackground(gc, bounds.x, bounds.y, bounds.width, bounds.height);\r
854\r
855 if (bounds.width < 2 || bounds.height < 2 || null == _timeProvider)\r
856 return;\r
857\r
858 _idealNameSpace = 0;\r
859 int nameSpace = _timeProvider.getNameSpace();\r
860\r
861 // draw empty name space background\r
b83af2c3
PT
862 gc.setBackground(_colors.getBkColor(false, false, true));\r
863 drawBackground(gc, bounds.x, bounds.y, nameSpace, bounds.height);\r
fb5cad3d 864\r
b83af2c3 865 drawItems(bounds, _timeProvider, _data._expandedItems, _topIndex, nameSpace, gc);\r
fb5cad3d
PT
866\r
867 // draw selected time\r
868 long time0 = _timeProvider.getTime0();\r
869 long time1 = _timeProvider.getTime1();\r
870 long selectedTime = _timeProvider.getSelectedTime();\r
871 double pixelsPerNanoSec = (bounds.width - nameSpace <= RIGHT_MARGIN) ? 0 : (double) (bounds.width - nameSpace - RIGHT_MARGIN) / (time1 - time0);\r
872 int x = bounds.x + nameSpace + (int) ((double) (selectedTime - time0) * pixelsPerNanoSec);\r
873 if (x >= nameSpace && x < bounds.x + bounds.width) {\r
874 gc.setForeground(_colors.getColor(TimeGraphColorScheme.SELECTED_TIME));\r
875 gc.drawLine(x, bounds.y, x, bounds.y + bounds.height);\r
876 }\r
877\r
878 // draw drag line, no line if name space is 0.\r
879 if (DRAG_SPLIT_LINE == _dragState) {\r
880 gc.setForeground(_colors.getColor(TimeGraphColorScheme.BLACK));\r
881 gc.drawLine(bounds.x + nameSpace, bounds.y, bounds.x + nameSpace, bounds.y + bounds.height - 1);\r
882 } else if (DRAG_NONE == _dragState && _mouseOverSplitLine && _timeProvider.getNameSpace() > 0) {\r
883 gc.setForeground(_colors.getColor(TimeGraphColorScheme.RED));\r
884 gc.drawLine(bounds.x + nameSpace, bounds.y, bounds.x + nameSpace, bounds.y + bounds.height - 1);\r
885 }\r
886 }\r
887\r
888 public void drawItems(Rectangle bounds, ITimeDataProvider timeProvider, TimeGraphItem[] items, int topIndex, int nameSpace, GC gc) {\r
fb5cad3d
PT
889 for (int i = topIndex; i < items.length; i++) {\r
890 TimeGraphItem item = (TimeGraphItem) items[i];\r
b83af2c3 891 drawItem(item, bounds, timeProvider, i, nameSpace, gc);\r
fb5cad3d 892 }\r
b83af2c3 893 fTimeGraphProvider.postDrawControl(bounds, gc);\r
fb5cad3d
PT
894 }\r
895\r
896 /**\r
897 * Draws the item\r
898 * \r
899 * @param item the item to draw\r
900 * @param bounds the container rectangle\r
901 * @param i the item index\r
902 * @param nameSpace the name space\r
903 * @param gc\r
904 */\r
b83af2c3
PT
905 protected void drawItem(TimeGraphItem item, Rectangle bounds, ITimeDataProvider timeProvider, int i, int nameSpace, GC gc) {\r
906 ITimeGraphEntry entry = item._trace;\r
fb5cad3d
PT
907 long time0 = timeProvider.getTime0();\r
908 long time1 = timeProvider.getTime1();\r
fb5cad3d
PT
909 long selectedTime = timeProvider.getSelectedTime();\r
910\r
911 Rectangle nameRect = getNameRect(bounds, i, nameSpace);\r
912 if (nameRect.y >= bounds.y + bounds.height) {\r
913 return;\r
914 }\r
915\r
bc51e30c 916 if (! item._trace.hasTimeEvents()) {\r
fb5cad3d
PT
917 Rectangle statesRect = getStatesRect(bounds, i, nameSpace);\r
918 nameRect.width += statesRect.width;\r
919 drawName(item, nameRect, gc);\r
920 } else {\r
921 drawName(item, nameRect, gc);\r
922 }\r
923 Rectangle rect = getStatesRect(bounds, i, nameSpace);\r
b83af2c3 924 if (rect.isEmpty()) {\r
bc51e30c 925 fTimeGraphProvider.postDrawEntry(entry, rect, gc);\r
fb5cad3d 926 return;\r
b83af2c3 927 }\r
fb5cad3d
PT
928 if (time1 <= time0) {\r
929 gc.setBackground(_colors.getBkColor(false, false, false));\r
930 gc.fillRectangle(rect);\r
bc51e30c 931 fTimeGraphProvider.postDrawEntry(entry, rect, gc);\r
fb5cad3d
PT
932 return;\r
933 }\r
934\r
935 // Initialize _rect1 to same values as enclosing rectangle rect\r
936 Rectangle stateRect = Utils.clone(rect);\r
937 boolean selected = item._selected;\r
938 // K pixels per second\r
939 double pixelsPerNanoSec = (rect.width <= RIGHT_MARGIN) ? 0 : (double) (rect.width - RIGHT_MARGIN) / (time1 - time0);\r
940\r
bc51e30c 941 if (item._trace.hasTimeEvents()) {\r
b83af2c3 942 fillSpace(rect, gc, selected);\r
fb5cad3d
PT
943 // Drawing rectangle is smaller than reserved space\r
944 stateRect.y += 3;\r
945 stateRect.height -= 6;\r
946\r
b83af2c3
PT
947 long maxDuration = (timeProvider.getTimeSpace() == 0) ? Long.MAX_VALUE : 1 * (time1 - time0) / timeProvider.getTimeSpace();\r
948 Iterator<ITimeEvent> iterator = entry.getTimeEventsIterator(time0, time1, maxDuration);\r
949\r
950 int lastX = -1;\r
951 while (iterator.hasNext()) {\r
952 ITimeEvent event = iterator.next();\r
953 int x = rect.x + (int) ((event.getTime() - time0) * pixelsPerNanoSec);\r
954 int xEnd = rect.x + (int) ((event.getTime() + event.getDuration() - time0) * pixelsPerNanoSec);\r
955 if (x >= rect.x + rect.width || xEnd < rect.x) {\r
956 // event is out of bounds\r
957 continue;\r
958 }\r
959 xEnd = Math.min(rect.x + rect.width, xEnd);\r
960 stateRect.x = Math.max(rect.x, x);\r
961 stateRect.width = Math.max(0, xEnd - stateRect.x + 1);\r
962 if (stateRect.x == lastX) {\r
963 stateRect.width -= 1;\r
964 if (stateRect.width > 0) {\r
965 gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));\r
966 gc.drawPoint(stateRect.x, stateRect.y - 2);\r
967 stateRect.x += 1;\r
f7e7159c 968 }\r
b83af2c3
PT
969 } else {\r
970 lastX = x;\r
fb5cad3d 971 }\r
b83af2c3
PT
972 boolean timeSelected = selectedTime >= event.getTime() && selectedTime < event.getTime() + event.getDuration();\r
973 drawState(_colors, event, stateRect, gc, selected, timeSelected);\r
fb5cad3d
PT
974 }\r
975 }\r
bc51e30c 976 fTimeGraphProvider.postDrawEntry(entry, rect, gc);\r
fb5cad3d
PT
977 }\r
978\r
b83af2c3 979 protected void drawName(TimeGraphItem item, Rectangle bounds, GC gc) {\r
bc51e30c
PT
980 boolean hasTimeEvents = item._trace.hasTimeEvents();\r
981 if (! hasTimeEvents) {\r
fb5cad3d
PT
982 gc.setBackground(_colors.getBkColorGroup(item._selected, _isInFocus));\r
983 gc.fillRectangle(bounds);\r
984 if (item._selected && _isInFocus) {\r
985 gc.setForeground(_colors.getBkColor(item._selected, _isInFocus, false));\r
986 gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1);\r
987 }\r
988 } else {\r
989 gc.setBackground(_colors.getBkColor(item._selected, _isInFocus, true));\r
990 gc.setForeground(_colors.getFgColor(item._selected, _isInFocus));\r
991 gc.fillRectangle(bounds);\r
992 }\r
993\r
994 // No name to be drawn\r
995 if (_timeProvider.getNameSpace() == 0) {\r
996 return;\r
997 }\r
998\r
999 int leftMargin = MARGIN + item.level * EXPAND_SIZE;\r
1000 if (item._hasChildren) {\r
1001 gc.setForeground(_colors.getFgColorGroup(false, false));\r
1002 gc.setBackground(_colors.getBkColor(false, false, false));\r
1003 Rectangle rect = Utils.clone(bounds);\r
1004 rect.x += leftMargin;\r
1005 rect.y += (bounds.height - EXPAND_SIZE) / 2;\r
1006 rect.width = EXPAND_SIZE;\r
1007 rect.height = EXPAND_SIZE;\r
1008 gc.fillRectangle(rect);\r
1009 gc.drawRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1);\r
1010 int midy = rect.y + rect.height / 2;\r
1011 gc.drawLine(rect.x + 2, midy, rect.x + rect.width - 3, midy);\r
1012 if (!item._expanded) {\r
1013 int midx = rect.x + rect.width / 2;\r
1014 gc.drawLine(midx, rect.y + 2, midx, rect.y + rect.height - 3);\r
1015 }\r
1016 }\r
1017 leftMargin += EXPAND_SIZE + MARGIN;\r
1018\r
1019 Image img = fTimeGraphProvider.getItemImage(item._trace);\r
1020 if (img != null) {\r
1021 // draw icon\r
1022 int imgHeight = img.getImageData().height;\r
1023 int imgWidth = img.getImageData().width;\r
1024 int x = leftMargin;\r
1025 int y = bounds.y + (bounds.height - imgHeight) / 2;\r
1026 gc.drawImage(img, x, y);\r
1027 leftMargin += imgWidth + MARGIN;\r
1028 }\r
1029 String name = item._name;\r
1030 Point size = gc.stringExtent(name);\r
1031 if (_idealNameSpace < leftMargin + size.x + MARGIN) {\r
1032 _idealNameSpace = leftMargin + size.x + MARGIN;\r
1033 }\r
bc51e30c 1034 if (hasTimeEvents) {\r
fb5cad3d
PT
1035 // cut long string with "..."\r
1036 int width = bounds.width - leftMargin;\r
1037 int cuts = 0;\r
1038 while (size.x > width && name.length() > 1) {\r
1039 cuts++;\r
1040 name = name.substring(0, name.length() - 1);\r
1041 size = gc.stringExtent(name + "..."); //$NON-NLS-1$\r
1042 }\r
1043 if (cuts > 0) {\r
1044 name += "..."; //$NON-NLS-1$\r
1045 }\r
1046 }\r
1047 Rectangle rect = Utils.clone(bounds);\r
1048 rect.x += leftMargin;\r
1049 rect.width -= leftMargin;\r
1050 // draw text\r
1051 if (rect.width > 0) {\r
b83af2c3
PT
1052 rect.y += (bounds.height - gc.stringExtent(name).y) / 2;\r
1053 gc.setForeground(_colors.getFgColor(item._selected, _isInFocus));\r
fb5cad3d
PT
1054 int textWidth = Utils.drawText(gc, name, rect, true);\r
1055 leftMargin += textWidth + MARGIN;\r
1056 rect.y -= 2;\r
1057\r
bc51e30c 1058 if (hasTimeEvents) {\r
fb5cad3d
PT
1059 // draw middle line\r
1060 int x = bounds.x + leftMargin;\r
1061 int width = bounds.width - x;\r
1062 int midy = bounds.y + bounds.height / 2;\r
1063 gc.setForeground(_colors.getColor(TimeGraphColorScheme.MID_LINE));\r
1064 gc.drawLine(x, midy, x + width, midy);\r
1065 }\r
1066 }\r
1067 }\r
1068\r
b83af2c3
PT
1069 protected void drawState(TimeGraphColorScheme colors, ITimeEvent event,\r
1070 Rectangle rect, GC gc, boolean selected, boolean timeSelected) {\r
fb5cad3d 1071\r
549f3c43 1072 int colorIdx = fTimeGraphProvider.getStateTableIndex(event);\r
b83af2c3
PT
1073 if (colorIdx < 0) {\r
1074 return;\r
f7e7159c 1075 }\r
b83af2c3 1076 boolean visible = rect.width == 0 ? false : true;\r
fb5cad3d
PT
1077\r
1078 if (visible) {\r
b83af2c3
PT
1079 Color stateColor = null;\r
1080 if (colorIdx < fEventColorMap.length) {\r
1081 stateColor = fEventColorMap[colorIdx];\r
1082 } else {\r
1083 stateColor = Display.getDefault().getSystemColor(SWT.COLOR_BLACK);\r
1084 }\r
1085 \r
1086 timeSelected = timeSelected && selected;\r
1087 if (timeSelected) {\r
1088 // modify the color?\r
1089 }\r
fb5cad3d 1090 // fill all rect area\r
b83af2c3 1091 gc.setBackground(stateColor);\r
fb5cad3d 1092 gc.fillRectangle(rect);\r
b83af2c3
PT
1093 // get the border color?\r
1094 gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));\r
fb5cad3d
PT
1095\r
1096 // draw bounds\r
1097 if (!timeSelected) {\r
b83af2c3
PT
1098 // Draw the top and bottom borders i.e. no side borders\r
1099 // top\r
1100 gc.drawLine(rect.x, rect.y, rect.x + rect.width - 1, rect.y);\r
1101 // bottom\r
1102 gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width - 1, rect.y + rect.height - 1);\r
fb5cad3d
PT
1103 }\r
1104 } else {\r
b83af2c3
PT
1105 gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));\r
1106 gc.drawPoint(rect.x, rect.y - 2);\r
1107 /*\r
fb5cad3d
PT
1108 // selected rectangle area is not visible but can be represented\r
1109 // with a broken vertical line of specified width.\r
b83af2c3 1110 int width = 1;\r
fb5cad3d 1111 rect.width = width;\r
b83af2c3 1112 gc.setForeground(stateColor);\r
fb5cad3d
PT
1113 int s = gc.getLineStyle();\r
1114 int w = gc.getLineWidth();\r
1115 gc.setLineStyle(SWT.LINE_DOT);\r
1116 gc.setLineWidth(width);\r
b83af2c3 1117 // Trace.debug("Rectangle not visible, drawing vertical line with: "\r
fb5cad3d
PT
1118 // + rect.x + "," + rect.y + "," + rect.x + "," + rect.y\r
1119 // + rect.height);\r
b83af2c3 1120 gc.drawLine(rect.x, rect.y, rect.x, rect.y + rect.height - 1);\r
fb5cad3d
PT
1121 gc.setLineStyle(s);\r
1122 gc.setLineWidth(w);\r
b83af2c3
PT
1123 if (!timeSelected) {\r
1124 gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));\r
1125 gc.drawPoint(rect.x, rect.y);\r
1126 gc.drawPoint(rect.x, rect.y + rect.height - 1);\r
1127 }\r
1128 */\r
fb5cad3d 1129 }\r
b83af2c3 1130 fTimeGraphProvider.postDrawEvent(event, rect, gc);\r
fb5cad3d
PT
1131 }\r
1132\r
b83af2c3 1133 protected void fillSpace(Rectangle rect, GC gc, boolean selected) {\r
fb5cad3d
PT
1134 gc.setBackground(_colors.getBkColor(selected, _isInFocus, false));\r
1135 gc.fillRectangle(rect);\r
1136 // draw middle line\r
1137 gc.setForeground(_colors.getColor(TimeGraphColorScheme.MID_LINE));\r
1138 int midy = rect.y + rect.height / 2;\r
1139 gc.drawLine(rect.x, midy, rect.x + rect.width, midy);\r
1140 }\r
1141\r
1142 @Override\r
1143 public void keyTraversed(TraverseEvent e) {\r
1144 if ((e.detail == SWT.TRAVERSE_TAB_NEXT) || (e.detail == SWT.TRAVERSE_TAB_PREVIOUS))\r
1145 e.doit = true;\r
1146 }\r
1147\r
1148 @Override\r
1149 public void keyPressed(KeyEvent e) {\r
1150 int idx = -1;\r
1151 if (_data._expandedItems.length == 0) {\r
1152 return;\r
1153 }\r
1154 if (SWT.HOME == e.keyCode) {\r
1155 idx = 0;\r
1156 } else if (SWT.END == e.keyCode) {\r
1157 idx = _data._expandedItems.length - 1;\r
1158 } else if (SWT.ARROW_DOWN == e.keyCode) {\r
1159 idx = getSelectedIndex();\r
1160 if (idx < 0)\r
1161 idx = 0;\r
1162 else if (idx < _data._expandedItems.length - 1)\r
1163 idx++;\r
1164 } else if (SWT.ARROW_UP == e.keyCode) {\r
1165 idx = getSelectedIndex();\r
1166 if (idx < 0)\r
1167 idx = 0;\r
1168 else if (idx > 0)\r
1169 idx--;\r
1170 } else if (SWT.ARROW_LEFT == e.keyCode) {\r
1171 selectPrevEvent();\r
1172 } else if (SWT.ARROW_RIGHT == e.keyCode) {\r
1173 selectNextEvent();\r
1174 } else if (SWT.PAGE_DOWN == e.keyCode) {\r
1175 int page = countPerPage();\r
1176 idx = getSelectedIndex();\r
1177 if (idx < 0)\r
1178 idx = 0;\r
1179 idx += page;\r
1180 if (idx >= _data._expandedItems.length)\r
1181 idx = _data._expandedItems.length - 1;\r
1182 } else if (SWT.PAGE_UP == e.keyCode) {\r
1183 int page = countPerPage();\r
1184 idx = getSelectedIndex();\r
1185 if (idx < 0)\r
1186 idx = 0;\r
1187 idx -= page;\r
1188 if (idx < 0)\r
1189 idx = 0;\r
1190 } else if (SWT.CR == e.keyCode) {\r
1191 idx = getSelectedIndex();\r
1192 if (idx >= 0) {\r
1193 if (_data._expandedItems[idx]._hasChildren) {\r
1194 toggle(idx);\r
1195 } else {\r
1196 fireDefaultSelection();\r
1197 }\r
1198 }\r
1199 idx = -1;\r
1200 }\r
1201 if (idx >= 0) {\r
1202 selectItem(idx, false);\r
1203 fireSelectionChanged();\r
1204 }\r
1205 }\r
1206\r
1207 @Override\r
1208 public void keyReleased(KeyEvent e) {\r
1209 }\r
1210\r
1211 @Override\r
1212 public void focusGained(FocusEvent e) {\r
1213 _isInFocus = true;\r
e9f70626
PT
1214 if (mouseScrollFilterListener == null) {\r
1215 mouseScrollFilterListener = new Listener() {\r
1216 // This filter is used to prevent horizontal scrolling of the view\r
1217 // when the mouse wheel is used to zoom\r
1218 @Override\r
1219 public void handleEvent(Event event) {\r
1220 event.doit = false;\r
1221 }\r
1222 };\r
1223 getDisplay().addFilter(SWT.MouseWheel, mouseScrollFilterListener);\r
1224 }\r
fb5cad3d
PT
1225 redraw();\r
1226 }\r
1227\r
1228 @Override\r
1229 public void focusLost(FocusEvent e) {\r
1230 _isInFocus = false;\r
e9f70626
PT
1231 if (mouseScrollFilterListener != null) {\r
1232 getDisplay().removeFilter(SWT.MouseWheel, mouseScrollFilterListener);\r
1233 mouseScrollFilterListener = null;\r
1234 }\r
fb5cad3d
PT
1235 if (DRAG_NONE != _dragState) {\r
1236 setCapture(false);\r
1237 _dragState = DRAG_NONE;\r
1238 }\r
1239 redraw();\r
1240 }\r
1241\r
1242 public boolean isInFocus() {\r
1243 return _isInFocus;\r
1244 }\r
1245\r
b83af2c3
PT
1246 /**\r
1247 * Provide the possibilty to control the wait cursor externally e.g. data\r
1248 * requests in progress\r
1249 * \r
1250 * @param waitInd\r
1251 */\r
1252 public void waitCursor(boolean waitInd) {\r
1253 // Update cursor as indicated\r
1254 if (waitInd) {\r
1255 setCursor(_WaitCursor);\r
1256 _isWaitCursor = true;\r
1257 } else {\r
1258 setCursor(null);\r
1259 _isWaitCursor = false;\r
1260 }\r
1261\r
1262 // Get ready for next mouse move\r
1263 _isDragCursor3 = false;\r
1264 }\r
1265\r
1266 /**\r
1267 * <p>\r
1268 * If the x, y position is over the vertical split line (name to time\r
1269 * ranges), then change the cursor to a drag cursor to indicate the user the\r
1270 * possibility of resizing\r
1271 * </p>\r
1272 * \r
1273 * @param x\r
1274 * @param y\r
1275 */\r
1276 void updateCursor(int x, int y) {\r
1277 // if Wait cursor not active, check for the need to change to a drag\r
1278 // cursor\r
1279 if (_isWaitCursor == false) {\r
1280 boolean isSplitLine = isOverSplitLine(x);\r
1281 // No dragcursor is name space is fixed to zero\r
1282 if (isSplitLine && !_isDragCursor3 && _timeProvider.getNameSpace() > 0) {\r
1283 setCursor(_dragCursor3);\r
1284 _isDragCursor3 = true;\r
1285 } else if (!isSplitLine && _isDragCursor3) {\r
1286 setCursor(null);\r
1287 _isDragCursor3 = false;\r
1288 }\r
1289 }\r
1290 }\r
1291\r
fb5cad3d
PT
1292 @Override\r
1293 public void mouseMove(MouseEvent e) {\r
1294 if (null == _timeProvider)\r
1295 return;\r
1296 Point size = getCtrlSize();\r
1297 if (DRAG_TRACE_ITEM == _dragState) {\r
1298 int nameWidth = _timeProvider.getNameSpace();\r
1299 int x = e.x - nameWidth;\r
1300 if (x > 0 && size.x > nameWidth && _dragX != x) {\r
1301 _dragX = x;\r
1302 double pixelsPerNanoSec = (size.x - nameWidth <= RIGHT_MARGIN) ? 0 : (double) (size.x - nameWidth - RIGHT_MARGIN) / (_time1bak - _time0bak);\r
1303 long timeDelta = (long) ((pixelsPerNanoSec == 0) ? 0 : ((_dragX - _dragX0) / pixelsPerNanoSec));\r
1304 long time1 = _time1bak - timeDelta;\r
1305 long maxTime = _timeProvider.getMaxTime();\r
1306 if (time1 > maxTime)\r
1307 time1 = maxTime;\r
1308 long time0 = time1 - (_time1bak - _time0bak);\r
1309 if (time0 < _timeProvider.getMinTime()) {\r
1310 time0 = _timeProvider.getMinTime();\r
1311 time1 = time0 + (_time1bak - _time0bak);\r
1312 }\r
1313 _timeProvider.setStartFinishTime(time0, time1);\r
1314 }\r
1315 } else if (DRAG_SPLIT_LINE == _dragState) {\r
1316 _dragX = e.x;\r
1317 _timeProvider.setNameSpace(e.x);\r
1318 } else if (DRAG_NONE == _dragState) {\r
1319 boolean mouseOverSplitLine = isOverSplitLine(e.x);\r
1320 if (_mouseOverSplitLine != mouseOverSplitLine) {\r
1321 redraw();\r
1322 }\r
1323 _mouseOverSplitLine = mouseOverSplitLine;\r
fb5cad3d
PT
1324 }\r
1325 updateCursor(e.x, e.y);\r
1326 }\r
1327\r
1328 @Override\r
1329 public void mouseDoubleClick(MouseEvent e) {\r
1330 if (null == _timeProvider)\r
1331 return;\r
1332 if (1 == e.button) {\r
1333 if (isOverSplitLine(e.x) && _timeProvider.getNameSpace() != 0) {\r
1334 _timeProvider.setNameSpace(_idealNameSpace);\r
1335 boolean mouseOverSplitLine = isOverSplitLine(e.x);\r
1336 if (_mouseOverSplitLine != mouseOverSplitLine) {\r
1337 redraw();\r
1338 }\r
1339 _mouseOverSplitLine = mouseOverSplitLine;\r
1340 return;\r
1341 }\r
1342 int idx = getItemIndexAtY(e.y);\r
1343 if (idx >= 0) {\r
1344 selectItem(idx, false);\r
1345 fireDefaultSelection();\r
1346 }\r
1347 }\r
1348 }\r
1349\r
fb5cad3d
PT
1350 @Override\r
1351 public void mouseDown(MouseEvent e) {\r
1352 if (null == _timeProvider)\r
1353 return;\r
1354 int idx;\r
1355 if (1 == e.button) {\r
1356 int nameSpace = _timeProvider.getNameSpace();\r
1357 if (nameSpace != 0) {\r
1358 if (isOverSplitLine(e.x)) {\r
1359 _dragState = DRAG_SPLIT_LINE;\r
1360 _dragX = _dragX0 = e.x;\r
1361 _time0bak = _timeProvider.getTime0();\r
1362 _time1bak = _timeProvider.getTime1();\r
1363 redraw();\r
1364 return;\r
1365 }\r
1366 }\r
1367\r
1368 idx = getItemIndexAtY(e.y);\r
1369 if (idx >= 0) {\r
1370 TimeGraphItem item = _data._expandedItems[idx];\r
1371 if (item._hasChildren && e.x < nameSpace && e.x < MARGIN + (item.level + 1) * EXPAND_SIZE) {\r
1372 toggle(idx);\r
1373 } else {\r
1374 long hitTime = getTimeAtX(e.x);\r
1375 if (hitTime >= 0) {\r
1376 // _timeProvider.setSelectedTimeInt(hitTime, false);\r
1377 setCapture(true);\r
1378 _dragState = DRAG_TRACE_ITEM;\r
1379 _dragX = _dragX0 = e.x - nameSpace;\r
1380 _time0bak = _timeProvider.getTime0();\r
1381 _time1bak = _timeProvider.getTime1();\r
1382 }\r
1383 }\r
1384 selectItem(idx, false);\r
1385 fireSelectionChanged();\r
1386 } else {\r
1387 selectItem(idx, false); // clear selection\r
1388 redraw();\r
1389 fireSelectionChanged();\r
1390 }\r
1391 }\r
1392 }\r
1393\r
1394 @Override\r
1395 public void mouseUp(MouseEvent e) {\r
1396 if (DRAG_NONE != _dragState) {\r
1397 setCapture(false);\r
1398 if (DRAG_TRACE_ITEM == _dragState) {\r
1399 // Notify time provider to check the need for listener\r
1400 // notification\r
1401 _timeProvider.notifyStartFinishTime();\r
1402 if (_dragX == _dragX0) { // click without drag\r
1403 long time = getTimeAtX(e.x);\r
3ac6ad1a 1404 _timeProvider.setSelectedTimeNotify(time, false);\r
fb5cad3d
PT
1405 }\r
1406 } else if (DRAG_SPLIT_LINE == _dragState) {\r
1407 redraw();\r
1408 }\r
1409 _dragState = DRAG_NONE;\r
1410 }\r
1411 }\r
1412\r
fb5cad3d
PT
1413 @Override\r
1414 public void mouseEnter(MouseEvent e) {\r
fb5cad3d
PT
1415 }\r
1416\r
1417 @Override\r
1418 public void mouseExit(MouseEvent e) {\r
fb5cad3d
PT
1419 if (_mouseOverSplitLine) {\r
1420 _mouseOverSplitLine = false;\r
1421 redraw();\r
1422 }\r
1423 }\r
1424\r
1425 @Override\r
1426 public void mouseHover(MouseEvent e) {\r
1427 }\r
1428\r
1429 @Override\r
1430 public void mouseScrolled(MouseEvent e) {\r
1431 if ((mouseScrollFilterListener == null) || _dragState != DRAG_NONE) {\r
1432 return;\r
1433 }\r
e9f70626
PT
1434 boolean zoomScroll = false;\r
1435 Point p = getParent().toControl(getDisplay().getCursorLocation());\r
1436 Point parentSize = getParent().getSize();\r
1437 if (p.x >= 0 && p.x < parentSize.x && p.y >= 0 && p.y < parentSize.y) {\r
1438 // over the parent control\r
1439 if (e.x > getCtrlSize().x) {\r
1440 // over the horizontal scroll bar\r
1441 zoomScroll = false;\r
1442 } else if (e.y >= 0 && e.y < getCtrlSize().y && e.x < _timeProvider.getNameSpace()) {\r
1443 // over the name space\r
1444 zoomScroll = false;\r
1445 } else {\r
1446 zoomScroll = true;\r
1447 }\r
1448 }\r
1449 if (zoomScroll && _timeProvider.getTime0() != _timeProvider.getTime1()) {\r
fb5cad3d
PT
1450 if (e.count > 0) {\r
1451 zoom(true);\r
1452 } else if (e.count < 0) {\r
1453 zoom(false);\r
1454 }\r
e9f70626
PT
1455 } else {\r
1456 setTopIndex(getTopIndex() - e.count);\r
fb5cad3d
PT
1457 }\r
1458 }\r
1459\r
b83af2c3
PT
1460 @Override\r
1461 public void controlMoved(ControlEvent e) {\r
1462 }\r
1463\r
1464 @Override\r
1465 public void controlResized(ControlEvent e) {\r
1466 adjustScrolls();\r
1467 }\r
1468\r
1469 @Override\r
1470 public void widgetDefaultSelected(SelectionEvent e) {\r
1471 }\r
1472\r
1473 @Override\r
1474 public void widgetSelected(SelectionEvent e) {\r
1475 if (e.widget == getVerticalBar()) {\r
1476 setTopIndex(getVerticalBar().getSelection());\r
1477 } else if (e.widget == getHorizontalBar() && null != _timeProvider) {\r
1478 int start = getHorizontalBar().getSelection();\r
1479 long time0 = _timeProvider.getTime0();\r
1480 long time1 = _timeProvider.getTime1();\r
1481 long timeMin = _timeProvider.getMinTime();\r
1482 long timeMax = _timeProvider.getMaxTime();\r
1483 long delta = timeMax - timeMin;\r
1484\r
1485 long range = time1 - time0;\r
1486 // _timeRangeFixed = true;\r
1487 time0 = timeMin + Math.round(delta * ((double) start / H_SCROLLBAR_MAX));\r
1488 time1 = time0 + range;\r
1489\r
1490 // TODO: Follow-up with Bug 310310\r
1491 // In Linux SWT.DRAG is the only value received\r
1492 // https://bugs.eclipse.org/bugs/show_bug.cgi?id=310310\r
1493 if (e.detail == SWT.DRAG) {\r
1494 _timeProvider.setStartFinishTime(time0, time1);\r
1495 } else {\r
1496 _timeProvider.setStartFinishTimeNotify(time0, time1);\r
1497 }\r
1498 }\r
1499 }\r
1500\r
fb5cad3d
PT
1501 public boolean isVisibleVerticalScroll() {\r
1502 return _visibleVerticalScroll;\r
1503 }\r
1504\r
1505 @Override\r
1506 public int getBorderWidth() {\r
1507 return _borderWidth;\r
1508 }\r
1509\r
1510 public void setBorderWidth(int borderWidth) {\r
1511 this._borderWidth = borderWidth;\r
1512 }\r
1513\r
1514 public int getHeaderHeight() {\r
1515 return _headerHeight;\r
1516 }\r
1517\r
1518 public void setHeaderHeight(int headerHeight) {\r
1519 this._headerHeight = headerHeight;\r
1520 }\r
1521\r
1522 public int getItemHeight() {\r
1523 return _itemHeight;\r
1524 }\r
1525\r
1526 public void setItemHeight(int rowHeight) {\r
1527 this._itemHeight = rowHeight;\r
1528 }\r
1529\r
1530 public void setMinimumItemWidth(int width) {\r
1531 this._minimumItemWidth = width;\r
1532 }\r
1533\r
1534 public int getMinimumItemWidth() {\r
1535 return _minimumItemWidth;\r
1536 }\r
1537\r
1538 public Vector<ITimeGraphEntry> getFilteredOut() {\r
1539 return _data.getFilteredOut();\r
1540 }\r
1541\r
1542 // @Override\r
1543 @Override\r
1544 public void addSelectionChangedListener(ISelectionChangedListener listener) {\r
1545 if (listener != null) {\r
1546 if (!_selectionChangedListeners.contains(listener)) {\r
1547 _selectionChangedListeners.add(listener);\r
1548 }\r
1549 }\r
1550 }\r
1551\r
1552 // @Override\r
1553 @Override\r
1554 public void removeSelectionChangedListener(ISelectionChangedListener listener) {\r
1555 if (listener != null) {\r
1556 _selectionChangedListeners.remove(listener);\r
1557 }\r
1558 }\r
1559\r
1560 // @Override\r
1561 @Override\r
1562 public void setSelection(ISelection selection) {\r
1563 if (selection instanceof TimeGraphSelection) {\r
1564 TimeGraphSelection sel = (TimeGraphSelection) selection;\r
1565 Object ob = sel.getFirstElement();\r
1566 if (ob instanceof ITimeGraphEntry) {\r
1567 ITimeGraphEntry trace = (ITimeGraphEntry) ob;\r
1568 selectItem(trace, false);\r
1569 }\r
1570 }\r
1571\r
1572 }\r
1573\r
1574}\r
1575\r
1576class ItemData {\r
1577 public TimeGraphItem[] _expandedItems = new TimeGraphItem[0];\r
1578 public TimeGraphItem[] _items = new TimeGraphItem[0];\r
1579 private ITimeGraphEntry _traces[] = new ITimeGraphEntry[0];\r
1580 private boolean traceFilter[] = new boolean[0];\r
1581 private Vector<ITimeGraphEntry> filteredOut = new Vector<ITimeGraphEntry>();\r
b83af2c3 1582 public ITimeGraphPresentationProvider provider;\r
fb5cad3d
PT
1583\r
1584 public ItemData() {\r
1585 }\r
1586\r
1587 TimeGraphItem findItem(ITimeGraphEntry entry) {\r
1588 if (entry == null)\r
1589 return null;\r
1590\r
1591 for (int i = 0; i < _items.length; i++) {\r
1592 TimeGraphItem item = _items[i];\r
1593 if (item._trace == entry) {\r
1594 return item;\r
1595 }\r
1596 }\r
1597\r
1598 return null;\r
1599 }\r
1600\r
1601 int findItemIndex(ITimeGraphEntry trace) {\r
1602 if (trace == null)\r
1603 return -1;\r
1604\r
1605 for (int i = 0; i < _expandedItems.length; i++) {\r
1606 TimeGraphItem item = _expandedItems[i];\r
1607 if (item._trace == trace) {\r
1608 return i;\r
1609 }\r
1610 }\r
1611\r
1612 return -1;\r
1613 }\r
1614\r
1615 public void refreshData() {\r
1616 List<TimeGraphItem> itemList = new ArrayList<TimeGraphItem>();\r
1617 filteredOut.clear();\r
1618 for (int i = 0; i < _traces.length; i++) {\r
1619 ITimeGraphEntry entry = _traces[i];\r
1620 refreshData(itemList, null, 0, entry);\r
1621 }\r
1622 _items = itemList.toArray(new TimeGraphItem[0]);\r
1623 updateExpandedItems();\r
1624 }\r
1625\r
1626 private void refreshData(List<TimeGraphItem> itemList, TimeGraphItem parent, int level, ITimeGraphEntry entry) {\r
1627 TimeGraphItem item = new TimeGraphItem(entry, entry.getName(), level);\r
1628 if (parent != null) {\r
1629 parent.children.add(item);\r
1630 }\r
b83af2c3 1631 item.itemHeight = provider.getItemHeight(entry);\r
fb5cad3d
PT
1632 itemList.add(item);\r
1633 if (entry.hasChildren()) {\r
1634 item._expanded = true;\r
1635 item._hasChildren = true;\r
1636 for (ITimeGraphEntry child : entry.getChildren()) {\r
1637 refreshData(itemList, item, level + 1, child);\r
1638 }\r
1639 }\r
1640 }\r
1641\r
1642 public void updateExpandedItems() {\r
1643 List<TimeGraphItem> expandedItemList = new ArrayList<TimeGraphItem>();\r
1644 for (int i = 0; i < _traces.length; i++) {\r
1645 ITimeGraphEntry entry = _traces[i];\r
1646 TimeGraphItem item = findItem(entry);\r
1647 refreshExpanded(expandedItemList, item);\r
1648 }\r
1649 _expandedItems = expandedItemList.toArray(new TimeGraphItem[0]);\r
1650 }\r
1651\r
1652 private void refreshExpanded(List<TimeGraphItem> expandedItemList, TimeGraphItem item) {\r
1653 expandedItemList.add(item);\r
1654 if (item._hasChildren && item._expanded) {\r
1655 for (TimeGraphItem child : item.children) {\r
1656 refreshExpanded(expandedItemList, child);\r
1657 }\r
1658 }\r
1659 }\r
1660\r
1661 public void expandItem(int idx) {\r
1662 if (idx < 0 || idx >= _expandedItems.length)\r
1663 return;\r
1664 TimeGraphItem item = (TimeGraphItem) _expandedItems[idx];\r
1665 if (item._hasChildren && !item._expanded) {\r
1666 item._expanded = true;\r
1667 updateExpandedItems();\r
1668 }\r
1669 }\r
1670\r
1671 public void refreshData(ITimeGraphEntry traces[]) {\r
1672 if (traces == null || traces.length == 0) {\r
1673 traceFilter = null;\r
1674 } else if (traceFilter == null || traces.length != traceFilter.length) {\r
1675 traceFilter = new boolean[traces.length];\r
1676 java.util.Arrays.fill(traceFilter, true);\r
1677 }\r
1678\r
1679 _traces = traces;\r
1680 refreshData();\r
1681 }\r
1682\r
b83af2c3 1683 public ITimeGraphEntry[] getTraces() {\r
fb5cad3d
PT
1684 return _traces;\r
1685 }\r
1686\r
1687 public boolean[] getTraceFilter() {\r
1688 return traceFilter;\r
1689 }\r
1690\r
1691 public Vector<ITimeGraphEntry> getFilteredOut() {\r
1692 return filteredOut;\r
1693 }\r
1694}\r
This page took 0.103777 seconds and 5 git commands to generate.