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