Skip to content

Commit fa18a9b

Browse files
Touch support for pins 0, 1, 2 (#33)
1 parent 1e0fe19 commit fa18a9b

File tree

2 files changed

+87
-31
lines changed

2 files changed

+87
-31
lines changed

src/board/ui.ts

Lines changed: 86 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
import svgText from "../microbit-drawing.svg";
44
import { AudioUI } from "./audio";
5-
import { MICROBIT_HAL_PIN_FACE } from "./constants";
5+
import {
6+
MICROBIT_HAL_PIN_FACE,
7+
MICROBIT_HAL_PIN_P0,
8+
MICROBIT_HAL_PIN_P1,
9+
MICROBIT_HAL_PIN_P2,
10+
} from "./constants";
611
import {
712
convertAccelerometerStringToNumber,
813
convertSoundEventStringToNumber,
@@ -74,8 +79,12 @@ export class BoardUI {
7479
this.pins = Array(33);
7580
this.pins[MICROBIT_HAL_PIN_FACE] = new PinUI(
7681
this.svg.querySelector("#Logo")!,
77-
"pin_logo"
82+
"pinLogo",
83+
onSensorChange
7884
);
85+
this.pins[MICROBIT_HAL_PIN_P0] = new PinUI(null, "pin0", onSensorChange);
86+
this.pins[MICROBIT_HAL_PIN_P1] = new PinUI(null, "pin1", onSensorChange);
87+
this.pins[MICROBIT_HAL_PIN_P2] = new PinUI(null, "pin2", onSensorChange);
7988
this.audio = new AudioUI();
8089
this.temperature = new RangeSensor("temperature", -5, 50, 21, "°C");
8190
this.accelerometer = new AccelerometerUI(onSensorChange);
@@ -90,6 +99,10 @@ export class BoardUI {
9099
this.microphone.soundLevel,
91100
this.buttons[0].button,
92101
this.buttons[1].button,
102+
this.pins[MICROBIT_HAL_PIN_FACE].pin,
103+
this.pins[MICROBIT_HAL_PIN_P0].pin,
104+
this.pins[MICROBIT_HAL_PIN_P1].pin,
105+
this.pins[MICROBIT_HAL_PIN_P2].pin,
93106
...this.accelerometer.sensors,
94107
];
95108
this.sensorsById = new Map();
@@ -288,6 +301,7 @@ export class ButtonUI {
288301
public button: RangeSensor;
289302
private _presses: number = 0;
290303
private _mouseDown: boolean = false;
304+
private _internalChange: boolean = false;
291305
private keyListener: (e: KeyboardEvent) => void;
292306
private mouseDownListener: (e: MouseEvent) => void;
293307
private mouseUpListener: (e: MouseEvent) => void;
@@ -301,7 +315,10 @@ export class ButtonUI {
301315
this._presses = 0;
302316
this.button = new RangeSensor(label, 0, 1, 0, undefined);
303317
this.button.onchange = (_, curr: number): void => {
304-
this.onSensorChange();
318+
if (this._internalChange == true) {
319+
this.onSensorChange();
320+
this._internalChange = false;
321+
}
305322
if (curr) {
306323
this._presses++;
307324
}
@@ -319,8 +336,10 @@ export class ButtonUI {
319336
case " ":
320337
e.preventDefault();
321338
if (e.type === "keydown") {
339+
this._internalChange = true;
322340
this.press();
323341
} else {
342+
this._internalChange = true;
324343
this.release();
325344
}
326345
}
@@ -329,15 +348,21 @@ export class ButtonUI {
329348
this.mouseDownListener = (e) => {
330349
e.preventDefault();
331350
this._mouseDown = true;
351+
this._internalChange = true;
332352
this.press();
333353
};
334354
this.mouseUpListener = (e) => {
335355
e.preventDefault();
336-
this._mouseDown = false;
337-
this.release();
356+
if (this._mouseDown) {
357+
this._mouseDown = false;
358+
this._internalChange = true;
359+
this.release();
360+
}
338361
};
339362
this.mouseLeaveListener = (e) => {
340363
if (this._mouseDown) {
364+
this._mouseDown = false;
365+
this._internalChange = true;
341366
this.release();
342367
}
343368
};
@@ -495,73 +520,104 @@ export class MicrophoneUI {
495520
}
496521

497522
export class PinUI {
498-
private _isTouched: boolean;
523+
public pin: RangeSensor;
524+
private _mouseDown: boolean = false;
525+
private _internalChange: boolean = false;
499526
private keyListener: (e: KeyboardEvent) => void;
500527
private mouseDownListener: (e: MouseEvent) => void;
501528
private mouseUpListener: (e: MouseEvent) => void;
502529
private mouseLeaveListener: (e: MouseEvent) => void;
503530

504-
constructor(private element: SVGElement, private label: string) {
505-
this.label = label;
506-
this._isTouched = false;
531+
constructor(
532+
private element: SVGElement | null,
533+
label: string,
534+
private onSensorChange: () => void
535+
) {
536+
this.pin = new RangeSensor(label, 0, 1, 0, undefined);
537+
this.pin.onchange = (): void => {
538+
if (this._internalChange == true) {
539+
this.onSensorChange();
540+
this._internalChange = false;
541+
}
542+
this.render();
543+
};
507544

508-
this.element = element;
509-
this.element.setAttribute("role", "button");
510-
this.element.setAttribute("tabindex", "0");
511-
this.element.ariaLabel = label;
512-
this.element.style.cursor = "pointer";
545+
if (this.element) {
546+
this.element.setAttribute("role", "button");
547+
this.element.setAttribute("tabindex", "0");
548+
this.element.ariaLabel = label;
549+
this.element.style.cursor = "pointer";
550+
}
513551

514552
this.keyListener = (e) => {
515553
switch (e.key) {
516554
case "Enter":
517555
case " ":
518556
e.preventDefault();
519557
if (e.type === "keydown") {
558+
this._internalChange = true;
520559
this.press();
521560
} else {
561+
this._internalChange = true;
522562
this.release();
523563
}
524564
}
525565
};
526566

527567
this.mouseDownListener = (e) => {
528568
e.preventDefault();
569+
this._mouseDown = true;
570+
this._internalChange = true;
529571
this.press();
530572
};
531573
this.mouseUpListener = (e) => {
532574
e.preventDefault();
533-
this.release();
575+
if (this._mouseDown) {
576+
this._mouseDown = false;
577+
this._internalChange = true;
578+
this.release();
579+
}
534580
};
535581
this.mouseLeaveListener = (e) => {
536-
this.release();
582+
if (this._mouseDown) {
583+
this._mouseDown = false;
584+
this._internalChange = true;
585+
this.release();
586+
}
537587
};
538588

539-
this.element.addEventListener("mousedown", this.mouseDownListener);
540-
this.element.addEventListener("mouseup", this.mouseUpListener);
541-
this.element.addEventListener("keydown", this.keyListener);
542-
this.element.addEventListener("keyup", this.keyListener);
543-
this.element.addEventListener("mouseleave", this.mouseLeaveListener);
589+
if (this.element) {
590+
this.element.addEventListener("mousedown", this.mouseDownListener);
591+
this.element.addEventListener("mouseup", this.mouseUpListener);
592+
this.element.addEventListener("keydown", this.keyListener);
593+
this.element.addEventListener("keyup", this.keyListener);
594+
this.element.addEventListener("mouseleave", this.mouseLeaveListener);
595+
}
544596
}
545597

546598
press() {
547-
this._isTouched = true;
548-
this.render();
599+
this.pin.setValue(
600+
this.pin.value === this.pin.min ? this.pin.max : this.pin.min
601+
);
549602
}
550603

551604
release() {
552-
this._isTouched = false;
553-
this.render();
605+
this.pin.setValue(
606+
this.pin.value === this.pin.max ? this.pin.min : this.pin.max
607+
);
554608
}
555609

556610
isTouched() {
557-
return this._isTouched;
611+
return !!this.pin.value;
558612
}
559613

560614
render() {
561-
const fill = this._isTouched ? "red" : "url(#an)";
562-
this.element.querySelectorAll("path").forEach((p) => {
563-
p.style.fill = fill;
564-
});
615+
if (this.element) {
616+
const fill = !!this.pin.value ? "red" : "url(#an)";
617+
this.element.querySelectorAll("path").forEach((p) => {
618+
p.style.fill = fill;
619+
});
620+
}
565621
}
566622

567623
initialize() {}

src/microbithal_js.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ void microbit_hal_pin_write_analog_u10(int pin, int value) {
144144
}
145145

146146
int microbit_hal_pin_is_touched(int pin) {
147-
if (pin == MICROBIT_HAL_PIN_FACE) {
147+
if (pin == MICROBIT_HAL_PIN_FACE || pin == MICROBIT_HAL_PIN_P0 || pin == MICROBIT_HAL_PIN_P1 || pin == MICROBIT_HAL_PIN_P2) {
148148
return mp_js_hal_pin_is_touched(pin);
149149
}
150150
/*

0 commit comments

Comments
 (0)