2 package com.badlogic.gdx.backends.jglfw;
4 import static com.badlogic.jglfw.Glfw.*;
6 import com.badlogic.gdx.Input;
7 import com.badlogic.gdx.InputProcessor;
8 import com.badlogic.jglfw.GlfwCallbackAdapter;
10 import java.awt.Color;
11 import java.awt.FlowLayout;
12 import java.awt.event.WindowEvent;
13 import java.awt.event.WindowFocusListener;
15 import javax.swing.JDialog;
16 import javax.swing.JLabel;
17 import javax.swing.JOptionPane;
18 import javax.swing.JPanel;
19 import javax.swing.JTextField;
20 import javax.swing.OverlayLayout;
21 import javax.swing.SwingUtilities;
22 import javax.swing.border.EmptyBorder;
23 import javax.swing.event.DocumentEvent;
24 import javax.swing.event.DocumentListener;
26 /** An implementation of the {@link Input} interface hooking GLFW panel for input.
28 * @author Nathan Sweet */
29 public class JglfwInput implements Input {
31 InputProcessor processor;
36 public JglfwInput (final JglfwApplication app) {
39 app.callbacks.add(new GlfwCallbackAdapter() {
40 private int mouseX, mouseY, mousePressed;
41 private char lastCharacter;
43 public void key (long window, int key, int action) {
44 key = getGdxKeyCode(key);
48 if (processor != null) processor.keyDown(key);
51 char character = characterForKeyCode(key);
52 if (character != 0) character(window, character);
56 if (processor != null) processor.keyUp(key);
59 if (processor != null && lastCharacter != 0) processor.keyTyped(lastCharacter);
62 app.graphics.requestRendering();
65 public void character (long window, char character) {
66 lastCharacter = character;
67 if (processor != null) processor.keyTyped(character);
68 app.graphics.requestRendering();
71 public void scroll (long window, double scrollX, double scrollY) {
72 if (processor != null) processor.scrolled((int)-Math.signum(scrollY));
73 app.graphics.requestRendering();
76 public void mouseButton (long window, int button, boolean pressed) {
80 if (processor != null) processor.touchDown(mouseX, mouseY, 0, button);
84 if (processor != null) processor.touchUp(mouseX, mouseY, 0, button);
86 app.graphics.requestRendering();
89 public void cursorPos (long window, int x, int y) {
94 if (processor != null) {
96 processor.touchDragged(mouseX, mouseY, 0);
98 processor.mouseMoved(mouseX, mouseY);
100 app.graphics.requestRendering();
103 public void cursorEnter (long window, boolean entered) {
108 public void update () {
113 public float getAccelerometerX () {
117 public float getAccelerometerY () {
121 public float getAccelerometerZ () {
126 return glfwGetCursorPosX(app.graphics.window);
129 public int getX (int pointer) {
137 return glfwGetCursorPosY(app.graphics.window);
140 public int getY (int pointer) {
147 public int getDeltaX () {
151 public int getDeltaX (int pointer) {
158 public int getDeltaY () {
162 public int getDeltaY (int pointer) {
169 public boolean isTouched () {
170 return glfwGetMouseButton(app.graphics.window, 0) || glfwGetMouseButton(app.graphics.window, 1)
171 || glfwGetMouseButton(app.graphics.window, 2);
174 public boolean isTouched (int pointer) {
181 public boolean justTouched () {
185 public boolean isButtonPressed (int button) {
186 return glfwGetMouseButton(app.graphics.window, button);
189 public boolean isKeyPressed (int key) {
190 if (key == Input.Keys.ANY_KEY)
191 return pressedKeys > 0;
193 return glfwGetKey(app.graphics.window, getJglfwKeyCode(key));
196 public void getTextInput (final TextInputListener listener, final String title, final String text) {
197 SwingUtilities.invokeLater(new Runnable() {
199 final String output = JOptionPane.showInputDialog(null, title, text);
200 app.postRunnable(new Runnable() {
203 listener.input(output);
212 public void getPlaceholderTextInput (final TextInputListener listener, final String title, final String placeholder) {
213 SwingUtilities.invokeLater(new Runnable() {
215 JPanel panel = new JPanel(new FlowLayout());
217 JPanel textPanel = new JPanel() {
218 public boolean isOptimizedDrawingEnabled () {
222 textPanel.setLayout(new OverlayLayout(textPanel));
223 panel.add(textPanel);
225 final JTextField textField = new JTextField(20);
226 textField.setAlignmentX(0.0f);
227 textPanel.add(textField);
229 final JLabel placeholderLabel = new JLabel(placeholder);
230 placeholderLabel.setForeground(Color.GRAY);
231 placeholderLabel.setAlignmentX(0.0f);
232 textPanel.add(placeholderLabel, 0);
234 textField.getDocument().addDocumentListener(new DocumentListener() {
235 public void removeUpdate (DocumentEvent event) {
239 public void insertUpdate (DocumentEvent event) {
243 public void changedUpdate (DocumentEvent event) {
247 private void updated () {
248 placeholderLabel.setVisible(textField.getText().length() == 0);
252 JOptionPane pane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null,
254 pane.setComponentOrientation(JOptionPane.getRootFrame().getComponentOrientation());
255 pane.selectInitialValue();
257 placeholderLabel.setBorder(new EmptyBorder(textField.getBorder().getBorderInsets(textField)));
259 JDialog dialog = pane.createDialog(null, title);
260 dialog.addWindowFocusListener(new WindowFocusListener() {
261 public void windowLostFocus (WindowEvent arg0) {
264 public void windowGainedFocus (WindowEvent arg0) {
265 textField.requestFocusInWindow();
268 dialog.setVisible(true);
271 Object selectedValue = pane.getValue();
272 if (selectedValue != null && (selectedValue instanceof Integer) && (Integer)selectedValue == JOptionPane.OK_OPTION)
273 listener.input(textField.getText());
280 public void setOnscreenKeyboardVisible (boolean visible) {
283 public void vibrate (int milliseconds) {
286 public void vibrate (long[] pattern, int repeat) {
289 public void cancelVibrate () {
292 public float getAzimuth () {
296 public float getPitch () {
300 public float getRoll () {
304 public void getRotationMatrix (float[] matrix) {
307 public long getCurrentEventTime () {
311 public void setCatchBackKey (boolean catchBack) {
314 public void setCatchMenuKey (boolean catchMenu) {
317 public void setInputProcessor (InputProcessor processor) {
318 this.processor = processor;
321 public InputProcessor getInputProcessor () {
325 public boolean isPeripheralAvailable (Peripheral peripheral) {
326 return peripheral == Peripheral.HardwareKeyboard;
329 public int getRotation () {
333 public Orientation getNativeOrientation () {
334 return Orientation.Landscape;
337 public void setCursorCatched (boolean captured) {
338 glfwSetInputMode(app.graphics.window, GLFW_CURSOR_MODE, captured ? GLFW_CURSOR_CAPTURED : GLFW_CURSOR_NORMAL);
341 public boolean isCursorCatched () {
342 return glfwGetInputMode(app.graphics.window, GLFW_CURSOR_MODE) == GLFW_CURSOR_CAPTURED;
345 public void setCursorPosition (int x, int y) {
346 glfwSetCursorPos(app.graphics.window, x, y);
349 char characterForKeyCode (int key) {
350 // Map certain key codes to character codes.
356 case Keys.FORWARD_DEL:
362 static public int getGdxKeyCode (int lwjglKeyCode) {
363 switch (lwjglKeyCode) {
364 case GLFW_KEY_LEFT_BRACKET:
365 return Input.Keys.LEFT_BRACKET;
366 case GLFW_KEY_RIGHT_BRACKET:
367 return Input.Keys.RIGHT_BRACKET;
368 case GLFW_KEY_GRAVE_ACCENT:
369 return Input.Keys.GRAVE;
370 case GLFW_KEY_KP_MULTIPLY:
371 return Input.Keys.STAR;
372 case GLFW_KEY_NUM_LOCK:
373 return Input.Keys.NUM;
374 case GLFW_KEY_KP_DECIMAL:
375 return Input.Keys.PERIOD;
376 case GLFW_KEY_KP_DIVIDE:
377 return Input.Keys.SLASH;
379 return Input.Keys.SYM;
380 case GLFW_KEY_KP_EQUAL:
381 return Input.Keys.EQUALS;
383 return Input.Keys.EQUALS;
384 case GLFW_KEY_KP_ENTER:
385 return Input.Keys.ENTER;
387 return Input.Keys.NUM_0;
389 return Input.Keys.NUM_1;
391 return Input.Keys.NUM_2;
393 return Input.Keys.NUM_3;
395 return Input.Keys.NUM_4;
397 return Input.Keys.NUM_5;
399 return Input.Keys.NUM_6;
401 return Input.Keys.NUM_7;
403 return Input.Keys.NUM_8;
405 return Input.Keys.NUM_9;
459 return Input.Keys.ALT_LEFT;
461 return Input.Keys.ALT_RIGHT;
462 case GLFW_KEY_BACKSLASH:
463 return Input.Keys.BACKSLASH;
465 return Input.Keys.COMMA;
466 case GLFW_KEY_DELETE:
467 return Input.Keys.FORWARD_DEL;
469 return Input.Keys.DPAD_LEFT;
471 return Input.Keys.DPAD_RIGHT;
473 return Input.Keys.DPAD_UP;
475 return Input.Keys.DPAD_DOWN;
477 return Input.Keys.ENTER;
479 return Input.Keys.HOME;
481 return Input.Keys.MINUS;
482 case GLFW_KEY_PERIOD:
483 return Input.Keys.PERIOD;
484 case GLFW_KEY_KP_ADD:
485 return Input.Keys.PLUS;
486 case GLFW_KEY_SEMICOLON:
487 return Input.Keys.SEMICOLON;
488 case GLFW_KEY_LSHIFT:
489 return Input.Keys.SHIFT_LEFT;
490 case GLFW_KEY_RSHIFT:
491 return Input.Keys.SHIFT_RIGHT;
493 return Input.Keys.SLASH;
495 return Input.Keys.SPACE;
497 return Input.Keys.TAB;
498 case GLFW_KEY_LEFT_CONTROL:
499 return Input.Keys.CONTROL_LEFT;
500 case GLFW_KEY_RIGHT_CONTROL:
501 return Input.Keys.CONTROL_RIGHT;
502 case GLFW_KEY_ESCAPE:
503 return Input.Keys.ESCAPE;
505 return Input.Keys.END;
506 case GLFW_KEY_INSERT:
507 return Input.Keys.INSERT;
508 case GLFW_KEY_BACKSPACE:
509 return Input.Keys.DEL;
510 case GLFW_KEY_KP_SUBTRACT:
511 return Input.Keys.MINUS;
512 case GLFW_KEY_APOSTROPHE:
513 return Input.Keys.APOSTROPHE;
515 return Input.Keys.F1;
517 return Input.Keys.F2;
519 return Input.Keys.F3;
521 return Input.Keys.F4;
523 return Input.Keys.F5;
525 return Input.Keys.F6;
527 return Input.Keys.F7;
529 return Input.Keys.F8;
531 return Input.Keys.F9;
533 return Input.Keys.F10;
535 return Input.Keys.F11;
537 return Input.Keys.F12;
539 return Input.Keys.NUM_0;
541 return Input.Keys.NUM_1;
543 return Input.Keys.NUM_2;
545 return Input.Keys.NUM_3;
547 return Input.Keys.NUM_4;
549 return Input.Keys.NUM_5;
551 return Input.Keys.NUM_6;
553 return Input.Keys.NUM_7;
555 return Input.Keys.NUM_8;
557 return Input.Keys.NUM_9;
559 return Input.Keys.UNKNOWN;
563 static public int getJglfwKeyCode (int gdxKeyCode) {
564 switch (gdxKeyCode) {
565 case Input.Keys.LEFT_BRACKET:
566 return GLFW_KEY_LEFT_BRACKET;
567 case Input.Keys.RIGHT_BRACKET:
568 return GLFW_KEY_RIGHT_BRACKET;
569 case Input.Keys.GRAVE:
570 return GLFW_KEY_GRAVE_ACCENT;
571 case Input.Keys.STAR:
572 return GLFW_KEY_KP_MULTIPLY;
574 return GLFW_KEY_NUM_LOCK;
575 case Input.Keys.EQUALS:
576 return GLFW_KEY_MENU;
578 return GLFW_KEY_MENU;
579 case Input.Keys.NUM_0:
581 case Input.Keys.NUM_1:
583 case Input.Keys.NUM_2:
585 case Input.Keys.NUM_3:
587 case Input.Keys.NUM_4:
589 case Input.Keys.NUM_5:
591 case Input.Keys.NUM_6:
593 case Input.Keys.NUM_7:
595 case Input.Keys.NUM_8:
597 case Input.Keys.NUM_9:
651 case Input.Keys.ALT_LEFT:
652 return GLFW_KEY_LALT;
653 case Input.Keys.ALT_RIGHT:
654 return GLFW_KEY_RALT;
655 case Input.Keys.BACKSLASH:
656 return GLFW_KEY_BACKSLASH;
657 case Input.Keys.COMMA:
658 return GLFW_KEY_COMMA;
659 case Input.Keys.FORWARD_DEL:
660 return GLFW_KEY_DELETE;
661 case Input.Keys.DPAD_LEFT:
662 return GLFW_KEY_LEFT;
663 case Input.Keys.DPAD_RIGHT:
664 return GLFW_KEY_RIGHT;
665 case Input.Keys.DPAD_UP:
667 case Input.Keys.DPAD_DOWN:
668 return GLFW_KEY_DOWN;
669 case Input.Keys.ENTER:
670 return GLFW_KEY_ENTER;
671 case Input.Keys.HOME:
672 return GLFW_KEY_HOME;
673 case Input.Keys.MINUS:
674 return GLFW_KEY_MINUS;
675 case Input.Keys.PERIOD:
676 return GLFW_KEY_PERIOD;
677 case Input.Keys.PLUS:
678 return GLFW_KEY_KP_ADD;
679 case Input.Keys.SEMICOLON:
680 return GLFW_KEY_SEMICOLON;
681 case Input.Keys.SHIFT_LEFT:
682 return GLFW_KEY_LSHIFT;
683 case Input.Keys.SHIFT_RIGHT:
684 return GLFW_KEY_RSHIFT;
685 case Input.Keys.SLASH:
686 return GLFW_KEY_SLASH;
687 case Input.Keys.SPACE:
688 return GLFW_KEY_SPACE;
692 return GLFW_KEY_BACKSPACE;
693 case Input.Keys.CONTROL_LEFT:
694 return GLFW_KEY_LEFT_CONTROL;
695 case Input.Keys.CONTROL_RIGHT:
696 return GLFW_KEY_RIGHT_CONTROL;
697 case Input.Keys.ESCAPE:
698 return GLFW_KEY_ESCAPE;