tmf: add mouse selection provider for swt charts
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / viewers / xycharts / TmfXYChartViewer.java
1 /**********************************************************************
2 * Copyright (c) 2013 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Bernd Hufmann - Initial API and implementation
11 **********************************************************************/
12 package org.eclipse.linuxtools.tmf.ui.viewers.xycharts;
13
14 import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
15 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
16 import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
17 import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal;
18 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
19 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
20 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
21 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSelectedSignal;
22 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
23 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
24 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
25 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
26 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
27 import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager;
28 import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewer;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.widgets.Composite;
31 import org.eclipse.swt.widgets.Control;
32 import org.eclipse.swt.widgets.Display;
33 import org.swtchart.Chart;
34 import org.swtchart.IAxis;
35 import org.swtchart.ISeries;
36 import org.swtchart.ISeriesSet;
37
38 /**
39 * Base class for a XY-Chart based on SWT chart. It provides a methods to define
40 * zoom, selection and tool tip providers. It also provides call backs to be
41 * notified by any changes caused by selection and zoom.
42 *
43 * @author Bernd Hufmann
44 * @since 3.0
45 */
46 public abstract class TmfXYChartViewer extends TmfViewer implements ITmfChartTimeProvider {
47
48 // ------------------------------------------------------------------------
49 // Attributes
50 // ------------------------------------------------------------------------
51 /**
52 * The offset to apply to any x position. This offset ensures better
53 * precision when converting long to double and back.
54 */
55 private long fTimeOffset;
56 /** Start time of trace */
57 private long fStartTime;
58 /** End time of trace */
59 private long fEndTime;
60 /** Start time of current time range */
61 private long fWindowStartTime;
62 /** End time of current time range */
63 private long fWindowEndTime;
64 /** Duration of current time range */
65 private long fWindowDuration;
66 /** Current begin time of selection range */
67 private long fSelectionBeginTime;
68 /** Current end of selection range */
69 private long fSelectionEndTime;
70 /** The trace that is displayed by this viewer */
71 private ITmfTrace fTrace;
72 /** The SWT Chart reference */
73 private Chart fSwtChart;
74 /** The mouse selection provider */
75 private TmfBaseProvider fMouseSelectionProvider;
76
77 // ------------------------------------------------------------------------
78 // Constructors
79 // ------------------------------------------------------------------------
80
81 /**
82 * Constructs a TmfXYChartViewer.
83 *
84 * @param parent
85 * The parent composite
86 * @param title
87 * The title of the viewer
88 * @param xLabel
89 * The label of the xAxis
90 * @param yLabel
91 * The label of the yAXIS
92 */
93 public TmfXYChartViewer(Composite parent, String title, String xLabel, String yLabel) {
94 super(parent, title);
95 fSwtChart = new Chart(parent, SWT.NONE);
96
97 IAxis xAxis = fSwtChart.getAxisSet().getXAxis(0);
98 IAxis yAxis = fSwtChart.getAxisSet().getYAxis(0);
99
100 /* Set the title/labels, or hide them if they are not provided */
101 if (title == null) {
102 fSwtChart.getTitle().setVisible(false);
103 } else {
104 fSwtChart.getTitle().setText(title);
105 }
106 if (xLabel == null) {
107 xAxis.getTitle().setVisible(false);
108 } else {
109 xAxis.getTitle().setText(xLabel);
110 }
111 if (yLabel == null) {
112 yAxis.getTitle().setVisible(false);
113 } else {
114 yAxis.getTitle().setText(yLabel);
115 }
116
117 fMouseSelectionProvider = new TmfMouseSelectionProvider(this);
118 }
119
120 // ------------------------------------------------------------------------
121 // Getter/Setters
122 // ------------------------------------------------------------------------
123 /**
124 * Sets the time offset to apply.
125 * @see ITmfChartTimeProvider#getTimeOffset()
126 *
127 * @param timeOffset
128 * The time offset to apply
129 */
130 protected void setTimeOffset(long timeOffset) {
131 fTimeOffset = timeOffset;
132 }
133
134 /**
135 * Sets the start time of the trace
136 *
137 * @param startTime
138 * The start time to set
139 */
140 protected void setStartTime(long startTime) {
141 fStartTime = startTime;
142 }
143
144 /**
145 * Sets the end time of the trace
146 *
147 * @param endTime
148 * The start time to set
149 */
150 protected void setEndTime(long endTime) {
151 fEndTime = endTime;
152 }
153
154 /**
155 * Sets the start time of the current time range window
156 *
157 * @param windowStartTime
158 * The start time to set
159 */
160 protected void setWindowStartTime(long windowStartTime) {
161 fWindowStartTime = windowStartTime;
162 }
163
164 /**
165 * Sets the end time of the current time range window
166 *
167 * @param windowEndTime
168 * The start time to set
169 */
170 protected void setWindowEndTime(long windowEndTime) {
171 fWindowEndTime = windowEndTime;
172 }
173
174 /**
175 * Sets the start time of the current time range window
176 *
177 * @param windowDuration
178 * The start time to set
179 */
180 protected void setWindowDuration(long windowDuration) {
181 fWindowDuration = windowDuration;
182 }
183
184 /**
185 * Sets the begin time of the selection range.
186 *
187 * @param selectionBeginTime
188 * The begin time to set
189 */
190 protected void setSelectionBeginTime(long selectionBeginTime) {
191 fSelectionBeginTime = selectionBeginTime;
192 }
193
194 /**
195 * Sets the end time of the selection range.
196 *
197 * @param selectionEndTime
198 * The end time to set
199 */
200 protected void setSelectionEndTime(long selectionEndTime) {
201 fSelectionEndTime = selectionEndTime;
202 }
203
204 /**
205 * Sets the trace that is displayed by this viewer.
206 *
207 * @param trace
208 * The trace to set
209 */
210 protected void setTrace(ITmfTrace trace) {
211 fTrace = trace;
212 }
213
214 /**
215 * Gets the trace that is displayed by this viewer.
216 *
217 * @return the trace
218 */
219 protected ITmfTrace getTrace() {
220 return fTrace;
221 }
222
223 /**
224 * Sets the SWT Chart reference
225 *
226 * @param chart
227 * The SWT chart to set.
228 */
229 protected void setSwtChart(Chart chart) {
230 fSwtChart = chart;
231 }
232
233 /**
234 * Gets the SWT Chart reference
235 *
236 * @return the SWT chart to set.
237 */
238 protected Chart getSwtChart() {
239 return fSwtChart;
240 }
241
242 /**
243 * Sets a mouse selection provider. An existing provider will be
244 * disposed. Use <code>null</code> to disable the mouse selection provider.
245 *
246 * @param provider
247 * The selection provider to set
248 */
249 public void setSelectionProvider(TmfBaseProvider provider) {
250 if (fMouseSelectionProvider != null) {
251 fMouseSelectionProvider.dispose();
252 }
253 fMouseSelectionProvider = provider;
254 }
255
256 // ------------------------------------------------------------------------
257 // ITmfChartTimeProvider
258 // ------------------------------------------------------------------------
259 @Override
260 public long getStartTime() {
261 return fStartTime;
262 }
263
264 @Override
265 public long getEndTime() {
266 return fEndTime;
267 }
268
269 @Override
270 public long getWindowStartTime() {
271 return fWindowStartTime;
272 }
273
274 @Override
275 public long getWindowEndTime() {
276 return fWindowEndTime;
277 }
278
279 @Override
280 public long getWindowDuration() {
281 return fWindowDuration;
282 }
283
284 @Override
285 public long getSelectionBeginTime() {
286 return fSelectionBeginTime;
287 }
288
289 @Override
290 public long getSelectionEndTime() {
291 return fSelectionEndTime;
292 }
293
294 @Override
295 public long getTimeOffset() {
296 return fTimeOffset;
297 }
298
299 @Override
300 public void updateSelectionRange(final long currentBeginTime, final long currentEndTime) {
301 if (fTrace != null) {
302 setSelectionBeginTime(currentBeginTime);
303 setSelectionEndTime(currentEndTime);
304
305 final ITmfTimestamp startTimestamp = new TmfTimestamp(fSelectionBeginTime, ITmfTimestamp.NANOSECOND_SCALE);
306 final ITmfTimestamp endTimestamp = new TmfTimestamp(fSelectionEndTime, ITmfTimestamp.NANOSECOND_SCALE);
307
308 TmfTimeSynchSignal signal = new TmfTimeSynchSignal(TmfXYChartViewer.this, startTimestamp, endTimestamp);
309 broadcast(signal);
310 }
311 }
312
313 // ------------------------------------------------------------------------
314 // ITmfViewer interface
315 // ------------------------------------------------------------------------
316 @Override
317 public Control getControl() {
318 return fSwtChart;
319 }
320
321 @Override
322 public void refresh() {
323 fSwtChart.redraw();
324 }
325
326 // ------------------------------------------------------------------------
327 // TmfComponent
328 // ------------------------------------------------------------------------
329 @Override
330 public void dispose() {
331 super.dispose();
332 fSwtChart.dispose();
333
334 if (fMouseSelectionProvider != null) {
335 fMouseSelectionProvider.dispose();
336 }
337 }
338
339 // ------------------------------------------------------------------------
340 // Operations
341 // ------------------------------------------------------------------------
342 /**
343 * A Method to load a trace into the viewer.
344 *
345 * @param trace
346 * A trace to apply in the viewer
347 */
348 public void loadTrace(ITmfTrace trace) {
349 fTrace = trace;
350
351 long timestamp = TmfTraceManager.getInstance().getSelectionBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
352 long windowStartTime = TmfTraceManager.getInstance().getCurrentRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
353 long startTime = fTrace.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
354 long endTime = fTrace.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
355
356 setSelectionBeginTime(timestamp);
357 setSelectionEndTime(timestamp);
358 setStartTime(startTime);
359 setWindowStartTime(windowStartTime);
360 setWindowDuration(fTrace.getInitialRangeOffset().getValue());
361 setEndTime(endTime);
362 setWindowEndTime(windowStartTime + getWindowDuration());
363 clearContent();
364 updateContent();
365 }
366
367 /**
368 * Resets the content of the viewer
369 */
370 public void reset() {
371 // Reset the internal data
372 setSelectionBeginTime(0);
373 setSelectionEndTime(0);
374 setStartTime(0);
375 setWindowStartTime(0);
376 setWindowDuration(0);
377 setEndTime(0);
378 setWindowEndTime(0);
379 setTrace(null);
380 clearContent();
381 }
382
383 /**
384 * Method to implement to update the chart content.
385 */
386 protected abstract void updateContent();
387
388 // ------------------------------------------------------------------------
389 // Signal Handler
390 // ------------------------------------------------------------------------
391
392 /**
393 * Signal handler for handling of the trace opened signal.
394 *
395 * @param signal
396 * The trace opened signal {@link TmfTraceOpenedSignal}
397 */
398 @TmfSignalHandler
399 public void traceOpened(TmfTraceOpenedSignal signal) {
400 fTrace = signal.getTrace();
401 loadTrace(getTrace());
402 }
403
404 /**
405 * Signal handler for handling of the trace selected signal.
406 *
407 * @param signal
408 * The trace selected signal {@link TmfTraceSelectedSignal}
409 */
410 @TmfSignalHandler
411 public void traceSelected(TmfTraceSelectedSignal signal) {
412 if (fTrace != signal.getTrace()) {
413 fTrace = signal.getTrace();
414 loadTrace(getTrace());
415 }
416 }
417
418 /**
419 * Signal handler for handling of the trace closed signal.
420 *
421 * @param signal
422 * The trace closed signal {@link TmfTraceClosedSignal}
423 */
424 @TmfSignalHandler
425 public void traceClosed(TmfTraceClosedSignal signal) {
426
427 if (signal.getTrace() != fTrace) {
428 return;
429 }
430
431 // Reset the internal data
432 fTrace = null;
433 reset();
434 }
435
436 /**
437 * Signal handler for handling of the time synch signal.
438 *
439 * @param signal
440 * The time synch signal {@link TmfTimeSynchSignal}
441 */
442 @TmfSignalHandler
443 public void selectionRangeUpdated(TmfTimeSynchSignal signal) {
444 if ((signal.getSource() != this) && (fTrace != null)) {
445 ITmfTimestamp selectedTime = signal.getBeginTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE);
446 ITmfTimestamp selectedEndTime = signal.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE);
447 setSelectionBeginTime(selectedTime.getValue());
448 setSelectionEndTime(selectedEndTime.getValue());
449 if (fMouseSelectionProvider != null) {
450 fMouseSelectionProvider.refresh();
451 }
452 }
453 }
454
455 /**
456 * Signal handler for handling of the time range synch signal.
457 *
458 * @param signal
459 * The time range synch signal {@link TmfRangeSynchSignal}
460 */
461 @TmfSignalHandler
462 public void timeRangeUpdated(TmfRangeSynchSignal signal) {
463
464 if (fTrace != null) {
465 // Validate the time range
466 TmfTimeRange range = signal.getCurrentRange().getIntersection(fTrace.getTimeRange());
467 if (range == null) {
468 return;
469 }
470
471 if (signal.getSource() != this) {
472 // Update the time range
473 long windowStartTime = range.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
474 long windowEndTime = range.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
475 long windowDuration = windowEndTime - windowStartTime;
476
477 setWindowStartTime(windowStartTime);
478 setWindowEndTime(windowEndTime);
479 setWindowDuration(windowDuration);
480 }
481 }
482 updateContent();
483 }
484
485 /**
486 * Signal handler for handling of the trace range updated signal.
487 *
488 * @param signal
489 * The trace range signal {@link TmfTraceRangeUpdatedSignal}
490 */
491 @TmfSignalHandler
492 public void traceRangeUpdated(TmfTraceRangeUpdatedSignal signal) {
493
494 if (signal.getTrace() != fTrace) {
495 return;
496 }
497
498 TmfTimeRange fullRange = signal.getRange();
499
500 long traceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
501 long traceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
502
503 setStartTime(traceStartTime);
504 setEndTime(traceEndTime);
505 }
506
507 /**
508 * Signal handler for handling of the trace updated signal.
509 *
510 * @param signal
511 * The trace updated signal {@link TmfTraceUpdatedSignal}
512 */
513 @TmfSignalHandler
514 public void traceUpdated(TmfTraceUpdatedSignal signal) {
515 if (signal.getTrace() != fTrace) {
516 return;
517 }
518 TmfTimeRange fullRange = signal.getTrace().getTimeRange();
519 long traceStartTime = fullRange.getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
520 long traceEndTime = fullRange.getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
521
522 setStartTime(traceStartTime);
523 setEndTime(traceEndTime);
524 }
525
526 /**
527 * Signal handler for handling the signal that notifies about an updated
528 * timestamp format.
529 *
530 * @param signal
531 * The trace updated signal
532 * {@link TmfTimestampFormatUpdateSignal}
533 */
534 @TmfSignalHandler
535 public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) {
536 fSwtChart.getAxisSet().adjustRange();
537 fSwtChart.redraw();
538 }
539
540 // ------------------------------------------------------------------------
541 // Helper Methods
542 // ------------------------------------------------------------------------
543
544 /**
545 * Clears the view content.
546 */
547 protected void clearContent() {
548 if (!fSwtChart.isDisposed()) {
549 ISeriesSet set = fSwtChart.getSeriesSet();
550 ISeries[] series = set.getSeries();
551 for (int i = 0; i < series.length; i++) {
552 set.deleteSeries(series[i].getId());
553 }
554 fSwtChart.redraw();
555 }
556 }
557
558 /**
559 * Returns the current or default display.
560 *
561 * @return the current or default display
562 */
563 protected static Display getDisplay() {
564 Display display = Display.getCurrent();
565 // may be null if outside the UI thread
566 if (display == null) {
567 display = Display.getDefault();
568 }
569 return display;
570 }
571
572 }
This page took 0.043652 seconds and 5 git commands to generate.