29ca3f9809084fde4b5975eb8e9c384ec9c76860
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / viewers / xycharts / TmfXYChartViewer.java
1 /**********************************************************************
2 * Copyright (c) 2013, 2016 Ericsson, École Polytechnique de Montréal
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 * Geneviève Bastien - Moved some methods to TmfTimeViewer
12 * Patrick Tasse - Fix setFocus
13 **********************************************************************/
14 package org.eclipse.tracecompass.tmf.ui.viewers.xycharts;
15
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.events.MouseAdapter;
18 import org.eclipse.swt.events.MouseEvent;
19 import org.eclipse.swt.widgets.Composite;
20 import org.eclipse.swt.widgets.Control;
21 import org.eclipse.swt.widgets.Display;
22 import org.eclipse.tracecompass.tmf.core.signal.TmfSelectionRangeUpdatedSignal;
23 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
24 import org.eclipse.tracecompass.tmf.core.signal.TmfTimestampFormatUpdateSignal;
25 import org.eclipse.tracecompass.tmf.core.signal.TmfWindowRangeUpdatedSignal;
26 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
27 import org.eclipse.tracecompass.tmf.ui.viewers.TmfTimeViewer;
28 import org.swtchart.Chart;
29 import org.swtchart.IAxis;
30 import org.swtchart.ISeries;
31 import org.swtchart.ISeriesSet;
32 import org.swtchart.Range;
33
34 /**
35 * Base class for a XY-Chart based on SWT chart. It provides a methods to define
36 * zoom, selection and tool tip providers. It also provides call backs to be
37 * notified by any changes caused by selection and zoom.
38 *
39 * @author Bernd Hufmann
40 */
41 public abstract class TmfXYChartViewer extends TmfTimeViewer implements ITmfChartTimeProvider {
42
43 // ------------------------------------------------------------------------
44 // Attributes
45 // ------------------------------------------------------------------------
46 /** The SWT Chart reference */
47 private Chart fSwtChart;
48 /** The mouse selection provider */
49 private TmfBaseProvider fMouseSelectionProvider;
50 /** The mouse drag zoom provider */
51 private TmfBaseProvider fMouseDragZoomProvider;
52 /** The mouse wheel zoom provider */
53 private TmfBaseProvider fMouseWheelZoomProvider;
54 /** The tooltip provider */
55 private TmfBaseProvider fToolTipProvider;
56 /** The middle mouse drag provider */
57 private TmfBaseProvider fMouseDragProvider;
58 /**
59 * Whether or not to send time alignment signals. This should be set to true
60 * for viewers that are part of an aligned view.
61 */
62 private boolean fSendTimeAlignSignals = false;
63
64
65 // ------------------------------------------------------------------------
66 // Constructors
67 // ------------------------------------------------------------------------
68
69 /**
70 * Constructs a TmfXYChartViewer.
71 *
72 * @param parent
73 * The parent composite
74 * @param title
75 * The title of the viewer
76 * @param xLabel
77 * The label of the xAxis
78 * @param yLabel
79 * The label of the yAXIS
80 */
81 public TmfXYChartViewer(Composite parent, String title, String xLabel, String yLabel) {
82 super(parent, title);
83 fSwtChart = new Chart(parent, SWT.NONE) {
84 @Override
85 public boolean setFocus() {
86 return fSwtChart.getPlotArea().setFocus();
87 }
88 };
89 fSwtChart.getPlotArea().addMouseListener(new MouseAdapter() {
90 @Override
91 public void mouseDown(MouseEvent e) {
92 fSwtChart.getPlotArea().setFocus();
93 }
94 });
95
96 IAxis xAxis = fSwtChart.getAxisSet().getXAxis(0);
97 IAxis yAxis = fSwtChart.getAxisSet().getYAxis(0);
98
99 /* Set the title/labels, or hide them if they are not provided */
100 if (title == null) {
101 fSwtChart.getTitle().setVisible(false);
102 } else {
103 fSwtChart.getTitle().setText(title);
104 }
105 if (xLabel == null) {
106 xAxis.getTitle().setVisible(false);
107 } else {
108 xAxis.getTitle().setText(xLabel);
109 }
110 if (yLabel == null) {
111 yAxis.getTitle().setVisible(false);
112 } else {
113 yAxis.getTitle().setText(yLabel);
114 }
115
116 fMouseSelectionProvider = new TmfMouseSelectionProvider(this);
117 fMouseDragZoomProvider = new TmfMouseDragZoomProvider(this);
118 fMouseWheelZoomProvider = new TmfMouseWheelZoomProvider(this);
119 fToolTipProvider = new TmfSimpleTooltipProvider(this);
120 fMouseDragProvider = new TmfMouseDragProvider(this);
121
122 fSwtChart.addDisposeListener((e) -> {
123 internalDispose();
124 });
125 }
126
127 // ------------------------------------------------------------------------
128 // Getter/Setters
129 // ------------------------------------------------------------------------
130
131 /**
132 * Sets the SWT Chart reference
133 *
134 * @param chart
135 * The SWT chart to set.
136 */
137 protected void setSwtChart(Chart chart) {
138 fSwtChart = chart;
139 }
140
141 /**
142 * Gets the SWT Chart reference
143 *
144 * @return the SWT chart to set.
145 */
146 protected Chart getSwtChart() {
147 return fSwtChart;
148 }
149
150 /**
151 * Sets a mouse selection provider. An existing provider will be
152 * disposed. Use <code>null</code> to disable the mouse selection provider.
153 *
154 * @param provider
155 * The selection provider to set
156 */
157 public void setSelectionProvider(TmfBaseProvider provider) {
158 if (fMouseSelectionProvider != null) {
159 fMouseSelectionProvider.dispose();
160 }
161 fMouseSelectionProvider = provider;
162 }
163
164 /**
165 * Sets a mouse drag zoom provider. An existing provider will be
166 * disposed. Use <code>null</code> to disable the mouse drag zoom provider.
167 *
168 * @param provider
169 * The mouse drag zoom provider to set
170 */
171 public void setMouseDragZoomProvider(TmfBaseProvider provider) {
172 if (fMouseDragZoomProvider != null) {
173 fMouseDragZoomProvider.dispose();
174 }
175 fMouseDragZoomProvider = provider;
176 }
177
178 /**
179 * Sets a mouse wheel zoom provider. An existing provider will be
180 * disposed. Use <code>null</code> to disable the mouse wheel zoom
181 * provider.
182 *
183 * @param provider
184 * The mouse wheel zoom provider to set
185 */
186 public void setMouseWheelZoomProvider(TmfBaseProvider provider) {
187 if (fMouseWheelZoomProvider != null) {
188 fMouseWheelZoomProvider.dispose();
189 }
190 fMouseWheelZoomProvider = provider;
191 }
192
193 /**
194 * Sets a tooltip provider. An existing provider will be
195 * disposed. Use <code>null</code> to disable the tooltip provider.
196 *
197 * @param provider
198 * The tooltip provider to set
199 */
200 public void setTooltipProvider(TmfBaseProvider provider) {
201 if (fToolTipProvider != null) {
202 fToolTipProvider.dispose();
203 }
204 fToolTipProvider = provider;
205 }
206
207 /**
208 * Sets a mouse drag provider. An existing provider will be
209 * disposed. Use <code>null</code> to disable the mouse drag provider.
210 *
211 * @param provider
212 * The mouse drag provider to set
213 */
214 public void setMouseDrageProvider(TmfBaseProvider provider) {
215 if (fMouseDragProvider != null) {
216 fMouseDragProvider.dispose();
217 }
218 fMouseDragProvider = provider;
219 }
220
221 // ------------------------------------------------------------------------
222 // ITmfChartTimeProvider
223 // ------------------------------------------------------------------------
224
225 @Override
226 public long getTimeOffset() {
227 return getWindowStartTime() - 1;
228 }
229
230 // ------------------------------------------------------------------------
231 // ITmfViewer interface
232 // ------------------------------------------------------------------------
233 @Override
234 public Control getControl() {
235 return fSwtChart;
236 }
237
238 @Override
239 public void refresh() {
240 fSwtChart.redraw();
241 }
242
243 // ------------------------------------------------------------------------
244 // TmfComponent
245 // ------------------------------------------------------------------------
246
247 @Override
248 public void dispose() {
249 fSwtChart.dispose();
250 }
251
252 private void internalDispose() {
253 super.dispose();
254
255 if (fMouseSelectionProvider != null) {
256 fMouseSelectionProvider.dispose();
257 }
258
259 if (fMouseDragZoomProvider != null) {
260 fMouseDragZoomProvider.dispose();
261 }
262
263 if (fMouseWheelZoomProvider != null) {
264 fMouseWheelZoomProvider.dispose();
265 }
266
267 if (fToolTipProvider != null) {
268 fToolTipProvider.dispose();
269 }
270
271 if (fMouseDragProvider != null) {
272 fMouseDragProvider.dispose();
273 }
274 }
275
276 // ------------------------------------------------------------------------
277 // Operations
278 // ------------------------------------------------------------------------
279 /**
280 * A Method to load a trace into the viewer.
281 *
282 * @param trace
283 * A trace to apply in the viewer
284 */
285 @Override
286 public void loadTrace(ITmfTrace trace) {
287 super.loadTrace(trace);
288 clearContent();
289 updateContent();
290 }
291
292 /**
293 * Resets the content of the viewer
294 */
295 @Override
296 public void reset() {
297 super.reset();
298 setStartTime(0);
299 setEndTime(0);
300 clearContent();
301 }
302
303 /**
304 * Method to implement to update the chart content.
305 */
306 protected abstract void updateContent();
307
308 // ------------------------------------------------------------------------
309 // Signal Handler
310 // ------------------------------------------------------------------------
311
312 /**
313 * Signal handler for handling of the time synch signal.
314 *
315 * @param signal
316 * The time synch signal {@link TmfSelectionRangeUpdatedSignal}
317 */
318 @Override
319 @TmfSignalHandler
320 public void selectionRangeUpdated(TmfSelectionRangeUpdatedSignal signal) {
321 super.selectionRangeUpdated(signal);
322 if (signal != null && (signal.getSource() != this) && (getTrace() != null)) {
323 if (fMouseSelectionProvider != null) {
324 fMouseSelectionProvider.refresh();
325 }
326 }
327 }
328
329 /**
330 * Signal handler for handling of the window range signal.
331 *
332 * @param signal
333 * The {@link TmfWindowRangeUpdatedSignal}
334 */
335 @Override
336 @TmfSignalHandler
337 public void windowRangeUpdated(TmfWindowRangeUpdatedSignal signal) {
338 super.windowRangeUpdated(signal);
339 updateContent();
340 }
341
342 /**
343 * Signal handler for handling the signal that notifies about an updated
344 * timestamp format.
345 *
346 * @param signal
347 * The trace updated signal
348 * {@link TmfTimestampFormatUpdateSignal}
349 */
350 @TmfSignalHandler
351 public void timestampFormatUpdated(TmfTimestampFormatUpdateSignal signal) {
352 fSwtChart.getAxisSet().adjustRange();
353 fSwtChart.redraw();
354 }
355
356 // ------------------------------------------------------------------------
357 // Helper Methods
358 // ------------------------------------------------------------------------
359
360 /**
361 * Clears the view content.
362 */
363 protected void clearContent() {
364 if (!fSwtChart.isDisposed()) {
365 ISeriesSet set = fSwtChart.getSeriesSet();
366 ISeries[] series = set.getSeries();
367 for (int i = 0; i < series.length; i++) {
368 set.deleteSeries(series[i].getId());
369 }
370 for (IAxis axis: fSwtChart.getAxisSet().getAxes()){
371 axis.setRange(new Range(0,1));
372 }
373 fSwtChart.redraw();
374 }
375 }
376
377 /**
378 * Returns the current or default display.
379 *
380 * @return the current or default display
381 */
382 protected static Display getDisplay() {
383 Display display = Display.getCurrent();
384 // may be null if outside the UI thread
385 if (display == null) {
386 display = Display.getDefault();
387 }
388 return display;
389 }
390
391 /**
392 * Get the offset of the point area, relative to the XY chart viewer
393 * control. We consider the point area to be from where the first point
394 * could be drawn to where the last point could be drawn.
395 *
396 * @return the offset in pixels
397 *
398 * @since 1.0
399 */
400 public int getPointAreaOffset() {
401
402 int pixelCoordinate = 0;
403 IAxis[] xAxes = getSwtChart().getAxisSet().getXAxes();
404 if (xAxes.length > 0) {
405 IAxis axis = xAxes[0];
406 pixelCoordinate = axis.getPixelCoordinate(axis.getRange().lower);
407 }
408 return getSwtChart().toControl(getSwtChart().getPlotArea().toDisplay(pixelCoordinate, 0)).x;
409 }
410
411 /**
412 * Get the width of the point area. We consider the point area to be from
413 * where the first point could be drawn to where the last point could be
414 * drawn. The point area differs from the plot area because there might be a
415 * gap between where the plot area start and where the fist point is drawn.
416 * This also matches the width that the use can select.
417 *
418 * @return the width in pixels
419 *
420 * @since 1.0
421 */
422 public int getPointAreaWidth() {
423 IAxis[] xAxes = getSwtChart().getAxisSet().getXAxes();
424 if (xAxes.length > 0) {
425 IAxis axis = xAxes[0];
426 int x1 = getPointAreaOffset();
427 int x2 = axis.getPixelCoordinate(axis.getRange().upper);
428 x2 = getSwtChart().toControl(getSwtChart().getPlotArea().toDisplay(x2, 0)).x;
429 int width = x2 - x1;
430 return width;
431 }
432
433 return getSwtChart().getPlotArea().getSize().x;
434 }
435
436 /**
437 * Sets whether or not to send time alignment signals. This should be set to
438 * true for viewers that are part of an aligned view.
439 *
440 * @param sendTimeAlignSignals
441 * whether or not to send time alignment signals
442 * @since 1.0
443 */
444 public void setSendTimeAlignSignals(boolean sendTimeAlignSignals) {
445 fSendTimeAlignSignals = sendTimeAlignSignals;
446 }
447
448 /**
449 * Returns whether or not to send time alignment signals.
450 *
451 * @return whether or not to send time alignment signals.
452 * @since 1.0
453 */
454 public boolean isSendTimeAlignSignals() {
455 return fSendTimeAlignSignals;
456 }
457 }
This page took 0.040248 seconds and 4 git commands to generate.