playn.java.JavaInput Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of playn-java-base Show documentation
Show all versions of playn-java-base Show documentation
Code shared by all PlayN Java (JVM) backends
/**
* Copyright 2010-2015 The PlayN Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package playn.java;
import java.util.Deque;
import java.util.concurrent.ConcurrentLinkedDeque;
import playn.core.*;
import pythagoras.f.Point;
import react.Slot;
public class JavaInput extends Input {
protected final JavaPlatform plat;
// used for injecting keyboard evnets
private final Deque kevQueue = new ConcurrentLinkedDeque<>();
// these are used for touch emulation
private boolean mouseDown;
private Point pivot;
private float x, y;
private int currentId;
public JavaInput (JavaPlatform plat) {
super(plat);
this.plat = plat;
// if touch emulation is configured, wire it up
if (plat.config.emulateTouch) emulateTouch();
}
/** Posts a key event received from elsewhere (i.e. a native UI component). This is useful for
* applications that are using GL in Canvas mode and sharing keyboard focus with other (non-GL)
* components. The event will be queued and dispatched on the next frame, after GL keyboard
* events.
*
* @param time the time (in millis since epoch) at which the event was generated, or 0 if N/A.
* @param key the key that was pressed or released, or null for a char typed event
* @param pressed whether the key was pressed or released, ignored if key is null
* @param typedCh the character that was typed, ignored if key is not null
* @param modFlags modifier key state flags (generated by {@link #modifierFlags})
*/
public void postKey (long time, Key key, boolean pressed, char typedCh, int modFlags) {
kevQueue.add(key == null ?
new Keyboard.TypedEvent(modFlags, time, typedCh) :
new Keyboard.KeyEvent(modFlags, time, key, pressed));
}
protected void emulateTouch () {
final Key pivotKey = plat.config.pivotKey;
keyboardEvents.connect(new Slot() {
public void onEmit (Keyboard.Event event) {
if (event instanceof Keyboard.KeyEvent) {
Keyboard.KeyEvent kevent = (Keyboard.KeyEvent)event;
if (kevent.key == pivotKey && kevent.down) {
pivot = new Point(x, y);
}
}
}
});
mouseEvents.connect(new Slot() {
public void onEmit (Mouse.Event event) {
if (event instanceof Mouse.ButtonEvent) {
Mouse.ButtonEvent bevent = (Mouse.ButtonEvent)event;
if (bevent.button == Mouse.ButtonEvent.Id.LEFT) {
if (mouseDown = bevent.down) {
currentId += 2; // skip an id in case of pivot
dispatchTouch(event, Touch.Event.Kind.START);
} else {
pivot = null;
dispatchTouch(event, Touch.Event.Kind.END);
}
}
} else if (event instanceof Mouse.MotionEvent) {
if (mouseDown) dispatchTouch(event, Touch.Event.Kind.MOVE);
// keep track of the current mouse position for pivot
x = event.x; y = event.y;
}
}
});
// TODO: it's pesky that both mouse and touch events are dispatched when touch is emulated, it
// would be nice to throw away the mouse events and only have touch, but we rely on something
// generating the mouse events so we can't throw them away just yet... plus it could be useful
// to keep wheel events... blah
}
@Override public boolean hasMouse () { return true; }
@Override public boolean hasHardwareKeyboard() { return true; }
@Override public boolean hasTouch () { return plat.config.emulateTouch; }
void update () {
// dispatch any queued keyboard events
Keyboard.Event kev;
while ((kev = kevQueue.poll()) != null) {
if (keyboardEnabled) plat.dispatchEvent(keyboardEvents, kev);
}
}
private void dispatchTouch (Mouse.Event event, Touch.Event.Kind kind) {
if (touchEnabled) {
float ex = event.x, ey = event.y;
Touch.Event main = toTouch(event.time, ex, ey, kind, 0);
Touch.Event[] evs = (pivot == null) ?
new Touch.Event[] { main } :
new Touch.Event[] { main, toTouch(event.time, 2*pivot.x-ex, 2*pivot.y-ey, kind, 1) };
plat.dispatchEvent(touchEvents, evs);
}
}
private Touch.Event toTouch (double time, float x, float y, Touch.Event.Kind kind, int idoff) {
return new Touch.Event(0, time, x, y, kind, currentId+idoff);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy