Commit | Line | Data |
---|---|---|
6e512b93 ASL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009 Ericsson | |
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 | * William Bourque - Initial API and implementation | |
3e9fdb8b FC |
11 | * |
12 | * Modifications: | |
13 | * 2010-06-20 Yuriy Vashchuk - Selection "red square" window optimisation. | |
14 | * Null pointer exception correction. | |
6e512b93 ASL |
15 | *******************************************************************************/ |
16 | package org.eclipse.linuxtools.lttng.ui.views.histogram; | |
17 | ||
18 | import org.eclipse.swt.events.MouseEvent; | |
19 | import org.eclipse.swt.events.MouseListener; | |
20 | import org.eclipse.swt.events.MouseMoveListener; | |
21 | import org.eclipse.swt.events.MouseWheelListener; | |
22 | ||
23 | /** | |
24 | * <b><u>HistogramCanvasMouseListener</u></b> | |
25 | * <p> | |
26 | * Implementation of a MouseListener for the need of the HistogramCanvas | |
27 | * <p> | |
28 | */ | |
29 | public class HistogramCanvasMouseListener implements MouseMoveListener, MouseListener, MouseWheelListener | |
30 | { | |
f05aabed FC |
31 | private DelayedMouseScroll mouseScrollListener = null; |
32 | private ParentHistogramCanvas parentCanvas = null; | |
33 | private int oldWindowXPositionCenter = 0; | |
6e512b93 | 34 | |
f05aabed | 35 | private boolean isWindowMoving = false; |
6e512b93 ASL |
36 | |
37 | /** | |
38 | * HistogramCanvasMouseListener constructor | |
39 | * | |
40 | * @param newCanvas Related canvas | |
41 | */ | |
f05aabed | 42 | public HistogramCanvasMouseListener(ParentHistogramCanvas newCanvas) { |
6e512b93 ASL |
43 | parentCanvas = newCanvas; |
44 | } | |
45 | ||
46 | /** | |
47 | * Function called when the mouse is moved.<p> | |
48 | * If the mouse button is clicked, we will move the selection window. | |
49 | * | |
50 | * @param event The generated mouse event when the mouse moved. | |
51 | */ | |
d4011df2 | 52 | @Override |
6e512b93 | 53 | public void mouseMove(MouseEvent event) { |
3e9fdb8b | 54 | if ( parentCanvas.getHistogramContent() != null && isWindowMoving == true ) { |
f05aabed | 55 | |
1406f802 | 56 | parentCanvas.setWindowCenterPosition(event.x); |
6e512b93 ASL |
57 | } |
58 | } | |
59 | ||
60 | /** | |
61 | * Function called when the mouse buttons are clicked.<p> | |
62 | * If the button is the first one (left button), turn on the "move window" mode | |
63 | * | |
64 | * @param event The generated mouse event when the mouse button was pressed. | |
65 | */ | |
d4011df2 | 66 | @Override |
6e512b93 | 67 | public void mouseDown(MouseEvent event) { |
3e9fdb8b | 68 | if ( parentCanvas.getHistogramContent() != null && event.button == 1) { |
6e512b93 | 69 | isWindowMoving = true; |
f05aabed FC |
70 | |
71 | oldWindowXPositionCenter = parentCanvas.getCurrentWindow().getWindowXPositionCenter(); | |
1406f802 | 72 | parentCanvas.setWindowCenterPosition(event.x); |
6e512b93 ASL |
73 | } |
74 | } | |
75 | ||
76 | /** | |
77 | * Function called when the mouse buttons are released.<p> | |
78 | * If the button is the first one (left button), turn off the "move window" mode | |
79 | * | |
80 | * @param event The generated mouse event when the mouse button was released. | |
81 | */ | |
d4011df2 | 82 | @Override |
6e512b93 | 83 | public void mouseUp(MouseEvent event) { |
3e9fdb8b | 84 | if ( parentCanvas.getHistogramContent() != null && event.button == 1) { |
6e512b93 | 85 | isWindowMoving = false; |
f05aabed FC |
86 | |
87 | if( oldWindowXPositionCenter != parentCanvas.getCurrentWindow().getWindowXPositionCenter()) { | |
88 | parentCanvas.notifyParentSelectionWindowChangedAsynchronously(); | |
89 | } | |
6e512b93 ASL |
90 | } |
91 | } | |
92 | ||
93 | /** | |
94 | * Function called when the mouse perform a double-click.<p> | |
95 | * Don't do anything yet... | |
96 | * | |
97 | * @param event The generated mouse event when the mouse double-click was issued. | |
98 | */ | |
d4011df2 | 99 | @Override |
6e512b93 | 100 | public void mouseDoubleClick(MouseEvent event) { |
550d787e | 101 | // System.out.println("mouseDoubleClick"); |
6e512b93 ASL |
102 | } |
103 | ||
104 | /** | |
105 | * Function called when the mouse scroll button is used.<p> | |
106 | * Start a "ScrollListener" that will wait for more scroll clicks as they are asynchonous. | |
107 | * After a certain delay, the parent canvas will get notified. | |
108 | * | |
109 | * @param event The generated mouse event when the mouse scroll was spinned. | |
110 | */ | |
d4011df2 | 111 | @Override |
6e512b93 ASL |
112 | public void mouseScrolled(MouseEvent event) { |
113 | ||
114 | // Start a scrollListener if none exist yet and start its thread | |
115 | // Otherwise, we will just notify the one that is currenly alive... | |
116 | // Badly timed event could happen while the thread is dying but we can live with loss scroll events, I believe. | |
117 | if ( mouseScrollListener == null ) { | |
118 | mouseScrollListener = new DelayedMouseScroll(this, HistogramConstant.FULL_WAIT_MS_TIME_BETWEEN_MOUSE_SCROLL, HistogramConstant.INTERVAL_WAIT_MS_TIME_BETWEEN_POLL ); | |
119 | mouseScrollListener.start(); | |
120 | } | |
121 | ||
122 | // *** NOTE *** | |
123 | // We need to refer to the "count" to know if the scroll is done backward or forward. | |
124 | // Positive count mean it is done backward (from the wall in the direction of the hand) | |
125 | // Negative count mean it is done backward (from the hand in the direction of the wall) | |
126 | if ( event.count > 0) { | |
127 | mouseScrollListener.incrementMouseScroll(); | |
128 | } | |
129 | else { | |
130 | mouseScrollListener.decrementMouseScroll(); | |
131 | } | |
132 | } | |
f05aabed FC |
133 | |
134 | /** | |
135 | * This will calculate the correct zoom time and call the canvas to resize its selection window. | |
136 | * | |
137 | * @param nbMouseScroll | |
138 | * @return new window timerange | |
139 | */ | |
140 | public long receiveMouseScrollCount(int nbMouseScroll) { | |
141 | ||
142 | double ajustedTime = 0; | |
143 | long selectedWindowSize = parentCanvas.getSelectedWindowSize(); | |
144 | ||
145 | // If we received Negative scroll event, ZoomOut by ZOOM_OUT_FACTOR * the number of scroll events received. | |
146 | if ( nbMouseScroll < 0 ) { | |
147 | ajustedTime = (double)selectedWindowSize * HistogramConstant.ZOOM_OUT_FACTOR; | |
148 | ajustedTime = ajustedTime * Math.abs(nbMouseScroll); | |
149 | ajustedTime = selectedWindowSize + ajustedTime; | |
150 | } | |
151 | // If we received Positive scroll event, ZoomIn by ZOOM_IN_FACTOR * the number of scroll events received. | |
152 | else { | |
153 | if(selectedWindowSize > 2) { | |
154 | ajustedTime = (double)selectedWindowSize * HistogramConstant.ZOOM_IN_FACTOR; | |
155 | ajustedTime = ajustedTime * Math.abs(nbMouseScroll); | |
156 | ajustedTime = selectedWindowSize - ajustedTime; | |
157 | } | |
158 | } | |
159 | ||
160 | return (long)ajustedTime; | |
161 | ||
162 | } | |
6e512b93 ASL |
163 | |
164 | /** | |
165 | * Function that will be called at the end of the "wait time" for scroll events.<p> | |
166 | * This will calculate the correct zoom time and call the canvas to resize its selection window. | |
167 | * | |
168 | * @param nbMouseScroll | |
169 | */ | |
f05aabed | 170 | public void receiveMouseScrollCountWithNotification(int nbMouseScroll) { |
6e512b93 | 171 | |
3e9fdb8b | 172 | if(parentCanvas.getHistogramContent() != null) { |
6e512b93 | 173 | |
3e9fdb8b FC |
174 | mouseScrollListener = null; |
175 | ||
f05aabed FC |
176 | // Resize the canvas selection window |
177 | parentCanvas.resizeWindowByAbsoluteTime( receiveMouseScrollCount(nbMouseScroll) ); | |
178 | } | |
179 | } | |
180 | ||
181 | /** | |
182 | * Function that will be called on mouse scroll.<p> | |
183 | * This will calculate the correct zoom time and call the canvas to resize its selection window. | |
184 | * | |
185 | * @param nbMouseScroll | |
186 | */ | |
187 | public void receiveMouseScrollCountWithoutNotification(int nbMouseScroll) { | |
188 | if(parentCanvas.getHistogramContent() != null) { | |
3e9fdb8b FC |
189 | |
190 | // Resize the canvas selection window | |
f05aabed | 191 | parentCanvas.resizeWindowByAbsoluteTimeWithoutNotification( receiveMouseScrollCount(nbMouseScroll) ); |
6e512b93 | 192 | } |
6e512b93 | 193 | } |
f05aabed | 194 | |
6e512b93 ASL |
195 | } |
196 | ||
197 | /** | |
198 | * <b><u>DelayedMouseScroll Inner Class</u></b> | |
199 | * <p> | |
200 | * Asynchronous "Mouse Scroll Listener" | |
201 | * <p> | |
202 | * This class role is to wait for mouse scroll and count them during a certain delay.<p> | |
203 | * Once the time is up, it will notify the mouse listener of the number of scroll events received.<p> | |
204 | * | |
205 | * Note that a new scroll event received will reset the wait timer. | |
206 | */ | |
207 | class DelayedMouseScroll extends Thread { | |
208 | ||
209 | private HistogramCanvasMouseListener mouseListener = null; | |
210 | ||
211 | private long waitTimeBetweenScroll = 0; | |
212 | private long waitTimeBetweenCheck = 0; | |
213 | ||
214 | private long lastScrollTime = 0L; | |
215 | private int nbScrollClick = 0; | |
216 | ||
217 | /** | |
218 | * Constructor of the DelayedMouseScroll listener.<p> | |
219 | * Object will be initialized but start() need to be called for it start listening for scroll. | |
220 | * | |
221 | * @param newListener The parent mouse listener | |
222 | * @param newWaitFullTime The time to wait for scroll events | |
223 | * @param newWaitBeforeCheck The delay between polling for scroll events | |
224 | */ | |
225 | public DelayedMouseScroll(HistogramCanvasMouseListener newListener, long newWaitFullTime, long newWaitBeforePoll) { | |
226 | ||
227 | mouseListener = newListener; | |
228 | ||
229 | // Get the current system time. | |
230 | // This will be used to determine since how long we wait for click | |
231 | lastScrollTime = System.currentTimeMillis(); | |
232 | ||
233 | waitTimeBetweenScroll = newWaitFullTime; | |
234 | waitTimeBetweenCheck = newWaitBeforePoll; | |
235 | } | |
236 | ||
237 | /** | |
238 | * Increment the counter for the number of scroll events received.<p> | |
239 | * This is intended to be called by the MouseListener. | |
240 | * | |
241 | * Note : A new scroll event receive will reset the wait timer. | |
242 | */ | |
243 | public void incrementMouseScroll() { | |
244 | // Reset the wait timer | |
245 | lastScrollTime = System.currentTimeMillis(); | |
246 | nbScrollClick++; | |
f05aabed | 247 | mouseListener.receiveMouseScrollCountWithoutNotification(nbScrollClick); |
6e512b93 ASL |
248 | } |
249 | ||
250 | /** | |
251 | * Decrement the counter for the number of scroll events received.<p> | |
252 | * This is intended to be called by the MouseListener. | |
253 | * | |
254 | * Note : A new scroll event receive will reset the wait timer. | |
255 | */ | |
256 | public void decrementMouseScroll() { | |
257 | // Reset the wait timer | |
258 | lastScrollTime = System.currentTimeMillis(); | |
259 | nbScrollClick--; | |
f05aabed | 260 | mouseListener.receiveMouseScrollCountWithoutNotification(nbScrollClick); |
6e512b93 ASL |
261 | } |
262 | ||
263 | /** | |
264 | * Threaded execution method.<p> | |
265 | * This is the real "wait" method that will wait for mouse scroll events.<p> | |
266 | * | |
267 | * The function will wake every "waitTimeBetweenCheck" to check if we exhausted the timer.<p> | |
268 | * So, the "longest" we could wait after the last event is "waitTimeBetweenScroll" + "waitTimeBetweenCheck" | |
269 | * | |
270 | */ | |
13198c7a | 271 | @Override |
6e512b93 ASL |
272 | public void run() { |
273 | // Check if we waited more than "waitTimeBetweenScroll" | |
274 | while ( (System.currentTimeMillis() - lastScrollTime) < waitTimeBetweenScroll ) { | |
275 | try { | |
276 | Thread.sleep(waitTimeBetweenCheck); | |
277 | } | |
278 | catch (Exception e) { } | |
279 | } | |
280 | ||
281 | // Tell the mouse listener the number of click received | |
f05aabed | 282 | mouseListener.receiveMouseScrollCountWithNotification(nbScrollClick); |
6e512b93 ASL |
283 | } |
284 | } |