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
11 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.histogram
;
14 import org
.eclipse
.swt
.widgets
.Canvas
;
15 import org
.eclipse
.swt
.widgets
.Composite
;
16 import org
.eclipse
.swt
.widgets
.Display
;
19 * <b><u>HistogramCanvas</u></b>
21 * Canvas implementation aimed to draw histograms.
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.
26 public class HistogramCanvas
extends Canvas
28 protected AsyncCanvasRedrawer canvasRedrawer
= null;
29 protected HistogramContent histogramContent
= null;
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;
37 protected HistogramSelectedWindow currentWindow
= null;
41 * HistogramCanvas constructor
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
46 public HistogramCanvas(Composite parent
, int style
) {
50 // New selected window, not visible by default
51 createNewSelectedWindow(0L);
55 * Create the needed "event listeners" and hook them to the Canvas.
57 protected void addNeededListeners() {
58 createAndAddCanvasRedrawer();
59 createAndAddPaintListener();
60 createAndAddMouseListener();
61 createAndAddKeyListener();
62 createAndAddFocusListener();
63 createAndAddControlListener();
67 * Create a canvas redrawer and bind it to this canvas.<p>
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.
73 protected void createAndAddCanvasRedrawer() {
74 canvasRedrawer
= new AsyncCanvasRedrawer(this);
78 * Create a histogram paint listener and bind it to this canvas.<p>
80 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasPaintListener
82 protected void createAndAddPaintListener() {
83 paintListener
= new HistogramCanvasPaintListener(this);
84 this.addPaintListener( paintListener
);
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.
91 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasMouseListener
93 protected void createAndAddMouseListener() {
94 mouseListener
= new HistogramCanvasMouseListener(this);
95 this.addMouseListener(mouseListener
);
96 this.addMouseMoveListener(mouseListener
);
97 this.addMouseWheelListener(mouseListener
);
101 * Create a histogram key listener and bind it to this canvas.<p>
103 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasKeyListener
105 protected void createAndAddKeyListener() {
106 keyListener
= new HistogramCanvasKeyListener(this);
107 this.addKeyListener(keyListener
);
111 * Create a histogram focus listener and bind it to this canvas.<p>
113 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasFocusListener
115 protected void createAndAddFocusListener() {
116 focusListener
= new HistogramCanvasFocusListener(this);
117 this.addFocusListener(focusListener
);
121 * Create a histogram control listener and bind it to this canvas.<p>
123 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramCanvasControlListener
125 protected void createAndAddControlListener() {
126 controlListener
= new HistogramCanvasControlListener(this);
127 this.addControlListener(controlListener
);
131 * Create a new HistogramContent for this HistogramCanvas<p>
132 * A new <I>empty</I> content will then be created.
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.
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.
142 public void createNewHistogramContent(int canvasSize
, int widthPerBar
, int barsHeight
, double maxBarsDifferenceToAverage
) {
143 histogramContent
= new HistogramContent( canvasSize
/ widthPerBar
, canvasSize
, widthPerBar
, barsHeight
, maxBarsDifferenceToAverage
);
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>
151 * @param windowTimeDuration Time width (in nanosecond) of the window.
153 public void createNewSelectedWindow(long windowTimeDuration
) {
154 currentWindow
= new HistogramSelectedWindow(histogramContent
);
156 currentWindow
.setWindowTimeWidth(windowTimeDuration
);
157 currentWindow
.setWindowXPositionCenter(0);
160 public HistogramContent
getHistogramContent() {
161 return histogramContent
;
165 * Getter for the selection window<p>
167 * @return the current selection window
169 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramSelectedWindow
171 public HistogramSelectedWindow
getCurrentWindow() {
172 return currentWindow
;
176 * Getter for the selection window width<p>
178 * @return Time width (in nanosecond) of the selection window.
180 public long getSelectedWindowSize() {
181 return currentWindow
.getWindowTimeWidth();
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>
190 * @param newSelectedWindowSize New time width (in nanosecond) of the selection window.
192 public void setSelectedWindowSize(long newSelectedWindowSize
) {
194 if ( newSelectedWindowSize
<= 0 ) {
195 newSelectedWindowSize
= 1L;
197 else if ( newSelectedWindowSize
> (2*histogramContent
.getCompleteTimeInterval()) ) {
198 newSelectedWindowSize
= (2*histogramContent
.getCompleteTimeInterval());
201 currentWindow
.setWindowTimeWidth(newSelectedWindowSize
);
205 * Method to call the "Asynchronous redrawer" for this canvas<p>
206 * This allow safe redraw from different threads.
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);
215 canvasRedrawer
.asynchronousRedraw();
219 * Method to call the "Asynchronous NotifyParentSelectionWindowChanged" for this canvas<p>
220 * This allow safe update UI objects from different threads.
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);
229 canvasRedrawer
.asynchronousNotifyParentSelectionWindowChanged();
233 * Method to call the "Asynchronous NotifyParentUpdatedInformation" for this canvas<p>
234 * This allow safe redraw from different threads.
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);
243 canvasRedrawer
.asynchronousNotifyParentUpdatedInformation();
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.
250 * <B>METHOD INTENDED TO BE EXTENDED</B>
252 * @param newRelativeXPosition New position relative to the last known absolute position.
254 public void moveWindow(int newRelativeXPosition
) {
255 // Nothing : function is a place holder
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.
262 * <B>METHOD INTENDED TO BE EXTENDED</B>
264 * @param newRelativeXPosition New absolute position.
266 public void setWindowCenterPosition(int newAbsoluteXPosition
) {
267 // Nothing : function is a place holder
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.
274 * <B>METHOD INTENDED TO BE EXTENDED</B>
276 * @param newTime New absoulte time (in nanoseconds) to apply to the window.
278 public void resizeWindowByAbsoluteTime(long newTime
) {
279 // Nothing : function is a place holder
283 * Function that is called to tell the parent that the selection window changed.<p>
285 * <B>METHOD INTENDED TO BE EXTENDED</B>
288 public void notifyParentSelectionWindowChanged() {
289 // Nothing : function is a place holder
293 * Function that is called to tell the parent that some information changed.<p>
295 * <B>METHOD INTENDED TO BE EXTENDED</B>
298 public void notifyParentUpdatedInformation() {
299 // Nothing : function is a place holder
305 * <b><u>AsyncCanvasRedrawer Inner Class</u></b>
307 * Asynchronous redrawer for the HistogramCanvas
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.
312 class AsyncCanvasRedrawer
{
314 private HistogramCanvas parentCanvas
= null;
317 * AsyncCanvasRedrawer constructor.
319 * @param newCanvas Related histogram canvas.
321 public AsyncCanvasRedrawer(HistogramCanvas newCanvas
) {
322 parentCanvas
= newCanvas
;
326 * Function to redraw the related canvas asynchonously.<p>
328 * Basically, it just run "canvas.redraw()" in asyncExec.
331 public void asynchronousRedraw() {
332 Display display
= parentCanvas
.getDisplay();
333 display
.asyncExec(new Runnable() {
335 parentCanvas
.redraw();
341 * Function to asynchonously notify the parent of the related canvas that the window changed.<p>
343 * Basically, it just run "notifyParentSelectionWindowChanged()" in asyncExec.
346 public void asynchronousNotifyParentSelectionWindowChanged() {
347 Display display
= parentCanvas
.getDisplay();
348 display
.asyncExec(new Runnable() {
350 parentCanvas
.notifyParentSelectionWindowChanged();
356 * Function to asynchonously notify the parent of the related canvas that information changed.<p>
358 * Basically, it just run "notifyParentUpdatedInformation()" in asyncExec.
361 public void asynchronousNotifyParentUpdatedInformation() {
362 Display display
= parentCanvas
.getDisplay();
363 display
.asyncExec(new Runnable() {
365 parentCanvas
.notifyParentUpdatedInformation();