// // ControllerScriptingInterface.h // interface/src/scripting // // Created by Brad Hefta-Gaub on 12/17/13. // Copyright 2013 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #ifndef hifi_ControllerScriptingInterface_h #define hifi_ControllerScriptingInterface_h #include #include #include #include #include #include #include #include class ScriptEngine; /**jsdoc * The Controller API provides facilities to interact with computer and controller hardware. * *
Functions:
* *

Properties

*
    *
  • {@link Controller.getActions|getActions}
  • *
  • {@link Controller.getHardware|getHardware}
  • *
  • {@link Controller.getStandard|getStandard}
  • *
* *

Mappings

*
    *
  • {@link Controller.disableMapping|disableMapping}
  • *
  • {@link Controller.enableMapping|enableMapping}
  • *
  • {@link Controller.loadMapping|loadMapping}
  • *
  • {@link Controller.newMapping|newMapping}
  • *
  • {@link Controller.parseMapping|parseMapping}
  • *
* *

Input, Hardware, and Action Reflection

*
    *
  • {@link Controller.findAction|findAction}
  • *
  • {@link Controller.findDevice|findDevice}
  • *
  • {@link Controller.getActionNames|getActionNames}
  • *
  • {@link Controller.getAllActions|getAllActions}
  • *
  • {@link Controller.getAvailableInputs|getAvailableInputs}
  • *
  • {@link Controller.getDeviceName|getDeviceName}
  • *
  • {@link Controller.getDeviceNames|getDeviceNames}
  • *
* *

Input, Hardware, and Action Events

*
    *
  • {@link Controller.actionEvent|actionEvent}
  • *
  • {@link Controller.hardwareChanged|hardwareChanged}
  • *
  • {@link Controller.inputEvent|inputEvent}
  • *
* *

Mouse, Keyboard, and Touch Events

*
    *
  • {@link Controller.keyPressEvent|keyPressEvent}
  • *
  • {@link Controller.keyReleaseEvent|keyReleaseEvent}
  • *
  • {@link Controller.mouseDoublePressEvent|mouseDoublePressEvent}
  • *
  • {@link Controller.mouseMoveEvent|mouseMoveEvent}
  • *
  • {@link Controller.mousePressEvent|mousePressEvent}
  • *
  • {@link Controller.mouseReleaseEvent|mouseReleaseEvent}
  • *
  • {@link Controller.touchBeginEvent|touchBeginEvent}
  • *
  • {@link Controller.touchEndEvent|touchEndEvent}
  • *
  • {@link Controller.touchUpdateEvent|touchUpdateEvent}
  • *
  • {@link Controller.wheelEvent|wheelEvent}
  • *
* *

Control Capturing

*
    *
  • {@link Controller.captureMouseEvents|captureMouseEvents}
  • *
  • {@link Controller.captureTouchEvents|captureTouchEvents}
  • *
  • {@link Controller.captureWheelEvents|captureWheelEvents}
  • *
  • {@link Controller.releaseMouseEvents|releaseMouseEvents}
  • *
  • {@link Controller.releaseTouchEvents|releaseTouchEvents}
  • *
  • {@link Controller.releaseWheelEvents|releaseWheelEvents}
  • *
* *

Action Capturing

*
    *
  • {@link Controller.captureActionEvents|captureActionEvents}
  • *
  • {@link Controller.captureEntityClickEvents|captureEntityClickEvents}
  • *
  • {@link Controller.captureJoystick|captureJoystick}
  • *
  • {@link Controller.captureKeyEvents|captureKeyEvents}
  • *
  • {@link Controller.releaseActionEvents|releaseActionEvents}
  • *
  • {@link Controller.releaseEntityClickEvents|releaseEntityClickEvents}
  • *
  • {@link Controller.releaseJoystick|releaseJoystick}
  • *
  • {@link Controller.releaseKeyEvents|releaseKeyEvents}
  • *
* *

Controller and Action Values

*
    *
  • {@link Controller.getValue|getValue}
  • *
  • {@link Controller.getAxisValue|getAxisValue}
  • *
  • {@link Controller.getPoseValue|getgetPoseValue}
  • *
  • {@link Controller.getButtonValue|getButtonValue} for a particular device
  • *
  • {@link Controller.getAxisValue(0)|getAxisValue} for a particular device
  • *
  • {@link Controller.getPoseValue(0)|getPoseValue} for a particular device
  • *
  • {@link Controller.getActionValue|getActionValue}
  • *
* *

Haptics

*
    *
  • {@link Controller.triggerHapticPulse|triggerHapticPulse}
  • *
  • {@link Controller.triggerHapticPulseOnDevice|triggerHapticPulseOnDevice}
  • *
  • {@link Controller.triggerShortHapticPulse|triggerShortHapticPulse}
  • *
  • {@link Controller.triggerShortHapticPulseOnDevice|triggerShortHapticPulseOnDevice}
  • *
* *

Display Information

*
    *
  • {@link Controller.getViewportDimensions|getViewportDimensions}
  • *
  • {@link Controller.getRecommendedHUDRect|getRecommendedHUDRect}
  • *
* *

Virtual Game Pad

*
    *
  • {@link Controller.setVPadEnabled|setVPadEnabled}
  • *
  • {@link Controller.setVPadHidden|setVPadHidden}
  • *
  • {@link Controller.setVPadExtraBottomMargin|setVPadExtraBottomMargin}
  • *
* *

Input Recordings

*
    *
  • {@link Controller.startInputRecording|startInputRecording}
  • *
  • {@link Controller.stopInputRecording|stopInputRecording}
  • *
  • {@link Controller.saveInputRecording|saveInputRecording}
  • *
  • {@link Controller.getInputRecorderSaveDirectory|getInputRecorderSaveDirectory}
  • *
  • {@link Controller.loadInputRecording|loadInputRecording}
  • *
  • {@link Controller.startInputPlayback|startInputPlayback}
  • *
  • {@link Controller.stopInputPlayback|stopInputPlayback}
  • *
* * @namespace Controller * * @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end * points in a {@link RouteObject} mapping. A synonym for Controller.Hardware.Actions. * Read-only.
* Default mappings are provided from the Controller.Hardware.Keyboard and Controller.Standard to * actions in * * keyboardMouse.json and * * standard.json, respectively. * * @property {Controller.Hardware} Hardware - Standard and hardware-specific controller and computer outputs, plus predefined * actions on Interface and the user's avatar. The outputs can be mapped to Actions or functions in a * {@link RouteObject} mapping. Additionally, hardware-specific controller outputs can be mapped to Standard * controller outputs. Read-only. * * @property {Controller.Standard} Standard - Standard controller outputs that can be mapped to Actions or * functions in a {@link RouteObject} mapping. Read-only.
* Each hardware device has a mapping from its outputs to Controller.Standard items, specified in a JSON file. * For example, * leapmotion.json and * vive.json. */ /// handles scripting of input controller commands from JS class ControllerScriptingInterface : public controller::ScriptingInterface { Q_OBJECT public: virtual ~ControllerScriptingInterface() {} void emitKeyPressEvent(QKeyEvent* event); void emitKeyReleaseEvent(QKeyEvent* event); void emitMouseMoveEvent(QMouseEvent* event); void emitMousePressEvent(QMouseEvent* event); void emitMouseDoublePressEvent(QMouseEvent* event); void emitMouseReleaseEvent(QMouseEvent* event); void emitTouchBeginEvent(const TouchEvent& event); void emitTouchEndEvent(const TouchEvent& event); void emitTouchUpdateEvent(const TouchEvent& event); void emitWheelEvent(QWheelEvent* event); bool isKeyCaptured(QKeyEvent* event) const; bool isKeyCaptured(const KeyEvent& event) const; bool isJoystickCaptured(int joystickIndex) const; bool areEntityClicksCaptured() const; public slots: /**jsdoc * Disable default Interface actions for a particular key event. * @function Controller.captureKeyEvents * @param {KeyEvent} event - Details of the key event to be captured. The key property must be specified. The * text property is ignored. The other properties default to false. * @example Disable left and right strafing. * var STRAFE_LEFT = { "key": 16777234, isShifted: true }; * var STRAFE_RIGHT = { "key": 16777236, isShifted: true }; * * Controller.captureKeyEvents(STRAFE_LEFT); * Controller.captureKeyEvents(STRAFE_RIGHT); * * Script.scriptEnding.connect(function () { * Controller.releaseKeyEvents(STRAFE_LEFT); * Controller.releaseKeyEvents(STRAFE_RIGHT); * }); */ virtual void captureKeyEvents(const KeyEvent& event); /**jsdoc * Re-enable default Interface actions for a particular key event that has been disabled using * {@link Controller.captureKeyEvents|captureKeyEvents}. * @function Controller.releaseKeyEvents * @param {KeyEvent} event - Details of the key event to release from capture. The key property must be * specified. The text property is ignored. The other properties default to false. */ virtual void releaseKeyEvents(const KeyEvent& event); /**jsdoc * Disable default Interface actions for a joystick. * @function Controller.captureJoystick * @param {number} joystickID - The integer ID of the joystick. * @deprecated This function no longer has any effect. */ virtual void captureJoystick(int joystickIndex); /**jsdoc * Re-enable default Interface actions for a joystick that has been disabled using * {@link Controller.captureJoystick|captureJoystick}. * @function Controller.releaseJoystick * @param {number} joystickID - The integer ID of the joystick. * @deprecated This function no longer has any effect. */ virtual void releaseJoystick(int joystickIndex); /**jsdoc * Disable {@link Entities.mousePressOnEntity} and {@link Entities.mouseDoublePressOnEntity} events on entities. * @function Controller.captureEntityClickEvents * @example Disable entity click events for a short period. * Entities.mousePressOnEntity.connect(function (entityID, event) { * print("Clicked on entity: " + entityID); * }); * * Script.setTimeout(function () { * Controller.captureEntityClickEvents(); * }, 5000); * * Script.setTimeout(function () { * Controller.releaseEntityClickEvents(); * }, 10000); */ virtual void captureEntityClickEvents(); /**jsdoc * Re-enable {@link Entities.mousePressOnEntity} and {@link Entities.mouseDoublePressOnEntity} events on entities that were * disabled using {@link Controller.captureEntityClickEvents|captureEntityClickEvents}. * @function Controller.releaseEntityClickEvents */ virtual void releaseEntityClickEvents(); /**jsdoc * Get the dimensions of the Interface window's interior if in desktop mode or the HUD surface if in HMD mode. * @function Controller.getViewportDimensions * @returns {Vec2} The dimensions of the Interface window interior if in desktop mode or HUD surface if in HMD mode. */ virtual glm::vec2 getViewportDimensions() const; /**jsdoc * Get the recommended area to position UI on the HUD surface if in HMD mode or Interface's window interior if in desktop * mode. * @function Controller.getRecommendedHUDRect * @returns {Rect} The recommended area in which to position UI. */ virtual QVariant getRecommendedHUDRect() const; /**jsdoc * Enables or disables the virtual game pad that is displayed on certain devices (e.g., Android). * @function Controller.setVPadEnabled * @param {boolean} enable - If true then the virtual game pad doesn't work, otherwise it does work provided * that it is not hidden by {@link Controller.setVPadHidden|setVPadHidden}. * */ virtual void setVPadEnabled(bool enable); /**jsdoc * Shows or hides the virtual game pad that is displayed on certain devices (e.g., Android). * @function Controller.setVPadHidden * @param {boolean} hidden - If true then the virtual game pad is hidden, otherwise it is shown. */ virtual void setVPadHidden(bool hidden); // Call it when a window should hide it /**jsdoc * Sets the amount of extra margin between the virtual game pad that is displayed on certain devices (e.g., Android) and * the bottom of the display. * @function Controller.setVPadExtraBottomMargin * @param {number} margin - Integer number of pixels in the extra margin. */ virtual void setVPadExtraBottomMargin(int margin); signals: /**jsdoc * Triggered when a keyboard key is pressed. * @function Controller.keyPressEvent * @param {KeyEvent} event - Details of the key press. * @returns {Signal} * @example Report the KeyEvent details for each key press. * Controller.keyPressEvent.connect(function (event) { * print(JSON.stringify(event)); * }); */ void keyPressEvent(const KeyEvent& event); /**jsdoc * Triggered when a keyboard key is released from being pressed. * @function Controller.keyReleaseEvent * @param {KeyEvent} event - Details of the key release. * @returns {Signal} */ void keyReleaseEvent(const KeyEvent& event); /**jsdoc * Triggered when the mouse moves. * @function Controller.mouseMoveEvent * @param {MouseEvent} event - Details of the mouse movement. * @returns {Signal} * @example Report the MouseEvent details for each mouse move. * Controller.mouseMoveEvent.connect(function (event) { * print(JSON.stringify(event)); * }); */ void mouseMoveEvent(const MouseEvent& event); /**jsdoc * Triggered when a mouse button is pressed. * @function Controller.mousePressEvent * @param {MouseEvent} event - Details of the button press. * @returns {Signal} */ void mousePressEvent(const MouseEvent& event); /**jsdoc * Triggered when a mouse button is double-pressed. * @function Controller.mouseDoublePressEvent * @param {MouseEvent} event - Details of the button double-press. * @returns {Signal} */ void mouseDoublePressEvent(const MouseEvent& event); /**jsdoc * Triggered when a mouse button is released from being pressed. * @function Controller.mouseReleaseEvent * @param {MouseEvent} event - Details of the button release. * @returns {Signal} */ void mouseReleaseEvent(const MouseEvent& event); /**jsdoc * Triggered when a touch event starts in the Interface window on a touch-enabled display or device. * @function Controller.touchBeginEvent * @param {TouchEvent} event - Details of the touch begin. * @returns {Signal} * @example Report the TouchEvent details when a touch event starts. * Controller.touchBeginEvent.connect(function (event) { * print(JSON.stringify(event)); * }); */ void touchBeginEvent(const TouchEvent& event); /**jsdoc * Triggered when a touch event ends in the Interface window on a touch-enabled display or device. * @function Controller.touchEndEvent * @param {TouchEvent} event - Details of the touch end. * @returns {Signal} */ void touchEndEvent(const TouchEvent& event); /**jsdoc * Triggered when a touch event update occurs in the Interface window on a touch-enabled display or device. * @function Controller.touchUpdateEvent * @param {TouchEvent} event - Details of the touch update. * @returns {Signal} */ void touchUpdateEvent(const TouchEvent& event); /**jsdoc * Triggered when the mouse wheel is rotated. * @function Controller.wheelEvent * @param {WheelEvent} event - Details of the wheel movement. * @returns {Signal} * @example Report the WheelEvent details for each wheel rotation. * Controller.wheelEvent.connect(function (event) { * print(JSON.stringify(event)); * }); */ void wheelEvent(const WheelEvent& event); private: QMultiMap _capturedKeys; QSet _capturedJoysticks; bool _captureEntityClicks; using InputKey = controller::InputController::Key; }; const int NUMBER_OF_SPATIALCONTROLS_PER_PALM = 2; // the hand and the tip const int NUMBER_OF_JOYSTICKS_PER_PALM = 1; const int NUMBER_OF_TRIGGERS_PER_PALM = 1; const int NUMBER_OF_BUTTONS_PER_PALM = 6; const int PALM_SPATIALCONTROL = 0; const int TIP_SPATIALCONTROL = 1; #endif // hifi_ControllerScriptingInterface_h