1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
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
10 * William Bourque - Initial API and implementation
13 * 2010-06-20 Yuriy Vashchuk - Histogram optimisations.
14 * 2010-07-16 Yuriy Vashchuk - Histogram class simplification.
15 * Selection Window related methods has been
16 * implemented in Parent Histogram.
17 *******************************************************************************/
18 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.histogram
;
20 import org
.eclipse
.swt
.widgets
.Canvas
;
21 import org
.eclipse
.swt
.widgets
.Composite
;
22 import org
.eclipse
.swt
.widgets
.Display
;
25 * <b><u>HistogramCanvas</u></b>
27 * Canvas implementation aimed to draw histograms.
29 * This canvas goal is to display certain "HistogramContent" onto an histogram.<p>
30 * Several method exist to extend it so it should suit most needs.
32 public class HistogramCanvas
extends Canvas
34 private static HistogramView histogramView
= null;
36 protected AsyncCanvasRedrawer canvasRedrawer
= null;
37 protected HistogramContent histogramContent
= null;
40 // 2010-07-16 Yuriy: Moved to child classes.
41 protected HistogramCanvasPaintListener paintListener = null;
42 protected HistogramCanvasMouseListener mouseListener = null;
43 protected HistogramCanvasKeyListener keyListener = null;
44 protected HistogramCanvasControlListener controlListener = null;
46 protected HistogramCanvasFocusListener focusListener
= null;
49 // 2010-07-16 Yuriy: Moved to parent histogram class.
50 protected HistogramSelectedWindow currentWindow = null;
54 * HistogramCanvas constructor
56 * @param parent Composite control which will be the parent of the new instance (cannot be null)
57 * @param Style the style of control to construct
59 public HistogramCanvas(HistogramView histogramView
, Composite parent
, int style
) {
61 HistogramCanvas
.histogramView
= histogramView
;
65 // 2010-06-20 Yuriy: Moved to parent hitogram class.
66 // New selected window, not visible by default
67 createNewSelectedWindow(0L);
72 * Create the needed "event listeners" and hook them to the Canvas.
75 protected void addNeededListeners() {
76 createAndAddCanvasRedrawer();
77 createAndAddFocusListener();
80 // 2010-06-20 Yuriy: Moved to derived classes.
81 createAndAddPaintListener();
82 createAndAddMouseListener();
83 createAndAddKeyListener();
84 createAndAddControlListener();
89 * Create a canvas redrawer and bind it to this canvas.<p>
91 * Note : AsyncCanvasRedrawer is an internal class
92 * This is used to redraw the canvas from a different thread
93 * without^H^H^H with less danger.
95 protected void createAndAddCanvasRedrawer() {
96 canvasRedrawer
= new AsyncCanvasRedrawer(this);
100 * Create a histogram paint listener and bind it to this canvas.<p>
102 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasPaintListener
105 // 2010-07-16 Yuriy: Moved to derived classes.
106 protected void createAndAddPaintListener() {
107 paintListener = new HistogramCanvasPaintListener(this);
108 this.addPaintListener( paintListener );
112 * Create a histogram mouse listener and bind it to this canvas.<p>
113 * Note : this mouse listener handle the mouse, the move and the wheel at once.
115 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasMouseListener
118 // 2010-07-16 Yuriy: Moved to parent histogram class
119 protected void createAndAddMouseListener() {
120 mouseListener = new HistogramCanvasMouseListener(this);
121 this.addMouseListener(mouseListener);
122 this.addMouseMoveListener(mouseListener);
123 this.addMouseWheelListener(mouseListener);
128 * Create a histogram key listener and bind it to this canvas.<p>
130 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasKeyListener
133 // 2010-07-16 Yuriy: Moved to parent histogram class
134 protected void createAndAddKeyListener() {
135 keyListener = new HistogramCanvasKeyListener(this);
136 this.addKeyListener(keyListener);
140 * Create a histogram focus listener and bind it to this canvas.<p>
142 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasFocusListener
144 protected void createAndAddFocusListener() {
145 focusListener
= new HistogramCanvasFocusListener(this);
146 this.addFocusListener(focusListener
);
150 * Create a histogram control listener and bind it to this canvas.<p>
152 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
155 // 2010-07-16 Yuriy: Moved to derived classes.
156 protected void createAndAddControlListener() {
157 controlListener = new HistogramCanvasControlListener(this);
158 this.addControlListener(controlListener);
162 * Create a new HistogramContent for this HistogramCanvas<p>
163 * A new <I>empty</I> content will then be created.
165 * 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
166 * of the correct size.
168 * @param canvasSize Size of the parent canvas.
169 * @param widthPerBar Width of the histogram "bars"
170 * @param barsHeight Height of the histogram "bars"
171 * @param maxBarsDifferenceToAverage Factor used to "chop" bars that are too tall. Set to something big (100.0?) if not needed.
173 public void createNewHistogramContent(int canvasSize
, int widthPerBar
, int barsHeight
, double maxBarsDifferenceToAverage
) {
174 histogramContent
= new HistogramContent( canvasSize
/ widthPerBar
, canvasSize
, widthPerBar
, barsHeight
, maxBarsDifferenceToAverage
);
178 * Create a new selection window of the size (time width) given.<p>
179 * The window initial position is at X = 0.
180 * The window is created hidden, it won't be draw unless it is set to visible.<p>
182 * @param windowTimeDuration Time width (in nanosecond) of the window.
185 // 2010-07-16 Yuriy: Moved to parent histogram class.
186 public void createNewSelectedWindow(long windowTimeDuration) {
187 currentWindow = new HistogramSelectedWindow(histogramContent);
189 currentWindow.setWindowTimeWidth(windowTimeDuration);
190 currentWindow.setWindowXPositionCenter(0);
193 public HistogramContent
getHistogramContent() {
194 return histogramContent
;
198 * Getter for the selection window<p>
200 * @return the current selection window
202 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramSelectedWindow
205 // 2010-07-16 Yuriy: Moved to parent histogram class.
206 public HistogramSelectedWindow getCurrentWindow() {
207 return currentWindow;
212 * Getter for the selection window width<p>
214 * @return Time width (in nanosecond) of the selection window.
217 // 2010-07-16 Yuriy: Moved to parent histogram class.
218 public long getSelectedWindowSize() {
219 return currentWindow.getWindowTimeWidth();
224 * Setter for the selection window width<p>
225 * The window size will be ajusted if it does not respect one of these constraints :
226 * - The window size cannot be smaller than a single histogram content interval.<p>
227 * - The window size cannot be larger than twice the histogram content complete time interval.<p>
229 * @param newSelectedWindowSize New time width (in nanosecond) of the selection window.
232 // 2010-07-16 Yuriy: Moved to parent histogram class.
233 public void setSelectedWindowSize(long newSelectedWindowSize) {
235 if ( newSelectedWindowSize <= 0 ) {
236 newSelectedWindowSize = 1L;
238 else if ( newSelectedWindowSize > (2*histogramContent.getCompleteTimeInterval()) ) {
239 newSelectedWindowSize = (2*histogramContent.getCompleteTimeInterval());
242 currentWindow.setWindowTimeWidth(newSelectedWindowSize);
246 * Method to call the "Asynchronous redrawer" for this canvas<p>
247 * This allow safe redraw from different threads.
250 public void redrawAsynchronously() {
251 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
252 if ( canvasRedrawer
== null ) {
253 canvasRedrawer
= new AsyncCanvasRedrawer(this);
256 canvasRedrawer
.asynchronousRedraw();
260 * Method to call the "Asynchronous NotifyParentSelectionWindowChanged" for this canvas<p>
261 * This allow safe update UI objects from different threads.
265 // 2010-07-16 Yuriy: Moved to parent histogram class.
266 public void notifyParentSelectionWindowChangedAsynchronously() {
267 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
268 if ( canvasRedrawer == null ) {
269 canvasRedrawer = new AsyncCanvasRedrawer(this);
272 canvasRedrawer.asynchronousNotifyParentSelectionWindowChanged();
277 * Method to call the "Asynchronous NotifyParentUpdatedInformation" for this canvas<p>
278 * This allow safe redraw from different threads.
281 public void notifyParentUpdatedInformationAsynchronously() {
282 // Create a new redrawer in case it doesn't exist yet (we never know with thread!)
283 if ( canvasRedrawer
== null ) {
284 canvasRedrawer
= new AsyncCanvasRedrawer(this);
287 canvasRedrawer
.asynchronousNotifyParentUpdatedInformation();
291 * Function that is called when the selection window is moved.<p>
292 * Note: Given position should be relative to the previous (centered) absolute position.
294 * <B>METHOD INTENDED TO BE EXTENDED</B>
296 * @param newRelativeXPosition New position relative to the last known absolute position.
299 // 2010-07-16 Yuriy: Moved to parent histogram class.
300 public void moveWindow(int newRelativeXPosition) {
301 // Nothing : function is a place holder
306 * Function that is called when the selection window is re-centered.<p>
307 * Note: Given position should be absolute to the window and need to be the selection window center.
309 * <B>METHOD INTENDED TO BE EXTENDED</B>
311 * @param newRelativeXPosition New absolute position.
314 // 2010-07-16 Yuriy: Moved to parent histogram class.
315 public void setWindowCenterPosition(int newAbsoluteXPosition) {
316 // Nothing : function is a place holder
321 * Function that is called when the selection window size (time width) changed by an absolute time.<p>
322 * Note: Given time should be in nanoseconds, positive.
324 * <B>METHOD INTENDED TO BE EXTENDED</B>
326 * @param newTime New absoulte time (in nanoseconds) to apply to the window.
330 // 2010-07-16 Yuriy: Moved to parent histogram class.
331 public void resizeWindowByAbsoluteTime(long newTime) {
332 // Nothing : function is a place holder
336 * Function that is called to tell the parent that the selection window changed.<p>
338 * <B>METHOD INTENDED TO BE EXTENDED</B>
342 // 2010-07-16 Yuriy: Moved to parent histogram class.
343 public void notifyParentSelectionWindowChanged() {
344 // Nothing : function is a place holder
348 * Function that is called to tell the parent that some information changed.<p>
350 * <B>METHOD INTENDED TO BE EXTENDED</B>
353 public void notifyParentUpdatedInformation() {
354 // Nothing : function is a place holder
360 * @return view instance
363 public static HistogramView
getHistogramView() {
364 return histogramView
;
370 * @param histogramView reference to object
372 public static void setHistogramView(HistogramView histogramView
) {
373 HistogramCanvas
.histogramView
= histogramView
;
379 * <b><u>AsyncCanvasRedrawer Inner Class</u></b>
381 * Asynchronous redrawer for the HistogramCanvas
383 * This class role is to call method that update the UI on asynchronously.
384 * This should prevent any "invalid thread access" exception when trying to update UI from a different thread.
386 class AsyncCanvasRedrawer
{
388 private HistogramCanvas parentCanvas
= null;
391 * AsyncCanvasRedrawer constructor.
393 * @param newCanvas Related histogram canvas.
395 public AsyncCanvasRedrawer(HistogramCanvas newCanvas
) {
396 parentCanvas
= newCanvas
;
400 * Function to redraw the related canvas asynchonously.<p>
402 * Basically, it just run "canvas.redraw()" in asyncExec.
405 public void asynchronousRedraw() {
406 if ((parentCanvas
!= null) && (!parentCanvas
.isDisposed())) {
407 Display display
= parentCanvas
.getDisplay();
408 display
.asyncExec(new Runnable() {
410 if ((parentCanvas
!= null) && (!parentCanvas
.isDisposed())) {
411 parentCanvas
.redraw();
419 * Function to asynchronously notify the parent of the related canvas that the window changed.<p>
421 * Basically, it just run "notifyParentSelectionWindowChanged()" in asyncExec.
425 // 2010-07-16 Yuriy: Moved to parent histogram class.
426 public void asynchronousNotifyParentSelectionWindowChanged() {
427 if(parentCanvas != null) {
428 Display display = parentCanvas.getDisplay();
429 display.asyncExec(new Runnable() {
431 parentCanvas.notifyParentSelectionWindowChanged();
439 * Function to asynchonously notify the parent of the related canvas that information changed.<p>
441 * Basically, it just run "notifyParentUpdatedInformation()" in asyncExec.
444 public void asynchronousNotifyParentUpdatedInformation() {
445 if((parentCanvas
!= null) && (!parentCanvas
.isDisposed())) {
446 Display display
= parentCanvas
.getDisplay();
447 display
.asyncExec(new Runnable() {
449 if((parentCanvas
!= null) && (!parentCanvas
.isDisposed())) {
450 parentCanvas
.notifyParentUpdatedInformation();