1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.backends.gwt; 18 19 import com.badlogic.gdx.Gdx; 20 import com.badlogic.gdx.Input; 21 import com.badlogic.gdx.InputProcessor; 22 import com.badlogic.gdx.Input.Buttons; 23 import com.badlogic.gdx.backends.gwt.widgets.TextInputDialogBox; 24 import com.badlogic.gdx.backends.gwt.widgets.TextInputDialogBox.TextInputDialogListener; 25 import com.badlogic.gdx.utils.IntMap; 26 import com.badlogic.gdx.utils.IntSet; 27 import com.badlogic.gdx.utils.TimeUtils; 28 import com.gargoylesoftware.htmlunit.javascript.host.Navigator; 29 import com.google.gwt.core.client.JavaScriptObject; 30 import com.google.gwt.core.client.JsArray; 31 import com.google.gwt.dom.client.CanvasElement; 32 import com.google.gwt.dom.client.Document; 33 import com.google.gwt.dom.client.Element; 34 import com.google.gwt.dom.client.NativeEvent; 35 import com.google.gwt.dom.client.Touch; 36 import com.google.gwt.event.dom.client.KeyCodes; 37 import com.google.gwt.logging.client.ConsoleLogHandler; 38 39 public class GwtInput implements Input { 40 static final int MAX_TOUCHES = 20; 41 boolean justTouched = false; 42 private IntMap<Integer> touchMap = new IntMap<Integer>(20); 43 private boolean[] touched = new boolean[MAX_TOUCHES]; 44 private int[] touchX = new int[MAX_TOUCHES]; 45 private int[] touchY = new int[MAX_TOUCHES]; 46 private int[] deltaX = new int[MAX_TOUCHES]; 47 private int[] deltaY = new int[MAX_TOUCHES]; 48 IntSet pressedButtons = new IntSet(); 49 int pressedKeyCount = 0; 50 boolean[] pressedKeys = new boolean[256]; 51 boolean keyJustPressed = false; 52 boolean[] justPressedKeys = new boolean[256]; 53 InputProcessor processor; 54 char lastKeyCharPressed; 55 float keyRepeatTimer; 56 long currentEventTimeStamp; 57 final CanvasElement canvas; 58 boolean hasFocus = true; 59 GwtInput(CanvasElement canvas)60 public GwtInput (CanvasElement canvas) { 61 this.canvas = canvas; 62 hookEvents(); 63 } 64 reset()65 void reset () { 66 justTouched = false; 67 if (keyJustPressed) { 68 keyJustPressed = false; 69 for (int i = 0; i < justPressedKeys.length; i++) { 70 justPressedKeys[i] = false; 71 } 72 } 73 } 74 75 @Override getAccelerometerX()76 public float getAccelerometerX () { 77 return 0; 78 } 79 80 @Override getAccelerometerY()81 public float getAccelerometerY () { 82 return 0; 83 } 84 85 @Override getAccelerometerZ()86 public float getAccelerometerZ () { 87 return 0; 88 } 89 90 @Override getGyroscopeX()91 public float getGyroscopeX () { 92 // TODO Auto-generated method stub 93 return 0; 94 } 95 96 @Override getGyroscopeY()97 public float getGyroscopeY () { 98 // TODO Auto-generated method stub 99 return 0; 100 } 101 102 @Override getGyroscopeZ()103 public float getGyroscopeZ () { 104 // TODO Auto-generated method stub 105 return 0; 106 } 107 108 @Override getX()109 public int getX () { 110 return touchX[0]; 111 } 112 113 @Override getX(int pointer)114 public int getX (int pointer) { 115 return touchX[pointer]; 116 } 117 118 @Override getDeltaX()119 public int getDeltaX () { 120 return deltaX[0]; 121 } 122 123 @Override getDeltaX(int pointer)124 public int getDeltaX (int pointer) { 125 return deltaX[pointer]; 126 } 127 128 @Override getY()129 public int getY () { 130 return touchY[0]; 131 } 132 133 @Override getY(int pointer)134 public int getY (int pointer) { 135 return touchY[pointer]; 136 } 137 138 @Override getDeltaY()139 public int getDeltaY () { 140 return deltaY[0]; 141 } 142 143 @Override getDeltaY(int pointer)144 public int getDeltaY (int pointer) { 145 return deltaY[pointer]; 146 } 147 148 @Override isTouched()149 public boolean isTouched () { 150 for (int pointer = 0; pointer < MAX_TOUCHES; pointer++) { 151 if (touched[pointer]) { 152 return true; 153 } 154 } 155 return false; 156 } 157 158 @Override justTouched()159 public boolean justTouched () { 160 return justTouched; 161 } 162 163 @Override isTouched(int pointer)164 public boolean isTouched (int pointer) { 165 return touched[pointer]; 166 } 167 168 @Override isButtonPressed(int button)169 public boolean isButtonPressed (int button) { 170 return pressedButtons.contains(button) && touched[0]; 171 } 172 173 @Override isKeyPressed(int key)174 public boolean isKeyPressed (int key) { 175 if (key == Keys.ANY_KEY) { 176 return pressedKeyCount > 0; 177 } 178 if (key < 0 || key > 255) { 179 return false; 180 } 181 return pressedKeys[key]; 182 } 183 184 @Override isKeyJustPressed(int key)185 public boolean isKeyJustPressed (int key) { 186 if (key == Keys.ANY_KEY) { 187 return keyJustPressed; 188 } 189 if (key < 0 || key > 255) { 190 return false; 191 } 192 return justPressedKeys[key]; 193 } 194 getTextInput(TextInputListener listener, String title, String text, String hint)195 public void getTextInput (TextInputListener listener, String title, String text, String hint) { 196 TextInputDialogBox dialog = new TextInputDialogBox(title, text, hint); 197 final TextInputListener capturedListener = listener; 198 dialog.setListener(new TextInputDialogListener() { 199 @Override 200 public void onPositive (String text) { 201 if (capturedListener != null) { 202 capturedListener.input(text); 203 } 204 } 205 206 @Override 207 public void onNegative () { 208 if (capturedListener != null) { 209 capturedListener.canceled(); 210 } 211 } 212 }); 213 } 214 215 @Override setOnscreenKeyboardVisible(boolean visible)216 public void setOnscreenKeyboardVisible (boolean visible) { 217 } 218 219 @Override vibrate(int milliseconds)220 public void vibrate (int milliseconds) { 221 } 222 223 @Override vibrate(long[] pattern, int repeat)224 public void vibrate (long[] pattern, int repeat) { 225 } 226 227 @Override cancelVibrate()228 public void cancelVibrate () { 229 } 230 231 @Override getAzimuth()232 public float getAzimuth () { 233 return 0; 234 } 235 236 @Override getPitch()237 public float getPitch () { 238 return 0; 239 } 240 241 @Override getRoll()242 public float getRoll () { 243 return 0; 244 } 245 246 @Override getRotationMatrix(float[] matrix)247 public void getRotationMatrix (float[] matrix) { 248 } 249 250 @Override getCurrentEventTime()251 public long getCurrentEventTime () { 252 return currentEventTimeStamp; 253 } 254 255 @Override setCatchBackKey(boolean catchBack)256 public void setCatchBackKey (boolean catchBack) { 257 } 258 259 @Override isCatchBackKey()260 public boolean isCatchBackKey () { 261 return false; 262 } 263 264 @Override setCatchMenuKey(boolean catchMenu)265 public void setCatchMenuKey (boolean catchMenu) { 266 } 267 268 @Override isCatchMenuKey()269 public boolean isCatchMenuKey () { 270 return false; 271 } 272 273 @Override setInputProcessor(InputProcessor processor)274 public void setInputProcessor (InputProcessor processor) { 275 this.processor = processor; 276 } 277 278 @Override getInputProcessor()279 public InputProcessor getInputProcessor () { 280 return processor; 281 } 282 283 @Override isPeripheralAvailable(Peripheral peripheral)284 public boolean isPeripheralAvailable (Peripheral peripheral) { 285 if (peripheral == Peripheral.Accelerometer) return false; 286 if (peripheral == Peripheral.Compass) return false; 287 if (peripheral == Peripheral.HardwareKeyboard) return true; 288 if (peripheral == Peripheral.MultitouchScreen) return isTouchScreen(); 289 if (peripheral == Peripheral.OnscreenKeyboard) return false; 290 if (peripheral == Peripheral.Vibrator) return false; 291 return false; 292 } 293 294 @Override getRotation()295 public int getRotation () { 296 return 0; 297 } 298 299 @Override getNativeOrientation()300 public Orientation getNativeOrientation () { 301 return Orientation.Landscape; 302 } 303 304 /** from https://github.com/toji/game-shim/blob/master/game-shim.js 305 * @return is Cursor catched */ isCursorCatchedJSNI()306 private native boolean isCursorCatchedJSNI () /*-{ 307 if (!navigator.pointer) { 308 navigator.pointer = navigator.webkitPointer || navigator.mozPointer; 309 } 310 if (navigator.pointer) { 311 if (typeof (navigator.pointer.isLocked) === "boolean") { 312 // Chrome initially launched with this interface 313 return navigator.pointer.isLocked; 314 } else if (typeof (navigator.pointer.isLocked) === "function") { 315 // Some older builds might provide isLocked as a function 316 return navigator.pointer.isLocked(); 317 } else if (typeof (navigator.pointer.islocked) === "function") { 318 // For compatibility with early Firefox build 319 return navigator.pointer.islocked(); 320 } 321 } 322 return false; 323 }-*/; 324 325 /** from https://github.com/toji/game-shim/blob/master/game-shim.js 326 * @param element Canvas */ setCursorCatchedJSNI(CanvasElement element)327 private native void setCursorCatchedJSNI (CanvasElement element) /*-{ 328 // Navigator pointer is not the right interface according to spec. 329 // Here for backwards compatibility only 330 if (!navigator.pointer) { 331 navigator.pointer = navigator.webkitPointer || navigator.mozPointer; 332 } 333 // element.requestPointerLock 334 if (!element.requestPointerLock) { 335 element.requestPointerLock = (function() { 336 return element.webkitRequestPointerLock 337 || element.mozRequestPointerLock || function() { 338 if (navigator.pointer) { 339 navigator.pointer.lock(element); 340 } 341 }; 342 })(); 343 } 344 element.requestPointerLock(); 345 }-*/; 346 347 /** from https://github.com/toji/game-shim/blob/master/game-shim.js */ exitCursorCatchedJSNI()348 private native void exitCursorCatchedJSNI () /*-{ 349 if (!$doc.exitPointerLock) { 350 $doc.exitPointerLock = (function() { 351 return $doc.webkitExitPointerLock || $doc.mozExitPointerLock 352 || function() { 353 if (navigator.pointer) { 354 var elem = this; 355 navigator.pointer.unlock(); 356 } 357 }; 358 })(); 359 } 360 }-*/; 361 362 /** from https://github.com/toji/game-shim/blob/master/game-shim.js 363 * @param event JavaScript Mouse Event 364 * @return movement in x direction */ getMovementXJSNI(NativeEvent event)365 private native float getMovementXJSNI (NativeEvent event) /*-{ 366 return event.movementX || event.webkitMovementX || 0; 367 }-*/; 368 369 /** from https://github.com/toji/game-shim/blob/master/game-shim.js 370 * @param event JavaScript Mouse Event 371 * @return movement in y direction */ getMovementYJSNI(NativeEvent event)372 private native float getMovementYJSNI (NativeEvent event) /*-{ 373 return event.movementY || event.webkitMovementY || 0; 374 }-*/; 375 isTouchScreen()376 private static native boolean isTouchScreen () /*-{ 377 return (('ontouchstart' in window) || (navigator.msMaxTouchPoints > 0)); 378 }-*/; 379 380 /** works only for Chrome > Version 18 with enabled Mouse Lock enable in about:flags or start Chrome with the 381 * --enable-pointer-lock flag */ 382 @Override setCursorCatched(boolean catched)383 public void setCursorCatched (boolean catched) { 384 if (catched) 385 setCursorCatchedJSNI(canvas); 386 else 387 exitCursorCatchedJSNI(); 388 } 389 390 @Override isCursorCatched()391 public boolean isCursorCatched () { 392 return isCursorCatchedJSNI(); 393 } 394 395 @Override setCursorPosition(int x, int y)396 public void setCursorPosition (int x, int y) { 397 // FIXME?? 398 } 399 400 // kindly borrowed from our dear playn friends... addEventListener(JavaScriptObject target, String name, GwtInput handler, boolean capture)401 static native void addEventListener (JavaScriptObject target, String name, GwtInput handler, boolean capture) /*-{ 402 target 403 .addEventListener( 404 name, 405 function(e) { 406 handler.@com.badlogic.gdx.backends.gwt.GwtInput::handleEvent(Lcom/google/gwt/dom/client/NativeEvent;)(e); 407 }, capture); 408 }-*/; 409 getMouseWheelVelocity(NativeEvent evt)410 private static native float getMouseWheelVelocity (NativeEvent evt) /*-{ 411 var delta = 0.0; 412 var agentInfo = @com.badlogic.gdx.backends.gwt.GwtApplication::agentInfo()(); 413 414 if (agentInfo.isFirefox) { 415 if (agentInfo.isMacOS) { 416 delta = 1.0 * evt.detail; 417 } else { 418 delta = 1.0 * evt.detail / 3; 419 } 420 } else if (agentInfo.isOpera) { 421 if (agentInfo.isLinux) { 422 delta = -1.0 * evt.wheelDelta / 80; 423 } else { 424 // on mac 425 delta = -1.0 * evt.wheelDelta / 40; 426 } 427 } else if (agentInfo.isChrome || agentInfo.isSafari) { 428 delta = -1.0 * evt.wheelDelta / 120; 429 // handle touchpad for chrome 430 if (Math.abs(delta) < 1) { 431 if (agentInfo.isWindows) { 432 delta = -1.0 * evt.wheelDelta; 433 } else if (agentInfo.isMacOS) { 434 delta = -1.0 * evt.wheelDelta / 3; 435 } 436 } 437 } 438 return delta; 439 }-*/; 440 441 /** Kindly borrowed from PlayN. **/ getMouseWheelEvent()442 protected static native String getMouseWheelEvent () /*-{ 443 if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) { 444 return "DOMMouseScroll"; 445 } else { 446 return "mousewheel"; 447 } 448 }-*/; 449 450 /** Kindly borrowed from PlayN. **/ getRelativeX(NativeEvent e, CanvasElement target)451 protected int getRelativeX (NativeEvent e, CanvasElement target) { 452 float xScaleRatio = target.getWidth() * 1f / target.getClientWidth(); // Correct for canvas CSS scaling 453 return Math.round(xScaleRatio 454 * (e.getClientX() - target.getAbsoluteLeft() + target.getScrollLeft() + target.getOwnerDocument().getScrollLeft())); 455 } 456 457 /** Kindly borrowed from PlayN. **/ getRelativeY(NativeEvent e, CanvasElement target)458 protected int getRelativeY (NativeEvent e, CanvasElement target) { 459 float yScaleRatio = target.getHeight() * 1f / target.getClientHeight(); // Correct for canvas CSS scaling 460 return Math.round(yScaleRatio 461 * (e.getClientY() - target.getAbsoluteTop() + target.getScrollTop() + target.getOwnerDocument().getScrollTop())); 462 } 463 getRelativeX(Touch touch, CanvasElement target)464 protected int getRelativeX (Touch touch, CanvasElement target) { 465 float xScaleRatio = target.getWidth() * 1f / target.getClientWidth(); // Correct for canvas CSS scaling 466 return Math.round(xScaleRatio * touch.getRelativeX(target)); 467 } 468 getRelativeY(Touch touch, CanvasElement target)469 protected int getRelativeY (Touch touch, CanvasElement target) { 470 float yScaleRatio = target.getHeight() * 1f / target.getClientHeight(); // Correct for canvas CSS scaling 471 return Math.round(yScaleRatio * touch.getRelativeY(target)); 472 } 473 hookEvents()474 private void hookEvents () { 475 addEventListener(canvas, "mousedown", this, true); 476 addEventListener(Document.get(), "mousedown", this, true); 477 addEventListener(canvas, "mouseup", this, true); 478 addEventListener(Document.get(), "mouseup", this, true); 479 addEventListener(canvas, "mousemove", this, true); 480 addEventListener(Document.get(), "mousemove", this, true); 481 addEventListener(canvas, getMouseWheelEvent(), this, true); 482 addEventListener(Document.get(), "keydown", this, false); 483 addEventListener(Document.get(), "keyup", this, false); 484 addEventListener(Document.get(), "keypress", this, false); 485 486 addEventListener(canvas, "touchstart", this, true); 487 addEventListener(canvas, "touchmove", this, true); 488 addEventListener(canvas, "touchcancel", this, true); 489 addEventListener(canvas, "touchend", this, true); 490 491 } 492 getButton(int button)493 private int getButton (int button) { 494 if (button == NativeEvent.BUTTON_LEFT) return Buttons.LEFT; 495 if (button == NativeEvent.BUTTON_RIGHT) return Buttons.RIGHT; 496 if (button == NativeEvent.BUTTON_MIDDLE) return Buttons.MIDDLE; 497 return Buttons.LEFT; 498 } 499 handleEvent(NativeEvent e)500 private void handleEvent (NativeEvent e) { 501 if (e.getType().equals("mousedown")) { 502 if (!e.getEventTarget().equals(canvas) || touched[0]) { 503 float mouseX = getRelativeX(e, canvas); 504 float mouseY = getRelativeY(e, canvas); 505 if (mouseX < 0 || mouseX > Gdx.graphics.getWidth() || mouseY < 0 || mouseY > Gdx.graphics.getHeight()) { 506 hasFocus = false; 507 } 508 return; 509 } 510 hasFocus = true; 511 this.justTouched = true; 512 this.touched[0] = true; 513 this.pressedButtons.add(getButton(e.getButton())); 514 this.deltaX[0] = 0; 515 this.deltaY[0] = 0; 516 if (isCursorCatched()) { 517 this.touchX[0] += getMovementXJSNI(e); 518 this.touchY[0] += getMovementYJSNI(e); 519 } else { 520 this.touchX[0] = getRelativeX(e, canvas); 521 this.touchY[0] = getRelativeY(e, canvas); 522 } 523 this.currentEventTimeStamp = TimeUtils.nanoTime(); 524 if (processor != null) processor.touchDown(touchX[0], touchY[0], 0, getButton(e.getButton())); 525 } 526 527 if (e.getType().equals("mousemove")) { 528 if (isCursorCatched()) { 529 this.deltaX[0] = (int)getMovementXJSNI(e); 530 this.deltaY[0] = (int)getMovementYJSNI(e); 531 this.touchX[0] += getMovementXJSNI(e); 532 this.touchY[0] += getMovementYJSNI(e); 533 } else { 534 this.deltaX[0] = getRelativeX(e, canvas) - touchX[0]; 535 this.deltaY[0] = getRelativeY(e, canvas) - touchY[0]; 536 this.touchX[0] = getRelativeX(e, canvas); 537 this.touchY[0] = getRelativeY(e, canvas); 538 } 539 this.currentEventTimeStamp = TimeUtils.nanoTime(); 540 if (processor != null) { 541 if (touched[0]) 542 processor.touchDragged(touchX[0], touchY[0], 0); 543 else 544 processor.mouseMoved(touchX[0], touchY[0]); 545 } 546 } 547 548 if (e.getType().equals("mouseup")) { 549 if (!touched[0]) return; 550 this.pressedButtons.remove(getButton(e.getButton())); 551 this.touched[0] = pressedButtons.size > 0; 552 if (isCursorCatched()) { 553 this.deltaX[0] = (int)getMovementXJSNI(e); 554 this.deltaY[0] = (int)getMovementYJSNI(e); 555 this.touchX[0] += getMovementXJSNI(e); 556 this.touchY[0] += getMovementYJSNI(e); 557 } else { 558 this.deltaX[0] = getRelativeX(e, canvas) - touchX[0]; 559 this.deltaY[0] = getRelativeY(e, canvas) - touchY[0]; 560 this.touchX[0] = getRelativeX(e, canvas); 561 this.touchY[0] = getRelativeY(e, canvas); 562 } 563 this.currentEventTimeStamp = TimeUtils.nanoTime(); 564 this.touched[0] = false; 565 if (processor != null) processor.touchUp(touchX[0], touchY[0], 0, getButton(e.getButton())); 566 } 567 if (e.getType().equals(getMouseWheelEvent())) { 568 if (processor != null) { 569 processor.scrolled((int)getMouseWheelVelocity(e)); 570 } 571 this.currentEventTimeStamp = TimeUtils.nanoTime(); 572 e.preventDefault(); 573 } 574 if (e.getType().equals("keydown") && hasFocus) { 575 // System.out.println("keydown"); 576 int code = keyForCode(e.getKeyCode()); 577 if (code == 67) { 578 e.preventDefault(); 579 if (processor != null) { 580 processor.keyDown(code); 581 processor.keyTyped('\b'); 582 } 583 } else { 584 if (!pressedKeys[code]) { 585 pressedKeyCount++; 586 pressedKeys[code] = true; 587 keyJustPressed = true; 588 justPressedKeys[code] = true; 589 if (processor != null) { 590 processor.keyDown(code); 591 } 592 } 593 } 594 } 595 596 if (e.getType().equals("keypress") && hasFocus) { 597 // System.out.println("keypress"); 598 char c = (char)e.getCharCode(); 599 if (processor != null) processor.keyTyped(c); 600 } 601 602 if (e.getType().equals("keyup") && hasFocus) { 603 // System.out.println("keyup"); 604 int code = keyForCode(e.getKeyCode()); 605 if (pressedKeys[code]) { 606 pressedKeyCount--; 607 pressedKeys[code] = false; 608 } 609 if (processor != null) { 610 processor.keyUp(code); 611 } 612 } 613 614 if (e.getType().equals("touchstart")) { 615 this.justTouched = true; 616 JsArray<Touch> touches = e.getChangedTouches(); 617 for (int i = 0, j = touches.length(); i < j; i++) { 618 Touch touch = touches.get(i); 619 int real = touch.getIdentifier(); 620 int touchId; 621 touchMap.put(real, touchId = getAvailablePointer()); 622 touched[touchId] = true; 623 touchX[touchId] = getRelativeX(touch, canvas); 624 touchY[touchId] = getRelativeY(touch, canvas); 625 deltaX[touchId] = 0; 626 deltaY[touchId] = 0; 627 if (processor != null) { 628 processor.touchDown(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT); 629 } 630 } 631 this.currentEventTimeStamp = TimeUtils.nanoTime(); 632 e.preventDefault(); 633 } 634 if (e.getType().equals("touchmove")) { 635 JsArray<Touch> touches = e.getChangedTouches(); 636 for (int i = 0, j = touches.length(); i < j; i++) { 637 Touch touch = touches.get(i); 638 int real = touch.getIdentifier(); 639 int touchId = touchMap.get(real); 640 deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId]; 641 deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId]; 642 touchX[touchId] = getRelativeX(touch, canvas); 643 touchY[touchId] = getRelativeY(touch, canvas); 644 if (processor != null) { 645 processor.touchDragged(touchX[touchId], touchY[touchId], touchId); 646 } 647 } 648 this.currentEventTimeStamp = TimeUtils.nanoTime(); 649 e.preventDefault(); 650 } 651 if (e.getType().equals("touchcancel")) { 652 JsArray<Touch> touches = e.getChangedTouches(); 653 for (int i = 0, j = touches.length(); i < j; i++) { 654 Touch touch = touches.get(i); 655 int real = touch.getIdentifier(); 656 int touchId = touchMap.get(real); 657 touchMap.remove(real); 658 touched[touchId] = false; 659 deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId]; 660 deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId]; 661 touchX[touchId] = getRelativeX(touch, canvas); 662 touchY[touchId] = getRelativeY(touch, canvas); 663 if (processor != null) { 664 processor.touchUp(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT); 665 } 666 } 667 this.currentEventTimeStamp = TimeUtils.nanoTime(); 668 e.preventDefault(); 669 } 670 if (e.getType().equals("touchend")) { 671 JsArray<Touch> touches = e.getChangedTouches(); 672 for (int i = 0, j = touches.length(); i < j; i++) { 673 Touch touch = touches.get(i); 674 int real = touch.getIdentifier(); 675 int touchId = touchMap.get(real); 676 touchMap.remove(real); 677 touched[touchId] = false; 678 deltaX[touchId] = getRelativeX(touch, canvas) - touchX[touchId]; 679 deltaY[touchId] = getRelativeY(touch, canvas) - touchY[touchId]; 680 touchX[touchId] = getRelativeX(touch, canvas); 681 touchY[touchId] = getRelativeY(touch, canvas); 682 if (processor != null) { 683 processor.touchUp(touchX[touchId], touchY[touchId], touchId, Buttons.LEFT); 684 } 685 } 686 this.currentEventTimeStamp = TimeUtils.nanoTime(); 687 e.preventDefault(); 688 } 689 // if(hasFocus) e.preventDefault(); 690 } 691 getAvailablePointer()692 private int getAvailablePointer () { 693 for (int i = 0; i < MAX_TOUCHES; i++) { 694 if (!touchMap.containsValue(i, false)) return i; 695 } 696 return -1; 697 } 698 699 /** borrowed from PlayN, thanks guys **/ keyForCode(int keyCode)700 private static int keyForCode (int keyCode) { 701 switch (keyCode) { 702 case KeyCodes.KEY_ALT: 703 return Keys.ALT_LEFT; 704 case KeyCodes.KEY_BACKSPACE: 705 return Keys.BACKSPACE; 706 case KeyCodes.KEY_CTRL: 707 return Keys.CONTROL_LEFT; 708 case KeyCodes.KEY_DELETE: 709 return Keys.DEL; 710 case KeyCodes.KEY_DOWN: 711 return Keys.DOWN; 712 case KeyCodes.KEY_END: 713 return Keys.END; 714 case KeyCodes.KEY_ENTER: 715 return Keys.ENTER; 716 case KeyCodes.KEY_ESCAPE: 717 return Keys.ESCAPE; 718 case KeyCodes.KEY_HOME: 719 return Keys.HOME; 720 case KeyCodes.KEY_LEFT: 721 return Keys.LEFT; 722 case KeyCodes.KEY_PAGEDOWN: 723 return Keys.PAGE_DOWN; 724 case KeyCodes.KEY_PAGEUP: 725 return Keys.PAGE_UP; 726 case KeyCodes.KEY_RIGHT: 727 return Keys.RIGHT; 728 case KeyCodes.KEY_SHIFT: 729 return Keys.SHIFT_LEFT; 730 case KeyCodes.KEY_TAB: 731 return Keys.TAB; 732 case KeyCodes.KEY_UP: 733 return Keys.UP; 734 735 case KEY_PAUSE: 736 return Keys.UNKNOWN; // FIXME 737 case KEY_CAPS_LOCK: 738 return Keys.UNKNOWN; // FIXME 739 case KEY_SPACE: 740 return Keys.SPACE; 741 case KEY_INSERT: 742 return Keys.INSERT; 743 case KEY_0: 744 return Keys.NUM_0; 745 case KEY_1: 746 return Keys.NUM_1; 747 case KEY_2: 748 return Keys.NUM_2; 749 case KEY_3: 750 return Keys.NUM_3; 751 case KEY_4: 752 return Keys.NUM_4; 753 case KEY_5: 754 return Keys.NUM_5; 755 case KEY_6: 756 return Keys.NUM_6; 757 case KEY_7: 758 return Keys.NUM_7; 759 case KEY_8: 760 return Keys.NUM_8; 761 case KEY_9: 762 return Keys.NUM_9; 763 case KEY_A: 764 return Keys.A; 765 case KEY_B: 766 return Keys.B; 767 case KEY_C: 768 return Keys.C; 769 case KEY_D: 770 return Keys.D; 771 case KEY_E: 772 return Keys.E; 773 case KEY_F: 774 return Keys.F; 775 case KEY_G: 776 return Keys.G; 777 case KEY_H: 778 return Keys.H; 779 case KEY_I: 780 return Keys.I; 781 case KEY_J: 782 return Keys.J; 783 case KEY_K: 784 return Keys.K; 785 case KEY_L: 786 return Keys.L; 787 case KEY_M: 788 return Keys.M; 789 case KEY_N: 790 return Keys.N; 791 case KEY_O: 792 return Keys.O; 793 case KEY_P: 794 return Keys.P; 795 case KEY_Q: 796 return Keys.Q; 797 case KEY_R: 798 return Keys.R; 799 case KEY_S: 800 return Keys.S; 801 case KEY_T: 802 return Keys.T; 803 case KEY_U: 804 return Keys.U; 805 case KEY_V: 806 return Keys.V; 807 case KEY_W: 808 return Keys.W; 809 case KEY_X: 810 return Keys.X; 811 case KEY_Y: 812 return Keys.Y; 813 case KEY_Z: 814 return Keys.Z; 815 case KEY_LEFT_WINDOW_KEY: 816 return Keys.UNKNOWN; // FIXME 817 case KEY_RIGHT_WINDOW_KEY: 818 return Keys.UNKNOWN; // FIXME 819 // case KEY_SELECT_KEY: return Keys.SELECT_KEY; 820 case KEY_NUMPAD0: 821 return Keys.NUMPAD_0; 822 case KEY_NUMPAD1: 823 return Keys.NUMPAD_1; 824 case KEY_NUMPAD2: 825 return Keys.NUMPAD_2; 826 case KEY_NUMPAD3: 827 return Keys.NUMPAD_3; 828 case KEY_NUMPAD4: 829 return Keys.NUMPAD_4; 830 case KEY_NUMPAD5: 831 return Keys.NUMPAD_5; 832 case KEY_NUMPAD6: 833 return Keys.NUMPAD_6; 834 case KEY_NUMPAD7: 835 return Keys.NUMPAD_7; 836 case KEY_NUMPAD8: 837 return Keys.NUMPAD_8; 838 case KEY_NUMPAD9: 839 return Keys.NUMPAD_9; 840 case KEY_MULTIPLY: 841 return Keys.UNKNOWN; // FIXME 842 case KEY_ADD: 843 return Keys.PLUS; 844 case KEY_SUBTRACT: 845 return Keys.MINUS; 846 case KEY_DECIMAL_POINT_KEY: 847 return Keys.PERIOD; 848 case KEY_DIVIDE: 849 return Keys.UNKNOWN; // FIXME 850 case KEY_F1: 851 return Keys.F1; 852 case KEY_F2: 853 return Keys.F2; 854 case KEY_F3: 855 return Keys.F3; 856 case KEY_F4: 857 return Keys.F4; 858 case KEY_F5: 859 return Keys.F5; 860 case KEY_F6: 861 return Keys.F6; 862 case KEY_F7: 863 return Keys.F7; 864 case KEY_F8: 865 return Keys.F8; 866 case KEY_F9: 867 return Keys.F9; 868 case KEY_F10: 869 return Keys.F10; 870 case KEY_F11: 871 return Keys.F11; 872 case KEY_F12: 873 return Keys.F12; 874 case KEY_NUM_LOCK: 875 return Keys.NUM; 876 case KEY_SCROLL_LOCK: 877 return Keys.UNKNOWN; // FIXME 878 case KEY_SEMICOLON: 879 return Keys.SEMICOLON; 880 case KEY_EQUALS: 881 return Keys.EQUALS; 882 case KEY_COMMA: 883 return Keys.COMMA; 884 case KEY_DASH: 885 return Keys.MINUS; 886 case KEY_PERIOD: 887 return Keys.PERIOD; 888 case KEY_FORWARD_SLASH: 889 return Keys.SLASH; 890 case KEY_GRAVE_ACCENT: 891 return Keys.UNKNOWN; // FIXME 892 case KEY_OPEN_BRACKET: 893 return Keys.LEFT_BRACKET; 894 case KEY_BACKSLASH: 895 return Keys.BACKSLASH; 896 case KEY_CLOSE_BRACKET: 897 return Keys.RIGHT_BRACKET; 898 case KEY_SINGLE_QUOTE: 899 return Keys.APOSTROPHE; 900 default: 901 return Keys.UNKNOWN; 902 } 903 } 904 905 // these are absent from KeyCodes; we know not why... 906 private static final int KEY_PAUSE = 19; 907 private static final int KEY_CAPS_LOCK = 20; 908 private static final int KEY_SPACE = 32; 909 private static final int KEY_INSERT = 45; 910 private static final int KEY_0 = 48; 911 private static final int KEY_1 = 49; 912 private static final int KEY_2 = 50; 913 private static final int KEY_3 = 51; 914 private static final int KEY_4 = 52; 915 private static final int KEY_5 = 53; 916 private static final int KEY_6 = 54; 917 private static final int KEY_7 = 55; 918 private static final int KEY_8 = 56; 919 private static final int KEY_9 = 57; 920 private static final int KEY_A = 65; 921 private static final int KEY_B = 66; 922 private static final int KEY_C = 67; 923 private static final int KEY_D = 68; 924 private static final int KEY_E = 69; 925 private static final int KEY_F = 70; 926 private static final int KEY_G = 71; 927 private static final int KEY_H = 72; 928 private static final int KEY_I = 73; 929 private static final int KEY_J = 74; 930 private static final int KEY_K = 75; 931 private static final int KEY_L = 76; 932 private static final int KEY_M = 77; 933 private static final int KEY_N = 78; 934 private static final int KEY_O = 79; 935 private static final int KEY_P = 80; 936 private static final int KEY_Q = 81; 937 private static final int KEY_R = 82; 938 private static final int KEY_S = 83; 939 private static final int KEY_T = 84; 940 private static final int KEY_U = 85; 941 private static final int KEY_V = 86; 942 private static final int KEY_W = 87; 943 private static final int KEY_X = 88; 944 private static final int KEY_Y = 89; 945 private static final int KEY_Z = 90; 946 private static final int KEY_LEFT_WINDOW_KEY = 91; 947 private static final int KEY_RIGHT_WINDOW_KEY = 92; 948 private static final int KEY_SELECT_KEY = 93; 949 private static final int KEY_NUMPAD0 = 96; 950 private static final int KEY_NUMPAD1 = 97; 951 private static final int KEY_NUMPAD2 = 98; 952 private static final int KEY_NUMPAD3 = 99; 953 private static final int KEY_NUMPAD4 = 100; 954 private static final int KEY_NUMPAD5 = 101; 955 private static final int KEY_NUMPAD6 = 102; 956 private static final int KEY_NUMPAD7 = 103; 957 private static final int KEY_NUMPAD8 = 104; 958 private static final int KEY_NUMPAD9 = 105; 959 private static final int KEY_MULTIPLY = 106; 960 private static final int KEY_ADD = 107; 961 private static final int KEY_SUBTRACT = 109; 962 private static final int KEY_DECIMAL_POINT_KEY = 110; 963 private static final int KEY_DIVIDE = 111; 964 private static final int KEY_F1 = 112; 965 private static final int KEY_F2 = 113; 966 private static final int KEY_F3 = 114; 967 private static final int KEY_F4 = 115; 968 private static final int KEY_F5 = 116; 969 private static final int KEY_F6 = 117; 970 private static final int KEY_F7 = 118; 971 private static final int KEY_F8 = 119; 972 private static final int KEY_F9 = 120; 973 private static final int KEY_F10 = 121; 974 private static final int KEY_F11 = 122; 975 private static final int KEY_F12 = 123; 976 private static final int KEY_NUM_LOCK = 144; 977 private static final int KEY_SCROLL_LOCK = 145; 978 private static final int KEY_SEMICOLON = 186; 979 private static final int KEY_EQUALS = 187; 980 private static final int KEY_COMMA = 188; 981 private static final int KEY_DASH = 189; 982 private static final int KEY_PERIOD = 190; 983 private static final int KEY_FORWARD_SLASH = 191; 984 private static final int KEY_GRAVE_ACCENT = 192; 985 private static final int KEY_OPEN_BRACKET = 219; 986 private static final int KEY_BACKSLASH = 220; 987 private static final int KEY_CLOSE_BRACKET = 221; 988 private static final int KEY_SINGLE_QUOTE = 222; 989 990 } 991