pxt-common-packages 12.2.12 → 12.2.14

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.
@@ -341,15 +341,25 @@ declare namespace pxsim.browserEvents {
341
341
  ArrowRight = 39,
342
342
  PageDown = 34,
343
343
  End = 35,
344
- Home = 36
344
+ Home = 36,
345
+ LeftShift = 1016,
346
+ RightShift = 1017,
347
+ LeftControl = 1018,
348
+ RightControl = 1019,
349
+ Backspace = 8,
350
+ Delete = 46
345
351
  }
346
352
  function onKeyboardEvent(event: KeyboardEvent, pressed: boolean): void;
347
- function getValueForKey(event: KeyboardEvent): 0 | Key;
353
+ function getValueForKey(event: KeyboardEvent): 0 | Key.Zero | Key.One | Key.Two | Key.Three | Key.Four | Key.Five | Key.Six | Key.Seven | Key.Eight | Key.Nine | Key.BackTick | Key.Hyphen | Key.Equals | Key.Q | Key.W | Key.E | Key.R | Key.T | Key.Y | Key.U | Key.I | Key.O | Key.P | Key.OpenBracket | Key.CloseBracket | Key.BackSlash | Key.A | Key.S | Key.D | Key.F | Key.G | Key.H | Key.Space | Key.PageUp | Key.J | Key.K | Key.L | Key.SemiColon | Key.Apostrophe | Key.Z | Key.X | Key.C | Key.V | Key.B | Key.N | Key.M | Key.Comma | Key.Period | Key.ForwardSlash | Key.Shift | Key.Enter | Key.CapsLock | Key.Tab | Key.Control | Key.Meta | Key.Alt | Key.ArrowUp | Key.ArrowDown | Key.ArrowLeft | Key.ArrowRight | Key.PageDown | Key.End | Key.Home | Key.Backspace | Key.Delete;
348
354
  }
349
355
  declare namespace pxsim.browserEvents {
350
356
  interface BrowserEventsBoard extends CommonBoard {
351
357
  mouseState: MouseState;
352
358
  }
359
+ const INTERNAL_KEY_DOWN = 6870;
360
+ const INTERNAL_KEY_UP = 6871;
361
+ const INTERNAL_POINTER_DOWN = 6868;
362
+ const INTERNAL_POINTER_UP = 6869;
353
363
  type MouseEvent = "pointerdown" | "pointerup" | "pointermove" | "pointerleave" | "pointerenter" | "pointercancel" | "pointerover" | "pointerout";
354
364
  class MouseState {
355
365
  protected x: number;
@@ -813,16 +813,42 @@ var pxsim;
813
813
  Key[Key["PageDown"] = 34] = "PageDown";
814
814
  Key[Key["End"] = 35] = "End";
815
815
  Key[Key["Home"] = 36] = "Home";
816
+ Key[Key["LeftShift"] = 1016] = "LeftShift";
817
+ Key[Key["RightShift"] = 1017] = "RightShift";
818
+ Key[Key["LeftControl"] = 1018] = "LeftControl";
819
+ Key[Key["RightControl"] = 1019] = "RightControl";
820
+ Key[Key["Backspace"] = 8] = "Backspace";
821
+ Key[Key["Delete"] = 46] = "Delete";
816
822
  })(Key = browserEvents.Key || (browserEvents.Key = {}));
817
823
  function onKeyboardEvent(event, pressed) {
824
+ const eventValue = getValueForKey(event);
825
+ fireEvent(eventValue, pressed);
826
+ if (eventValue === Key.Shift) {
827
+ if (event.location === event.DOM_KEY_LOCATION_LEFT) {
828
+ fireEvent(Key.LeftShift, pressed);
829
+ }
830
+ else if (event.location === event.DOM_KEY_LOCATION_RIGHT) {
831
+ fireEvent(Key.RightShift, pressed);
832
+ }
833
+ }
834
+ if (eventValue === Key.Control) {
835
+ if (event.location === event.DOM_KEY_LOCATION_LEFT) {
836
+ fireEvent(Key.LeftControl, pressed);
837
+ }
838
+ else if (event.location === event.DOM_KEY_LOCATION_RIGHT) {
839
+ fireEvent(Key.RightControl, pressed);
840
+ }
841
+ }
842
+ }
843
+ browserEvents.onKeyboardEvent = onKeyboardEvent;
844
+ function fireEvent(key, pressed) {
818
845
  if (pressed) {
819
- pxsim.board().bus.queue(6866, getValueForKey(event));
846
+ pxsim.board().bus.queue(browserEvents.INTERNAL_KEY_DOWN, key);
820
847
  }
821
848
  else {
822
- pxsim.board().bus.queue(6867, getValueForKey(event));
849
+ pxsim.board().bus.queue(browserEvents.INTERNAL_KEY_UP, key);
823
850
  }
824
851
  }
