浏览代码

Add support for event.key values and handle blur events to DeviceInputSystem (#9816)

* Added event info to onInputChanged info for keyboard input changes.  Also, changed HTMLElement for keyboard to input element for engine (canvas)

* Added handling for when a window loses focus (keyboard only)

* Added backup value for IE users

* Adding tabIndex to canvas element, just in case tabIndex is not set (only when tabIndex == -1)
Dave Solares 4 年之前
父节点
当前提交
8f7433fa03
共有 2 个文件被更改,包括 54 次插入27 次删除
  1. 39 20
      src/DeviceInput/deviceInputSystem.ts
  2. 15 7
      src/Inputs/scene.inputManager.ts

+ 39 - 20
src/DeviceInput/deviceInputSystem.ts

@@ -48,7 +48,7 @@ export class DeviceInputSystem implements IDisposable {
     /**
      * Callback to be triggered when event driven input is updated
      */
-    public onInputChanged: (deviceType: DeviceType, deviceSlot: number, inputIndex: number, previousState: Nullable<number>, currentState: Nullable<number>) => void;
+    public onInputChanged: (deviceType: DeviceType, deviceSlot: number, inputIndex: number, previousState: Nullable<number>, currentState: Nullable<number>, eventData?: any) => void;
 
     // Private Members
     private _inputs: Array<Array<Array<number>>> = [];
@@ -59,6 +59,7 @@ export class DeviceInputSystem implements IDisposable {
 
     private _keyboardDownEvent = (evt: any) => { };
     private _keyboardUpEvent = (evt: any) => { };
+    private _keyboardBlurEvent = (evt: any) => { };
 
     private _pointerMoveEvent = (evt: any) => { };
     private _pointerDownEvent = (evt: any) => { };
@@ -82,6 +83,8 @@ export class DeviceInputSystem implements IDisposable {
 
         if (inputElement) {
             this._elementToAttachTo = inputElement;
+            // Set tab index for the inputElement to the engine's canvasTabIndex, if and only if the element's tab index is -1
+            this._elementToAttachTo.tabIndex = (this._elementToAttachTo.tabIndex !== -1) ? this._elementToAttachTo.tabIndex : engine.canvasTabIndex;
             this._handleKeyActions();
             this._handlePointerActions();
             this._handleGamepadActions();
@@ -158,10 +161,13 @@ export class DeviceInputSystem implements IDisposable {
      * Dispose of all the eventlisteners
      */
     public dispose() {
+        // Blur Events
+        this._elementToAttachTo.removeEventListener("blur", this._keyboardBlurEvent);
+
         // Keyboard Events
         if (this._keyboardActive) {
-            window.removeEventListener("keydown", this._keyboardDownEvent);
-            window.removeEventListener("keyup", this._keyboardUpEvent);
+            this._elementToAttachTo.removeEventListener("keydown", this._keyboardDownEvent);
+            this._elementToAttachTo.removeEventListener("keyup", this._keyboardUpEvent);
         }
 
         // Pointer Events
@@ -276,7 +282,7 @@ export class DeviceInputSystem implements IDisposable {
             if (kbKey) {
                 kbKey[evt.keyCode] = 1;
                 if (this.onInputChanged) {
-                    this.onInputChanged(DeviceType.Keyboard, 0, evt.keyCode, 0, kbKey[evt.keyCode]);
+                    this.onInputChanged(DeviceType.Keyboard, 0, evt.keyCode, 0, kbKey[evt.keyCode], evt);
                 }
             }
         });
@@ -291,13 +297,26 @@ export class DeviceInputSystem implements IDisposable {
             if (kbKey) {
                 kbKey[evt.keyCode] = 0;
                 if (this.onInputChanged) {
-                    this.onInputChanged(DeviceType.Keyboard, 0, evt.keyCode, 1, kbKey[evt.keyCode]);
+                    this.onInputChanged(DeviceType.Keyboard, 0, evt.keyCode, 1, kbKey[evt.keyCode], evt);
+                }
+            }
+        });
+
+        this._keyboardBlurEvent = ((evt) => {
+            if (this._keyboardActive) {
+                const kbKey = this._inputs[DeviceType.Keyboard][0];
+
+                for (let i = 0; i < kbKey.length; i++) {
+                    if (kbKey[i] !== 0) {
+                        kbKey[i] = 0;
+                    }
                 }
             }
         });
 
-        window.addEventListener("keydown", this._keyboardDownEvent);
-        window.addEventListener("keyup", this._keyboardUpEvent);
+        this._elementToAttachTo.addEventListener("keydown", this._keyboardDownEvent);
+        this._elementToAttachTo.addEventListener("keyup", this._keyboardUpEvent);
+        this._elementToAttachTo.addEventListener("blur", this._keyboardBlurEvent);
     }
 
     /**
@@ -331,16 +350,16 @@ export class DeviceInputSystem implements IDisposable {
 
                 if (this.onInputChanged) {
                     if (previousHorizontal !== evt.clientX) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Horizontal, previousHorizontal, pointer[PointerInput.Horizontal]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Horizontal, previousHorizontal, pointer[PointerInput.Horizontal], evt);
                     }
                     if (previousVertical !== evt.clientY) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Vertical, previousVertical, pointer[PointerInput.Vertical]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Vertical, previousVertical, pointer[PointerInput.Vertical], evt);
                     }
                     if (pointer[PointerInput.DeltaHorizontal] !== 0) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.DeltaHorizontal, previousDeltaHorizontal, pointer[PointerInput.DeltaHorizontal]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.DeltaHorizontal, previousDeltaHorizontal, pointer[PointerInput.DeltaHorizontal], evt);
                     }
                     if (pointer[PointerInput.DeltaVertical] !== 0) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.DeltaVertical, previousDeltaVertical, pointer[PointerInput.DeltaVertical]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.DeltaVertical, previousDeltaVertical, pointer[PointerInput.DeltaVertical], evt);
                     }
                 }
             }
@@ -370,12 +389,12 @@ export class DeviceInputSystem implements IDisposable {
 
                 if (this.onInputChanged) {
                     if (previousHorizontal !== evt.clientX) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Horizontal, previousHorizontal, pointer[PointerInput.Horizontal]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Horizontal, previousHorizontal, pointer[PointerInput.Horizontal], evt);
                     }
                     if (previousVertical !== evt.clientY) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Vertical, previousVertical, pointer[PointerInput.Vertical]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Vertical, previousVertical, pointer[PointerInput.Vertical], evt);
                     }
-                    this.onInputChanged(deviceType, deviceSlot, evt.button + 2, previousButton, pointer[evt.button + 2]);
+                    this.onInputChanged(deviceType, deviceSlot, evt.button + 2, previousButton, pointer[evt.button + 2], evt);
                 }
             }
         });
@@ -396,12 +415,12 @@ export class DeviceInputSystem implements IDisposable {
 
                 if (this.onInputChanged) {
                     if (previousHorizontal !== evt.clientX) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Horizontal, previousHorizontal, pointer[PointerInput.Horizontal]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Horizontal, previousHorizontal, pointer[PointerInput.Horizontal], evt);
                     }
                     if (previousVertical !== evt.clientY) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Vertical, previousVertical, pointer[PointerInput.Vertical]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.Vertical, previousVertical, pointer[PointerInput.Vertical], evt);
                     }
-                    this.onInputChanged(deviceType, deviceSlot, evt.button + 2, previousButton, pointer[evt.button + 2]);
+                    this.onInputChanged(deviceType, deviceSlot, evt.button + 2, previousButton, pointer[evt.button + 2], evt);
                 }
             }
             // We don't want to unregister the mouse because we may miss input data when a mouse is moving after a click
@@ -465,13 +484,13 @@ export class DeviceInputSystem implements IDisposable {
 
                 if (this.onInputChanged) {
                     if (evt.deltaX !== 0) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.MouseWheelX, previousWheelScrollX, pointer[PointerInput.MouseWheelX]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.MouseWheelX, previousWheelScrollX, pointer[PointerInput.MouseWheelX], evt);
                     }
                     if (evt.deltaY !== 0) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.MouseWheelY, previousWheelScrollY, pointer[PointerInput.MouseWheelY]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.MouseWheelY, previousWheelScrollY, pointer[PointerInput.MouseWheelY], evt);
                     }
                     if (evt.deltaZ !== 0) {
-                        this.onInputChanged(deviceType, deviceSlot, PointerInput.MouseWheelZ, previousWheelScrollZ, pointer[PointerInput.MouseWheelZ]);
+                        this.onInputChanged(deviceType, deviceSlot, PointerInput.MouseWheelZ, previousWheelScrollZ, pointer[PointerInput.MouseWheelZ], evt);
                     }
                 }
             }

+ 15 - 7
src/Inputs/scene.inputManager.ts

@@ -801,7 +801,7 @@ export class InputManager {
             }
         };
 
-        this._deviceInputSystem.onInputChanged = (deviceType, deviceSlot, inputIndex, previousState, currentState) => {
+        this._deviceInputSystem.onInputChanged = (deviceType, deviceSlot, inputIndex, previousState, currentState, eventData) => {
             let isKeyboardActive = this._deviceInputSystem.isDeviceAvailable(DeviceType.Keyboard);
 
             const altKey = (isKeyboardActive && this._deviceInputSystem.pollInput(DeviceType.Keyboard, 0, Constants.INPUT_ALT_KEY) === 1);
@@ -826,12 +826,15 @@ export class InputManager {
                 evt.key = String.fromCharCode(inputIndex);
                 evt.keyCode = inputIndex;
 
+                // If we have the actual event data, use that.  Otherwise, default to derived data.
+                let currentEvent = eventData || evt;
+
                 if (currentState === 1) {
-                    this._onKeyDown((evt as IKeyboardEvent));
+                    this._onKeyDown((currentEvent as IKeyboardEvent));
                 }
 
                 if (currentState === 0) {
-                    this._onKeyUp((evt as IKeyboardEvent));
+                    this._onKeyUp((currentEvent as IKeyboardEvent));
                 }
             }
 
@@ -860,21 +863,25 @@ export class InputManager {
                     evt.type = "pointerdown";
                     evt.button = (inputIndex - 2);
 
-                    this._onPointerDown((evt as IPointerEvent));
+                    let currentEvent = eventData || evt;
+
+                    this._onPointerDown((currentEvent as IPointerEvent));
                 }
 
                 if (attachUp && inputIndex >= PointerInput.LeftClick && inputIndex <= PointerInput.RightClick && currentState === 0) {   // Pointer Up
                     evt.type = "pointerup";
                     evt.button = (inputIndex - 2);
+                    let currentEvent = eventData || evt;
 
-                    this._onPointerUp((evt as IPointerEvent));
+                    this._onPointerUp((currentEvent as IPointerEvent));
                 }
 
                 if (attachMove) {
                     if (inputIndex === PointerInput.Horizontal || inputIndex === PointerInput.Vertical || inputIndex === PointerInput.DeltaHorizontal || inputIndex === PointerInput.DeltaVertical) {
                         evt.type = "pointermove";
+                        let currentEvent = eventData || evt;
 
-                        this._onPointerMove((evt as IPointerEvent));
+                        this._onPointerMove((currentEvent as IPointerEvent));
                     }
                     else if (inputIndex === PointerInput.MouseWheelX || inputIndex === PointerInput.MouseWheelY || inputIndex === PointerInput.MouseWheelZ) {
                         /*
@@ -894,7 +901,8 @@ export class InputManager {
 
                         // If we have a delta, use it.
                         if (deltaX !== 0 || deltaY !== 0 || deltaZ !== 0) {
-                            this._onPointerMove((evt as IWheelEvent));
+                            let currentEvent = eventData || evt;
+                            this._onPointerMove((currentEvent as IWheelEvent));
                         }
                     }
                 }