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) {
47 if (processor != null) processor.keyDown(getGdxKeyCode(key));
51 if (processor != null) processor.keyDown(getGdxKeyCode(key));
54 if (processor != null && lastCharacter != 0) processor.keyTyped(lastCharacter);
57 app.graphics.requestRendering();
60 public void character (long window, char character) {
61 // FIXME controll chars like backspace aren't reported by this callback but
63 lastCharacter = character;
64 if (processor != null) processor.keyTyped(character);
65 app.graphics.requestRendering();
68 public void scroll (long window, double scrollX, double scrollY) {
69 if (processor != null) processor.scrolled((int)-Math.signum(scrollY));
70 app.graphics.requestRendering();
73 public void mouseButton (long window, int button, boolean pressed) {
77 if (processor != null) processor.touchDown(mouseX, mouseY, 0, button);
81 if (processor != null) processor.touchUp(mouseX, mouseY, 0, button);
83 app.graphics.requestRendering();
86 public void cursorPos (long window, int x, int y) {
91 if (processor != null) {
93 processor.touchDragged(mouseX, mouseY, 0);
95 processor.mouseMoved(mouseX, mouseY);
97 app.graphics.requestRendering();
100 public void cursorEnter (long window, boolean entered) {
105 public void update () {
110 public float getAccelerometerX () {
114 public float getAccelerometerY () {
118 public float getAccelerometerZ () {
123 return glfwGetCursorPosX(app.graphics.window);
126 public int getX (int pointer) {
134 return app.graphics.getHeight() - 1 - glfwGetCursorPosY(app.graphics.window);
137 public int getY (int pointer) {
144 public int getDeltaX () {
148 public int getDeltaX (int pointer) {
155 public int getDeltaY () {
159 public int getDeltaY (int pointer) {
166 public boolean isTouched () {
167 return glfwGetMouseButton(app.graphics.window, 0) || glfwGetMouseButton(app.graphics.window, 1)
168 || glfwGetMouseButton(app.graphics.window, 2);
171 public boolean isTouched (int pointer) {
178 public boolean justTouched () {
182 public boolean isButtonPressed (int button) {
183 return glfwGetMouseButton(app.graphics.window, button);
186 public boolean isKeyPressed (int key) {
187 if (key == Input.Keys.ANY_KEY)
188 return pressedKeys > 0;
190 return glfwGetKey(app.graphics.window, key);
193 public void getTextInput (final TextInputListener listener, final String title, final String text) {
194 SwingUtilities.invokeLater(new Runnable() {
196 final String output = JOptionPane.showInputDialog(null, title, text);
197 app.postRunnable(new Runnable() {
200 listener.input(output);
209 public void getPlaceholderTextInput (final TextInputListener listener, final String title, final String placeholder) {
210 SwingUtilities.invokeLater(new Runnable() {
212 JPanel panel = new JPanel(new FlowLayout());
214 JPanel textPanel = new JPanel() {
215 public boolean isOptimizedDrawingEnabled () {
219 textPanel.setLayout(new OverlayLayout(textPanel));
220 panel.add(textPanel);
222 final JTextField textField = new JTextField(20);
223 textField.setAlignmentX(0.0f);
224 textPanel.add(textField);
226 final JLabel placeholderLabel = new JLabel(placeholder);
227 placeholderLabel.setForeground(Color.GRAY);
228 placeholderLabel.setAlignmentX(0.0f);
229 textPanel.add(placeholderLabel, 0);
231 textField.getDocument().addDocumentListener(new DocumentListener() {
232 public void removeUpdate (DocumentEvent event) {
236 public void insertUpdate (DocumentEvent event) {
240 public void changedUpdate (DocumentEvent event) {
244 private void updated () {
245 placeholderLabel.setVisible(textField.getText().length() == 0);
249 JOptionPane pane = new JOptionPane(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null,
251 pane.setComponentOrientation(JOptionPane.getRootFrame().getComponentOrientation());
252 pane.selectInitialValue();
254 placeholderLabel.setBorder(new EmptyBorder(textField.getBorder().getBorderInsets(textField)));
256 JDialog dialog = pane.createDialog(null, title);
257 dialog.addWindowFocusListener(new WindowFocusListener() {
258 public void windowLostFocus (WindowEvent arg0) {
261 public void windowGainedFocus (WindowEvent arg0) {
262 textField.requestFocusInWindow();
265 dialog.setVisible(true);
268 Object selectedValue = pane.getValue();
269 if (selectedValue != null && (selectedValue instanceof Integer) && (Integer)selectedValue == JOptionPane.OK_OPTION)
270 listener.input(textField.getText());
277 public void setOnscreenKeyboardVisible (boolean visible) {
280 public void vibrate (int milliseconds) {
283 public void vibrate (long[] pattern, int repeat) {
286 public void cancelVibrate () {
289 public float getAzimuth () {
293 public float getPitch () {
297 public float getRoll () {
301 public void getRotationMatrix (float[] matrix) {
304 public long getCurrentEventTime () {
308 public void setCatchBackKey (boolean catchBack) {
311 public void setCatchMenuKey (boolean catchMenu) {
314 public void setInputProcessor (InputProcessor processor) {
315 this.processor = processor;
318 public InputProcessor getInputProcessor () {
322 public boolean isPeripheralAvailable (Peripheral peripheral) {
323 return peripheral == Peripheral.HardwareKeyboard;
326 public int getRotation () {
330 public Orientation getNativeOrientation () {
331 return Orientation.Landscape;
334 public void setCursorCatched (boolean captured) {
335 glfwSetInputMode(app.graphics.window, GLFW_CURSOR_MODE, captured ? GLFW_CURSOR_CAPTURED : GLFW_CURSOR_NORMAL);
338 public boolean isCursorCatched () {
339 return glfwGetInputMode(app.graphics.window, GLFW_CURSOR_MODE) == GLFW_CURSOR_CAPTURED;
342 public void setCursorPosition (int x, int y) {
343 glfwSetCursorPos(app.graphics.window, x, y);
346 static public int getGdxKeyCode (int lwjglKeyCode) {
347 switch (lwjglKeyCode) {
348 case GLFW_KEY_LEFT_BRACKET:
349 return Input.Keys.LEFT_BRACKET;
350 case GLFW_KEY_RIGHT_BRACKET:
351 return Input.Keys.RIGHT_BRACKET;
352 case GLFW_KEY_GRAVE_ACCENT:
353 return Input.Keys.GRAVE;
354 case GLFW_KEY_KP_MULTIPLY:
355 return Input.Keys.STAR;
356 case GLFW_KEY_NUM_LOCK:
357 return Input.Keys.NUM;
358 case GLFW_KEY_KP_DECIMAL:
359 return Input.Keys.PERIOD;
360 case GLFW_KEY_KP_DIVIDE:
361 return Input.Keys.SLASH;
363 return Input.Keys.SYM;
364 case GLFW_KEY_KP_EQUAL:
365 return Input.Keys.EQUALS;
367 return Input.Keys.EQUALS;
368 case GLFW_KEY_KP_ENTER:
369 return Input.Keys.ENTER;
371 return Input.Keys.NUM_0;
373 return Input.Keys.NUM_1;
375 return Input.Keys.NUM_2;
377 return Input.Keys.NUM_3;
379 return Input.Keys.NUM_4;
381 return Input.Keys.NUM_5;
383 return Input.Keys.NUM_6;
385 return Input.Keys.NUM_7;
387 return Input.Keys.NUM_8;
389 return Input.Keys.NUM_9;
443 return Input.Keys.ALT_LEFT;
445 return Input.Keys.ALT_RIGHT;
446 case GLFW_KEY_BACKSLASH:
447 return Input.Keys.BACKSLASH;
449 return Input.Keys.COMMA;
450 case GLFW_KEY_DELETE:
451 return Input.Keys.FORWARD_DEL;
453 return Input.Keys.DPAD_LEFT;
455 return Input.Keys.DPAD_RIGHT;
457 return Input.Keys.DPAD_UP;
459 return Input.Keys.DPAD_DOWN;
461 return Input.Keys.ENTER;
463 return Input.Keys.HOME;
465 return Input.Keys.MINUS;
466 case GLFW_KEY_PERIOD:
467 return Input.Keys.PERIOD;
468 case GLFW_KEY_KP_ADD:
469 return Input.Keys.PLUS;
470 case GLFW_KEY_SEMICOLON:
471 return Input.Keys.SEMICOLON;
472 case GLFW_KEY_LSHIFT:
473 return Input.Keys.SHIFT_LEFT;
474 case GLFW_KEY_RSHIFT:
475 return Input.Keys.SHIFT_RIGHT;
477 return Input.Keys.SLASH;
479 return Input.Keys.SPACE;
481 return Input.Keys.TAB;
482 case GLFW_KEY_LEFT_CONTROL:
483 return Input.Keys.CONTROL_LEFT;
484 case GLFW_KEY_RIGHT_CONTROL:
485 return Input.Keys.CONTROL_RIGHT;
486 case GLFW_KEY_ESCAPE:
487 return Input.Keys.ESCAPE;
489 return Input.Keys.END;
490 case GLFW_KEY_INSERT:
491 return Input.Keys.INSERT;
492 case GLFW_KEY_BACKSPACE:
493 return Input.Keys.DEL;
494 case GLFW_KEY_KP_SUBTRACT:
495 return Input.Keys.MINUS;
496 case GLFW_KEY_APOSTROPHE:
497 return Input.Keys.APOSTROPHE;
499 return Input.Keys.F1;
501 return Input.Keys.F2;
503 return Input.Keys.F3;
505 return Input.Keys.F4;
507 return Input.Keys.F5;
509 return Input.Keys.F6;
511 return Input.Keys.F7;
513 return Input.Keys.F8;
515 return Input.Keys.F9;
517 return Input.Keys.F10;
519 return Input.Keys.F11;
521 return Input.Keys.F12;
523 return Input.Keys.NUM_0;
525 return Input.Keys.NUM_1;
527 return Input.Keys.NUM_2;
529 return Input.Keys.NUM_3;
531 return Input.Keys.NUM_4;
533 return Input.Keys.NUM_5;
535 return Input.Keys.NUM_6;
537 return Input.Keys.NUM_7;
539 return Input.Keys.NUM_8;
541 return Input.Keys.NUM_9;
543 return Input.Keys.UNKNOWN;
547 static public int getJglfwKeyCode (int gdxKeyCode) {
548 switch (gdxKeyCode) {
549 case Input.Keys.LEFT_BRACKET:
550 return GLFW_KEY_LEFT_BRACKET;
551 case Input.Keys.RIGHT_BRACKET:
552 return GLFW_KEY_RIGHT_BRACKET;
553 case Input.Keys.GRAVE:
554 return GLFW_KEY_GRAVE_ACCENT;
555 case Input.Keys.STAR:
556 return GLFW_KEY_KP_MULTIPLY;
558 return GLFW_KEY_NUM_LOCK;
559 case Input.Keys.EQUALS:
560 return GLFW_KEY_MENU;
562 return GLFW_KEY_MENU;
563 case Input.Keys.NUM_0:
565 case Input.Keys.NUM_1:
567 case Input.Keys.NUM_2:
569 case Input.Keys.NUM_3:
571 case Input.Keys.NUM_4:
573 case Input.Keys.NUM_5:
575 case Input.Keys.NUM_6:
577 case Input.Keys.NUM_7:
579 case Input.Keys.NUM_8:
581 case Input.Keys.NUM_9:
635 case Input.Keys.ALT_LEFT:
636 return GLFW_KEY_LALT;
637 case Input.Keys.ALT_RIGHT:
638 return GLFW_KEY_RALT;
639 case Input.Keys.BACKSLASH:
640 return GLFW_KEY_BACKSLASH;
641 case Input.Keys.COMMA:
642 return GLFW_KEY_COMMA;
643 case Input.Keys.FORWARD_DEL:
644 return GLFW_KEY_DELETE;
645 case Input.Keys.DPAD_LEFT:
646 return GLFW_KEY_LEFT;
647 case Input.Keys.DPAD_RIGHT:
648 return GLFW_KEY_RIGHT;
649 case Input.Keys.DPAD_UP:
651 case Input.Keys.DPAD_DOWN:
652 return GLFW_KEY_DOWN;
653 case Input.Keys.ENTER:
654 return GLFW_KEY_ENTER;
655 case Input.Keys.HOME:
656 return GLFW_KEY_HOME;
657 case Input.Keys.MINUS:
658 return GLFW_KEY_MINUS;
659 case Input.Keys.PERIOD:
660 return GLFW_KEY_PERIOD;
661 case Input.Keys.PLUS:
662 return GLFW_KEY_KP_ADD;
663 case Input.Keys.SEMICOLON:
664 return GLFW_KEY_SEMICOLON;
665 case Input.Keys.SHIFT_LEFT:
666 return GLFW_KEY_LSHIFT;
667 case Input.Keys.SHIFT_RIGHT:
668 return GLFW_KEY_RSHIFT;
669 case Input.Keys.SLASH:
670 return GLFW_KEY_SLASH;
671 case Input.Keys.SPACE:
672 return GLFW_KEY_SPACE;
676 return GLFW_KEY_BACKSPACE;
677 case Input.Keys.CONTROL_LEFT:
678 return GLFW_KEY_LEFT_CONTROL;
679 case Input.Keys.CONTROL_RIGHT:
680 return GLFW_KEY_RIGHT_CONTROL;
681 case Input.Keys.ESCAPE:
682 return GLFW_KEY_ESCAPE;