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 * <b><u>HistogramZoom</u></b>
24 public class HistogramZoom
implements MouseWheelListener
{
26 // ------------------------------------------------------------------------
28 // ------------------------------------------------------------------------
30 private final static double ZOOM_FACTOR
= 0.8;
32 // ------------------------------------------------------------------------
34 // ------------------------------------------------------------------------
36 private final Histogram fHistogram
;
37 private final Canvas fCanvas
;
39 private long fAbsoluteStartTime
;
40 private long fAbsoluteEndTime
;
41 private final long fMinWindowSize
;
43 private long fRangeStartTime
;
44 private long fRangeDuration
;
46 private MouseScrollCounter fScrollCounter
;
48 // ------------------------------------------------------------------------
50 // ------------------------------------------------------------------------
52 public HistogramZoom(Histogram histogram
, Canvas canvas
, long start
, long end
) {
53 fHistogram
= histogram
;
55 fAbsoluteStartTime
= start
;
56 fAbsoluteEndTime
= end
;
57 fMinWindowSize
= fCanvas
.getBounds().x
;
59 fRangeStartTime
= fAbsoluteStartTime
;
60 fRangeDuration
= fAbsoluteStartTime
+ fMinWindowSize
;
62 canvas
.addMouseWheelListener(this);
65 // ------------------------------------------------------------------------
67 // ------------------------------------------------------------------------
69 public synchronized long getStartTime() {
70 return fRangeStartTime
;
73 public synchronized long getEndTime() {
74 return fRangeStartTime
+ fRangeDuration
;
77 public synchronized long getDuration() {
78 return fRangeDuration
;
81 // ------------------------------------------------------------------------
83 // ------------------------------------------------------------------------
85 public synchronized void stop() {
86 if (fScrollCounter
!= null) {
87 fScrollCounter
.interrupt();
88 fScrollCounter
= null;
92 public synchronized void setFullRange(long startTime
, long endTime
) {
93 fAbsoluteStartTime
= startTime
;
94 fAbsoluteEndTime
= endTime
;
97 public synchronized void setNewRange(long startTime
, long duration
) {
98 if (startTime
< fAbsoluteStartTime
)
99 startTime
= fAbsoluteStartTime
;
101 long endTime
= startTime
+ duration
;
102 if (endTime
> fAbsoluteEndTime
) {
103 endTime
= fAbsoluteEndTime
;
104 if (endTime
- duration
> fAbsoluteStartTime
)
105 startTime
= endTime
- duration
;
107 startTime
= fAbsoluteStartTime
;
111 fRangeStartTime
= startTime
;
112 fRangeDuration
= endTime
- startTime
;
115 // ------------------------------------------------------------------------
116 // MouseWheelListener
117 // ------------------------------------------------------------------------
119 private long fMouseTimestamp
= 0;
122 public synchronized void mouseScrolled(MouseEvent event
) {
123 if (fScrollCounter
== null) {
124 fScrollCounter
= new MouseScrollCounter(this);
125 fScrollCounter
.start();
126 fMouseTimestamp
= fHistogram
.getTimestamp(event
.x
);
128 fScrollCounter
.incrementMouseScroll(event
.count
);
131 private synchronized void zoom(int nbClicks
) {
132 // The job is finished
133 fScrollCounter
= null;
135 // Compute the new time range
136 long requestedRange
= (nbClicks
> 0) ? Math
.round(ZOOM_FACTOR
* fRangeDuration
) : (long) Math
.ceil(fRangeDuration
* (1.0 / ZOOM_FACTOR
));
138 // Perform a proportional zoom wrt the mouse position
139 double ratio
= ((double) (fMouseTimestamp
- fRangeStartTime
)) / fRangeDuration
;
140 long requestedStart
= validateStart(fRangeStartTime
+ (long) ((fRangeDuration
- requestedRange
) * ratio
));
141 long requestedEnd
= validateEnd(requestedStart
, requestedStart
+ requestedRange
);
142 requestedStart
= validateStart(requestedEnd
- requestedRange
);
144 fHistogram
.updateTimeRange(requestedStart
, requestedEnd
);
147 private long validateStart(long start
) {
148 if (start
< fAbsoluteStartTime
)
149 start
= fAbsoluteStartTime
;
150 if (start
> fAbsoluteEndTime
)
151 start
= fAbsoluteEndTime
- fMinWindowSize
;
155 private long validateEnd(long start
, long end
) {
156 if (end
> fAbsoluteEndTime
)
157 end
= fAbsoluteEndTime
;
158 if (end
< start
+ fMinWindowSize
)
159 end
= start
+ fMinWindowSize
;
163 // ------------------------------------------------------------------------
164 // DelayedMouseScroll
165 // ------------------------------------------------------------------------
167 private static class MouseScrollCounter
extends Thread
{
169 // --------------------------------------------------------------------
171 // --------------------------------------------------------------------
173 private final static long QUIET_TIME
= 100L;
174 private final static long POLLING_INTERVAL
= 10L;
176 // --------------------------------------------------------------------
178 // --------------------------------------------------------------------
180 private HistogramZoom fZoom
= null;
182 private long fLastPoolTime
= 0L;
183 private int nbScrollClick
= 0;
185 // --------------------------------------------------------------------
187 // --------------------------------------------------------------------
189 public MouseScrollCounter(HistogramZoom zoom
) {
191 fLastPoolTime
= System
.currentTimeMillis();
194 // --------------------------------------------------------------------
196 // --------------------------------------------------------------------
198 public void incrementMouseScroll(int nbScrolls
) {
199 fLastPoolTime
= System
.currentTimeMillis();
200 nbScrollClick
+= nbScrolls
;
203 // --------------------------------------------------------------------
205 // --------------------------------------------------------------------
209 while ((System
.currentTimeMillis() - fLastPoolTime
) < QUIET_TIME
) {
211 Thread
.sleep(POLLING_INTERVAL
);
212 } catch (Exception e
) {
216 // Done waiting. Notify the histogram.
217 if (!isInterrupted())
218 fZoom
.zoom(nbScrollClick
);