2 package com.badlogic.gdx.backends.jglfw;
4 import static com.badlogic.jglfw.Glfw.*;
6 import com.badlogic.gdx.Gdx;
7 import com.badlogic.gdx.Input;
8 import com.badlogic.gdx.InputProcessor;
9 import com.badlogic.gdx.utils.GdxRuntimeException;
10 import com.badlogic.jglfw.GlfwCallback;
12 import java.awt.Color;
13 import java.awt.FlowLayout;
14 import java.awt.event.WindowEvent;
15 import java.awt.event.WindowFocusListener;
17 import javax.swing.JDialog;
18 import javax.swing.JLabel;
19 import javax.swing.JOptionPane;
20 import javax.swing.JPanel;
21 import javax.swing.JTextField;
22 import javax.swing.OverlayLayout;
23 import javax.swing.SwingUtilities;
24 import javax.swing.border.EmptyBorder;
25 import javax.swing.event.DocumentEvent;
26 import javax.swing.event.DocumentListener;
28 /** An implementation of the {@link Input} interface hooking GLFW panel for input.
30 * @author Nathan Sweet */
31 public class JglfwInput implements Input {
32 JglfwGraphics graphics;
33 InputProcessor processor;
35 boolean justTouched = false;
36 long currentEventTimeStamp;
39 public JglfwInput (JglfwGraphics graphics) {
40 this.graphics = graphics;
42 glfwSetCallback(new GlfwCallback() {
43 private int mouseX, mouseY, mousePressed;
44 private char lastCharacter;
46 public void key (long window, int key, int action) {
49 if (processor != null) processor.keyDown(getGdxKeyCode(key));
52 if (processor != null) processor.keyDown(getGdxKeyCode(key));
55 if (processor != null && lastCharacter != 0) processor.keyTyped(lastCharacter);
58 Gdx.graphics.requestRendering();
61 public void character (long window, char character) {
62 lastCharacter = character;
63 if (processor != null) processor.keyTyped(character);
64 Gdx.graphics.requestRendering();
67 public void scroll (long window, double scrollX, double scrollY) {
68 if (processor != null) processor.scrolled((int)-Math.signum(scrollY));
69 Gdx.graphics.requestRendering();
72 public void mouseButton (long window, int button, boolean pressed) {
75 if (processor != null) processor.touchDown(mouseX, mouseY, 0, button);
78 if (processor != null) processor.touchUp(mouseX, mouseY, 0, button);
80 Gdx.graphics.requestRendering();
83 public void cursorPos (long window, int x, int y) {
86 if (processor != null) {
88 processor.touchDragged(mouseX, mouseY, 0);
90 processor.mouseMoved(mouseX, mouseY);
92 Gdx.graphics.requestRendering();
95 public void cursorEnter (long window, boolean entered) {
98 public void windowSize (long window, int width, int height) {
101 public void windowRefresh (long window) {
104 public void windowPos (long window, int x, int y) {
107 public void windowIconify (long window, boolean iconified) {
110 public void windowFocus (long window, boolean focused) {
113 public boolean windowClose (long window) {
117 public void monitor (long monitor, boolean connected) {
120 public void error (int error, String description) {
121 throw new GdxRuntimeException("GLFW error " + error + ": " + description);
126 public float getAccelerometerX () {
130 public float getAccelerometerY () {
134 public float getAccelerometerZ () {
139 return glfwGetCursorPosX(graphics.window);
142 public int getX (int pointer) {
150 return graphics.getHeight() - 1 - glfwGetCursorPosY(graphics.window);
153 public int getY (int pointer) {
160 public int getDeltaX () {
164 public int getDeltaX (int pointer) {
171 public int getDeltaY () {
175 public int getDeltaY (int pointer) {
182 public boolean isTouched () {
183 return glfwGetMouseButton(graphics.window, 0) || glfwGetMouseButton(graphics.window, 1)
184 || glfwGetMouseButton(graphics.window, 2);
187 public boolean justTouched () {
191 public boolean isTouched (int pointer) {
198 public boolean isButtonPressed (int button) {
199 return glfwGetMouseButton(graphics.window, button);
202 public boolean isKeyPressed (int key) {
203 if (key == Input.Keys.ANY_KEY)
204 return pressedKeys > 0;
206 return glfwGetKey(graphics.window, key);
209 public void getTextInput (final TextInputListener listener, final String title, final String text) {
210 SwingUtilities.invokeLater(new Runnable() {
212 final String output = JOptionPane.showInputDialog(null, title, text);
213 Gdx.app.postRunnable(new Runnable() {
216 listener.input(output);
225 public void getPlaceholderTextInput (final TextInputListener listener, final String title, final String placeholder) {
226 SwingUtilities.invokeLater(new Runnable() {
228 JPanel panel = new JPanel(new FlowLayout());
230 JPanel textPanel = new JPanel() {
231 public boolean isOptimizedDrawingEnabled () {
235 textPanel.setLayout(new OverlayLayout(textPanel));
236 panel.add(textPanel);
238 final JTextField textField = new JTextField(20);
239 textField.setAlignmentX(0.0f);
240 textPanel.add(textField);
242 final JLabel placeholderLabel = new JLabel(placeholder);
243 placeholderLabel.setForeground(Color.GRAY);
244 placeholderLabel.setAlignmentX(0.0f);
245 textPanel.add(placeholderLabel, 0);
247 textField.getDocument().addDocumentListener(new DocumentListener() {
248 public void removeUpdate (DocumentEvent event) {
252 public void insertUpdate (DocumentEvent event) {
256 public void changedUpdate (DocumentEvent event) {
260 private void updated () {
261 placeholderLabel.setVisible(textField.getText().length() == 0);
265 JOptionPane pane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null,
267 pane.setComponentOrientation(JOptionPane.getRootFrame().getComponentOrientation());
268 pane.selectInitialValue();
270 placeholderLabel.setBorder(new EmptyBorder(textField.getBorder().getBorderInsets(textField)));
272 JDialog dialog = pane.createDialog(null, title);
273 dialog.addWindowFocusListener(new WindowFocusListener() {
274 public void windowLostFocus (WindowEvent arg0) {
277 public void windowGainedFocus (WindowEvent arg0) {
278 textField.requestFocusInWindow();
281 dialog.setVisible(true);
284 Object selectedValue = pane.getValue();
285 if (selectedValue != null && (selectedValue instanceof Integer) && (Integer)selectedValue == JOptionPane.OK_OPTION)
286 listener.input(textField.getText());
293 public void setOnscreenKeyboardVisible (boolean visible) {
296 public void vibrate (int milliseconds) {
299 public void vibrate (long[] pattern, int repeat) {
302 public void cancelVibrate () {
305 public float getAzimuth () {
309 public float getPitch () {
313 public float getRoll () {
317 public void getRotationMatrix (float[] matrix) {
320 public long getCurrentEventTime () {
321 return currentEventTimeStamp;
324 public void setCatchBackKey (boolean catchBack) {
327 public void setCatchMenuKey (boolean catchMenu) {
330 public void setInputProcessor (InputProcessor processor) {
331 this.processor = processor;
334 public InputProcessor getInputProcessor () {
338 public boolean isPeripheralAvailable (Peripheral peripheral) {
339 if (peripheral == Peripheral.HardwareKeyboard) return true;
343 public int getRotation () {
347 public Orientation getNativeOrientation () {
348 return Orientation.Landscape;
351 public void setCursorCatched (boolean captured) {
352 glfwSetInputMode(graphics.window, GLFW_CURSOR_MODE, captured ? GLFW_CURSOR_CAPTURED : GLFW_CURSOR_NORMAL);
355 public boolean isCursorCatched () {
356 return glfwGetInputMode(graphics.window, GLFW_CURSOR_MODE) == GLFW_CURSOR_CAPTURED;
359 public void setCursorPosition (int x, int y) {
360 glfwSetCursorPos(graphics.window, x, y);
363 public static int getGdxKeyCode (int lwjglKeyCode) {
364 switch (lwjglKeyCode) {
365 case GLFW_KEY_LEFT_BRACKET:
366 return Input.Keys.LEFT_BRACKET;
367 case GLFW_KEY_RIGHT_BRACKET:
368 return Input.Keys.RIGHT_BRACKET;
369 case GLFW_KEY_GRAVE_ACCENT:
370 return Input.Keys.GRAVE;
371 case GLFW_KEY_KP_MULTIPLY:
372 return Input.Keys.STAR;
373 case GLFW_KEY_NUM_LOCK:
374 return Input.Keys.NUM;
375 case GLFW_KEY_KP_DECIMAL:
376 return Input.Keys.PERIOD;
377 case GLFW_KEY_KP_DIVIDE:
378 return Input.Keys.SLASH;
380 return Input.Keys.SYM;
381 case GLFW_KEY_KP_EQUAL:
382 return Input.Keys.EQUALS;
384 return Input.Keys.EQUALS;
385 case GLFW_KEY_KP_ENTER:
386 return Input.Keys.ENTER;
388 return Input.Keys.NUM_0;
390 return Input.Keys.NUM_1;
392 return Input.Keys.NUM_2;
394 return Input.Keys.NUM_3;
396 return Input.Keys.NUM_4;
398 return Input.Keys.NUM_5;
400 return Input.Keys.NUM_6;
402 return Input.Keys.NUM_7;
404 return Input.Keys.NUM_8;
406 return Input.Keys.NUM_9;
460 return Input.Keys.ALT_LEFT;
462 return Input.Keys.ALT_RIGHT;
463 case GLFW_KEY_BACKSLASH:
464 return Input.Keys.BACKSLASH;
466 return Input.Keys.COMMA;
467 case GLFW_KEY_DELETE:
468 return Input.Keys.FORWARD_DEL;
470 return Input.Keys.DPAD_LEFT;
472 return Input.Keys.DPAD_RIGHT;
474 return Input.Keys.DPAD_UP;
476 return Input.Keys.DPAD_DOWN;
478 return Input.Keys.ENTER;
480 return Input.Keys.HOME;
482 return Input.Keys.MINUS;
483 case GLFW_KEY_PERIOD:
484 return Input.Keys.PERIOD;
485 case GLFW_KEY_KP_ADD:
486 return Input.Keys.PLUS;
487 case GLFW_KEY_SEMICOLON:
488 return Input.Keys.SEMICOLON;
489 case GLFW_KEY_LSHIFT:
490 return Input.Keys.SHIFT_LEFT;
491 case GLFW_KEY_RSHIFT:
492 return Input.Keys.SHIFT_RIGHT;
494 return Input.Keys.SLASH;
496 return Input.Keys.SPACE;
498 return Input.Keys.TAB;
499 case GLFW_KEY_LEFT_CONTROL:
500 return Input.Keys.CONTROL_LEFT;
501 case GLFW_KEY_RIGHT_CONTROL:
502 return Input.Keys.CONTROL_RIGHT;
503 case GLFW_KEY_ESCAPE:
504 return Input.Keys.ESCAPE;
506 return Input.Keys.END;
507 case GLFW_KEY_INSERT:
508 return Input.Keys.INSERT;
509 case GLFW_KEY_BACKSPACE:
510 return Input.Keys.DEL;
511 case GLFW_KEY_KP_SUBTRACT:
512 return Input.Keys.MINUS;
513 case GLFW_KEY_APOSTROPHE:
514 return Input.Keys.APOSTROPHE;
516 return Input.Keys.F1;
518 return Input.Keys.F2;
520 return Input.Keys.F3;
522 return Input.Keys.F4;
524 return Input.Keys.F5;
526 return Input.Keys.F6;
528 return Input.Keys.F7;
530 return Input.Keys.F8;
532 return Input.Keys.F9;
534 return Input.Keys.F10;
536 return Input.Keys.F11;
538 return Input.Keys.F12;
540 return Input.Keys.NUM_0;
542 return Input.Keys.NUM_1;
544 return Input.Keys.NUM_2;
546 return Input.Keys.NUM_3;
548 return Input.Keys.NUM_4;
550 return Input.Keys.NUM_5;
552 return Input.Keys.NUM_6;
554 return Input.Keys.NUM_7;
556 return Input.Keys.NUM_8;
558 return Input.Keys.NUM_9;
560 return Input.Keys.UNKNOWN;
564 public static int getJglfwKeyCode (int gdxKeyCode) {
565 switch (gdxKeyCode) {
566 case Input.Keys.LEFT_BRACKET:
567 return GLFW_KEY_LEFT_BRACKET;
568 case Input.Keys.RIGHT_BRACKET:
569 return GLFW_KEY_RIGHT_BRACKET;
570 case Input.Keys.GRAVE:
571 return GLFW_KEY_GRAVE_ACCENT;
572 case Input.Keys.STAR:
573 return GLFW_KEY_KP_MULTIPLY;
575 return GLFW_KEY_NUM_LOCK;
576 case Input.Keys.EQUALS:
577 return GLFW_KEY_MENU;
579 return GLFW_KEY_MENU;
580 case Input.Keys.NUM_0:
582 case Input.Keys.NUM_1:
584 case Input.Keys.NUM_2:
586 case Input.Keys.NUM_3:
588 case Input.Keys.NUM_4:
590 case Input.Keys.NUM_5:
592 case Input.Keys.NUM_6:
594 case Input.Keys.NUM_7:
596 case Input.Keys.NUM_8:
598 case Input.Keys.NUM_9:
652 case Input.Keys.ALT_LEFT:
653 return GLFW_KEY_LALT;
654 case Input.Keys.ALT_RIGHT:
655 return GLFW_KEY_RALT;
656 case Input.Keys.BACKSLASH:
657 return GLFW_KEY_BACKSLASH;
658 case Input.Keys.COMMA:
659 return GLFW_KEY_COMMA;
660 case Input.Keys.FORWARD_DEL:
661 return GLFW_KEY_DELETE;
662 case Input.Keys.DPAD_LEFT:
663 return GLFW_KEY_LEFT;
664 case Input.Keys.DPAD_RIGHT:
665 return GLFW_KEY_RIGHT;
666 case Input.Keys.DPAD_UP:
668 case Input.Keys.DPAD_DOWN:
669 return GLFW_KEY_DOWN;
670 case Input.Keys.ENTER:
671 return GLFW_KEY_ENTER;
672 case Input.Keys.HOME:
673 return GLFW_KEY_HOME;
674 case Input.Keys.MINUS:
675 return GLFW_KEY_MINUS;
676 case Input.Keys.PERIOD:
677 return GLFW_KEY_PERIOD;
678 case Input.Keys.PLUS:
679 return GLFW_KEY_KP_ADD;
680 case Input.Keys.SEMICOLON:
681 return GLFW_KEY_SEMICOLON;
682 case Input.Keys.SHIFT_LEFT:
683 return GLFW_KEY_LSHIFT;
684 case Input.Keys.SHIFT_RIGHT:
685 return GLFW_KEY_RSHIFT;
686 case Input.Keys.SLASH:
687 return GLFW_KEY_SLASH;
688 case Input.Keys.SPACE:
689 return GLFW_KEY_SPACE;
693 return GLFW_KEY_BACKSPACE;
694 case Input.Keys.CONTROL_LEFT:
695 return GLFW_KEY_LEFT_CONTROL;
696 case Input.Keys.CONTROL_RIGHT:
697 return GLFW_KEY_RIGHT_CONTROL;
698 case Input.Keys.ESCAPE:
699 return GLFW_KEY_ESCAPE;