825
- browserEvents.onKeyboardEvent = onKeyboardEvent;
826
852
  function getValueForKey(event) {
827
853
  switch (event.key) {
828
854
  case "0":
@@ -998,6 +1024,10 @@ var pxsim;
998
1024
  return Key.End;
999
1025
  case "Home":
1000
1026
  return Key.Home;
1027
+ case "Delete":
1028
+ return Key.Delete;
1029
+ case "Backspace":
1030
+ return Key.Backspace;
1001
1031
  default:
1002
1032
  return 0;
1003
1033
  }
@@ -1010,6 +1040,10 @@ var pxsim;
1010
1040
  var browserEvents;
1011
1041
  (function (browserEvents) {
1012
1042
  const THROTTLE_INTERVAL = 50;
1043
+ browserEvents.INTERNAL_KEY_DOWN = 6870;
1044
+ browserEvents.INTERNAL_KEY_UP = 6871;
1045
+ browserEvents.INTERNAL_POINTER_DOWN = 6868;
1046
+ browserEvents.INTERNAL_POINTER_UP = 6869;
1013
1047
  class MouseState {
1014
1048
  constructor() {
1015
1049
  this.onMove = pxsim.U.throttle(() => {
@@ -1032,9 +1066,16 @@ var pxsim;
1032
1066
  "pointerover",
1033
1067
  "pointerout",
1034
1068
  ];
1069
+ let eventId = 6857 + events.indexOf(event.type);
1070
+ if (event.type === "pointerdown") {
1071
+ eventId = browserEvents.INTERNAL_POINTER_DOWN;
1072
+ }
1073
+ else if (event.type === "pointerup") {
1074
+ eventId = browserEvents.INTERNAL_POINTER_UP;
1075
+ }
1035
1076
  // We add 1 to the button here because the left button is 0 and
1036
1077
  // that's used as a wildcard in our event bus
1037
- pxsim.board().bus.queue(6857 + events.indexOf(event.type), (event.button || 0) + 1);
1078
+ pxsim.board().bus.queue(eventId, (event.button || 0) + 1);
1038
1079
  }
1039
1080
  onWheelEvent(dx, dy, dz) {
1040
1081
  this.dx = dx;
@@ -27,6 +27,10 @@ int wheelDz() {
27
27
  return -1;
28
28
  }
29
29
 
30
+ //%
31
+ void _setCursorVisible(bool visible) {
32
+ }
33
+
30
34
  //%
31
35
  int currentTime() {
32
36
  return -1;
@@ -4,66 +4,94 @@
4
4
  //% block="Browser Events"
5
5
  namespace browserEvents {
6
6
  export enum Event {
7
+ //% block="pointer down"
7
8
  PointerDown = 6857,
9
+ //% block="pointer up"
8
10
  PointerUp = 6858,
11
+ //% block="pointer move"
9
12
  PointerMove = 6859,
13
+ //% block="pointer leave"
10
14
  PointerLeave = 6860,
15
+ //% block="pointer enter"
11
16
  PointerEnter = 6861,
17
+ //% block="pointer cancel"
12
18
  PointerCancel = 6862,
19
+ //% block="pointer over"
13
20
  PointerOver = 6863,
21
+ //% block="pointer out"
14
22
  PointerOut = 6864,
23
+ //% block="wheel"
15
24
  Wheel = 6865,
25
+ //% block="key down"
16
26
  KeyDown = 6866,
27
+ //% block="key up"
17
28
  KeyUp = 6867
18
29
  }
19
30
 
20
31
  export enum MouseButtonId {
32
+ //% block="left"
21
33
  Left = 1,
34
+ //% block="right"
22
35
  Right = 3,
36
+ //% block="wheel"
23
37
  Wheel = 2,
38
+ //% block="back"
24
39
  Back = 4,
40
+ //% block="forward"
25
41
  Forward = 5
26
42
  }
27
43
 
28
44
  export enum MouseButtonEvent {
45
+ //% block="pressed"
29
46
  Pressed = Event.PointerDown,
47
+ //% block="released"
30
48
  Released = Event.PointerUp,
31
49
  }
32
50
 
51
+ //% whenUsed
52
+ const INTERNAL_POINTER_DOWN = 6868;
53
+ //% whenUsed
54
+ const INTERNAL_POINTER_UP = 6869;
55
+
56
+ type MouseHandler = (x: number, y: number) => void;
57
+
33
58
  //% fixedInstances
34
59
  export class MouseButton {
35
60
  protected _pressed: boolean;
36
- protected pressHandler: (x: number, y: number) => void;
37
- protected pressListeners: ((x: number, y: number) => void)[];
38
- protected releaseHandler: (x: number, y: number) => void;
39
- protected releaseListeners: ((x: number, y: number) => void)[];
61
+
62
+ protected sceneStack: _SceneButtonHandlers<MouseHandler>[];
63
+
64
+ protected get state(): _SceneButtonHandlers<MouseHandler> {
65
+ return this.sceneStack[this.sceneStack.length - 1];
66
+ }
40
67
 
41
68
  constructor(public id: number) {
42
- control.internalOnEvent(Event.PointerDown, this.id, () => this.setPressed(true), 16);
43
- control.internalOnEvent(Event.PointerUp, this.id, () => this.setPressed(false), 16);
69
+ control.internalOnEvent(INTERNAL_POINTER_DOWN, this.id, () => this.setPressed(true), 16);
70
+ control.internalOnEvent(INTERNAL_POINTER_UP, this.id, () => this.setPressed(false), 16);
44
71
 
45
72
  this._pressed = false;
46
- this.pressListeners = [];
47
- this.releaseListeners = [];
73
+
74
+ this.sceneStack = [new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler)];
75
+
76
+ game.addScenePushHandler(() => {
77
+ this.sceneStack.push(new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler));
78
+ });
79
+ game.addScenePopHandler(() => {
80
+ this.sceneStack.pop();
81
+ if (this.sceneStack.length === 0) {
82
+ this.sceneStack = [new _SceneButtonHandlers<MouseHandler>(id, invokeMouseHandler)];
83
+ }
84
+ });
48
85
  }
49
86
 
50
87
  setPressed(pressed: boolean) {
51
88
  this._pressed = pressed;
89
+
52
90
  if (pressed) {
53
- if (this.pressHandler) {
54
- this.pressHandler(mouseX(), mouseY());
55
- }
56
- for (const handler of this.pressListeners) {
57
- handler(mouseX(), mouseY());
58
- }
91
+ control.raiseEvent(MouseButtonEvent.Pressed, this.id);
59
92
  }
60
93
  else {
61
- if (this.releaseHandler) {
62
- this.releaseHandler(mouseX(), mouseY());
63
- }
64
- for (const handler of this.releaseListeners) {
65
- handler(mouseX(), mouseY());
66
- }
94
+ control.raiseEvent(MouseButtonEvent.Released, this.id);
67
95
  }
68
96
  }
69
97
 
@@ -73,12 +101,7 @@ namespace browserEvents {
73
101
  //% group="Mouse"
74
102
  //% weight=50
75
103
  onEvent(event: MouseButtonEvent, handler: (x: number, y: number) => void) {
76
- if (event === MouseButtonEvent.Pressed) {
77
- this.pressHandler = handler;
78
- }
79
- else {
80
- this.releaseHandler = handler;
81
- }
104
+ this.state.onEvent(event, handler);
82
105
  }
83
106
 
84
107
  //% blockId=browserEvents_mouseButton_isPressed
@@ -98,24 +121,72 @@ namespace browserEvents {
98
121
  }
99
122
 
100
123
  addEventListener(event: MouseButtonEvent, handler: (x: number, y: number) => void) {
101
- if (event === MouseButtonEvent.Pressed) {
102
- this.pressListeners.push(handler);
103
- }
104
- else {
105
- this.releaseListeners.push(handler);
106
- }
124
+ this.state.addEventListener(event, handler);
107
125
  }
108
126
 
109
127
  removeEventListener(event: MouseButtonEvent, handler: (x: number, y: number) => void) {
110
- if (event === MouseButtonEvent.Pressed) {
111
- this.pressListeners = this.pressListeners.filter(p => p !== handler);
128
+ this.state.removeEventListener(event, handler);
129
+ }
130
+ }
131
+
132
+ export class _SceneButtonHandlers<U> {
133
+ protected handlers: ButtonHandler<U>[];
134
+
135
+ constructor(public id: number, protected invokeHandler: (handler: U) => void) {
136
+ this.handlers = [];
137
+ }
138
+
139
+ onEvent(event: number, handler: U) {
140
+ this.getHandler(event, true).handler = handler;
141
+ }
142
+
143
+ addEventListener(event: number, handler: U) {
144
+ this.getHandler(event, true).listeners.push(handler);
145
+ }
146
+
147
+ removeEventListener(event: number, handler: U) {
148
+ const eventHandler = this.getHandler(event);
149
+
150
+ if (eventHandler) {
151
+ eventHandler.listeners = eventHandler.listeners.filter(h => h !== handler);
112
152
  }
113
- else {
114
- this.releaseListeners = this.releaseListeners.filter(p => p !== handler);
153
+ }
154
+
155
+ protected getHandler(event: number, createIfMissing?: boolean) {
156
+ for (const handler of this.handlers) {
157
+ if (handler.event === event) return handler;
115
158
  }
159
+
160
+ if (createIfMissing) {
161
+ const newHandler = new ButtonHandler<U>(event, this.id, this.invokeHandler);
162
+ this.handlers.push(newHandler);
163
+ return newHandler;
164
+ }
165
+
166
+ return undefined;
116
167
  }
117
168
  }
118
169
 
170
+ class ButtonHandler<U> {
171
+ handler: U;
172
+ listeners: U[] = [];
173
+
174
+ constructor(public readonly event: number, id: number, invokeHandler: (handler: U) => void) {
175
+ control.onEvent(event, id, () => {
176
+ if (this.handler) {
177
+ invokeHandler(this.handler);
178
+ }
179
+ for (const listener of this.listeners) {
180
+ invokeHandler(listener);
181
+ }
182
+ });
183
+ }
184
+ }
185
+
186
+ function invokeMouseHandler(handler: MouseHandler) {
187
+ handler(mouseX(), mouseY());
188
+ }
189
+
119
190
  //% blockId=browserEvents_onEvent
120
191
  //% block="on browser event $event"
121
192
  //% draggableParameters="reporter"
@@ -147,6 +218,14 @@ namespace browserEvents {
147
218
  });
148
219
  }
149
220
 
221
+ //% blockId=browserEvents_setCursorVisible
222
+ //% block="set cursor visible $visible"
223
+ //% group="Mouse"
224
+ //% weight=0
225
+ export function setCursorVisible(visible: boolean) {
226
+ _setCursorVisible(visible);
227
+ }
228
+
150
229
  //% fixedInstance whenUsed block="left"
151
230
  export const MouseLeft = new MouseButton(MouseButtonId.Left);
152
231
 
@@ -62,14 +62,29 @@ namespace browserEvents {
62
62
  ArrowRight = 39,
63
63
  PageDown = 34,
64
64
  End = 35,
65
- Home = 36
65
+ Home = 36,
66
+ LeftShift = 1016,
67
+ RightShift = 1017,
68
+ LeftControl = 1018,
69
+ RightControl = 1019,
70
+ Backspace = 8,
71
+ Delete = 46,
66
72
  }
67
73
 
68
74
  export enum KeyEvent {
69
- Pressed,
70
- Released
75
+ //% block="pressed"
76
+ Pressed = 6872,
77
+ //% block="released"
78
+ Released = 6873,
79
+ //% block="repeat"
80
+ Repeat = 6874
71
81
  }
72
82
 
83
+ //% whenUsed
84
+ const INTERNAL_KEY_DOWN = 6870;
85
+ //% whenUsed
86
+ const INTERNAL_KEY_UP = 6871;
87
+
73
88
  export function keyToString(key: Key) {
74
89
  switch (key) {
75
90
  case Key.Q:
@@ -198,44 +213,95 @@ namespace browserEvents {
198
213
  return "-";
199
214
  case Key.Equals:
200
215
  return "=";
216
+ case Key.LeftShift:
217
+ return "LeftShift";
218
+ case Key.RightShift:
219
+ return "RightShift";
220
+ case Key.LeftControl:
221
+ return "LeftControl";
222
+ case Key.RightControl:
223
+ return "RightControl";
224
+ case Key.Backspace:
225
+ return "Backspace";
226
+ case Key.Delete:
227
+ return "Delete";
201
228
  }
202
229
  }
203
230
 
231
+ //% whenUsed
232
+ let _buttonsPendingInit: KeyButton[];
233
+
234
+ let defaultRepeatDelay = 500;
235
+ let defaultRepeatInterval = 30;
236
+
237
+ type KeyHandler = () => void;
204
238
 
205
239
  //% fixedInstances
206
240
  export class KeyButton {
207
241
  protected _pressed: boolean;
208
- protected pressHandler: () => void;
209
- protected pressListeners: (() => void)[];
210
- protected releaseHandler: () => void;
211
- protected releaseListeners: (() => void)[];
242
+ public repeatDelay: number;
243
+ public repeatInterval: number;
244
+ private _repeatCount: number;
245
+ private _pressedElapsed: number;
212
246
 
213
- constructor(public id: number) {
214
- control.onEvent(Event.KeyUp, this.id, () => this.setPressed(false), 16);
215
- control.onEvent(Event.KeyDown, this.id, () => this.setPressed(true), 16);
247
+ protected sceneStack: _SceneButtonHandlers<KeyHandler>[];
248
+
249
+ protected get state(): _SceneButtonHandlers<KeyHandler> {
250
+ return this.sceneStack[this.sceneStack.length - 1];
251
+ }
216
252
 
253
+ constructor(public id: number) {
254
+ // use internalOnEvent so that events fire regardless of the current scene
255
+ control.internalOnEvent(INTERNAL_KEY_UP, this.id, () => this.setPressed(false), 16);
256
+ control.internalOnEvent(INTERNAL_KEY_DOWN, this.id, () => this.setPressed(true), 16);
217
257
  this._pressed = false;
218
- this.pressListeners = [];
219
- this.releaseListeners = [];
258
+
259
+ // this code may run before game/scene.ts, in which case calling this.__registerUpdate
260
+ // will trigger an exception. to prevent that, start a thread that pauses until we
261
+ // detect that an event context has been registered and then call it
262
+ if (control.eventContext()) {
263
+ this.__registerUpdate();
264
+ }
265
+ else {
266
+ if (!_buttonsPendingInit) {
267
+ _buttonsPendingInit = [];
268
+ control.runInBackground(() => {
269
+ pauseUntil(() => !!control.eventContext());
270
+ for (const button of _buttonsPendingInit) {
271
+ button.__registerUpdate();
272
+ }
273
+ _buttonsPendingInit = undefined;
274
+ });
275
+ }
276
+ _buttonsPendingInit.push(this);
277
+ }
278
+
279
+ this.sceneStack = [new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler)];
280
+
281
+ game.addScenePushHandler(() => {
282
+ this.sceneStack.push(new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler));
283
+ this.__registerUpdate();
284
+ });
285
+ game.addScenePopHandler(() => {
286
+ this.sceneStack.pop();
287
+ if (this.sceneStack.length === 0) {
288
+ this.sceneStack = [new _SceneButtonHandlers<KeyHandler>(id, invokeKeyHandler)];
289
+ this.__registerUpdate();
290
+ }
291
+ });
220
292
  }
221
293
 
222
294
  setPressed(pressed: boolean) {
295
+ if (this._pressed === pressed) return;
296
+
223
297
  this._pressed = pressed;
224
298
  if (pressed) {
225
- if (this.pressHandler) {
226
- this.pressHandler();
227
- }
228
- for (const handler of this.pressListeners) {
229
- handler();
230
- }
299
+ this._repeatCount = 0;
300
+ this._pressedElapsed = 0;
301
+ control.raiseEvent(KeyEvent.Pressed, this.id);
231
302
  }
232
303
  else {
233
- if (this.releaseHandler) {
234
- this.releaseHandler();
235
- }
236
- for (const handler of this.releaseListeners) {
237
- handler();
238
- }
304
+ control.raiseEvent(KeyEvent.Released, this.id);
239
305
  }
240
306
  }
241
307
 
@@ -244,12 +310,7 @@ namespace browserEvents {
244
310
  //% group="Keyboard"
245
311
  //% weight=100
246
312
  onEvent(event: KeyEvent, handler: () => void) {
247
- if (event === KeyEvent.Pressed) {
248
- this.pressHandler = handler;
249
- }
250
- else {
251
- this.releaseHandler = handler;
252
- }
313
+ this.state.onEvent(event, handler);
253
314
  }
254
315
 
255
316
  //% blockId=browserEvents_key_isPressed
@@ -269,22 +330,38 @@ namespace browserEvents {
269
330
  }
270
331
 
271
332
  addEventListener(event: KeyEvent, handler: () => void) {
272
- if (event === KeyEvent.Pressed) {
273
- this.pressListeners.push(handler);
274
- }
275
- else {
276
- this.releaseListeners.push(handler);
277
- }
333
+ this.state.addEventListener(event, handler);
278
334
  }
279
335
 
280
336
  removeEventListener(event: KeyEvent, handler: () => void) {
281
- if (event === KeyEvent.Pressed) {
282
- this.pressListeners = this.pressListeners.filter(p => p !== handler);
283
- }
284
- else {
285
- this.releaseListeners = this.releaseListeners.filter(p => p !== handler);
337
+ this.state.removeEventListener(event, handler);
338
+ }
339
+
340
+ __update() {
341
+ const delay = this.repeatDelay === undefined ? defaultRepeatDelay : this.repeatDelay;
342
+ const interval = this.repeatInterval === undefined ? defaultRepeatInterval : this.repeatInterval;
343
+ if (!this._pressed) return;
344
+ this._pressedElapsed += game.eventContext().deltaTimeMillis;
345
+
346
+ // inital delay
347
+ if (this._pressedElapsed < delay)
348
+ return;
349
+
350
+ // repeat count for this step
351
+ const count = Math.floor((this._pressedElapsed - delay - interval) / interval);
352
+ if (count != this._repeatCount) {
353
+ this._repeatCount = count;
354
+ control.raiseEvent(KeyEvent.Repeat, this.id);
286
355
  }
287
356
  }
357
+
358
+ __registerUpdate() {
359
+ game.eventContext().registerFrameHandler(scene.CONTROLLER_PRIORITY, () => this.__update());
360
+ }
361
+ }
362
+
363
+ function invokeKeyHandler(handler: KeyHandler) {
364
+ handler();
288
365
  }
289
366
 
290
367
  //% fixedInstance whenUsed
@@ -476,6 +553,35 @@ namespace browserEvents {
476
553
  //% fixedInstance whenUsed
477
554
  export const Home = new KeyButton(Key.Home);
478
555
 
556
+ //% fixedInstance whenUsed
557
+ export const LeftShift = new KeyButton(Key.LeftShift);
558
+
559
+ //% fixedInstance whenUsed
560
+ export const RightShift = new KeyButton(Key.RightShift);
561
+
562
+ //% fixedInstance whenUsed
563
+ export const LeftControl = new KeyButton(Key.LeftControl);
564
+
565
+ //% fixedInstance whenUsed
566
+ export const RightControl = new KeyButton(Key.RightControl);
567
+
568
+ //% fixedInstance whenUsed
569
+ export const Backspace = new KeyButton(Key.Backspace);
570
+
571
+ //% fixedInstance whenUsed
572
+ export const Delete = new KeyButton(Key.Delete);
573
+
479
574
  //% fixedInstance whenUsed
480
575
  export const Any = new KeyButton(0);
576
+
577
+ //% blockId=browser_events_setKeyboardRepeatDefault
578
+ //% block="set keyboard repeat delay $delay ms interval $interval ms"
579
+ //% delay.defl=500
580
+ //% interval.defl=30
581
+ //% group="Keyboard"
582
+ //% weight=0
583
+ export function setKeyboardRepeatDefault(delay: number, interval: number) {
584
+ defaultRepeatDelay = Math.max(delay, 0);
585
+ defaultRepeatInterval = Math.max(interval, 1);
586
+ }
481
587
  }
@@ -9,6 +9,8 @@ declare namespace browserEvents {
9
9
  function wheelDy(): number;
10
10
  //% shim=browserEvents::wheelDz
11
11
  function wheelDz(): number;
12
+ //% shim=browserEvents::_setCursorVisible
13
+ function _setCursorVisible(visible: boolean): void;
12
14
 
13
15
  //% shim=browserEvents::currentTime
14
16
  function currentTime(): number;
@@ -62,15 +62,44 @@ namespace pxsim.browserEvents {
62
62
  ArrowRight = 39,
63
63
  PageDown = 34,
64
64
  End = 35,
65
- Home = 36
65
+ Home = 36,
66
+ LeftShift = 1016,
67
+ RightShift = 1017,
68
+ LeftControl = 1018,
69
+ RightControl = 1019,
70
+ Backspace = 8,
71
+ Delete = 46,
66
72
  }
67
73
 
68
74
  export function onKeyboardEvent(event: KeyboardEvent, pressed: boolean) {
75
+ const eventValue = getValueForKey(event);
76
+
77
+ fireEvent(eventValue as Key, pressed);
78
+
79
+ if (eventValue === Key.Shift) {
80
+ if (event.location === event.DOM_KEY_LOCATION_LEFT) {
81
+ fireEvent(Key.LeftShift, pressed);
82
+ }
83
+ else if (event.location === event.DOM_KEY_LOCATION_RIGHT) {
84
+ fireEvent(Key.RightShift, pressed);
85
+ }
86
+ }
87
+ if (eventValue === Key.Control) {
88
+ if (event.location === event.DOM_KEY_LOCATION_LEFT) {
89
+ fireEvent(Key.LeftControl, pressed);
90
+ }
91
+ else if (event.location === event.DOM_KEY_LOCATION_RIGHT) {
92
+ fireEvent(Key.RightControl, pressed);
93
+ }
94
+ }
95
+ }
96
+
97
+ function fireEvent(key: Key, pressed: boolean) {
69
98
  if (pressed) {
70
- board().bus.queue(6866, getValueForKey(event));
99
+ board().bus.queue(INTERNAL_KEY_DOWN, key);
71
100
  }
72
101
  else {
73
- board().bus.queue(6867, getValueForKey(event));
102
+ board().bus.queue(INTERNAL_KEY_UP, key);
74
103
  }
75
104
  }
76
105
 
@@ -249,6 +278,10 @@ namespace pxsim.browserEvents {
249
278
  return Key.End;
250
279
  case "Home":
251
280
  return Key.Home;
281
+ case "Delete":
282
+ return Key.Delete;
283
+ case "Backspace":
284
+ return Key.Backspace;
252
285
  default:
253
286
  return 0;
254
287
  }
@@ -5,6 +5,11 @@ namespace pxsim.browserEvents {
5
5
 
6
6
  const THROTTLE_INTERVAL = 50;
7
7
 
8
+ export const INTERNAL_KEY_DOWN = 6870;
9
+ export const INTERNAL_KEY_UP = 6871;
10
+ export const INTERNAL_POINTER_DOWN = 6868;
11
+ export const INTERNAL_POINTER_UP = 6869;
12
+
8
13
  export type MouseEvent = "pointerdown" | "pointerup" | "pointermove" | "pointerleave" | "pointerenter" | "pointercancel" | "pointerover" | "pointerout";
9
14
  export class MouseState {
10
15
  protected x: number;
@@ -43,10 +48,19 @@ namespace pxsim.browserEvents {
43
48
  "pointerout",
44
49
  ];
45
50
 
51
+ let eventId = 6857 + events.indexOf(event.type);
52
+
53
+ if (event.type === "pointerdown") {
54
+ eventId = INTERNAL_POINTER_DOWN;
55
+ }
56
+ else if (event.type === "pointerup") {
57
+ eventId = INTERNAL_POINTER_UP;
58
+ }
59
+
46
60
  // We add 1 to the button here because the left button is 0 and
47
61
  // that's used as a wildcard in our event bus
48
62
  board().bus.queue(
49
- 6857 + events.indexOf(event.type),
63
+ eventId,
50
64
  (event.button || 0) + 1
51
65
  );
52
66
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pxt-common-packages",
3
- "version": "12.2.12",
3
+ "version": "12.2.14",
4
4
  "description": "Microsoft MakeCode (PXT) common packages",
5
5
  "keywords": [
6
6
  "MakeCode",