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);
60 public void character (long window, char character) {
61 lastCharacter = character;
62 if (processor != null) processor.keyTyped(character);
65 public void scroll (long window, double scrollX, double scrollY) {
66 if (processor != null) processor.scrolled((int)-Math.signum(scrollY));
69 public void mouseButton (long window, int button, boolean pressed) {
72 if (processor != null) processor.touchDown(mouseX, mouseY, 0, button);
75 if (processor != null) processor.touchUp(mouseX, mouseY, 0, button);
79 public void cursorPos (long window, int x, int y) {
82 if (processor != null) {
84 processor.touchDragged(mouseX, mouseY, 0);
86 processor.mouseMoved(mouseX, mouseY);
90 public void cursorEnter (long window, boolean entered) {
93 public void windowSize (long window, int width, int height) {
96 public void windowRefresh (long window) {
99 public void windowPos (long window, int x, int y) {
102 public void windowIconify (long window, boolean iconified) {
105 public void windowFocus (long window, boolean focused) {
108 public boolean windowClose (long window) {
112 public void monitor (long monitor, boolean connected) {
115 public void error (int error, String description) {
116 throw new GdxRuntimeException("GLFW error " + error + ": " + description);
121 public float getAccelerometerX () {
125 public float getAccelerometerY () {
129 public float getAccelerometerZ () {
134 return glfwGetCursorPosX(graphics.window);
137 public int getX (int pointer) {
145 return graphics.getHeight() - 1 - glfwGetCursorPosY(graphics.window);
148 public int getY (int pointer) {
155 public int getDeltaX () {
159 public int getDeltaX (int pointer) {
166 public int getDeltaY () {
170 public int getDeltaY (int pointer) {
177 public boolean isTouched () {
178 return glfwGetMouseButton(graphics.window, 0) || glfwGetMouseButton(graphics.window, 1)
179 || glfwGetMouseButton(graphics.window, 2);
182 public boolean justTouched () {
186 public boolean isTouched (int pointer) {
193 public boolean isButtonPressed (int button) {
194 return glfwGetMouseButton(graphics.window, button);
197 public boolean isKeyPressed (int key) {
198 if (key == Input.Keys.ANY_KEY)
199 return pressedKeys > 0;
201 return glfwGetKey(graphics.window, key);
204 public void getTextInput (final TextInputListener listener, final String title, final String text) {
205 SwingUtilities.invokeLater(new Runnable() {
207 final String output = JOptionPane.showInputDialog(null, title, text);
208 Gdx.app.postRunnable(new Runnable() {
211 listener.input(output);
220 public void getPlaceholderTextInput (final TextInputListener listener, final String title, final String placeholder) {
221 SwingUtilities.invokeLater(new Runnable() {
223 JPanel panel = new JPanel(new FlowLayout());
225 JPanel textPanel = new JPanel() {
226 public boolean isOptimizedDrawingEnabled () {
230 textPanel.setLayout(new OverlayLayout(textPanel));
231 panel.add(textPanel);
233 final JTextField textField = new JTextField(20);
234 textField.setAlignmentX(0.0f);
235 textPanel.add(textField);
237 final JLabel placeholderLabel = new JLabel(placeholder);
238 placeholderLabel.setForeground(Color.GRAY);
239 placeholderLabel.setAlignmentX(0.0f);
240 textPanel.add(placeholderLabel, 0);
242 textField.getDocument().addDocumentListener(new DocumentListener() {
243 public void removeUpdate (DocumentEvent event) {
247 public void insertUpdate (DocumentEvent event) {
251 public void changedUpdate (DocumentEvent event) {
255 private void updated () {
256 placeholderLabel.setVisible(textField.getText().length() == 0);
260 JOptionPane pane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null,
262 pane.setComponentOrientation(JOptionPane.getRootFrame().getComponentOrientation());
263 pane.selectInitialValue();
265 placeholderLabel.setBorder(new EmptyBorder(textField.getBorder().getBorderInsets(textField)));
267 JDialog dialog = pane.createDialog(null, title);
268 dialog.addWindowFocusListener(new WindowFocusListener() {
269 public void windowLostFocus (WindowEvent arg0) {
272 public void windowGainedFocus (WindowEvent arg0) {
273 textField.requestFocusInWindow();
276 dialog.setVisible(true);
279 Object selectedValue = pane.getValue();
280 if (selectedValue != null && (selectedValue instanceof Integer) && (Integer)selectedValue == JOptionPane.OK_OPTION)
281 listener.input(textField.getText());
288 public void setOnscreenKeyboardVisible (boolean visible) {
291 public void vibrate (int milliseconds) {
294 public void vibrate (long[] pattern, int repeat) {
297 public void cancelVibrate () {
300 public float getAzimuth () {
304 public float getPitch () {
308 public float getRoll () {
312 public void getRotationMatrix (float[] matrix) {
315 public long getCurrentEventTime () {
316 return currentEventTimeStamp;
319 public void setCatchBackKey (boolean catchBack) {
322 public void setCatchMenuKey (boolean catchMenu) {
325 public void setInputProcessor (InputProcessor processor) {
326 this.processor = processor;
329 public InputProcessor getInputProcessor () {
333 public boolean isPeripheralAvailable (Peripheral peripheral) {
334 if (peripheral == Peripheral.HardwareKeyboard) return true;
338 public int getRotation () {
342 public Orientation getNativeOrientation () {
343 return Orientation.Landscape;
346 public void setCursorCatched (boolean captured) {
347 glfwSetInputMode(graphics.window, GLFW_CURSOR_MODE, captured ? GLFW_CURSOR_CAPTURED : GLFW_CURSOR_NORMAL);
350 public boolean isCursorCatched () {
351 return glfwGetInputMode(graphics.window, GLFW_CURSOR_MODE) == GLFW_CURSOR_CAPTURED;
354 public void setCursorPosition (int x, int y) {
355 glfwSetCursorPos(graphics.window, x, y);
358 public static int getGdxKeyCode (int lwjglKeyCode) {
359 switch (lwjglKeyCode) {
360 case GLFW_KEY_LEFT_BRACKET:
361 return Input.Keys.LEFT_BRACKET;
362 case GLFW_KEY_RIGHT_BRACKET:
363 return Input.Keys.RIGHT_BRACKET;
364 case GLFW_KEY_GRAVE_ACCENT:
365 return Input.Keys.GRAVE;
366 case GLFW_KEY_KP_MULTIPLY:
367 return Input.Keys.STAR;
368 case GLFW_KEY_NUM_LOCK:
369 return Input.Keys.NUM;
370 case GLFW_KEY_KP_DECIMAL:
371 return Input.Keys.PERIOD;
372 case GLFW_KEY_KP_DIVIDE:
373 return Input.Keys.SLASH;
375 return Input.Keys.SYM;
376 case GLFW_KEY_KP_EQUAL:
377 return Input.Keys.EQUALS;
379 return Input.Keys.EQUALS;
380 case GLFW_KEY_KP_ENTER:
381 return Input.Keys.ENTER;
383 return Input.Keys.NUM_0;
385 return Input.Keys.NUM_1;
387 return Input.Keys.NUM_2;
389 return Input.Keys.NUM_3;
391 return Input.Keys.NUM_4;
393 return Input.Keys.NUM_5;
395 return Input.Keys.NUM_6;
397 return Input.Keys.NUM_7;
399 return Input.Keys.NUM_8;
401 return Input.Keys.NUM_9;
455 return Input.Keys.ALT_LEFT;
457 return Input.Keys.ALT_RIGHT;
458 case GLFW_KEY_BACKSLASH:
459 return Input.Keys.BACKSLASH;
461 return Input.Keys.COMMA;
462 case GLFW_KEY_DELETE:
463 return Input.Keys.FORWARD_DEL;
465 return Input.Keys.DPAD_LEFT;
467 return Input.Keys.DPAD_RIGHT;
469 return Input.Keys.DPAD_UP;
471 return Input.Keys.DPAD_DOWN;
473 return Input.Keys.ENTER;
475 return Input.Keys.HOME;
477 return Input.Keys.MINUS;
478 case GLFW_KEY_PERIOD:
479 return Input.Keys.PERIOD;
480 case GLFW_KEY_KP_ADD:
481 return Input.Keys.PLUS;
482 case GLFW_KEY_SEMICOLON:
483 return Input.Keys.SEMICOLON;
484 case GLFW_KEY_LSHIFT:
485 return Input.Keys.SHIFT_LEFT;
486 case GLFW_KEY_RSHIFT:
487 return Input.Keys.SHIFT_RIGHT;
489 return Input.Keys.SLASH;
491 return Input.Keys.SPACE;
493 return Input.Keys.TAB;
494 case GLFW_KEY_LEFT_CONTROL:
495 return Input.Keys.CONTROL_LEFT;
496 case GLFW_KEY_RIGHT_CONTROL:
497 return Input.Keys.CONTROL_RIGHT;
498 case GLFW_KEY_ESCAPE:
499 return Input.Keys.ESCAPE;
501 return Input.Keys.END;
502 case GLFW_KEY_INSERT:
503 return Input.Keys.INSERT;
504 case GLFW_KEY_BACKSPACE:
505 return Input.Keys.DEL;
506 case GLFW_KEY_KP_SUBTRACT:
507 return Input.Keys.MINUS;
508 case GLFW_KEY_APOSTROPHE:
509 return Input.Keys.APOSTROPHE;
511 return Input.Keys.F1;
513 return Input.Keys.F2;
515 return Input.Keys.F3;
517 return Input.Keys.F4;
519 return Input.Keys.F5;
521 return Input.Keys.F6;
523 return Input.Keys.F7;
525 return Input.Keys.F8;
527 return Input.Keys.F9;
529 return Input.Keys.F10;
531 return Input.Keys.F11;
533 return Input.Keys.F12;
535 return Input.Keys.NUM_0;
537 return Input.Keys.NUM_1;
539 return Input.Keys.NUM_2;
541 return Input.Keys.NUM_3;
543 return Input.Keys.NUM_4;
545 return Input.Keys.NUM_5;
547 return Input.Keys.NUM_6;
549 return Input.Keys.NUM_7;
551 return Input.Keys.NUM_8;
553 return Input.Keys.NUM_9;
555 return Input.Keys.UNKNOWN;
559 public static int getJglfwKeyCode (int gdxKeyCode) {
560 switch (gdxKeyCode) {
561 case Input.Keys.LEFT_BRACKET:
562 return GLFW_KEY_LEFT_BRACKET;
563 case Input.Keys.RIGHT_BRACKET:
564 return GLFW_KEY_RIGHT_BRACKET;
565 case Input.Keys.GRAVE:
566 return GLFW_KEY_GRAVE_ACCENT;
567 case Input.Keys.STAR:
568 return GLFW_KEY_KP_MULTIPLY;
570 return GLFW_KEY_NUM_LOCK;
571 case Input.Keys.EQUALS:
572 return GLFW_KEY_MENU;
574 return GLFW_KEY_MENU;
575 case Input.Keys.NUM_0:
577 case Input.Keys.NUM_1:
579 case Input.Keys.NUM_2:
581 case Input.Keys.NUM_3:
583 case Input.Keys.NUM_4:
585 case Input.Keys.NUM_5:
587 case Input.Keys.NUM_6:
589 case Input.Keys.NUM_7:
591 case Input.Keys.NUM_8:
593 case Input.Keys.NUM_9:
647 case Input.Keys.ALT_LEFT:
648 return GLFW_KEY_LALT;
649 case Input.Keys.ALT_RIGHT:
650 return GLFW_KEY_RALT;
651 case Input.Keys.BACKSLASH:
652 return GLFW_KEY_BACKSLASH;
653 case Input.Keys.COMMA:
654 return GLFW_KEY_COMMA;
655 case Input.Keys.FORWARD_DEL:
656 return GLFW_KEY_DELETE;
657 case Input.Keys.DPAD_LEFT:
658 return GLFW_KEY_LEFT;
659 case Input.Keys.DPAD_RIGHT:
660 return GLFW_KEY_RIGHT;
661 case Input.Keys.DPAD_UP:
663 case Input.Keys.DPAD_DOWN:
664 return GLFW_KEY_DOWN;
665 case Input.Keys.ENTER:
666 return GLFW_KEY_ENTER;
667 case Input.Keys.HOME:
668 return GLFW_KEY_HOME;
669 case Input.Keys.MINUS:
670 return GLFW_KEY_MINUS;
671 case Input.Keys.PERIOD:
672 return GLFW_KEY_PERIOD;
673 case Input.Keys.PLUS:
674 return GLFW_KEY_KP_ADD;
675 case Input.Keys.SEMICOLON:
676 return GLFW_KEY_SEMICOLON;
677 case Input.Keys.SHIFT_LEFT:
678 return GLFW_KEY_LSHIFT;
679 case Input.Keys.SHIFT_RIGHT:
680 return GLFW_KEY_RSHIFT;
681 case Input.Keys.SLASH:
682 return GLFW_KEY_SLASH;
683 case Input.Keys.SPACE:
684 return GLFW_KEY_SPACE;
688 return GLFW_KEY_BACKSPACE;
689 case Input.Keys.CONTROL_LEFT:
690 return GLFW_KEY_LEFT_CONTROL;
691 case Input.Keys.CONTROL_RIGHT:
692 return GLFW_KEY_RIGHT_CONTROL;
693 case Input.Keys.ESCAPE:
694 return GLFW_KEY_ESCAPE;