]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/custom/MouseNavigator.java
Remove invalid SHA-256-Digests
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / custom / MouseNavigator.java
1 /**
2  * Copyright (c) 2019 Laurent CARON.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  * Laurent CARON (laurent.caron at gmail dot com) - initial API and implementation (bug 542777)
13  */
14 package org.eclipse.swt.custom;
15
16 import org.eclipse.swt.*;
17 import org.eclipse.swt.graphics.*;
18 import org.eclipse.swt.widgets.*;
19
20 /**
21  * This class add the following behaviour to <code>StyledText</code> widgets:
22  * <p>
23  * When the user clicks on the wheel, a circle with arrows appears. When the user moves the mouse,
24  * the StyledText content is scrolled (on the right or on the left for horizontal movements, up or down for vertical movements).
25  * </p>
26  *
27  * @since 3.110
28  */
29 class MouseNavigator {
30         private final StyledText parent;
31         boolean navigationActivated = false;
32         private GC gc;
33         private static final int CIRCLE_RADIUS = 15;
34         private static final int CENTRAL_POINT_RADIUS = 2;
35         private Point originalMouseLocation;
36         private final Listener mouseDownListener, mouseUpListener, paintListener, mouseMoveListener, focusOutListener;
37         private boolean hasHBar, hasVBar;
38         private Cursor previousCursor;
39
40         MouseNavigator(final StyledText styledText) {
41                 if (styledText == null) {
42                         SWT.error(SWT.ERROR_NULL_ARGUMENT);
43                 }
44                 if (styledText.isDisposed()) {
45                         SWT.error(SWT.ERROR_WIDGET_DISPOSED);
46                 }
47                 parent = styledText;
48
49                 mouseDownListener = (event) -> {
50                         onMouseDown(event);
51                 };
52                 parent.addListener(SWT.MouseDown, mouseDownListener);
53
54                 mouseUpListener = (event) -> {
55                         onMouseUp(event);
56                 };
57                 parent.addListener(SWT.MouseUp, mouseUpListener);
58
59                 paintListener = (event) -> {
60                         onPaint(event);
61                 };
62                 parent.addListener(SWT.Paint, paintListener);
63
64                 mouseMoveListener = (event) -> {
65                         onMouseMove(event);
66                 };
67                 parent.addListener(SWT.MouseMove, mouseMoveListener);
68
69                 focusOutListener = (event) -> {
70                         onFocusOut(event);
71                 };
72                 parent.addListener(SWT.FocusOut, focusOutListener);
73         }
74
75         void onMouseDown(Event e) {
76                 if ((e.button != 2) || navigationActivated) {
77                         return;
78                 }
79
80                 if (!parent.isVisible() || !parent.getEnabled() || parent.middleClickPressed) {
81                         return;
82                 }
83
84                 // Widget has no bar or bars are not enabled
85                 initBarState();
86
87                 if (!hasHBar && !hasVBar) {
88                         return;
89                 }
90
91                 navigationActivated = true;
92                 previousCursor = parent.getCursor();
93                 parent.setCursor(parent.getDisplay().getSystemCursor(SWT.CURSOR_ARROW));
94                 originalMouseLocation = getMouseLocation();
95                 parent.redraw();
96         }
97
98         private void initBarState() {
99                 hasHBar = computeHasHorizontalBar();
100                 hasVBar = computeHasVerticalBar();
101         }
102
103         private boolean computeHasHorizontalBar() {
104                 final ScrollBar horizontalBar = parent.getHorizontalBar();
105                 final boolean hasHorizontalBar = horizontalBar != null && horizontalBar.isVisible();
106                 final boolean exceedHorizontalSpace = parent.computeSize(SWT.DEFAULT, SWT.DEFAULT).x > parent.getSize().x;
107                 return hasHorizontalBar && exceedHorizontalSpace;
108         }
109
110         private boolean computeHasVerticalBar() {
111                 final ScrollBar verticalBar = parent.getVerticalBar();
112                 final boolean hasVerticalBar = verticalBar != null && verticalBar.isEnabled();
113                 final boolean exceedVerticalSpace = parent.computeSize(SWT.DEFAULT, SWT.DEFAULT).y > parent.getSize().y;
114                 return hasVerticalBar && exceedVerticalSpace;
115         }
116
117         private void onMouseUp(Event e) {
118                 if ((computeDist() < CIRCLE_RADIUS) && (computeDist() >= 0)) {
119                         return;
120                 }
121                 deactivate();
122         }
123
124         public int computeDist() {
125                 if (originalMouseLocation == null) {
126                         return -1;
127                 }
128                 final Point mouseLocation = getMouseLocation();
129                 final int deltaX = originalMouseLocation.x - mouseLocation.x;
130                 final int deltaY = originalMouseLocation.y - mouseLocation.y;
131                 final int dist = (int) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
132                 return dist;
133         }
134
135         private void deactivate() {
136                 parent.setCursor(previousCursor);
137                 navigationActivated = false;
138                 originalMouseLocation = null;
139                 parent.redraw();
140         }
141
142         private void onFocusOut(Event e) {
143                 deactivate();
144         }
145
146         private void onMouseMove(Event e) {
147                 if (!navigationActivated) {
148                         return;
149                 }
150
151                 final Point mouseLocation = getMouseLocation();
152                 final int deltaX = originalMouseLocation.x - mouseLocation.x;
153                 final int deltaY = originalMouseLocation.y - mouseLocation.y;
154                 final int dist = (int) Math.sqrt(deltaX * deltaX + deltaY * deltaY);
155                 if (dist < CIRCLE_RADIUS) {
156                         return;
157                 }
158
159                 parent.setRedraw(false);
160                 if (hasHBar) {
161                         final ScrollBar bar = parent.getHorizontalBar();
162                         bar.setSelection((int) (bar.getSelection() - deltaX * .1));
163                         fireSelectionEvent(e, bar);
164                 }
165
166                 if (hasVBar) {
167                         final ScrollBar bar = parent.getVerticalBar();
168                         bar.setSelection((int) (bar.getSelection() - deltaY * .1));
169                         fireSelectionEvent(e, bar);
170                 }
171                 parent.setRedraw(true);
172                 parent.redraw();
173         }
174
175         private void fireSelectionEvent(final Event e, final ScrollBar bar) {
176                 final Event event = new Event();
177                 event.widget = bar;
178                 event.display = parent.getDisplay();
179                 event.type = SWT.Selection;
180                 event.time = e.time;
181
182                 for (final Listener selectionListener : bar.getListeners(SWT.Selection)) {
183                         selectionListener.handleEvent(event);
184                 }
185         }
186
187         private Point getMouseLocation() {
188                 final Point cursorLocation = Display.getCurrent().getCursorLocation();
189                 final Point relativeCursorLocation = parent.toControl(cursorLocation);
190                 return relativeCursorLocation;
191         }
192
193         private void onPaint(final Event e) {
194                 if (!navigationActivated) {
195                         return;
196                 }
197
198                 final Rectangle rect = parent.getClientArea();
199                 if (rect.width == 0 || rect.height == 0) {
200                         return;
201                 }
202                 gc = e.gc;
203                 gc.setAntialias(SWT.ON);
204                 gc.setAdvanced(true);
205
206                 final Color oldForegroundColor = gc.getForeground();
207                 final Color oldBackgroundColor = gc.getBackground();
208                 gc.setBackground(parent.getForeground());
209
210                 drawCircle();
211                 drawCentralPoint();
212
213                 drawArrows();
214
215                 gc.setForeground(oldForegroundColor);
216                 gc.setBackground(oldBackgroundColor);
217         }
218
219         private void drawCircle() {
220                 gc.setBackground(parent.getBackground());
221                 gc.setForeground(parent.getForeground());
222                 gc.setAlpha(200);
223                 gc.fillOval(originalMouseLocation.x - CIRCLE_RADIUS, originalMouseLocation.y - CIRCLE_RADIUS, CIRCLE_RADIUS * 2, CIRCLE_RADIUS * 2);
224                 gc.setBackground(parent.getForeground());
225                 gc.setAlpha(255);
226                 gc.drawOval(originalMouseLocation.x - CIRCLE_RADIUS, originalMouseLocation.y - CIRCLE_RADIUS, CIRCLE_RADIUS * 2, CIRCLE_RADIUS * 2);
227         }
228
229         private void drawCentralPoint() {
230                 gc.fillOval(originalMouseLocation.x - CENTRAL_POINT_RADIUS, originalMouseLocation.y - CENTRAL_POINT_RADIUS, CENTRAL_POINT_RADIUS * 2, CENTRAL_POINT_RADIUS * 2);
231         }
232
233         private void drawArrows() {
234                 gc.setLineWidth(2);
235                 if (hasHBar) {
236                         drawHorizontalArrows();
237                 }
238                 if (hasVBar) {
239                         drawVerticalArrows();
240                 }
241         }
242
243         private void drawHorizontalArrows() {
244                 final int[] points = new int[6];
245                 // Left
246                 points[0] = originalMouseLocation.x - 6;
247                 points[1] = originalMouseLocation.y + 3;
248                 points[2] = originalMouseLocation.x - 9;
249                 points[3] = originalMouseLocation.y;
250                 points[4] = originalMouseLocation.x - 6;
251                 points[5] = originalMouseLocation.y - 3;
252                 gc.drawPolyline(points);
253
254                 // Right
255                 points[0] = originalMouseLocation.x + 7;
256                 points[1] = originalMouseLocation.y + 3;
257                 points[2] = originalMouseLocation.x + 10;
258                 points[3] = originalMouseLocation.y;
259                 points[4] = originalMouseLocation.x + 7;
260                 points[5] = originalMouseLocation.y - 3;
261                 gc.drawPolyline(points);
262         }
263
264         private void drawVerticalArrows() {
265                 final int[] points = new int[6];
266                 // Upper
267                 points[0] = originalMouseLocation.x - 3;
268                 points[1] = originalMouseLocation.y - 6;
269                 points[2] = originalMouseLocation.x;
270                 points[3] = originalMouseLocation.y - 10;
271                 points[4] = originalMouseLocation.x + 3;
272                 points[5] = originalMouseLocation.y - 6;
273                 gc.drawPolyline(points);
274
275                 // Lower
276                 points[0] = originalMouseLocation.x - 3;
277                 points[1] = originalMouseLocation.y + 7;
278                 points[2] = originalMouseLocation.x;
279                 points[3] = originalMouseLocation.y + 11;
280                 points[4] = originalMouseLocation.x + 3;
281                 points[5] = originalMouseLocation.y + 7;
282                 gc.drawPolyline(points);
283
284         }
285
286         void dispose() {
287                 if (parent.isDisposed()) {
288                         return;
289                 }
290                 parent.removeListener(SWT.MouseDown, mouseDownListener);
291                 parent.removeListener(SWT.MouseUp, mouseUpListener);
292                 parent.removeListener(SWT.Paint, paintListener);
293                 parent.removeListener(SWT.MouseMove, mouseMoveListener);
294                 parent.removeListener(SWT.MouseExit, focusOutListener);
295         }
296 }