pxt-microbit 7.1.23 → 7.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/built/block-tests.js +1 -1
- package/built/common-sim.d.ts +10 -0
- package/built/common-sim.js +38 -0
- package/built/sim.d.ts +13 -0
- package/built/sim.js +172 -71
- package/built/target-strings.json +1 -1
- package/built/target.js +1 -1
- package/built/target.json +1 -1
- package/built/targetlight.js +1 -0
- package/built/targetlight.json +1 -1
- package/built/theme.json +1 -1
- package/built/web/blockly.css +1 -1
- package/built/web/react-common-authcode.css +1 -1
- package/built/web/react-common-multiplayer.css +1 -1
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlblockly.css +1 -1
- package/built/web/rtlreact-common-authcode.css +1 -1
- package/built/web/rtlreact-common-multiplayer.css +1 -1
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +19 -19
- package/built/web/semantic.css +19 -19
- package/docs/extensions/extension-gallery.md +12 -0
- package/docs/reference/radio/on-received-message.md +25 -0
- package/docs/reference/radio/send-message.md +25 -0
- package/package.json +3 -3
- package/pxtarget.json +3 -1
- package/targetconfig.json +3 -0
package/built/sim.d.ts
CHANGED
|
@@ -817,17 +817,22 @@ declare namespace pxsim.visuals {
|
|
|
817
817
|
private microphoneLed;
|
|
818
818
|
private systemLed;
|
|
819
819
|
private antenna;
|
|
820
|
+
private antennaInitialized;
|
|
820
821
|
private rssi;
|
|
821
822
|
private lightLevelButton;
|
|
822
823
|
private lightLevelGradient;
|
|
824
|
+
private lightLevelInitialized;
|
|
823
825
|
private lightLevelText;
|
|
824
826
|
private thermometerGradient;
|
|
825
827
|
private thermometer;
|
|
828
|
+
private thermometerInitialized;
|
|
826
829
|
private thermometerText;
|
|
827
830
|
private soundLevelGradient;
|
|
828
831
|
private soundLevel;
|
|
832
|
+
private soundLevelInitialized;
|
|
829
833
|
private soundLevelText;
|
|
830
834
|
private shakeButton;
|
|
835
|
+
private shakeInitialized;
|
|
831
836
|
private shakeText;
|
|
832
837
|
private accTextX;
|
|
833
838
|
private accTextY;
|
|
@@ -868,6 +873,14 @@ declare namespace pxsim.visuals {
|
|
|
868
873
|
findParentElement(): SVGSVGElement;
|
|
869
874
|
private updateTilt;
|
|
870
875
|
private buildDom;
|
|
876
|
+
private buildAntennaElement;
|
|
877
|
+
private buildSoundLevel;
|
|
878
|
+
private buildThermometerElement;
|
|
879
|
+
private buildLightLevelElement;
|
|
880
|
+
private buildHeadElement;
|
|
881
|
+
private buildPinElements;
|
|
882
|
+
private buildShakeElement;
|
|
883
|
+
private buildButtonElements;
|
|
871
884
|
private updateHardwareVersion;
|
|
872
885
|
private positionV2Elements;
|
|
873
886
|
private attachEvents;
|
package/built/sim.js
CHANGED
|
@@ -4088,6 +4088,7 @@ var pxsim;
|
|
|
4088
4088
|
outline: none;
|
|
4089
4089
|
}
|
|
4090
4090
|
*:focus .sim-button-outer,
|
|
4091
|
+
.sim-antenna-outer:focus,
|
|
4091
4092
|
.sim-pin:focus,
|
|
4092
4093
|
.sim-thermometer:focus,
|
|
4093
4094
|
.sim-shake:focus,
|
|
@@ -4142,6 +4143,11 @@ path.sim-board {
|
|
|
4142
4143
|
"P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20",
|
|
4143
4144
|
"GND0", "GND", "+3v3", "GND1"
|
|
4144
4145
|
];
|
|
4146
|
+
const pinDrawOrder = [
|
|
4147
|
+
"P3", "P0", "P4", "P5", "P6", "P7", "P1", "P8", "P9", "P10", "P11",
|
|
4148
|
+
"P12", "P2", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20",
|
|
4149
|
+
"GND0", "GND", "+3v3", "GND1"
|
|
4150
|
+
];
|
|
4145
4151
|
const pinTitles = [
|
|
4146
4152
|
"P0, ANALOG IN",
|
|
4147
4153
|
"P1, ANALOG IN",
|
|
@@ -4168,6 +4174,11 @@ path.sim-board {
|
|
|
4168
4174
|
];
|
|
4169
4175
|
const MB_WIDTH = 500;
|
|
4170
4176
|
const MB_HEIGHT = 408;
|
|
4177
|
+
const LIGHT_LEVEL_BUTTON_POSITION_Y = 50;
|
|
4178
|
+
const LIGHT_LEVEL_BUTTON_RADIUS = 35;
|
|
4179
|
+
const ANTENNA_X = 380;
|
|
4180
|
+
const ANTENNA_WAVE_PERIOD_X = 18;
|
|
4181
|
+
const ANTENNA_WAVE_COUNT = 5;
|
|
4171
4182
|
visuals.themes = ["#3ADCFE", "#FFD43A", "#3AFFB3", "#FF3A54"].map(accent => {
|
|
4172
4183
|
return {
|
|
4173
4184
|
accent: accent,
|
|
@@ -4204,6 +4215,11 @@ path.sim-board {
|
|
|
4204
4215
|
constructor(props) {
|
|
4205
4216
|
this.props = props;
|
|
4206
4217
|
this.headInitialized = false;
|
|
4218
|
+
this.antennaInitialized = false;
|
|
4219
|
+
this.lightLevelInitialized = false;
|
|
4220
|
+
this.thermometerInitialized = false;
|
|
4221
|
+
this.soundLevelInitialized = false;
|
|
4222
|
+
this.shakeInitialized = false;
|
|
4207
4223
|
this.pinNmToCoord = {};
|
|
4208
4224
|
this.domHardwareVersion = 1;
|
|
4209
4225
|
this.moveHeadingOnClick = (ev) => {
|
|
@@ -4285,8 +4301,7 @@ path.sim-board {
|
|
|
4285
4301
|
else {
|
|
4286
4302
|
pxsim.svg.fills(this.heads.slice(1), theme.accent);
|
|
4287
4303
|
}
|
|
4288
|
-
|
|
4289
|
-
pxsim.svg.fill(this.shakeButton, theme.virtualButtonUp);
|
|
4304
|
+
pxsim.svg.fill(this.shakeButton, theme.virtualButtonUp);
|
|
4290
4305
|
this.pinGradients.forEach(lg => pxsim.svg.setGradientColors(lg, theme.pin, theme.pinActive));
|
|
4291
4306
|
pxsim.svg.setGradientColors(this.lightLevelGradient, theme.lightLevelOn, theme.lightLevelOff);
|
|
4292
4307
|
pxsim.svg.setGradientColors(this.thermometerGradient, theme.ledOff, theme.ledOn);
|
|
@@ -4353,8 +4368,9 @@ path.sim-board {
|
|
|
4353
4368
|
}
|
|
4354
4369
|
updateGestures() {
|
|
4355
4370
|
let state = this.board;
|
|
4356
|
-
if (state.accelerometerState.useShake && !this.
|
|
4357
|
-
this.
|
|
4371
|
+
if (state.accelerometerState.useShake && !this.shakeInitialized) {
|
|
4372
|
+
this.shakeInitialized = true;
|
|
4373
|
+
this.shakeButton.style.visibility = "visible";
|
|
4358
4374
|
pxsim.accessibility.makeFocusable(this.shakeButton);
|
|
4359
4375
|
pxsim.svg.fill(this.shakeButton, this.props.theme.virtualButtonUp);
|
|
4360
4376
|
pxsim.pointerEvents.down.forEach(evid => this.shakeButton.addEventListener(evid, ev => {
|
|
@@ -4455,18 +4471,9 @@ path.sim-board {
|
|
|
4455
4471
|
return;
|
|
4456
4472
|
let tmin = -5;
|
|
4457
4473
|
let tmax = 50;
|
|
4458
|
-
if (!this.
|
|
4459
|
-
|
|
4460
|
-
this.
|
|
4461
|
-
this.thermometer = pxsim.svg.child(this.g, "rect", {
|
|
4462
|
-
class: "sim-thermometer no-drag",
|
|
4463
|
-
x: 120,
|
|
4464
|
-
y: 110,
|
|
4465
|
-
width: 20,
|
|
4466
|
-
height: 160,
|
|
4467
|
-
rx: 5, ry: 5,
|
|
4468
|
-
fill: `url(#${gid})`
|
|
4469
|
-
});
|
|
4474
|
+
if (!this.thermometerInitialized) {
|
|
4475
|
+
this.thermometerInitialized = true;
|
|
4476
|
+
this.thermometer.style.visibility = "visible";
|
|
4470
4477
|
this.thermometerText = pxsim.svg.child(this.g, "text", { class: 'sim-text', x: 58, y: 130 });
|
|
4471
4478
|
if (this.props.runtime)
|
|
4472
4479
|
this.props.runtime.environmentGlobals[pxsim.localization.lf("temperature")] = state.thermometerState.temperature;
|
|
@@ -4488,6 +4495,7 @@ path.sim-board {
|
|
|
4488
4495
|
(ev) => {
|
|
4489
4496
|
let charCode = (typeof ev.which == "number") ? ev.which : ev.keyCode;
|
|
4490
4497
|
if (charCode === 40 || charCode === 37) { // Down/Left arrow
|
|
4498
|
+
ev.preventDefault();
|
|
4491
4499
|
state.thermometerState.temperature--;
|
|
4492
4500
|
if (state.thermometerState.temperature < -5) {
|
|
4493
4501
|
state.thermometerState.temperature = 50;
|
|
@@ -4495,6 +4503,7 @@ path.sim-board {
|
|
|
4495
4503
|
this.updateTemperature();
|
|
4496
4504
|
}
|
|
4497
4505
|
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4506
|
+
ev.preventDefault();
|
|
4498
4507
|
state.thermometerState.temperature++;
|
|
4499
4508
|
if (state.thermometerState.temperature > 50) {
|
|
4500
4509
|
state.thermometerState.temperature = -5;
|
|
@@ -4524,19 +4533,10 @@ path.sim-board {
|
|
|
4524
4533
|
return;
|
|
4525
4534
|
const tmin = 0; // state.microphoneState.min;
|
|
4526
4535
|
const tmax = 255; //state.microphoneState.max;
|
|
4527
|
-
if (!this.
|
|
4536
|
+
if (!this.soundLevelInitialized) {
|
|
4537
|
+
this.soundLevelInitialized = true;
|
|
4538
|
+
this.soundLevel.style.visibility = "visible";
|
|
4528
4539
|
const level = state.microphoneState.getLevel();
|
|
4529
|
-
let gid = "gradient-soundlevel";
|
|
4530
|
-
this.soundLevelGradient = pxsim.svg.linearGradient(this.defs, gid);
|
|
4531
|
-
this.soundLevel = pxsim.svg.child(this.g, "rect", {
|
|
4532
|
-
class: "sim-thermometer no-drag",
|
|
4533
|
-
x: 360,
|
|
4534
|
-
y: 110,
|
|
4535
|
-
width: 20,
|
|
4536
|
-
height: 160,
|
|
4537
|
-
rx: 5, ry: 5,
|
|
4538
|
-
fill: `url(#${gid})`
|
|
4539
|
-
});
|
|
4540
4540
|
this.soundLevelText = pxsim.svg.child(this.g, "text", { class: 'sim-text', x: 370, y: 90 });
|
|
4541
4541
|
if (this.props.runtime)
|
|
4542
4542
|
this.props.runtime.environmentGlobals[pxsim.localization.lf("sound level")] = state.microphoneState.getLevel();
|
|
@@ -4558,10 +4558,12 @@ path.sim-board {
|
|
|
4558
4558
|
(ev) => {
|
|
4559
4559
|
let charCode = (typeof ev.which == "number") ? ev.which : ev.keyCode;
|
|
4560
4560
|
if (charCode === 40 || charCode === 37) { // Down/Left arrow
|
|
4561
|
+
ev.preventDefault();
|
|
4561
4562
|
state.microphoneState.setLevel(state.microphoneState.getLevel() - 1);
|
|
4562
4563
|
this.updateMicrophone();
|
|
4563
4564
|
}
|
|
4564
4565
|
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4566
|
+
ev.preventDefault();
|
|
4565
4567
|
state.microphoneState.setLevel(state.microphoneState.getLevel() + 1);
|
|
4566
4568
|
this.updateMicrophone();
|
|
4567
4569
|
}
|
|
@@ -4620,30 +4622,45 @@ path.sim-board {
|
|
|
4620
4622
|
}
|
|
4621
4623
|
}
|
|
4622
4624
|
flashAntenna() {
|
|
4623
|
-
if (!this.
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
const
|
|
4629
|
-
const
|
|
4630
|
-
|
|
4625
|
+
if (!this.antennaInitialized) {
|
|
4626
|
+
this.antenna.style.visibility = "visible";
|
|
4627
|
+
this.antennaInitialized = true;
|
|
4628
|
+
const antennaWidth = ANTENNA_WAVE_PERIOD_X * ANTENNA_WAVE_COUNT;
|
|
4629
|
+
const valueMin = -128;
|
|
4630
|
+
const valueMax = -42;
|
|
4631
|
+
const setValue = (val) => {
|
|
4632
|
+
const rs = Math.max(valueMin, Math.min(valueMax, val));
|
|
4633
|
+
this.board.radioState.datagram.rssi = rs;
|
|
4634
|
+
this.updateRSSI();
|
|
4635
|
+
};
|
|
4631
4636
|
const pt = this.element.createSVGPoint();
|
|
4632
|
-
const
|
|
4637
|
+
const mouseEventHandler = (ev) => {
|
|
4633
4638
|
const state = this.board;
|
|
4634
4639
|
if (!state)
|
|
4635
4640
|
return;
|
|
4636
4641
|
const pos = pxsim.svg.cursorPoint(pt, this.element, ev);
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4642
|
+
setValue((-138 + (pos.x - ANTENNA_X) / antennaWidth * 100) | 0);
|
|
4643
|
+
};
|
|
4644
|
+
const keyboardEventHandler = (ev) => {
|
|
4645
|
+
var _a;
|
|
4646
|
+
const charCode = (typeof ev.which == "number") ? ev.which : ev.keyCode;
|
|
4647
|
+
const rs = (_a = this.board.radioState.datagram.rssi) !== null && _a !== void 0 ? _a : -75;
|
|
4648
|
+
if (charCode === 40 || charCode === 37) { // Down/Left arrow
|
|
4649
|
+
ev.preventDefault();
|
|
4650
|
+
setValue(rs - 1);
|
|
4651
|
+
}
|
|
4652
|
+
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4653
|
+
ev.preventDefault();
|
|
4654
|
+
setValue(rs + 1);
|
|
4655
|
+
}
|
|
4640
4656
|
};
|
|
4641
|
-
pxsim.svg.buttonEvents(
|
|
4642
|
-
pxsim.svg.buttonEvents(this.antenna,
|
|
4657
|
+
pxsim.svg.buttonEvents(this.antenna.children[0], mouseEventHandler, mouseEventHandler, mouseEventHandler, () => { });
|
|
4658
|
+
pxsim.svg.buttonEvents(this.antenna.children[1], mouseEventHandler, mouseEventHandler, mouseEventHandler, () => { });
|
|
4659
|
+
this.antenna.addEventListener('keydown', keyboardEventHandler);
|
|
4643
4660
|
pxsim.accessibility.makeFocusable(this.antenna);
|
|
4644
4661
|
pxsim.accessibility.setAria(this.antenna, "slider", "RSSI");
|
|
4645
|
-
this.antenna.setAttribute("aria-valuemin",
|
|
4646
|
-
this.antenna.setAttribute("aria-valuemax",
|
|
4662
|
+
this.antenna.setAttribute("aria-valuemin", `${valueMin}`);
|
|
4663
|
+
this.antenna.setAttribute("aria-valuemax", `${valueMax}`);
|
|
4647
4664
|
this.antenna.setAttribute("aria-orientation", "horizontal");
|
|
4648
4665
|
this.antenna.setAttribute("aria-valuenow", "");
|
|
4649
4666
|
pxsim.accessibility.setLiveContent("");
|
|
@@ -4651,7 +4668,7 @@ path.sim-board {
|
|
|
4651
4668
|
let now = Date.now();
|
|
4652
4669
|
if (now - this.lastAntennaFlash > 200) {
|
|
4653
4670
|
this.lastAntennaFlash = now;
|
|
4654
|
-
pxsim.svg.animate(this.antenna, 'sim-flash-stroke');
|
|
4671
|
+
pxsim.svg.animate(this.antenna.children[1], 'sim-flash-stroke');
|
|
4655
4672
|
}
|
|
4656
4673
|
this.updateRSSI();
|
|
4657
4674
|
}
|
|
@@ -4663,14 +4680,11 @@ path.sim-board {
|
|
|
4663
4680
|
if (v === undefined)
|
|
4664
4681
|
return;
|
|
4665
4682
|
if (!this.rssi) {
|
|
4666
|
-
let ax = 380;
|
|
4667
|
-
let dax = 18;
|
|
4668
4683
|
let ayt = 10;
|
|
4669
4684
|
let ayb = 40;
|
|
4670
|
-
const wh = dax * 5;
|
|
4671
4685
|
for (let i = 0; i < 4; ++i)
|
|
4672
|
-
pxsim.svg.child(this.g, "rect", { x:
|
|
4673
|
-
this.rssi = pxsim.svg.child(this.g, "text", { x:
|
|
4686
|
+
pxsim.svg.child(this.g, "rect", { x: ANTENNA_X - 90 + i * 6, y: ayt + 28 - i * 4, width: 4, height: 2 + i * 4, fill: "#fff" });
|
|
4687
|
+
this.rssi = pxsim.svg.child(this.g, "text", { x: ANTENNA_X - 64, y: ayb, class: "sim-text" });
|
|
4674
4688
|
this.rssi.textContent = "";
|
|
4675
4689
|
}
|
|
4676
4690
|
const vt = v.toString();
|
|
@@ -4690,23 +4704,16 @@ path.sim-board {
|
|
|
4690
4704
|
let state = this.board;
|
|
4691
4705
|
if (!state || !state.lightSensorState.usesLightLevel)
|
|
4692
4706
|
return;
|
|
4693
|
-
if (!this.
|
|
4694
|
-
|
|
4695
|
-
this.
|
|
4696
|
-
let cy = 50;
|
|
4697
|
-
let r = 35;
|
|
4698
|
-
this.lightLevelButton = pxsim.svg.child(this.g, "circle", {
|
|
4699
|
-
cx: `50px`, cy: `${cy}px`, r: `${r}px`,
|
|
4700
|
-
class: 'sim-light-level-button no-drag',
|
|
4701
|
-
fill: `url(#${gid})`
|
|
4702
|
-
});
|
|
4707
|
+
if (!this.lightLevelInitialized) {
|
|
4708
|
+
this.lightLevelInitialized = true;
|
|
4709
|
+
this.lightLevelButton.style.visibility = "visible";
|
|
4703
4710
|
let pt = this.element.createSVGPoint();
|
|
4704
4711
|
pxsim.svg.buttonEvents(this.lightLevelButton,
|
|
4705
4712
|
// move
|
|
4706
4713
|
(ev) => {
|
|
4707
4714
|
let pos = pxsim.svg.cursorPoint(pt, this.element, ev);
|
|
4708
|
-
let rs =
|
|
4709
|
-
let level = Math.max(0, Math.min(255, Math.floor((pos.y - (
|
|
4715
|
+
let rs = LIGHT_LEVEL_BUTTON_RADIUS / 2;
|
|
4716
|
+
let level = Math.max(0, Math.min(255, Math.floor((pos.y - (LIGHT_LEVEL_BUTTON_POSITION_Y - rs)) / (2 * rs) * 255)));
|
|
4710
4717
|
if (level != this.board.lightSensorState.lightLevel) {
|
|
4711
4718
|
this.board.lightSensorState.lightLevel = level;
|
|
4712
4719
|
this.applyLightLevel();
|
|
@@ -4720,6 +4727,7 @@ path.sim-board {
|
|
|
4720
4727
|
(ev) => {
|
|
4721
4728
|
let charCode = (typeof ev.which == "number") ? ev.which : ev.keyCode;
|
|
4722
4729
|
if (charCode === 40 || charCode === 37) { // Down/Left arrow
|
|
4730
|
+
ev.preventDefault();
|
|
4723
4731
|
this.board.lightSensorState.lightLevel--;
|
|
4724
4732
|
if (this.board.lightSensorState.lightLevel < 0) {
|
|
4725
4733
|
this.board.lightSensorState.lightLevel = 255;
|
|
@@ -4727,6 +4735,7 @@ path.sim-board {
|
|
|
4727
4735
|
this.applyLightLevel();
|
|
4728
4736
|
}
|
|
4729
4737
|
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
4738
|
+
ev.preventDefault();
|
|
4730
4739
|
this.board.lightSensorState.lightLevel++;
|
|
4731
4740
|
if (this.board.lightSensorState.lightLevel > 255) {
|
|
4732
4741
|
this.board.lightSensorState.lightLevel = 0;
|
|
@@ -4734,7 +4743,7 @@ path.sim-board {
|
|
|
4734
4743
|
this.applyLightLevel();
|
|
4735
4744
|
}
|
|
4736
4745
|
});
|
|
4737
|
-
this.lightLevelText = pxsim.svg.child(this.g, "text", { x: 85, y:
|
|
4746
|
+
this.lightLevelText = pxsim.svg.child(this.g, "text", { x: 85, y: LIGHT_LEVEL_BUTTON_POSITION_Y + LIGHT_LEVEL_BUTTON_RADIUS - 5, text: '', class: 'sim-text' });
|
|
4738
4747
|
if (this.props.runtime)
|
|
4739
4748
|
this.props.runtime.environmentGlobals[pxsim.localization.lf("lightLevel")] = state.lightSensorState.lightLevel;
|
|
4740
4749
|
this.updateTheme();
|
|
@@ -4872,6 +4881,74 @@ path.sim-board {
|
|
|
4872
4881
|
this.leds.push(led);
|
|
4873
4882
|
}
|
|
4874
4883
|
}
|
|
4884
|
+
// Order of construction affects tab ordering
|
|
4885
|
+
this.buildLightLevelElement();
|
|
4886
|
+
this.buildAntennaElement();
|
|
4887
|
+
this.buildHeadElement();
|
|
4888
|
+
this.buildThermometerElement();
|
|
4889
|
+
this.buildSoundLevel();
|
|
4890
|
+
this.buildShakeElement();
|
|
4891
|
+
this.buildButtonElements();
|
|
4892
|
+
this.buildPinElements();
|
|
4893
|
+
}
|
|
4894
|
+
buildAntennaElement() {
|
|
4895
|
+
this.antenna = pxsim.svg.child(this.g, "g", { class: "sim-antenna-outer" });
|
|
4896
|
+
const ayt = 10;
|
|
4897
|
+
const ayb = 40;
|
|
4898
|
+
const antennaWidth = ANTENNA_WAVE_PERIOD_X * ANTENNA_WAVE_COUNT;
|
|
4899
|
+
const borderOffset = 3;
|
|
4900
|
+
pxsim.svg.child(this.antenna, "rect", {
|
|
4901
|
+
x: ANTENNA_X - borderOffset,
|
|
4902
|
+
y: ayt - borderOffset,
|
|
4903
|
+
width: antennaWidth + 2 * borderOffset,
|
|
4904
|
+
height: ayb - ayt + 2 * borderOffset,
|
|
4905
|
+
fill: "transparent",
|
|
4906
|
+
rx: 2
|
|
4907
|
+
});
|
|
4908
|
+
let ax = ANTENNA_X;
|
|
4909
|
+
const dax = ANTENNA_WAVE_PERIOD_X;
|
|
4910
|
+
pxsim.svg.child(this.antenna, "polyline", { class: "sim-antenna", points: `${ax},${ayb} ${ax},${ayt} ${ax += dax},${ayt} ${ax},${ayb} ${ax += dax},${ayb} ${ax},${ayt} ${ax += dax},${ayt} ${ax},${ayb} ${ax += dax},${ayb} ${ax},${ayt} ${ax += dax},${ayt}` });
|
|
4911
|
+
this.antenna.style.visibility = "hidden";
|
|
4912
|
+
}
|
|
4913
|
+
buildSoundLevel() {
|
|
4914
|
+
let gid = "gradient-soundlevel";
|
|
4915
|
+
this.soundLevelGradient = pxsim.svg.linearGradient(this.defs, gid);
|
|
4916
|
+
this.soundLevel = pxsim.svg.child(this.g, "rect", {
|
|
4917
|
+
class: "sim-thermometer no-drag",
|
|
4918
|
+
x: 360,
|
|
4919
|
+
y: 110,
|
|
4920
|
+
width: 20,
|
|
4921
|
+
height: 160,
|
|
4922
|
+
rx: 5, ry: 5,
|
|
4923
|
+
fill: `url(#${gid})`
|
|
4924
|
+
});
|
|
4925
|
+
this.soundLevel.style.visibility = "hidden";
|
|
4926
|
+
}
|
|
4927
|
+
buildThermometerElement() {
|
|
4928
|
+
let gid = "gradient-thermometer";
|
|
4929
|
+
this.thermometerGradient = pxsim.svg.linearGradient(this.defs, gid);
|
|
4930
|
+
this.thermometer = pxsim.svg.child(this.g, "rect", {
|
|
4931
|
+
class: "sim-thermometer no-drag",
|
|
4932
|
+
x: 120,
|
|
4933
|
+
y: 110,
|
|
4934
|
+
width: 20,
|
|
4935
|
+
height: 160,
|
|
4936
|
+
rx: 5, ry: 5,
|
|
4937
|
+
fill: `url(#${gid})`
|
|
4938
|
+
});
|
|
4939
|
+
this.thermometer.style.visibility = "hidden";
|
|
4940
|
+
}
|
|
4941
|
+
buildLightLevelElement() {
|
|
4942
|
+
let gid = "gradient-light-level";
|
|
4943
|
+
this.lightLevelGradient = pxsim.svg.linearGradient(this.defs, gid);
|
|
4944
|
+
this.lightLevelButton = pxsim.svg.child(this.g, "circle", {
|
|
4945
|
+
cx: `50px`, cy: `${LIGHT_LEVEL_BUTTON_POSITION_Y}px`, r: `${LIGHT_LEVEL_BUTTON_RADIUS}px`,
|
|
4946
|
+
class: 'sim-light-level-button no-drag',
|
|
4947
|
+
fill: `url(#${gid})`
|
|
4948
|
+
});
|
|
4949
|
+
this.lightLevelButton.style.visibility = "hidden";
|
|
4950
|
+
}
|
|
4951
|
+
buildHeadElement() {
|
|
4875
4952
|
// head
|
|
4876
4953
|
this.head = pxsim.svg.child(this.g, "g", { class: "sim-head" });
|
|
4877
4954
|
pxsim.svg.child(this.head, "ellipse", { cx: 251, cy: 75, rx: 75, ry: 35, fill: "transparent" });
|
|
@@ -4884,22 +4961,33 @@ path.sim-board {
|
|
|
4884
4961
|
this.heads.push(pxsim.svg.path(this.headParts, "sim-theme", "M230.6,69.7c-2.9,0-5.3,2.4-5.3,5.3c0,2.9,2.4,5.3,5.3,5.3c2.9,0,5.3-2.4,5.3-5.3C235.9,72.1,233.5,69.7,230.6,69.7"));
|
|
4885
4962
|
this.heads.push(pxsim.svg.path(this.headParts, "sim-theme", "M269.7,80.3c2.9,0,5.3-2.4,5.3-5.3c0-2.9-2.4-5.3-5.3-5.3c-2.9,0-5.3,2.4-5.3,5.3C264.4,77.9,266.8,80.3,269.7,80.3"));
|
|
4886
4963
|
this.headText = pxsim.svg.child(this.g, "text", { x: 160, y: 60, class: "sim-text" });
|
|
4964
|
+
}
|
|
4965
|
+
buildPinElements() {
|
|
4887
4966
|
// https://www.microbit.co.uk/device/pins
|
|
4967
|
+
// The order of this.pins must match the edgeConnectorState.pins order.
|
|
4968
|
+
// The draw order must match the desired tab order. To this end we
|
|
4969
|
+
// create the drawlist in sim order and evaluate it in tab order.
|
|
4888
4970
|
// P0, P1, P2
|
|
4889
|
-
|
|
4971
|
+
let drawList = [
|
|
4890
4972
|
"M16.5,341.2c0,0.4-0.1,0.9-0.1,1.3v60.7c4.1,1.7,8.6,2.7,12.9,2.7h34.4v-64.7c0,0,0-0.1,0-0.1c0-13-10.6-23.6-23.7-23.6C27.2,317.6,16.5,328.1,16.5,341.2z M21.2,341.6c0-10.7,8.7-19.3,19.3-19.3c10.7,0,19.3,8.7,19.3,19.3c0,10.7-8.6,19.3-19.3,19.3C29.9,360.9,21.2,352.2,21.2,341.6z",
|
|
4891
4973
|
"M139.1,317.3c-12.8,0-22.1,10.3-23.1,23.1V406h46.2v-65.6C162.2,327.7,151.9,317.3,139.1,317.3zM139.3,360.1c-10.7,0-19.3-8.6-19.3-19.3c0-10.7,8.6-19.3,19.3-19.3c10.7,0,19.3,8.7,19.3,19.3C158.6,351.5,150,360.1,139.3,360.1z",
|
|
4892
4974
|
"M249,317.3c-12.8,0-22.1,10.3-23.1,23.1V406h46.2v-65.6C272.1,327.7,261.8,317.3,249,317.3z M249.4,360.1c-10.7,0-19.3-8.6-19.3-19.3c0-10.7,8.6-19.3,19.3-19.3c10.7,0,19.3,8.7,19.3,19.3C268.7,351.5,260.1,360.1,249.4,360.1z"
|
|
4893
|
-
].map((p
|
|
4975
|
+
].map((p) => () => pxsim.svg.path(this.g, "sim-pin sim-pin-touch", p));
|
|
4894
4976
|
// P3
|
|
4895
|
-
|
|
4977
|
+
drawList.push(() => pxsim.svg.path(this.g, "sim-pin", "M0,357.7v19.2c0,10.8,6.2,20.2,14.4,25.2v-44.4H0z"));
|
|
4896
4978
|
pins4onXs.forEach(x => {
|
|
4897
|
-
|
|
4979
|
+
drawList.push(() => pxsim.svg.child(this.g, "rect", { x: x, y: 356.7, width: 10, height: 50, class: "sim-pin" }));
|
|
4898
4980
|
});
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
this.pins.
|
|
4981
|
+
drawList.push(() => pxsim.svg.path(this.g, "sim-pin", "M483.6,402c8.2-5,14.4-14.4,14.4-25.1v-19.2h-14.4V402z"));
|
|
4982
|
+
drawList.push(() => pxsim.svg.path(this.g, "sim-pin", "M359.9,317.3c-12.8,0-22.1,10.3-23.1,23.1V406H383v-65.6C383,327.7,372.7,317.3,359.9,317.3z M360,360.1c-10.7,0-19.3-8.6-19.3-19.3c0-10.7,8.6-19.3,19.3-19.3c10.7,0,19.3,8.7,19.3,19.3C379.3,351.5,370.7,360.1,360,360.1z"));
|
|
4983
|
+
drawList.push(() => pxsim.svg.path(this.g, "sim-pin", "M458,317.6c-13,0-23.6,10.6-23.6,23.6c0,0,0,0.1,0,0.1h0V406H469c4.3,0,8.4-1,12.6-2.7v-60.7c0-0.4,0-0.9,0-1.3C481.6,328.1,471,317.6,458,317.6z M457.8,360.9c-10.7,0-19.3-8.6-19.3-19.3c0-10.7,8.6-19.3,19.3-19.3c10.7,0,19.3,8.7,19.3,19.3C477.1,352.2,468.4,360.9,457.8,360.9z"));
|
|
4984
|
+
this.pins = pinDrawOrder.reduce((pins, pinName) => {
|
|
4985
|
+
const simPinIndex = pinNames.indexOf(pinName);
|
|
4986
|
+
const newPin = drawList[simPinIndex]();
|
|
4987
|
+
pxsim.svg.hydrate(newPin, { title: pinTitles[simPinIndex] });
|
|
4988
|
+
pins[simPinIndex] = newPin;
|
|
4989
|
+
return pins;
|
|
4990
|
+
}, new Array(pinDrawOrder.length));
|
|
4903
4991
|
this.pinGradients = this.pins.map((pin, i) => {
|
|
4904
4992
|
let gid = "gradient-pin-" + i;
|
|
4905
4993
|
let lg = pxsim.svg.linearGradient(this.defs, gid);
|
|
@@ -4907,6 +4995,17 @@ path.sim-board {
|
|
|
4907
4995
|
return lg;
|
|
4908
4996
|
});
|
|
4909
4997
|
this.pinTexts = [67, 165, 275].map(x => pxsim.svg.child(this.g, "text", { class: "sim-text-pin", x: x, y: 345 }));
|
|
4998
|
+
}
|
|
4999
|
+
buildShakeElement() {
|
|
5000
|
+
this.shakeButton = pxsim.svg.child(this.g, "circle", {
|
|
5001
|
+
cx: 404,
|
|
5002
|
+
cy: 115,
|
|
5003
|
+
r: 12,
|
|
5004
|
+
class: "sim-shake",
|
|
5005
|
+
});
|
|
5006
|
+
this.shakeButton.style.visibility = "hidden";
|
|
5007
|
+
}
|
|
5008
|
+
buildButtonElements() {
|
|
4910
5009
|
this.buttonsOuter = [];
|
|
4911
5010
|
this.buttons = [];
|
|
4912
5011
|
const outerBtn = (left, top, label) => {
|
|
@@ -5130,6 +5229,7 @@ path.sim-board {
|
|
|
5130
5229
|
let state = this.board;
|
|
5131
5230
|
let pin = state.edgeConnectorState.pins[index];
|
|
5132
5231
|
if (charCode === 40 || charCode === 37) { // Down/Left arrow
|
|
5232
|
+
ev.preventDefault();
|
|
5133
5233
|
pin.value -= 10;
|
|
5134
5234
|
if (pin.value < 0) {
|
|
5135
5235
|
pin.value = 1023;
|
|
@@ -5137,6 +5237,7 @@ path.sim-board {
|
|
|
5137
5237
|
this.updatePin(pin, index);
|
|
5138
5238
|
}
|
|
5139
5239
|
else if (charCode === 38 || charCode === 39) { // Up/Right arrow
|
|
5240
|
+
ev.preventDefault();
|
|
5140
5241
|
pin.value += 10;
|
|
5141
5242
|
if (pin.value > 1023) {
|
|
5142
5243
|
pin.value = 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"A Blocks / JavaScript code editor for the micro:bit powered by Microsoft MakeCode.":"A Blocks / JavaScript code editor for the micro:bit powered by Microsoft MakeCode.","A micro-servo library":"A micro-servo library","Adds new blocks for message communication in the radio category":"Adds new blocks for message communication in the radio category","BETA - Camera, remote control and other Bluetooth services. App required.":"BETA - Camera, remote control and other Bluetooth services. App required.","Behind the MakeCode Hardware":"Behind the MakeCode Hardware","Blocks to JavaScript":"Blocks to JavaScript","Bluetooth services":"Bluetooth services","Buy":"Buy","Can't import microbit.co.uk scripts...":"Can't import microbit.co.uk scripts...","Coding Cards":"Coding Cards","Coding for Teachers":"Coding for Teachers","Color manipulation":"Color manipulation","Courses":"Courses","Data logging to flash memory. micro:bit (V2) only.":"Data logging to flash memory. micro:bit (V2) only.","Data logging to flash.":"Data logging to flash.","Deep Dive":"Deep Dive","Disable Bluetooth Event Service":"Disable Bluetooth Event Service","Download cancelled":"Download cancelled","Download failed, please try again":"Download failed, please try again","Download for V2 only":"Download for V2 only","Fashion":"Fashion","Fonts for displays (V2 only).":"Fonts for displays (V2 only).","Games":"Games","Go Back":"Go Back","Go to the old editor":"Go to the old editor","Great coding skills! Unfortunately, your program is too large to fit on a micro:bit V1😢. You can go back and try to make your program smaller, or you can download your program onto a micro:bit V2.":"Great coding skills! Unfortunately, your program is too large to fit on a micro:bit V1😢. You can go back and try to make your program smaller, or you can download your program onto a micro:bit V2.","Great coding skills! Unfortunately, your program is too large to fit on a micro:bit V2😢. You can go back and try to make your program smaller, or continue to use the simulator to run your code.":"Great coding skills! Unfortunately, your program is too large to fit on a micro:bit V2😢. You can go back and try to make your program smaller, or continue to use the simulator to run your code.","Hardware":"Hardware","Importing microbit.co.uk programs is not supported in this editor anymore. Please open this script in the https://makecode.microbit.org/v0 editor.":"Importing microbit.co.uk programs is not supported in this editor anymore. Please open this script in the https://makecode.microbit.org/v0 editor.","Jacdac":"Jacdac","JustWorks pairing (default): Pairing is automatic once the pairing is initiated.":"JustWorks pairing (default): Pairing is automatic once the pairing is initiated.","Live Coding":"Live Coding","MicroCode for the new micro:bit (V2)":"MicroCode for the new micro:bit (V2)","Microsoft MakeCode for micro:bit":"Microsoft MakeCode for micro:bit","Music":"Music","New? Start here!":"New? Start here!","No Pairing Required: Anyone can connect via Bluetooth.":"No Pairing Required: Anyone can connect via Bluetooth.","Oops, there was a problem downloading your code":"Oops, there was a problem downloading your code","Passkey pairing: Pairing requires 6 digit key to pair.":"Passkey pairing: Pairing requires 6 digit key to pair.","Radio Games":"Radio Games","Record sound clips. micro:bit (V2) only":"Record sound clips. micro:bit (V2) only","Reference":"Reference","Science":"Science","Science Experiments":"Science Experiments","Settings storage in internal flash":"Settings storage in internal flash","Support":"Support","Support for bitmaps (micro:bit V2 only).":"Support for bitmaps (micro:bit V2 only).","The microbit core library":"The microbit core library","The microphone library":"The microphone library","The radio services":"The radio services","Tools":"Tools","Toys":"Toys","Turtle":"Turtle","Tutorials":"Tutorials","Tutorials for the new micro:bit (V2)":"Tutorials for the new micro:bit (V2)","makecode.microbit.org":"makecode.microbit.org","{0} is a write only analog pin":"{0} is a write only analog pin","{id:extension-tag}Gaming":"Gaming","{id:extension-tag}Lights and Display":"Lights and Display","{id:extension-tag}Networking":"Networking","{id:extension-tag}Robotics":"Robotics","{id:extension-tag}Science":"Science","{id:extension-tag}Software":"Software","{id:type}Image":"Image","{id:type}LedSprite":"LedSprite","{id:var}image":"image","{id:var}sprite":"sprite"}
|
|
1
|
+
{"A Blocks / JavaScript code editor for the micro:bit powered by Microsoft MakeCode.":"A Blocks / JavaScript code editor for the micro:bit powered by Microsoft MakeCode.","A micro-servo library":"A micro-servo library","Adds new blocks for message communication in the radio category":"Adds new blocks for message communication in the radio category","BETA - Camera, remote control and other Bluetooth services. App required.":"BETA - Camera, remote control and other Bluetooth services. App required.","Behind the MakeCode Hardware":"Behind the MakeCode Hardware","Blocks to JavaScript":"Blocks to JavaScript","Bluetooth services":"Bluetooth services","Buy":"Buy","Can't import microbit.co.uk scripts...":"Can't import microbit.co.uk scripts...","Coding Cards":"Coding Cards","Coding for Teachers":"Coding for Teachers","Color manipulation":"Color manipulation","Courses":"Courses","Data logging to flash memory. micro:bit (V2) only.":"Data logging to flash memory. micro:bit (V2) only.","Data logging to flash.":"Data logging to flash.","Deep Dive":"Deep Dive","Disable Bluetooth Event Service":"Disable Bluetooth Event Service","Download cancelled":"Download cancelled","Download failed, please try again":"Download failed, please try again","Download for V2 only":"Download for V2 only","Fashion":"Fashion","Fonts for displays (V2 only).":"Fonts for displays (V2 only).","Games":"Games","Go Back":"Go Back","Go to the old editor":"Go to the old editor","Great coding skills! Unfortunately, your program is too large to fit on a micro:bit V1😢. You can go back and try to make your program smaller, or you can download your program onto a micro:bit V2.":"Great coding skills! Unfortunately, your program is too large to fit on a micro:bit V1😢. You can go back and try to make your program smaller, or you can download your program onto a micro:bit V2.","Great coding skills! Unfortunately, your program is too large to fit on a micro:bit V2😢. You can go back and try to make your program smaller, or continue to use the simulator to run your code.":"Great coding skills! Unfortunately, your program is too large to fit on a micro:bit V2😢. You can go back and try to make your program smaller, or continue to use the simulator to run your code.","Hardware":"Hardware","Importing microbit.co.uk programs is not supported in this editor anymore. Please open this script in the https://makecode.microbit.org/v0 editor.":"Importing microbit.co.uk programs is not supported in this editor anymore. Please open this script in the https://makecode.microbit.org/v0 editor.","Jacdac":"Jacdac","JustWorks pairing (default): Pairing is automatic once the pairing is initiated.":"JustWorks pairing (default): Pairing is automatic once the pairing is initiated.","Live Coding":"Live Coding","MicroCode for the new micro:bit (V2)":"MicroCode for the new micro:bit (V2)","Microsoft MakeCode for micro:bit":"Microsoft MakeCode for micro:bit","Music":"Music","New? Start here!":"New? Start here!","No Pairing Required: Anyone can connect via Bluetooth.":"No Pairing Required: Anyone can connect via Bluetooth.","Oops, there was a problem downloading your code":"Oops, there was a problem downloading your code","Passkey pairing: Pairing requires 6 digit key to pair.":"Passkey pairing: Pairing requires 6 digit key to pair.","Radio Games":"Radio Games","Record sound clips. micro:bit (V2) only":"Record sound clips. micro:bit (V2) only","Reference":"Reference","Science":"Science","Science Experiments":"Science Experiments","Settings storage in internal flash":"Settings storage in internal flash","Support":"Support","Support for bitmaps (micro:bit V2 only).":"Support for bitmaps (micro:bit V2 only).","The microbit core library":"The microbit core library","The microphone library":"The microphone library","The radio services":"The radio services","Tools":"Tools","Toys":"Toys","Turtle":"Turtle","Tutorials":"Tutorials","Tutorials for the new micro:bit (V2)":"Tutorials for the new micro:bit (V2)","makecode.microbit.org":"makecode.microbit.org","{0} is a write only analog pin":"{0} is a write only analog pin","{id:color-theme-name}High Contrast":"High Contrast","{id:color-theme-name}Micro:bit Light":"Micro:bit Light","{id:extension-tag}Gaming":"Gaming","{id:extension-tag}Lights and Display":"Lights and Display","{id:extension-tag}Networking":"Networking","{id:extension-tag}Robotics":"Robotics","{id:extension-tag}Science":"Science","{id:extension-tag}Software":"Software","{id:type}Image":"Image","{id:type}LedSprite":"LedSprite","{id:var}image":"image","{id:var}sprite":"sprite"}
|