
de.lessvoid.nifty.renderer.lwjgl.input.LwjglInputSystem Maven / Gradle / Ivy
package de.lessvoid.nifty.renderer.lwjgl.input;
/**
*
* @author Joseph
*/
import de.lessvoid.nifty.NiftyInputConsumer;
import de.lessvoid.nifty.input.keyboard.KeyboardInputEvent;
import de.lessvoid.nifty.spi.input.InputSystem;
import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
import org.lwjgl.BufferUtils;
import org.lwjgl.input.Cursor;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import javax.annotation.Nonnull;
import java.nio.IntBuffer;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Logger;
public class LwjglInputSystem implements InputSystem {
private final Logger log = Logger.getLogger(LwjglInputSystem.class.getName());
@Nonnull
private final LwjglKeyboardInputEventCreator keyboardEventCreator = new LwjglKeyboardInputEventCreator();
private final IntBuffer viewportBuffer = BufferUtils.createIntBuffer(4 * 4);
@Nonnull
private final ConcurrentLinkedQueue mouseEventsOut = new ConcurrentLinkedQueue();
private final ConcurrentLinkedQueue keyboardEventsOut = new
ConcurrentLinkedQueue();
public boolean niftyHasKeyboardFocus = true;
public boolean niftyTakesKeyboardFocusOnClick = false;
@Override
public void setResourceLoader(@Nonnull final NiftyResourceLoader resourceLoader) {
}
public void startup() throws Exception {
Mouse.create();
Keyboard.create();
Keyboard.enableRepeatEvents(true);
logMouseCapabilities();
}
public void shutdown() {
Mouse.destroy();
Keyboard.destroy();
}
// InputSystem Implementation
@Override
public void forwardEvents(@Nonnull final NiftyInputConsumer inputEventConsumer) {
mouseEventsOut.clear();
keyboardEventsOut.clear();
processMouseEvents(inputEventConsumer);
processKeyboardEvents(inputEventConsumer);
}
@Override
public void setMousePosition(final int x, final int y) {
int viewportHeight = getViewportHeight();
Mouse.setCursorPosition(x, viewportHeight - y);
}
// Additional methods to access events in case they've got not handled by Nifty
/**
* This can be called the check if any mouse events have not been handled by Nifty.
*
* @return true when mouse events are available and false if not
*/
public boolean hasNextMouseEvent() {
return mouseEventsOut.peek() != null;
}
/**
* Retrieve a unhandled mouse event from the internal queue.
*
* @return MouseInputEvent of the mouse event that was not handled by Nifty
*/
public MouseInputEvent nextMouseEvent() {
return mouseEventsOut.poll();
}
/**
* This can be called the check if any keyboard events have not been handled by Nifty.
*
* @return true when keyboard events are available and false if not
*/
public boolean hasNextKeyboardEvent() {
return keyboardEventsOut.peek() != null;
}
/**
* Retrieve a unhandled keyboard event from the internal queue.
*
* @return KeyboardInputEvent of the event that was not handled by Nifty
*/
public KeyboardInputEvent nextKeyboardEvent() {
return keyboardEventsOut.poll();
}
// Internals
private void processMouseEvents(@Nonnull final NiftyInputConsumer inputEventConsumer) {
int viewportHeight = getViewportHeight();
while (Mouse.next()) {
int mouseX = Mouse.getEventX();
int mouseY = viewportHeight - Mouse.getEventY();
int mouseWheel = Mouse.getEventDWheel() / 120; // not sure about that 120 here. works on my system and makes
// this return 1 if the wheel is moved the minimal amount.
int button = Mouse.getEventButton();
boolean buttonDown = Mouse.getEventButtonState();
// now send the event to nifty
boolean mouseEventProcessedByNifty = inputEventConsumer.processMouseEvent(mouseX, mouseY, mouseWheel, button,
buttonDown);
if (!mouseEventProcessedByNifty) {
log.fine("Nifty did not processed this mouse event. You can handle it.");
// nifty did not process this event, it did not hit any element
mouseEventsOut.offer(new MouseInputEvent(mouseX, mouseY, mouseWheel, button, buttonDown));
if (niftyTakesKeyboardFocusOnClick) {
log.fine("Nifty gave up the keyboard focus");
niftyHasKeyboardFocus = false; // give up focus if clicked outside nifty
}
} else {
log.fine("Nifty has processed this mouse event");
// nifty did handle that event. it hit an element and was processed by some GUI element
if (niftyTakesKeyboardFocusOnClick) { // take focus if nifty element is clicked
log.fine("Nifty takes the keyboard focus back");
niftyHasKeyboardFocus = true;
}
}
}
}
private void processKeyboardEvents(@Nonnull final NiftyInputConsumer inputEventConsumer) {
while (Keyboard.next()) {
KeyboardInputEvent event = keyboardEventCreator.createEvent(Keyboard.getEventKey(),
Keyboard.getEventCharacter(), Keyboard.getEventKeyState());
// due to or short-circuiting on true, the event will get forward to keyboardEventsOut if keyboardEventsOut=true
if (!niftyHasKeyboardFocus || !inputEventConsumer.processKeyboardEvent(event)) {
keyboardEventsOut.offer(event);
}
}
}
private int getViewportHeight() {
GL11.glGetInteger(GL11.GL_VIEWPORT, viewportBuffer);
return viewportBuffer.get(3);
}
private void logMouseCapabilities() {
int caps = Cursor.getCapabilities();
StringBuffer out = new StringBuffer();
if ((caps & Cursor.CURSOR_ONE_BIT_TRANSPARENCY) != 0) {
add(out, "CURSOR_ONE_BIT_TRANSPARENCY");
}
if ((caps & Cursor.CURSOR_8_BIT_ALPHA) != 0) {
add(out, "CURSOR_8_BIT_ALPHA");
}
if ((caps & Cursor.CURSOR_ANIMATION) != 0) {
add(out, "CURSOR_ANIMATION");
}
log.fine("native cursor support (" + caps + ") -> [" + out.toString() + "]");
log.fine("native cursor min size: " + Cursor.getMinCursorSize());
log.fine("native cursor max size: " + Cursor.getMaxCursorSize());
}
private static void add(@Nonnull StringBuffer out, String text) {
if (out.length() > 0) {
out.append(", ");
}
out.append(text);
}
public static class MouseInputEvent {
public float mouseX;
public float mouseY;
public float pmouseX;
public float pmouseY;
public int button;
public int scroll;
public boolean buttonDown;
MouseInputEvent(float mx, float my, int scroll, int button, boolean buttonDown) {
this.mouseX = mx;
this.mouseY = my;
this.button = button;
this.scroll = scroll;
this.buttonDown = buttonDown;
}
@Nonnull
@Override
public String toString() {
return this.button + "=" + this.buttonDown + " at " + this.mouseX + "," + this.mouseY + " scroll:" + this.scroll;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy