support for is-gesture (#1873)
* support for is-gesture * updated shims * activate shake button * refactor * refactor shake button
This commit is contained in:
		@@ -13,6 +13,7 @@ input.onPinPressed(TouchPin.P0, () => {
 | 
			
		||||
    
 | 
			
		||||
});
 | 
			
		||||
input.buttonIsPressed(Button.A);
 | 
			
		||||
input.isGesture(Gesture.Shake);
 | 
			
		||||
input.compassHeading();
 | 
			
		||||
input.pinIsPressed(TouchPin.P0);
 | 
			
		||||
input.temperature();
 | 
			
		||||
@@ -27,4 +28,6 @@ input.setAccelerometerRange(AcceleratorRange.OneG);
 | 
			
		||||
 | 
			
		||||
## See also
 | 
			
		||||
 | 
			
		||||
[onButtonPressed](/reference/input/on-button-pressed), [onGesture](/reference/input/on-gesture), [onPinPressed](/reference/input/on-pin-pressed), [buttonIsPressed](/reference/input/button-is-pressed), [compassHeading](/reference/input/compass-heading), [pinIsPressed](/reference/input/pin-is-pressed), [temperature](/reference/input/temperature), [acceleration](/reference/input/acceleration), [lightLevel](/reference/input/light-level), [rotation](/reference/input/rotation), [magneticForce](/reference/input/magnetic-force), [runningTime](/reference/input/running-time), [setAccelerometerRange](/reference/input/set-accelerometer-range), [calibrate-compass](/reference/input/calibrate-compass)
 | 
			
		||||
[onButtonPressed](/reference/input/on-button-pressed), [onGesture](/reference/input/on-gesture), [onPinPressed](/reference/input/on-pin-pressed), [buttonIsPressed](/reference/input/button-is-pressed), 
 | 
			
		||||
[is gesture](/reference/input/is-gesture),
 | 
			
		||||
[compassHeading](/reference/input/compass-heading), [pinIsPressed](/reference/input/pin-is-pressed), [temperature](/reference/input/temperature), [acceleration](/reference/input/acceleration), [lightLevel](/reference/input/light-level), [rotation](/reference/input/rotation), [magneticForce](/reference/input/magnetic-force), [runningTime](/reference/input/running-time), [setAccelerometerRange](/reference/input/set-accelerometer-range), [calibrate-compass](/reference/input/calibrate-compass)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								docs/reference/input/is-gesture.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								docs/reference/input/is-gesture.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
# Is Gesture
 | 
			
		||||
 | 
			
		||||
Tests if a gesture is currently detected.
 | 
			
		||||
 | 
			
		||||
```sig
 | 
			
		||||
input.isGesture(Gesture.Shake)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Parameters
 | 
			
		||||
 | 
			
		||||
* ``gesture`` means the way you hold or move the @boardname@. This can be `shake`, `logo up`, `logo down`, `screen up`, `screen down`, `tilt left`, `tilt right`, `free fall`, `3g`, or `6g`.
 | 
			
		||||
 | 
			
		||||
## Example: random number
 | 
			
		||||
 | 
			
		||||
This program shows a number from `2` to `9` when you shake the @boardname@.
 | 
			
		||||
 | 
			
		||||
```blocks
 | 
			
		||||
forever(function() {
 | 
			
		||||
    if (input.isGesture(Gesture.Shake)) {
 | 
			
		||||
        let x = Math.randomRange(2, 9)
 | 
			
		||||
        basic.showNumber(x)
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## See Also
 | 
			
		||||
 | 
			
		||||
[on gesture](/reference/input/on-gesture)
 | 
			
		||||
@@ -24,3 +24,6 @@ input.onGesture(Gesture.Shake,() => {
 | 
			
		||||
})
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## See Also
 | 
			
		||||
 | 
			
		||||
[is gesture](/reference/input/is-gesture)
 | 
			
		||||
@@ -340,6 +340,8 @@
 | 
			
		||||
  "input.calibrate": "Obsolete, use input.calibrateCompass instead.",
 | 
			
		||||
  "input.calibrateCompass": "Obsolete, compass calibration is automatic.",
 | 
			
		||||
  "input.compassHeading": "Get the current compass heading in degrees.",
 | 
			
		||||
  "input.isGesture": "Tests if a gesture is currently detected.",
 | 
			
		||||
  "input.isGesture|param|gesture": "the type of gesture to detect, eg: Gesture.Shake",
 | 
			
		||||
  "input.lightLevel": "Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright.",
 | 
			
		||||
  "input.magneticForce": "Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator.",
 | 
			
		||||
  "input.magneticForce|param|dimension": "TODO",
 | 
			
		||||
 
 | 
			
		||||
@@ -291,6 +291,7 @@
 | 
			
		||||
  "input.buttonIsPressed|block": "button|%NAME|is pressed",
 | 
			
		||||
  "input.calibrateCompass|block": "calibrate compass",
 | 
			
		||||
  "input.compassHeading|block": "compass heading (°)",
 | 
			
		||||
  "input.isGesture|block": "is %gesture gesture",
 | 
			
		||||
  "input.lightLevel|block": "light level",
 | 
			
		||||
  "input.magneticForce|block": "magnetic force (µT)|%NAME",
 | 
			
		||||
  "input.onButtonPressed|block": "on button|%NAME|pressed",
 | 
			
		||||
 
 | 
			
		||||
@@ -190,6 +190,19 @@ namespace input {
 | 
			
		||||
        registerWithDal(MICROBIT_ID_GESTURE, gi, body);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Tests if a gesture is currently detected.
 | 
			
		||||
     * @param gesture the type of gesture to detect, eg: Gesture.Shake
 | 
			
		||||
    */
 | 
			
		||||
    //% help=input/is-gesture weight=10 blockGap=8
 | 
			
		||||
    //% blockId=deviceisgesture block="is %gesture gesture"
 | 
			
		||||
    //% parts="accelerometer"
 | 
			
		||||
    //% gesture.fieldEditor="gestures" gesture.fieldOptions.columns=4
 | 
			
		||||
    bool isGesture(Gesture gesture) {
 | 
			
		||||
        int gi = (int)gesture;
 | 
			
		||||
        return uBit.accelerometer.getGesture() == gi;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
     /**
 | 
			
		||||
     * Do something when a pin is touched and released again (while also touching the GND pin).
 | 
			
		||||
     * @param name the pin that needs to be pressed, eg: TouchPin.P0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								libs/core/shims.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								libs/core/shims.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -228,6 +228,16 @@ declare namespace input {
 | 
			
		||||
    //% NAME.fieldEditor="gestures" NAME.fieldOptions.columns=4 shim=input::onGesture
 | 
			
		||||
    function onGesture(gesture: Gesture, body: () => void): void;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Tests if a gesture is currently detected.
 | 
			
		||||
     * @param gesture the type of gesture to detect, eg: Gesture.Shake
 | 
			
		||||
     */
 | 
			
		||||
    //% help=input/is-gesture weight=10 blockGap=8
 | 
			
		||||
    //% blockId=deviceisgesture block="is %gesture gesture"
 | 
			
		||||
    //% parts="accelerometer"
 | 
			
		||||
    //% gesture.fieldEditor="gestures" gesture.fieldOptions.columns=4 shim=input::isGesture
 | 
			
		||||
    function isGesture(gesture: Gesture): boolean;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Do something when a pin is touched and released again (while also touching the GND pin).
 | 
			
		||||
     * @param name the pin that needs to be pressed, eg: TouchPin.P0
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,39 @@
 | 
			
		||||
namespace pxsim.input {
 | 
			
		||||
    export function onGesture(gesture: number, handler: RefAction) {
 | 
			
		||||
    function accForGesture(gesture: number) {
 | 
			
		||||
        let b = board().accelerometerState;
 | 
			
		||||
        b.accelerometer.activate();
 | 
			
		||||
 | 
			
		||||
        if (gesture == 11 && !b.useShake) { // SAKE
 | 
			
		||||
        if (gesture == 11 && !b.useShake) { // SHAKE
 | 
			
		||||
            b.useShake = true;
 | 
			
		||||
            runtime.queueDisplayUpdate();
 | 
			
		||||
        }
 | 
			
		||||
        return b;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function onGesture(gesture: number, handler: RefAction) {
 | 
			
		||||
        const b = accForGesture(gesture);
 | 
			
		||||
        pxtcore.registerWithDal(DAL.MICROBIT_ID_GESTURE, gesture, handler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function isGesture(gesture: number): boolean {
 | 
			
		||||
        const b = accForGesture(gesture);
 | 
			
		||||
        return b.accelerometer.getGesture() == gesture;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function acceleration(dimension: number): number {
 | 
			
		||||
        let b = board().accelerometerState;
 | 
			
		||||
        let acc = b.accelerometer;
 | 
			
		||||
        switch (dimension) {
 | 
			
		||||
            case 0: 
 | 
			
		||||
            case 0:
 | 
			
		||||
                acc.activate(AccelerometerFlag.X);
 | 
			
		||||
                return acc.getX();
 | 
			
		||||
            case 1: 
 | 
			
		||||
            case 1:
 | 
			
		||||
                acc.activate(AccelerometerFlag.Y);
 | 
			
		||||
                return acc.getY();
 | 
			
		||||
            case 2:             
 | 
			
		||||
            case 2:
 | 
			
		||||
                acc.activate(AccelerometerFlag.Z);
 | 
			
		||||
                return acc.getZ();
 | 
			
		||||
            default: 
 | 
			
		||||
                acc.activate();            
 | 
			
		||||
            default:
 | 
			
		||||
                acc.activate();
 | 
			
		||||
                return Math.floor(Math.sqrt(acc.instantaneousAccelerationSquared()));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -249,7 +258,10 @@ namespace pxsim {
 | 
			
		||||
        updateGesture() {
 | 
			
		||||
            // Determine what it looks like we're doing based on the latest sample...
 | 
			
		||||
            let g = this.instantaneousPosture();
 | 
			
		||||
            this.setGesture(g);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private setGesture(g: number) {
 | 
			
		||||
            // Perform some low pass filtering to reduce jitter from any detected effects
 | 
			
		||||
            if (g == this.currentGesture) {
 | 
			
		||||
                if (this.sigma < DAL.MICROBIT_ACCELEROMETER_GESTURE_DAMPING)
 | 
			
		||||
@@ -267,6 +279,11 @@ namespace pxsim {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        forceGesture(g: number) {
 | 
			
		||||
            this.sigma = DAL.MICROBIT_ACCELEROMETER_GESTURE_DAMPING + 1;
 | 
			
		||||
            this.setGesture(g);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
          * Reads the X axis value of the latest update from the accelerometer.
 | 
			
		||||
          * @param system The coordinate system to use. By default, a simple cartesian system is provided.
 | 
			
		||||
@@ -378,6 +395,10 @@ namespace pxsim {
 | 
			
		||||
            return this.roll;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        getGesture(): number {
 | 
			
		||||
            return this.lastGesture;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Recalculate roll and pitch values for the current sample.
 | 
			
		||||
         * We only do this at most once per sample, as the necessary trigonemteric functions are rather
 | 
			
		||||
@@ -401,5 +422,9 @@ namespace pxsim {
 | 
			
		||||
        constructor(runtime: Runtime) {
 | 
			
		||||
            this.accelerometer = new Accelerometer(runtime);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        shake() {
 | 
			
		||||
            this.accelerometer.forceGesture(DAL.MICROBIT_ACCELEROMETER_EVT_SHAKE); // SHAKE == 11
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -433,10 +433,10 @@ path.sim-board {
 | 
			
		||||
                this.shakeButton.addEventListener(pointerEvents.up, ev => {
 | 
			
		||||
                    let state = this.board;
 | 
			
		||||
                    svg.fill(this.shakeButton, this.props.theme.virtualButtonUp);
 | 
			
		||||
                    this.board.bus.queue(DAL.MICROBIT_ID_GESTURE, 11); // GESTURE_SHAKE
 | 
			
		||||
                    this.board.accelerometerState.shake();
 | 
			
		||||
                })
 | 
			
		||||
                accessibility.enableKeyboardInteraction(this.shakeButton, undefined, () => {
 | 
			
		||||
                    this.board.bus.queue(DAL.MICROBIT_ID_GESTURE, 11);
 | 
			
		||||
                    this.board.accelerometerState.shake();
 | 
			
		||||
                });
 | 
			
		||||
                accessibility.setAria(this.shakeButton, "button", "Shake the board");
 | 
			
		||||
                this.shakeText = svg.child(this.g, "text", { x: 400, y: 110, class: "sim-text" }) as SVGTextElement;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user