Support for remote control buttons (#300)
* refactor beacon function inside IR sensor * towards sim support * channel labels * reverting to singletons * hiding unused apis * lazy allocation of button instances * tracking button state * hook up the state
This commit is contained in:
@ -13,6 +13,7 @@ namespace pxsim {
|
||||
motorState: EV3MotorState;
|
||||
screenState: EV3ScreenState;
|
||||
audioState: AudioState;
|
||||
remoteState: RemoteState;
|
||||
|
||||
inputNodes: SensorNode[] = [];
|
||||
brickNode: BrickNode;
|
||||
@ -38,6 +39,7 @@ namespace pxsim {
|
||||
this.motorState = new EV3MotorState();
|
||||
this.screenState = new EV3ScreenState();
|
||||
this.audioState = new AudioState();
|
||||
this.remoteState = new RemoteState();
|
||||
}
|
||||
|
||||
receiveMessage(msg: SimulatorMessage) {
|
||||
|
@ -1,6 +1,48 @@
|
||||
/// <reference path="./sensor.ts"/>
|
||||
|
||||
namespace pxsim {
|
||||
export enum InfraredRemoteButton {
|
||||
//% block="center beacon"
|
||||
CenterBeacon = 0x01,
|
||||
//% block="top left"
|
||||
TopLeft = 0x02,
|
||||
//% block="bottom left"
|
||||
BottomLeft = 0x04,
|
||||
//% block="top right"
|
||||
TopRight = 0x08,
|
||||
//% block="bottom right"
|
||||
BottomRight = 0x10,
|
||||
}
|
||||
|
||||
export class RemoteState {
|
||||
state: number = 0;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
unmapButtons() {
|
||||
switch(this.state) {
|
||||
case InfraredRemoteButton.TopLeft: return 1;
|
||||
case InfraredRemoteButton.BottomLeft: return 2;
|
||||
case InfraredRemoteButton.TopLeft: return 3;
|
||||
case InfraredRemoteButton.TopRight | InfraredRemoteButton.BottomRight: return 4;
|
||||
case InfraredRemoteButton.TopLeft | InfraredRemoteButton.TopRight: return 5;
|
||||
case InfraredRemoteButton.TopLeft | InfraredRemoteButton.BottomRight: return 6;
|
||||
case InfraredRemoteButton.BottomLeft | InfraredRemoteButton.TopRight: return 7;
|
||||
case InfraredRemoteButton.BottomLeft | InfraredRemoteButton.BottomRight: return 8;
|
||||
case InfraredRemoteButton.CenterBeacon: return 9;
|
||||
case InfraredRemoteButton.BottomLeft | InfraredRemoteButton.TopLeft: return 10;
|
||||
case InfraredRemoteButton.TopRight | InfraredRemoteButton.BottomRight: return 11;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
setPressed(btns: InfraredRemoteButton, down: boolean) {
|
||||
if (down) this.state = this.state | btns;
|
||||
else this.state = ~(~this.state | btns);
|
||||
}
|
||||
}
|
||||
|
||||
export enum InfraredSensorMode {
|
||||
None = -1,
|
||||
Proximity = 0,
|
||||
@ -29,7 +71,11 @@ namespace pxsim {
|
||||
}
|
||||
|
||||
getValue() {
|
||||
return this.proximity;
|
||||
switch(this.mode) {
|
||||
case InfraredSensorMode.Proximity: return this.proximity;
|
||||
case InfraredSensorMode.RemoteControl: return ev3board().remoteState.unmapButtons();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -234,6 +234,8 @@ namespace pxsim.visuals {
|
||||
const state = ev3board().getInputNodes()[0] as InfraredSensorNode;
|
||||
if (state.getMode() == InfraredSensorMode.Proximity)
|
||||
view = new ProximitySliderControl(this.element, this.defs, state, port);
|
||||
else if (state.getMode() == InfraredSensorMode.RemoteControl)
|
||||
view = new RemoteBeaconButtonsControl(this.element, this.defs, state, port);
|
||||
break;
|
||||
}
|
||||
case NodeType.GyroSensor: {
|
||||
|
57
sim/visuals/controls/remoteBeaconButtons.ts
Normal file
57
sim/visuals/controls/remoteBeaconButtons.ts
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
|
||||
namespace pxsim.visuals {
|
||||
enum InfraredRemoteButton {
|
||||
CenterBeacon = 0x01,
|
||||
TopLeft = 0x02,
|
||||
BottomLeft = 0x04,
|
||||
TopRight = 0x08,
|
||||
BottomRight = 0x10,
|
||||
}
|
||||
|
||||
export class RemoteBeaconButtonsControl extends ControlView<InfraredSensorNode> {
|
||||
private group: SVGGElement;
|
||||
|
||||
getInnerView() {
|
||||
this.group = svg.elt("g") as SVGGElement;
|
||||
this.group.setAttribute("transform", `translate(2, 2.5) scale(0.6)`)
|
||||
|
||||
const btnIds = [
|
||||
InfraredRemoteButton.CenterBeacon,
|
||||
InfraredRemoteButton.TopLeft,
|
||||
InfraredRemoteButton.TopRight,
|
||||
InfraredRemoteButton.BottomLeft,
|
||||
InfraredRemoteButton.BottomRight];
|
||||
const colors = ['#f12a21', '#ffd01b', '#006db3', '#00934b', '#6c2d00'];
|
||||
|
||||
let cy = -4;
|
||||
btnIds.forEach((cid, c) => {
|
||||
const cx = c % 2 == 0 ? 2.2 : 8.2;
|
||||
if (c % 2 == 0) cy += 5;
|
||||
if (btnIds[c]) {
|
||||
const circle = pxsim.svg.child(this.group, "circle", { 'class': 'sim-color-grid-circle', 'cx': cx, 'cy': cy, 'r': '2', 'style': `fill: ${colors[c]}` });
|
||||
pointerEvents.down.forEach(evid => circle.addEventListener(evid, ev => {
|
||||
ev3board().remoteState.setPressed(cid, true);
|
||||
}));
|
||||
circle.addEventListener(pointerEvents.leave, ev => {
|
||||
ev3board().remoteState.setPressed(cid, false);
|
||||
});
|
||||
circle.addEventListener(pointerEvents.up, ev => {
|
||||
ev3board().remoteState.setPressed(cid, true);
|
||||
});
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
return this.group;
|
||||
}
|
||||
|
||||
getInnerWidth() {
|
||||
return 10.2;
|
||||
}
|
||||
|
||||
getInnerHeight() {
|
||||
return 15;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user