Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/classes/com/apple/eawt/event/GestureHandler.java
41159 views
1
/*
2
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.apple.eawt.event;
27
28
import sun.awt.SunToolkit;
29
30
import java.awt.*;
31
import java.util.*;
32
import java.util.List;
33
34
import javax.swing.*;
35
36
import java.lang.annotation.Native;
37
38
final class GestureHandler {
39
private static final String CLIENT_PROPERTY = "com.apple.eawt.event.internalGestureHandler";
40
41
// native constants for the supported types of high-level gestures
42
@Native static final int PHASE = 1;
43
@Native static final int ROTATE = 2;
44
@Native static final int MAGNIFY = 3;
45
@Native static final int SWIPE = 4;
46
47
// installs a private instance of GestureHandler, if necessary
48
static void addGestureListenerTo(final JComponent component, final GestureListener listener) {
49
final Object value = component.getClientProperty(CLIENT_PROPERTY);
50
if (value instanceof GestureHandler) {
51
((GestureHandler)value).addListener(listener);
52
return;
53
}
54
55
if (value != null) return; // some other garbage is in our client property
56
57
final GestureHandler newHandler = new GestureHandler();
58
newHandler.addListener(listener);
59
component.putClientProperty(CLIENT_PROPERTY, newHandler);
60
}
61
62
// asks the installed GestureHandler to remove it's listener (does not uninstall the GestureHandler)
63
static void removeGestureListenerFrom(final JComponent component, final GestureListener listener) {
64
final Object value = component.getClientProperty(CLIENT_PROPERTY);
65
if (!(value instanceof GestureHandler)) return;
66
((GestureHandler)value).removeListener(listener);
67
}
68
69
70
// called from native - finds the deepest component with an installed GestureHandler,
71
// creates a single event, and dispatches it to a recursive notifier
72
static void handleGestureFromNative(final Window window, final int type, final double x, final double y, final double a, final double b) {
73
if (window == null) return; // should never happen...
74
75
SunToolkit.executeOnEventHandlerThread(window, new Runnable() {
76
public void run() {
77
final Component component = SwingUtilities.getDeepestComponentAt(window, (int)x, (int)y);
78
79
final PerComponentNotifier firstNotifier;
80
if (component instanceof RootPaneContainer) {
81
firstNotifier = getNextNotifierForComponent(((RootPaneContainer)component).getRootPane());
82
} else {
83
firstNotifier = getNextNotifierForComponent(component);
84
}
85
if (firstNotifier == null) return;
86
87
switch (type) {
88
case PHASE:
89
firstNotifier.recursivelyHandlePhaseChange(a, new GesturePhaseEvent());
90
return;
91
case ROTATE:
92
firstNotifier.recursivelyHandleRotate(new RotationEvent(a));
93
return;
94
case MAGNIFY:
95
firstNotifier.recursivelyHandleMagnify(new MagnificationEvent(a));
96
return;
97
case SWIPE:
98
firstNotifier.recursivelyHandleSwipe(a, b, new SwipeEvent());
99
return;
100
}
101
}
102
});
103
}
104
105
106
final List<GesturePhaseListener> phasers = new LinkedList<GesturePhaseListener>();
107
final List<RotationListener> rotaters = new LinkedList<RotationListener>();
108
final List<MagnificationListener> magnifiers = new LinkedList<MagnificationListener>();
109
final List<SwipeListener> swipers = new LinkedList<SwipeListener>();
110
111
GestureHandler() { }
112
113
void addListener(final GestureListener listener) {
114
if (listener instanceof GesturePhaseListener) phasers.add((GesturePhaseListener)listener);
115
if (listener instanceof RotationListener) rotaters.add((RotationListener)listener);
116
if (listener instanceof MagnificationListener) magnifiers.add((MagnificationListener)listener);
117
if (listener instanceof SwipeListener) swipers.add((SwipeListener)listener);
118
}
119
120
void removeListener(final GestureListener listener) {
121
phasers.remove(listener);
122
rotaters.remove(listener);
123
magnifiers.remove(listener);
124
swipers.remove(listener);
125
}
126
127
// notifies all listeners in a particular component/handler pair
128
// and recursively notifies up the component hierarchy
129
static class PerComponentNotifier {
130
final Component component;
131
final GestureHandler handler;
132
133
public PerComponentNotifier(final Component component, final GestureHandler handler) {
134
this.component = component;
135
this.handler = handler;
136
}
137
138
void recursivelyHandlePhaseChange(final double phase, final GesturePhaseEvent e) {
139
for (final GesturePhaseListener listener : handler.phasers) {
140
if (phase < 0) {
141
listener.gestureBegan(e);
142
} else {
143
listener.gestureEnded(e);
144
}
145
if (e.isConsumed()) return;
146
}
147
148
final PerComponentNotifier next = getNextNotifierForComponent(component.getParent());
149
if (next != null) next.recursivelyHandlePhaseChange(phase, e);
150
}
151
152
void recursivelyHandleRotate(final RotationEvent e) {
153
for (final RotationListener listener : handler.rotaters) {
154
listener.rotate(e);
155
if (e.isConsumed()) return;
156
}
157
158
final PerComponentNotifier next = getNextNotifierForComponent(component.getParent());
159
if (next != null) next.recursivelyHandleRotate(e);
160
}
161
162
void recursivelyHandleMagnify(final MagnificationEvent e) {
163
for (final MagnificationListener listener : handler.magnifiers) {
164
listener.magnify(e);
165
if (e.isConsumed()) return;
166
}
167
168
final PerComponentNotifier next = getNextNotifierForComponent(component.getParent());
169
if (next != null) next.recursivelyHandleMagnify(e);
170
}
171
172
void recursivelyHandleSwipe(final double x, final double y, final SwipeEvent e) {
173
for (final SwipeListener listener : handler.swipers) {
174
if (x < 0) listener.swipedLeft(e);
175
if (x > 0) listener.swipedRight(e);
176
if (y < 0) listener.swipedDown(e);
177
if (y > 0) listener.swipedUp(e);
178
if (e.isConsumed()) return;
179
}
180
181
final PerComponentNotifier next = getNextNotifierForComponent(component.getParent());
182
if (next != null) next.recursivelyHandleSwipe(x, y, e);
183
}
184
}
185
186
// helper function to get a handler from a Component
187
static GestureHandler getHandlerForComponent(final Component c) {
188
if (!(c instanceof JComponent)) return null;
189
final Object value = ((JComponent)c).getClientProperty(CLIENT_PROPERTY);
190
if (!(value instanceof GestureHandler)) return null;
191
return (GestureHandler)value;
192
}
193
194
// recursive helper to find the next component/handler pair
195
static PerComponentNotifier getNextNotifierForComponent(final Component c) {
196
if (c == null) return null;
197
198
final GestureHandler handler = getHandlerForComponent(c);
199
if (handler != null) {
200
return new PerComponentNotifier(c, handler);
201
}
202
203
return getNextNotifierForComponent(c.getParent());
204
}
205
}
206
207