(no commit message)
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / views / histogram / HistogramCanvas.java
1 /*******************************************************************************
2 * Copyright (c) 2009 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 * William Bourque - Initial API and implementation
11 *******************************************************************************/
12 package org.eclipse.linuxtools.lttng.ui.views.histogram;
13
14 import org.eclipse.swt.widgets.Canvas;
15 import org.eclipse.swt.widgets.Composite;
16 import org.eclipse.swt.widgets.Display;
17
18 /**
19 * <b><u>HistogramCanvas</u></b>
20 * <p>
21 * Canvas implementation aimed to draw histograms.
22 * <p>
23 * This canvas goal is to display certain "HistogramContent" onto an histogram.<p>
24 * Several method exist to extend it so it should suit most needs.
25 */
26 public class HistogramCanvas extends Canvas
27 {
28 protected AsyncCanvasRedrawer canvasRedrawer = null;
29 protected HistogramContent histogramContent = null;
30
31 protected HistogramCanvasPaintListener paintListener = null;
32 protected HistogramCanvasMouseListener mouseListener = null;
33 protected HistogramCanvasKeyListener keyListener = null;
34 protected HistogramCanvasFocusListener focusListener = null;
35 protected HistogramCanvasControlListener controlListener = null;
36
37 protected HistogramSelectedWindow currentWindow = null;
38
39
40 /**
41 * HistogramCanvas constructor
42 *
43 * @param parent Composite control which will be the parent of the new instance (cannot be null)
44 * @param Style the style of control to construct
45 */
46 public HistogramCanvas(Composite parent, int style) {
47 super(parent, style);
48 addNeededListeners();
49
50 // New selected window, not visible by default
51 createNewSelectedWindow(0L);
52 }
53
54 /*
55 * Create the needed "event listeners" and hook them to the Canvas.
56 */
57 protected void addNeededListeners() {
58 createAndAddCanvasRedrawer();
59 createAndAddPaintListener();
60 createAndAddMouseListener();
61 createAndAddKeyListener();
62 createAndAddFocusListener();
63 createAndAddControlListener();
64 }
65
66 /*
67 * Create a canvas redrawer and bind it to this canvas.<p>
68 *
69 * Note : AsyncCanvasRedrawer is an internal class
70 * This is used to redraw the canvas from a different thread
71 * without^H^H^H with less danger.
72 */
73 protected void createAndAddCanvasRedrawer() {
74 canvasRedrawer = new AsyncCanvasRedrawer(this);
75 }
76
77 /*
78 * Create a histogram paint listener and bind it to this canvas.<p>
79 *
80 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasPaintListener
81 */
82 protected void createAndAddPaintListener() {
83 paintListener = new HistogramCanvasPaintListener(this);
84 this.addPaintListener( paintListener );
85 }
86
87 /*
88 * Create a histogram mouse listener and bind it to this canvas.<p>
89 * Note : this mouse listener handle the mouse, the move and the wheel at once.
90 *
91 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasMouseListener
92 */
93 protected void createAndAddMouseListener() {
94 mouseListener = new HistogramCanvasMouseListener(this);
95 this.addMouseListener(mouseListener);
96 this.addMouseMoveListener(mouseListener);
97 this.addMouseWheelListener(mouseListener);
98 }
99
100 /*
101 * Create a histogram key listener and bind it to this canvas.<p>
102 *
103 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasKeyListener
104 */
105 protected void createAndAddKeyListener() {
106 keyListener = new HistogramCanvasKeyListener(this);
107 this.addKeyListener(keyListener);
108 }
109
110 /*
111 * Create a histogram focus listener and bind it to this canvas.<p>
112 *
113 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasFocusListener
114 */
115 protected void createAndAddFocusListener() {
116 focusListener = new HistogramCanvasFocusListener(this);
117 this.addFocusListener(focusListener);
118 }
119
120 /*
121 * Create a histogram control listener and bind it to this canvas.<p>
122 *
123 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
124 */
125 protected void createAndAddControlListener() {
126 controlListener = new HistogramCanvasControlListener(this);
127 this.addControlListener(controlListener);
128 }
129
130 /**
131 * Create a new HistogramContent for this HistogramCanvas<p>
132 * A new <I>empty</I> content will then be created.
133 *
134 * IMPORTANT NOTE : Canvas size, bar width and bar height need to be known at this point, as these dimension are used to create a content
135 * of the correct size.
136 *
137 * @param canvasSize Size of the parent canvas.
138 * @param widthPerBar Width of the histogram "bars"
139 * @param barsHeight Height of the histogram "bars"
140 * @param maxBarsDifferenceToAverage Factor used to "chop" bars that are too tall. Set to something big (100.0?) if not needed.
141 */
142 public void createNewHistogramContent(int canvasSize, int widthPerBar, int barsHeight, double maxBarsDifferenceToAverage) {
143 histogramContent = new HistogramContent( canvasSize / widthPerBar, canvasSize, widthPerBar, barsHeight, maxBarsDifferenceToAverage);
144 }
145
146 /**
147 * Create a new selection window of the size (time width) given.<p>
148 * The window initial position is at X = 0.
149 * The window is created hidden, it won't be draw unless it is set to visible.<p>
150 *
151 * @param windowTimeDuration Time width (in nanosecond) of the window.
152 */
153 public void createNewSelectedWindow(long windowTimeDuration) {
154 currentWindow = new HistogramSelectedWindow(histogramContent);
155
156 currentWindow.setWindowTimeWidth(windowTimeDuration);
157 currentWindow.setWindowXPositionCenter(0);
158 }
159
160 public HistogramContent getHistogramContent() {
161 return histogramContent;
162 }
163
164 /**
165 * Getter for the selection window<p>
166 *
167 * @return the current selection window
168 *
169 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramSelectedWindow
170 */
171 public HistogramSelectedWindow getCurrentWindow() {
172 return currentWindow;
173 }
174
175 /**
176 * Getter for the selection window width<p>
177 *
178 * @return Time width (in nanosecond) of the selection window.
179 */
180 public long getSelectedWindowSize() {
181 return currentWindow.getWindowTimeWidth();
182 }
183
184 /**
185 * Setter for the selection window width<p>
186 * The window size will be ajusted if it does not respect one of these constraints :
187 * - The window size cannot be smaller than a single histogram content interval.<p>
188 * - The window size cannot be larger than twice the histogram content complete time interval.<p>
189 *
190 * @param newSelectedWindowSize New time width (in nanosecond) of the selection window.
191 */
192 public void setSelectedWindowSize(long newSelectedWindowSize) {
193
194 if ( newSelectedWindowSize <= 0 ) {
195 newSelectedWindowSize = 1L;
196 }
197 else if ( newSelectedWindowSize > (2*histogramContent.getCompleteTimeInterval()) ) {
198 newSelectedWindowSize = (2*histogramContent.getCompleteTimeInterval());
199 }
200
201 currentWindow.setWindowTimeWidth(newSelectedWindowSize);
202 }
203
204 /**
205 * Method to call the "Asynchronous redrawer" for this canvas<p>
206 * This allow safe redraw from different threads.
207 *
208 */
209 public void redrawAsynchronously() {
210 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
211 if ( canvasRedrawer == null ) {
212 canvasRedrawer = new AsyncCanvasRedrawer(this);
213 }
214
215 canvasRedrawer.asynchronousRedraw();
216 }
217
218 /**
219 * Method to call the "Asynchronous NotifyParentSelectionWindowChanged" for this canvas<p>
220 * This allow safe update UI objects from different threads.
221 *
222 */
223 public void notifyParentSelectionWindowChangedAsynchronously() {
224 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
225 if ( canvasRedrawer == null ) {
226 canvasRedrawer = new AsyncCanvasRedrawer(this);
227 }
228
229 canvasRedrawer.asynchronousNotifyParentSelectionWindowChanged();
230 }
231
232 /**
233 * Method to call the "Asynchronous NotifyParentUpdatedInformation" for this canvas<p>
234 * This allow safe redraw from different threads.
235 *
236 */
237 public void notifyParentUpdatedInformationAsynchronously() {
238 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
239 if ( canvasRedrawer == null ) {
240 canvasRedrawer = new AsyncCanvasRedrawer(this);
241 }
242
243 canvasRedrawer.asynchronousNotifyParentUpdatedInformation();
244 }
245
246 /**
247 * Function that is called when the selection window is moved.<p>
248 * Note: Given position should be relative to the previous (centered) absolute position.
249 *
250 * <B>METHOD INTENDED TO BE EXTENDED</B>
251 *
252 * @param newRelativeXPosition New position relative to the last known absolute position.
253 */
254 public void moveWindow(int newRelativeXPosition) {
255 // Nothing : function is a place holder
256 }
257
258 /**
259 * Function that is called when the selection window is re-centered.<p>
260 * Note: Given position should be absolute to the window and need to be the selection window center.
261 *
262 * <B>METHOD INTENDED TO BE EXTENDED</B>
263 *
264 * @param newRelativeXPosition New absolute position.
265 */
266 public void setWindowCenterPosition(int newAbsoluteXPosition) {
267 // Nothing : function is a place holder
268 }
269
270 /**
271 * Function that is called when the selection window size (time width) changed by an absolute time.<p>
272 * Note: Given time should be in nanoseconds, positive.
273 *
274 * <B>METHOD INTENDED TO BE EXTENDED</B>
275 *
276 * @param newTime New absoulte time (in nanoseconds) to apply to the window.
277 */
278 public void resizeWindowByAbsoluteTime(long newTime) {
279 // Nothing : function is a place holder
280 }
281
282 /**
283 * Function that is called to tell the parent that the selection window changed.<p>
284 *
285 * <B>METHOD INTENDED TO BE EXTENDED</B>
286 *
287 */
288 public void notifyParentSelectionWindowChanged() {
289 // Nothing : function is a place holder
290 }
291
292 /**
293 * Function that is called to tell the parent that some information changed.<p>
294 *
295 * <B>METHOD INTENDED TO BE EXTENDED</B>
296 *
297 */
298 public void notifyParentUpdatedInformation() {
299 // Nothing : function is a place holder
300 }
301 }
302
303
304 /**
305 * <b><u>AsyncCanvasRedrawer Inner Class</u></b>
306 * <p>
307 * Asynchronous redrawer for the HistogramCanvas
308 * <p>
309 * This class role is to call method that update the UI on asynchronously.
310 * This should prevent any "invalid thread access" exception when trying to update UI from a different thread.
311 */
312 class AsyncCanvasRedrawer {
313
314 private HistogramCanvas parentCanvas = null;
315
316 /**
317 * AsyncCanvasRedrawer constructor.
318 *
319 * @param newCanvas Related histogram canvas.
320 */
321 public AsyncCanvasRedrawer(HistogramCanvas newCanvas) {
322 parentCanvas = newCanvas;
323 }
324
325 /**
326 * Function to redraw the related canvas asynchonously.<p>
327 *
328 * Basically, it just run "canvas.redraw()" in asyncExec.
329 *
330 */
331 public void asynchronousRedraw() {
332 Display display = parentCanvas.getDisplay();
333 display.asyncExec(new Runnable() {
334 public void run() {
335 parentCanvas.redraw();
336 }
337 });
338 }
339
340 /**
341 * Function to asynchonously notify the parent of the related canvas that the window changed.<p>
342 *
343 * Basically, it just run "notifyParentSelectionWindowChanged()" in asyncExec.
344 *
345 */
346 public void asynchronousNotifyParentSelectionWindowChanged() {
347 Display display = parentCanvas.getDisplay();
348 display.asyncExec(new Runnable() {
349 public void run() {
350 parentCanvas.notifyParentSelectionWindowChanged();
351 }
352 });
353 }
354
355 /**
356 * Function to asynchonously notify the parent of the related canvas that information changed.<p>
357 *
358 * Basically, it just run "notifyParentUpdatedInformation()" in asyncExec.
359 *
360 */
361 public void asynchronousNotifyParentUpdatedInformation() {
362 Display display = parentCanvas.getDisplay();
363 display.asyncExec(new Runnable() {
364 public void run() {
365 parentCanvas.notifyParentUpdatedInformation();
366 }
367 });
368 }
369 }
This page took 0.073487 seconds and 5 git commands to generate.