1 /*******************************************************************************
2 * Copyright (c) 2011, 2013 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 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Moved from LTTng to TMF
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.histogram
;
16 import org
.eclipse
.swt
.events
.MouseEvent
;
17 import org
.eclipse
.swt
.events
.MouseWheelListener
;
18 import org
.eclipse
.swt
.widgets
.Canvas
;
21 * Class to handle zooming within histogram windows..
24 * @author Francois Chouinard
27 public class HistogramZoom
implements MouseWheelListener
{
29 // ------------------------------------------------------------------------
31 // ------------------------------------------------------------------------
33 private final static double ZOOM_FACTOR
= 0.8;
35 // ------------------------------------------------------------------------
37 // ------------------------------------------------------------------------
39 private final Histogram fHistogram
;
40 private final Canvas fCanvas
;
42 private long fAbsoluteStartTime
;
43 private long fAbsoluteEndTime
;
44 private final long fMinWindowSize
;
46 private long fRangeStartTime
;
47 private long fRangeDuration
;
49 private MouseScrollCounter fScrollCounter
;
51 // ------------------------------------------------------------------------
53 // ------------------------------------------------------------------------
56 * Standard constructor.
59 * The parent histogram object
63 * The start time of the zoom area
65 * The end time of the zoom area
67 public HistogramZoom(Histogram histogram
, Canvas canvas
, long start
,
69 fHistogram
= histogram
;
71 fAbsoluteStartTime
= start
;
72 fAbsoluteEndTime
= end
;
73 fMinWindowSize
= fCanvas
.getBounds().x
;
75 fRangeStartTime
= fAbsoluteStartTime
;
76 fRangeDuration
= fAbsoluteStartTime
+ fMinWindowSize
;
78 canvas
.addMouseWheelListener(this);
81 // ------------------------------------------------------------------------
83 // ------------------------------------------------------------------------
86 * Get start time of the zoom window.
87 * @return the start time.
89 public synchronized long getStartTime() {
90 return fRangeStartTime
;
94 * Get the end time of the zoom window.
95 * @return the end time
97 public synchronized long getEndTime() {
98 return fRangeStartTime
+ fRangeDuration
;
102 * Get the duration of the zoom window.
103 * @return the duration of the zoom window.
105 public synchronized long getDuration() {
106 return fRangeDuration
;
109 // ------------------------------------------------------------------------
111 // ------------------------------------------------------------------------
114 * Stops the zooming (multiple consecutive execution)
116 public synchronized void stop() {
117 if (fScrollCounter
!= null) {
118 fScrollCounter
.interrupt();
119 fScrollCounter
= null;
124 * The the full time range of the histogram
126 * @param startTime the start time the histogram
127 * @param endTime the end time of the histogram
129 public synchronized void setFullRange(long startTime
, long endTime
) {
130 fAbsoluteStartTime
= startTime
;
131 fAbsoluteEndTime
= endTime
;
135 * Sets the new zoom window
136 * @param startTime the start time
137 * @param duration the duration
139 public synchronized void setNewRange(long startTime
, long duration
) {
140 long realStart
= startTime
;
142 if (realStart
< fAbsoluteStartTime
) {
143 realStart
= fAbsoluteStartTime
;
146 long endTime
= realStart
+ duration
;
147 if (endTime
> fAbsoluteEndTime
) {
148 endTime
= fAbsoluteEndTime
;
149 if (endTime
- duration
> fAbsoluteStartTime
) {
150 realStart
= endTime
- duration
;
152 realStart
= fAbsoluteStartTime
;
156 fRangeStartTime
= realStart
;
157 fRangeDuration
= endTime
- realStart
;
160 // ------------------------------------------------------------------------
161 // MouseWheelListener
162 // ------------------------------------------------------------------------
165 public synchronized void mouseScrolled(MouseEvent event
) {
166 if (fScrollCounter
== null) {
167 fScrollCounter
= new MouseScrollCounter(this);
168 fScrollCounter
.start();
170 fScrollCounter
.incrementMouseScroll(event
.count
);
173 private synchronized void zoom(int nbClicks
) {
174 // The job is finished
175 fScrollCounter
= null;
177 // Compute the new time range
178 long requestedRange
= (nbClicks
> 0) ? Math
.round(ZOOM_FACTOR
* fRangeDuration
) : (long) Math
.ceil(fRangeDuration
* (1.0 / ZOOM_FACTOR
));
180 // Distribute delta and adjust for boundaries
181 long requestedStart
= validateStart(fRangeStartTime
+ (fRangeDuration
- requestedRange
) / 2);
182 long requestedEnd
= validateEnd(requestedStart
, requestedStart
+ requestedRange
);
183 requestedStart
= validateStart(requestedEnd
- requestedRange
);
185 fHistogram
.updateTimeRange(requestedStart
, requestedEnd
);
188 private long validateStart(long start
) {
189 long realStart
= start
;
191 if (realStart
< fAbsoluteStartTime
) {
192 realStart
= fAbsoluteStartTime
;
194 if (realStart
> fAbsoluteEndTime
) {
195 realStart
= fAbsoluteEndTime
- fMinWindowSize
;
200 private long validateEnd(long start
, long end
) {
203 if (realEnd
> fAbsoluteEndTime
) {
204 realEnd
= fAbsoluteEndTime
;
206 if (realEnd
< start
+ fMinWindowSize
) {
207 realEnd
= start
+ fMinWindowSize
;
212 // ------------------------------------------------------------------------
213 // DelayedMouseScroll
214 // ------------------------------------------------------------------------
216 private static class MouseScrollCounter
extends Thread
{
218 // --------------------------------------------------------------------
220 // --------------------------------------------------------------------
222 private final static long QUIET_TIME
= 100L;
223 private final static long POLLING_INTERVAL
= 10L;
225 // --------------------------------------------------------------------
227 // --------------------------------------------------------------------
229 private HistogramZoom fZoom
= null;
231 private long fLastPoolTime
= 0L;
232 private int nbScrollClick
= 0;
234 // --------------------------------------------------------------------
236 // --------------------------------------------------------------------
239 * Constructor of inner class to handle consecutive scrolls of mouse wheel.
240 * @param zoom the histogram zoom reference
242 public MouseScrollCounter(HistogramZoom zoom
) {
244 fLastPoolTime
= System
.currentTimeMillis();
247 // --------------------------------------------------------------------
249 // --------------------------------------------------------------------
252 * Increments the number of scroll clicks.
253 * @param nbScrolls the number to add to the current value
255 public void incrementMouseScroll(int nbScrolls
) {
256 fLastPoolTime
= System
.currentTimeMillis();
257 nbScrollClick
+= nbScrolls
;
260 // --------------------------------------------------------------------
262 // --------------------------------------------------------------------
266 while ((System
.currentTimeMillis() - fLastPoolTime
) < QUIET_TIME
) {
268 Thread
.sleep(POLLING_INTERVAL
);
269 } catch (Exception e
) {
273 // Done waiting. Notify the histogram.
274 if (!isInterrupted()) {
275 fZoom
.zoom(nbScrollClick
);