1 /*******************************************************************************
2 * Copyright (c) 2011, 2012 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 // ------------------------------------------------------------------------
55 public HistogramZoom(Histogram histogram
, Canvas canvas
, long start
, long end
) {
56 fHistogram
= histogram
;
58 fAbsoluteStartTime
= start
;
59 fAbsoluteEndTime
= end
;
60 fMinWindowSize
= fCanvas
.getBounds().x
;
62 fRangeStartTime
= fAbsoluteStartTime
;
63 fRangeDuration
= fAbsoluteStartTime
+ fMinWindowSize
;
65 canvas
.addMouseWheelListener(this);
68 // ------------------------------------------------------------------------
70 // ------------------------------------------------------------------------
73 * Get start time of the zoom window.
74 * @return the start time.
76 public synchronized long getStartTime() {
77 return fRangeStartTime
;
81 * Get the end time of the zoom window.
82 * @return the end time
84 public synchronized long getEndTime() {
85 return fRangeStartTime
+ fRangeDuration
;
89 * Get the duration of the zoom window.
90 * @return the duration of the zoom window.
92 public synchronized long getDuration() {
93 return fRangeDuration
;
96 // ------------------------------------------------------------------------
98 // ------------------------------------------------------------------------
101 * Stops the zooming (multiple consecutive execution)
103 public synchronized void stop() {
104 if (fScrollCounter
!= null) {
105 fScrollCounter
.interrupt();
106 fScrollCounter
= null;
111 * The the full time range of the histogram
113 * @param startTime the start time the histogram
114 * @param endTime the end time of the histogram
116 public synchronized void setFullRange(long startTime
, long endTime
) {
117 fAbsoluteStartTime
= startTime
;
118 fAbsoluteEndTime
= endTime
;
122 * Sets the new zoom window
123 * @param startTime the start time
124 * @param duration the duration
126 public synchronized void setNewRange(long startTime
, long duration
) {
127 if (startTime
< fAbsoluteStartTime
)
128 startTime
= fAbsoluteStartTime
;
130 long endTime
= startTime
+ duration
;
131 if (endTime
> fAbsoluteEndTime
) {
132 endTime
= fAbsoluteEndTime
;
133 if (endTime
- duration
> fAbsoluteStartTime
)
134 startTime
= endTime
- duration
;
136 startTime
= fAbsoluteStartTime
;
140 fRangeStartTime
= startTime
;
141 fRangeDuration
= endTime
- startTime
;
144 // ------------------------------------------------------------------------
145 // MouseWheelListener
146 // ------------------------------------------------------------------------
148 private long fMouseTimestamp
= 0;
151 public synchronized void mouseScrolled(MouseEvent event
) {
152 if (fScrollCounter
== null) {
153 fScrollCounter
= new MouseScrollCounter(this);
154 fScrollCounter
.start();
155 fMouseTimestamp
= fHistogram
.getTimestamp(event
.x
);
157 fScrollCounter
.incrementMouseScroll(event
.count
);
160 private synchronized void zoom(int nbClicks
) {
161 // The job is finished
162 fScrollCounter
= null;
164 // Compute the new time range
165 long requestedRange
= (nbClicks
> 0) ? Math
.round(ZOOM_FACTOR
* fRangeDuration
) : (long) Math
.ceil(fRangeDuration
* (1.0 / ZOOM_FACTOR
));
167 // Perform a proportional zoom wrt the mouse position
168 double ratio
= ((double) (fMouseTimestamp
- fRangeStartTime
)) / fRangeDuration
;
169 long requestedStart
= validateStart(fRangeStartTime
+ (long) ((fRangeDuration
- requestedRange
) * ratio
));
170 long requestedEnd
= validateEnd(requestedStart
, requestedStart
+ requestedRange
);
171 requestedStart
= validateStart(requestedEnd
- requestedRange
);
173 fHistogram
.updateTimeRange(requestedStart
, requestedEnd
);
176 private long validateStart(long start
) {
177 if (start
< fAbsoluteStartTime
)
178 start
= fAbsoluteStartTime
;
179 if (start
> fAbsoluteEndTime
)
180 start
= fAbsoluteEndTime
- fMinWindowSize
;
184 private long validateEnd(long start
, long end
) {
185 if (end
> fAbsoluteEndTime
)
186 end
= fAbsoluteEndTime
;
187 if (end
< start
+ fMinWindowSize
)
188 end
= start
+ fMinWindowSize
;
192 // ------------------------------------------------------------------------
193 // DelayedMouseScroll
194 // ------------------------------------------------------------------------
196 private static class MouseScrollCounter
extends Thread
{
198 // --------------------------------------------------------------------
200 // --------------------------------------------------------------------
202 private final static long QUIET_TIME
= 100L;
203 private final static long POLLING_INTERVAL
= 10L;
205 // --------------------------------------------------------------------
207 // --------------------------------------------------------------------
209 private HistogramZoom fZoom
= null;
211 private long fLastPoolTime
= 0L;
212 private int nbScrollClick
= 0;
214 // --------------------------------------------------------------------
216 // --------------------------------------------------------------------
219 * Constructor of inner class to handle consecutive scrolls of mouse wheel.
220 * @param zoom the histogram zoom reference
222 public MouseScrollCounter(HistogramZoom zoom
) {
224 fLastPoolTime
= System
.currentTimeMillis();
227 // --------------------------------------------------------------------
229 // --------------------------------------------------------------------
232 * Increments the number of scroll clicks.
233 * @param nbScrolls the number to add to the current value
235 public void incrementMouseScroll(int nbScrolls
) {
236 fLastPoolTime
= System
.currentTimeMillis();
237 nbScrollClick
+= nbScrolls
;
240 // --------------------------------------------------------------------
242 // --------------------------------------------------------------------
246 while ((System
.currentTimeMillis() - fLastPoolTime
) < QUIET_TIME
) {
248 Thread
.sleep(POLLING_INTERVAL
);
249 } catch (Exception e
) {
253 // Done waiting. Notify the histogram.
254 if (!isInterrupted())
255 fZoom
.zoom(nbScrollClick
);