Commit | Line | Data |
---|---|---|
c392540b | 1 | /******************************************************************************* |
e0752744 | 2 | * Copyright (c) 2011, 2012 Ericsson |
c392540b FC |
3 | * |
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 | |
8 | * | |
9 | * Contributors: | |
10 | * Francois Chouinard - Initial API and implementation | |
e0752744 | 11 | * Francois Chouinard - Moved from LTTng to TMF |
c392540b FC |
12 | *******************************************************************************/ |
13 | ||
e0752744 | 14 | package org.eclipse.linuxtools.tmf.ui.views.histogram; |
c392540b FC |
15 | |
16 | import org.eclipse.swt.events.MouseEvent; | |
17 | import org.eclipse.swt.events.MouseWheelListener; | |
18 | import org.eclipse.swt.widgets.Canvas; | |
19 | ||
20 | /** | |
b544077e BH |
21 | * Class to handle zooming within histogram windows.. |
22 | * | |
23 | * @version 1.0 | |
24 | * @author Francois Chouinard | |
c392540b | 25 | * <p> |
c392540b FC |
26 | */ |
27 | public class HistogramZoom implements MouseWheelListener { | |
28 | ||
29 | // ------------------------------------------------------------------------ | |
30 | // Constants | |
31 | // ------------------------------------------------------------------------ | |
32 | ||
33 | private final static double ZOOM_FACTOR = 0.8; | |
34 | ||
35 | // ------------------------------------------------------------------------ | |
36 | // Attributes | |
37 | // ------------------------------------------------------------------------ | |
38 | ||
39 | private final Histogram fHistogram; | |
40 | private final Canvas fCanvas; | |
41 | ||
42 | private long fAbsoluteStartTime; | |
43 | private long fAbsoluteEndTime; | |
44 | private final long fMinWindowSize; | |
45 | ||
46 | private long fRangeStartTime; | |
47 | private long fRangeDuration; | |
48 | ||
49 | private MouseScrollCounter fScrollCounter; | |
50 | ||
51 | // ------------------------------------------------------------------------ | |
e0752744 | 52 | // Constructors |
c392540b FC |
53 | // ------------------------------------------------------------------------ |
54 | ||
55 | public HistogramZoom(Histogram histogram, Canvas canvas, long start, long end) { | |
56 | fHistogram = histogram; | |
57 | fCanvas = canvas; | |
58 | fAbsoluteStartTime = start; | |
59 | fAbsoluteEndTime = end; | |
60 | fMinWindowSize = fCanvas.getBounds().x; | |
61 | ||
62 | fRangeStartTime = fAbsoluteStartTime; | |
63 | fRangeDuration = fAbsoluteStartTime + fMinWindowSize; | |
64 | ||
65 | canvas.addMouseWheelListener(this); | |
66 | } | |
67 | ||
68 | // ------------------------------------------------------------------------ | |
69 | // Accessors | |
70 | // ------------------------------------------------------------------------ | |
71 | ||
b544077e BH |
72 | /** |
73 | * Get start time of the zoom window. | |
74 | * @return the start time. | |
75 | */ | |
5a5c2fc7 | 76 | public synchronized long getStartTime() { |
c392540b FC |
77 | return fRangeStartTime; |
78 | } | |
79 | ||
b544077e BH |
80 | /** |
81 | * Get the end time of the zoom window. | |
82 | * @return the end time | |
83 | */ | |
5a5c2fc7 | 84 | public synchronized long getEndTime() { |
c392540b FC |
85 | return fRangeStartTime + fRangeDuration; |
86 | } | |
87 | ||
b544077e BH |
88 | /** |
89 | * Get the duration of the zoom window. | |
90 | * @return the duration of the zoom window. | |
91 | */ | |
5a5c2fc7 | 92 | public synchronized long getDuration() { |
c392540b FC |
93 | return fRangeDuration; |
94 | } | |
95 | ||
96 | // ------------------------------------------------------------------------ | |
97 | // Operations | |
98 | // ------------------------------------------------------------------------ | |
99 | ||
b544077e BH |
100 | /** |
101 | * Stops the zooming (multiple consecutive execution) | |
102 | */ | |
c392540b FC |
103 | public synchronized void stop() { |
104 | if (fScrollCounter != null) { | |
105 | fScrollCounter.interrupt(); | |
106 | fScrollCounter = null; | |
107 | } | |
108 | } | |
109 | ||
b544077e BH |
110 | /** |
111 | * The the full time range of the histogram | |
112 | * | |
113 | * @param startTime the start time the histogram | |
114 | * @param endTime the end time of the histogram | |
115 | */ | |
8edafa7f | 116 | public synchronized void setFullRange(long startTime, long endTime) { |
c392540b FC |
117 | fAbsoluteStartTime = startTime; |
118 | fAbsoluteEndTime = endTime; | |
119 | } | |
120 | ||
b544077e BH |
121 | /** |
122 | * Sets the new zoom window | |
123 | * @param startTime the start time | |
124 | * @param duration the duration | |
125 | */ | |
8edafa7f | 126 | public synchronized void setNewRange(long startTime, long duration) { |
c392540b FC |
127 | if (startTime < fAbsoluteStartTime) |
128 | startTime = fAbsoluteStartTime; | |
129 | ||
130 | long endTime = startTime + duration; | |
131 | if (endTime > fAbsoluteEndTime) { | |
132 | endTime = fAbsoluteEndTime; | |
133 | if (endTime - duration > fAbsoluteStartTime) | |
134 | startTime = endTime - duration; | |
135 | else { | |
136 | startTime = fAbsoluteStartTime; | |
137 | } | |
138 | } | |
139 | ||
140 | fRangeStartTime = startTime; | |
141 | fRangeDuration = endTime - startTime; | |
142 | } | |
143 | ||
144 | // ------------------------------------------------------------------------ | |
145 | // MouseWheelListener | |
146 | // ------------------------------------------------------------------------ | |
147 | ||
148 | private long fMouseTimestamp = 0; | |
149 | ||
150 | @Override | |
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); | |
156 | } | |
157 | fScrollCounter.incrementMouseScroll(event.count); | |
158 | } | |
159 | ||
160 | private synchronized void zoom(int nbClicks) { | |
161 | // The job is finished | |
162 | fScrollCounter = null; | |
163 | ||
164 | // Compute the new time range | |
165 | long requestedRange = (nbClicks > 0) ? Math.round(ZOOM_FACTOR * fRangeDuration) : (long) Math.ceil(fRangeDuration * (1.0 / ZOOM_FACTOR)); | |
166 | ||
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); | |
172 | ||
173 | fHistogram.updateTimeRange(requestedStart, requestedEnd); | |
174 | } | |
175 | ||
176 | private long validateStart(long start) { | |
177 | if (start < fAbsoluteStartTime) | |
178 | start = fAbsoluteStartTime; | |
179 | if (start > fAbsoluteEndTime) | |
180 | start = fAbsoluteEndTime - fMinWindowSize; | |
181 | return start; | |
182 | } | |
183 | ||
184 | private long validateEnd(long start, long end) { | |
185 | if (end > fAbsoluteEndTime) | |
186 | end = fAbsoluteEndTime; | |
187 | if (end < start + fMinWindowSize) | |
188 | end = start + fMinWindowSize; | |
189 | return end; | |
190 | } | |
191 | ||
192 | // ------------------------------------------------------------------------ | |
193 | // DelayedMouseScroll | |
194 | // ------------------------------------------------------------------------ | |
195 | ||
5a5c2fc7 | 196 | private static class MouseScrollCounter extends Thread { |
c392540b FC |
197 | |
198 | // -------------------------------------------------------------------- | |
199 | // Constants | |
200 | // -------------------------------------------------------------------- | |
201 | ||
202 | private final static long QUIET_TIME = 100L; | |
203 | private final static long POLLING_INTERVAL = 10L; | |
204 | ||
205 | // -------------------------------------------------------------------- | |
206 | // Attributes | |
207 | // -------------------------------------------------------------------- | |
208 | ||
209 | private HistogramZoom fZoom = null; | |
210 | ||
211 | private long fLastPoolTime = 0L; | |
212 | private int nbScrollClick = 0; | |
213 | ||
214 | // -------------------------------------------------------------------- | |
e0752744 | 215 | // Constructors |
c392540b FC |
216 | // -------------------------------------------------------------------- |
217 | ||
b544077e BH |
218 | /** |
219 | * Constructor of inner class to handle consecutive scrolls of mouse wheel. | |
220 | * @param zoom the histogram zoom reference | |
221 | */ | |
c392540b FC |
222 | public MouseScrollCounter(HistogramZoom zoom) { |
223 | fZoom = zoom; | |
224 | fLastPoolTime = System.currentTimeMillis(); | |
225 | } | |
226 | ||
227 | // -------------------------------------------------------------------- | |
228 | // Operation | |
229 | // -------------------------------------------------------------------- | |
b544077e BH |
230 | |
231 | /** | |
232 | * Increments the number of scroll clicks. | |
233 | * @param nbScrolls the number to add to the current value | |
234 | */ | |
c392540b FC |
235 | public void incrementMouseScroll(int nbScrolls) { |
236 | fLastPoolTime = System.currentTimeMillis(); | |
237 | nbScrollClick += nbScrolls; | |
238 | } | |
239 | ||
240 | // -------------------------------------------------------------------- | |
241 | // Thread | |
242 | // -------------------------------------------------------------------- | |
243 | ||
244 | @Override | |
245 | public void run() { | |
246 | while ((System.currentTimeMillis() - fLastPoolTime) < QUIET_TIME) { | |
247 | try { | |
248 | Thread.sleep(POLLING_INTERVAL); | |
249 | } catch (Exception e) { | |
250 | return; | |
251 | } | |
252 | } | |
253 | // Done waiting. Notify the histogram. | |
254 | if (!isInterrupted()) | |
255 | fZoom.zoom(nbScrollClick); | |
256 | } | |
257 | } | |
258 | ||
259 | } |