pxt-common-packages 12.2.3 → 12.2.5

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.
Files changed (40) hide show
  1. package/libs/azureiot/built/debug/binary.js +461 -461
  2. package/libs/color/built/debug/binary.js +8 -8
  3. package/libs/color-sensor/built/debug/binary.js +8 -8
  4. package/libs/controller/built/debug/binary.js +7120 -7120
  5. package/libs/controller---none/built/debug/binary.js +7100 -7100
  6. package/libs/datalogger/built/debug/binary.js +63 -63
  7. package/libs/edge-connector/built/debug/binary.js +8 -8
  8. package/libs/esp32/built/debug/binary.js +462 -462
  9. package/libs/game/_locales/game-jsdoc-strings.json +2 -0
  10. package/libs/game/_locales/game-strings.json +2 -2
  11. package/libs/game/built/debug/binary.js +7039 -7039
  12. package/libs/game/numberprompt.ts +36 -444
  13. package/libs/game/prompt.ts +222 -258
  14. package/libs/game/pxt.json +2 -0
  15. package/libs/game/systemKeyboard.cpp +32 -0
  16. package/libs/game/systemKeyboard.d.ts +23 -0
  17. package/libs/lcd/built/debug/binary.js +8 -8
  18. package/libs/light-spectrum-sensor/built/debug/binary.js +8 -8
  19. package/libs/lora/built/debug/binary.js +8 -8
  20. package/libs/matrix-keypad/built/debug/binary.js +8 -8
  21. package/libs/mqtt/built/debug/binary.js +176 -176
  22. package/libs/net/built/debug/binary.js +176 -176
  23. package/libs/net-game/built/debug/binary.js +19979 -18810
  24. package/libs/palette/built/debug/binary.js +7038 -7038
  25. package/libs/pixel/built/debug/binary.js +8 -8
  26. package/libs/power/built/debug/binary.js +8 -8
  27. package/libs/proximity/built/debug/binary.js +8 -8
  28. package/libs/radio/built/debug/binary.js +8 -8
  29. package/libs/radio-broadcast/built/debug/binary.js +8 -8
  30. package/libs/rotary-encoder/built/debug/binary.js +8 -8
  31. package/libs/screen/_locales/screen-jsdoc-strings.json +2 -0
  32. package/libs/screen/_locales/screen-strings.json +4 -0
  33. package/libs/screen/built/debug/binary.js +50 -50
  34. package/libs/screen/fieldeditors.ts +1 -0
  35. package/libs/screen/image.d.ts +24 -0
  36. package/libs/screen/image.ts +25 -0
  37. package/libs/servo/built/debug/binary.js +8 -8
  38. package/libs/sprite-scaling/built/debug/binary.js +7038 -7038
  39. package/libs/storyboard/built/debug/binary.js +7038 -7038
  40. package/package.json +1 -1
@@ -4,371 +4,54 @@ namespace game {
4
4
  * Ask the player for a number value.
5
5
  * @param message The message to display on the text-entry screen
6
6
  * @param answerLength The maximum number of digits the user can enter (1 - 10)
7
+ * @param useSystemKeyboard Use the computer keyboard for typing if the game is being played in the simulator
7
8
  */
8
9
  //% weight=10 help=game/ask-for-number
9
- //% blockId=gameaskfornumber block="ask for number %message || and max length %answerLength"
10
+ //% blockId=gameaskfornumber
11
+ //% block="ask for number $message || and max length $answerLength use system keyboard $useSystemKeyboard"
10
12
  //% message.shadow=text
11
13
  //% message.defl=""
12
14
  //% answerLength.defl="6"
13
15
  //% answerLength.min=1
14
16
  //% answerLength.max=10
15
17
  //% group="Prompt"
16
- export function askForNumber(message: any, answerLength = 6) {
18
+ export function askForNumber(message: any, answerLength = 6, useSystemKeyboard = false) {
17
19
  answerLength = Math.max(0, Math.min(10, answerLength));
18
20
  let p = new game.NumberPrompt();
19
- const result = p.show(console.inspect(message), answerLength);
20
- return result;
21
+ const result = p.show(console.inspect(message), answerLength, useSystemKeyboard);
22
+ return parseFloat(result);
21
23
  }
22
24
 
23
-
24
- //% whenUsed=true
25
- const font = image.font8;
26
- //% whenUsed=true
27
- const PADDING_HORIZONTAL = 40;
28
- //% whenUsed=true
29
- const PADDING_VERTICAL = 4;
30
- //% whenUsed=true
31
- const PROMPT_LINE_SPACING = 2;
32
-
33
- //% whenUsed=true
34
- const NUM_LETTERS = 12;
35
- //% whenUsed=true
36
- const NUMPAD_ROW_LENGTH = 3;
37
- //% whenUsed=true
38
- const NUM_ROWS = Math.ceil(NUM_LETTERS / NUMPAD_ROW_LENGTH);
39
- //% whenUsed=true
40
- const INPUT_ROWS = 1;
41
-
42
- //% whenUsed=true
43
- const CONTENT_WIDTH = screen.width - PADDING_HORIZONTAL * 2;
44
- //% whenUsed=true
45
- const CONTENT_HEIGHT = screen.height - PADDING_VERTICAL * 2;
46
- //% whenUsed=true
47
- const CONTENT_TOP = PADDING_VERTICAL;
48
-
49
- // Dimensions of a "cell" that contains a letter
50
- //% whenUsed=true
51
- const CELL_HEIGHT = Math.floor(CONTENT_HEIGHT / (NUM_ROWS + 4));
52
- //% whenUsed=true
53
- const CELL_WIDTH = CELL_HEIGHT//Math.floor(CONTENT_WIDTH / NUMPAD_ROW_LENGTH);
54
- //% whenUsed=true
55
- const LETTER_OFFSET_X = Math.floor((CELL_WIDTH - font.charWidth) / 2);
56
- //% whenUsed=true
57
- const LETTER_OFFSET_Y = Math.floor((CELL_HEIGHT - font.charHeight) / 2);
58
- //% whenUsed=true
59
- const BLANK_PADDING = 1;
60
- //% whenUsed=true
61
- const ROW_LEFT = PADDING_HORIZONTAL + CELL_WIDTH / 2 + Math.floor((CONTENT_WIDTH - (CELL_WIDTH * NUMPAD_ROW_LENGTH)) / 2);
62
-
63
- // Dimensions of the bottom bar
64
- //% whenUsed=true
65
- const BOTTOM_BAR_NUMPAD_MARGIN = 4;
66
- //% whenUsed=true
67
- const BOTTOM_BAR_HEIGHT = PADDING_VERTICAL + BOTTOM_BAR_NUMPAD_MARGIN + CELL_HEIGHT;
68
- //% whenUsed=true
69
- const BOTTOM_BAR_TOP = screen.height - BOTTOM_BAR_HEIGHT;
70
- //% whenUsed=true
71
- const BOTTOM_BAR_BUTTON_WIDTH = PADDING_HORIZONTAL * 2 + font.charWidth * 3;
72
- //% whenUsed=true
73
- const BOTTOM_BAR_TEXT_Y = (BOTTOM_BAR_HEIGHT - font.charHeight) / 2;
74
- //% whenUsed=true
75
- const BOTTOM_BAR_CONFIRM_X = (BOTTOM_BAR_BUTTON_WIDTH - font.charWidth * 2) / 2;
76
-
77
- // Dimensions of the numpad area
78
- //% whenUsed=true
79
- const NUMPAD_HEIGHT = NUM_ROWS * CELL_HEIGHT;
80
- //% whenUsed=true
81
- const NUMPAD_TOP = screen.height - NUMPAD_HEIGHT - BOTTOM_BAR_HEIGHT;
82
- //% whenUsed=true
83
- const NUMPAD_INPUT_MARGIN = 4;
84
-
85
- // Dimensions of area where text is input
86
- //% whenUsed=true
87
- const INPUT_HEIGHT = INPUT_ROWS * CELL_HEIGHT;
88
- //% whenUsed=true
89
- const INPUT_TOP = NUMPAD_TOP - INPUT_HEIGHT - NUMPAD_INPUT_MARGIN;
90
-
91
- // Pixels kept blank on left and right sides of prompt
92
- //% whenUsed=true
93
- const PROMPT_MARGIN_HORIZ = 3;
94
-
95
- // Dimensions of prompt message area
96
- //% whenUsed=true
97
- const PROMPT_HEIGHT = INPUT_TOP - CONTENT_TOP;
98
- //% whenUsed=true
99
- const PROMPT_WIDTH = screen.width - PROMPT_MARGIN_HORIZ * 2
100
-
101
- //% whenUsed=true
102
- const confirmText = "OK";
103
-
104
-
105
- export class NumberPrompt {
106
- theme: PromptTheme;
107
-
108
- message: string;
109
- answerLength: number;
110
- result: string;
111
-
112
- private cursor: Sprite;
113
- private confirmButton: Sprite;
114
-
115
- private numbers: Sprite[];
116
- private inputs: Sprite[];
117
-
118
- private confirmPressed: boolean;
119
- private cursorRow: number;
120
- private cursorColumn: number;
121
- private hasDecimal: boolean;
122
- private inputIndex: number;
123
- private blink: boolean;
124
- private frameCount: number;
125
-
25
+ export class NumberPrompt extends Prompt {
126
26
  constructor(theme?: PromptTheme) {
127
- if (theme) {
128
- this.theme = theme;
129
- }
130
- else {
131
- this.theme = {
132
- colorPrompt: 1,
133
- colorInput: 3,
134
- colorInputHighlighted: 5,
135
- colorInputText: 1,
136
- colorAlphabet: 1,
137
- colorCursor: 7,
138
- colorBackground: 15,
139
- colorBottomBackground: 3,
140
- colorBottomText: 1,
141
- };
142
- }
143
- this.cursorRow = 0;
144
- this.cursorColumn = 0;
145
- this.hasDecimal = false;
146
- this.inputIndex = 0;
147
- }
148
-
149
- show(message: string, answerLength: number) : number {
150
- this.message = message;
151
- this.answerLength = answerLength;
152
- this.inputIndex = 0;
153
-
154
- controller._setUserEventsEnabled(false);
155
- game.pushScene()
27
+ super(theme);
156
28
 
157
- this.draw();
158
- this.registerHandlers();
159
- this.confirmPressed = false;
160
-
161
- pauseUntil(() => this.confirmPressed);
162
-
163
- game.popScene();
164
- controller._setUserEventsEnabled(true);
165
-
166
- return parseFloat(this.result);
29
+ this.keyboardColumns = 3;
30
+ this.keyboardRows = 4;
167
31
  }
168
32
 
169
- private draw() {
170
- this.drawPromptText();
171
- this.drawNumpad();
172
- this.drawInputarea();
173
- this.drawBottomBar();
33
+ protected numbersOnly() {
34
+ return true;
174
35
  }
175
36
 
176
- private drawPromptText() {
177
- const prompt = sprites.create(layoutText(this.message, PROMPT_WIDTH, PROMPT_HEIGHT, this.theme.colorPrompt), -1);
178
- prompt.x = screen.width / 2
179
- prompt.y = CONTENT_TOP + Math.floor((PROMPT_HEIGHT - prompt.height) / 2) + Math.floor(prompt.height / 2);
180
- }
37
+ protected drawBottomBar() {
38
+ this.drawBottomBarBackground();
181
39
 
182
- private drawInputarea() {
183
- const answerLeft = (screen.width - this.answerLength * CELL_WIDTH) / 2
184
-
185
- this.inputs = [];
186
- for (let i = 0; i < this.answerLength; i++) {
187
- const blank = image.create(CELL_WIDTH, CELL_HEIGHT);
188
- this.drawInput(blank, "", this.theme.colorInput);
189
-
190
- const s = sprites.create(blank, -1);
191
- s.left = answerLeft + i * CELL_WIDTH;
192
- s.y = INPUT_TOP;
193
- this.inputs.push(s);
194
- }
40
+ this.drawConfirm(this.cursorRow === 4);
195
41
  }
196
42
 
197
- private drawNumpad() {
198
- const cursorImage = image.create(CELL_WIDTH, CELL_HEIGHT);
199
- cursorImage.fill(this.theme.colorCursor);
200
- this.cursor = sprites.create(cursorImage, -1);
201
- this.cursor.z = -1;
202
- this.updateCursor();
203
-
204
- this.numbers = [];
205
- for (let j = 0; j < NUM_LETTERS; j++) {
206
- const letter = image.create(CELL_WIDTH, CELL_HEIGHT);
207
-
208
- const col2 = j % NUMPAD_ROW_LENGTH;
209
- const row2 = Math.floor(j / NUMPAD_ROW_LENGTH);
210
-
211
- const t = sprites.create(letter, -1);
212
- t.x = ROW_LEFT + col2 * CELL_WIDTH;
213
- t.y = NUMPAD_TOP + row2 * CELL_HEIGHT;
214
-
215
- this.numbers.push(t);
216
- }
217
- this.updateKeyboard();
218
- }
219
-
220
- private drawBottomBar() {
221
- const bg = image.create(screen.width, BOTTOM_BAR_HEIGHT);
222
- bg.fill(this.theme.colorBottomBackground);
223
-
224
- const bgSprite = sprites.create(bg, -1);
225
- bgSprite.x = screen.width / 2;
226
- bgSprite.y = BOTTOM_BAR_TOP + BOTTOM_BAR_HEIGHT / 2;
227
- bgSprite.z = -1;
228
-
229
- this.confirmButton = sprites.create(image.create(BOTTOM_BAR_BUTTON_WIDTH, BOTTOM_BAR_HEIGHT), -1);
230
- this.confirmButton.right = screen.width;
231
- this.confirmButton.y = BOTTOM_BAR_TOP + Math.ceil(BOTTOM_BAR_HEIGHT / 2);
232
-
233
- this.updateButtons();
234
- }
235
-
236
- private updateButtons() {
237
- if (this.cursorRow === 4) {
238
- this.confirmButton.image.fill(this.theme.colorCursor);
239
- }
240
- else {
241
- this.confirmButton.image.fill(this.theme.colorBottomBackground);
242
- }
243
-
244
- this.confirmButton.image.print(confirmText, BOTTOM_BAR_CONFIRM_X, BOTTOM_BAR_TEXT_Y);
245
- }
246
-
247
- private updateCursor() {
248
- if (this.cursorRow === 4) {
249
- this.cursor.image.fill(0);
250
- this.updateButtons();
251
- }
252
- else {
253
- this.cursor.x = ROW_LEFT + this.cursorColumn * CELL_WIDTH;
254
- this.cursor.y = NUMPAD_TOP + this.cursorRow * CELL_HEIGHT;
255
- }
256
- }
257
-
258
- private updateSelectedInput() {
259
- if (this.inputIndex < this.answerLength) {
260
- const u = this.inputs[this.inputIndex];
261
- if (this.blink) {
262
- this.drawInput(u.image, "", this.theme.colorInput);
263
- }
264
- else {
265
- this.drawInput(u.image, "", this.theme.colorInputHighlighted)
266
- }
267
- }
268
- }
269
-
270
- private updateKeyboard() {
271
- const len = this.numbers.length;
272
- for (let k = 0; k < len; k++) {
273
- const img = this.numbers[k].image;
274
- img.fill(0);
275
- img.print(getSymbolFromIndex(k), LETTER_OFFSET_X, LETTER_OFFSET_Y);
276
- }
277
- }
278
-
279
- private drawInput(img: Image, char: string, color: number) {
280
- img.fill(0);
281
- img.fillRect(BLANK_PADDING, CELL_HEIGHT - 1, CELL_WIDTH - BLANK_PADDING * 2, 1, color)
282
-
283
- if (char) {
284
- img.print(char, LETTER_OFFSET_X, LETTER_OFFSET_Y, this.theme.colorInputText, font);
285
- }
286
- }
287
-
288
- private registerHandlers() {
289
- controller.up.onEvent(SYSTEM_KEY_DOWN, () => {
290
- this.moveVertical(true);
291
- })
292
-
293
- controller.down.onEvent(SYSTEM_KEY_DOWN, () => {
294
- this.moveVertical(false);
295
- })
296
-
297
- controller.right.onEvent(SYSTEM_KEY_DOWN, () => {
298
- this.moveHorizontal(true);
299
- });
300
-
301
- controller.left.onEvent(SYSTEM_KEY_DOWN, () => {
302
- this.moveHorizontal(false);
303
- });
304
-
305
- controller.A.onEvent(SYSTEM_KEY_DOWN, () => {
306
- this.confirm();
307
- });
308
-
309
- controller.B.onEvent(SYSTEM_KEY_DOWN, () => {
310
- this.delete();
311
- });
312
-
313
-
314
- this.frameCount = 0;
315
- this.blink = true;
316
-
317
- game.onUpdate(() => {
318
- this.frameCount = (this.frameCount + 1) % 30;
319
-
320
- if (this.frameCount === 0) {
321
- this.blink = !this.blink;
322
-
323
- this.updateSelectedInput();
324
- }
325
- })
326
- }
327
-
328
- private moveVertical(up: boolean) {
329
- if (up) {
330
- if (this.cursorRow === 4) {
331
- this.cursor.image.fill(this.theme.colorCursor);
332
- this.cursorRow = 3;
333
-
334
- this.updateButtons();
335
- }
336
- else {
337
- this.cursorRow = Math.max(0, this.cursorRow - 1);
338
- }
339
- }
340
- else {
341
- this.cursorRow = Math.min(4, this.cursorRow + 1);
342
- }
343
-
344
- this.updateCursor();
345
- }
346
-
347
- private moveHorizontal(right: boolean) {
348
- if (right) {
349
- this.cursorColumn = (this.cursorColumn + 1) % NUMPAD_ROW_LENGTH;
350
- }
351
- else {
352
- this.cursorColumn = (this.cursorColumn + (NUMPAD_ROW_LENGTH - 1)) % NUMPAD_ROW_LENGTH;
353
- }
354
-
355
- this.updateCursor();
356
- }
357
-
358
- private confirm() {
43
+ protected confirm() {
359
44
  if (this.cursorRow === 4) {
360
45
  this.confirmPressed = true;
361
46
  } else {
362
- if (this.inputIndex >= this.answerLength) return;
47
+ if (this.selectionStart >= this.answerLength) return;
363
48
 
364
- const index = this.cursorColumn + this.cursorRow * NUMPAD_ROW_LENGTH
365
- const letter = getSymbolFromIndex(index);
49
+ const index = this.cursorColumn + this.cursorRow * this.keyboardColumns
50
+ const letter = this.getSymbolForIndex(index);
366
51
 
367
52
  if (letter === ".") {
368
- if(this.hasDecimal) {
53
+ if (this.result.indexOf(".") !== -1) {
369
54
  return;
370
- } else {
371
- this.hasDecimal = true;
372
55
  }
373
56
  }
374
57
 
@@ -383,121 +66,30 @@ namespace game {
383
66
  this.result += letter;
384
67
  }
385
68
 
386
- const sprite = this.inputs[this.inputIndex];
387
69
  this.changeInputIndex(1);
388
- this.drawInput(sprite.image, letter, this.theme.colorInput);
389
70
  }
390
71
  }
391
72
 
392
- private delete() {
393
- if (this.inputIndex <= 0) return;
394
-
395
- if (this.inputIndex < this.answerLength) {
396
- this.drawInput(this.inputs[this.inputIndex].image, "", this.theme.colorInput);
397
- }
398
-
399
- if (this.result.charAt(this.result.length - 1) === ".") {
400
- this.hasDecimal = false;
401
- }
402
-
403
- this.result = this.result.substr(0, this.result.length - 1);
404
-
405
- this.changeInputIndex(-1);
406
- }
407
-
408
- private changeInputIndex(delta: number) {
409
- this.inputIndex += delta;
410
- this.frameCount = 0
411
- this.blink = false;
412
- this.updateSelectedInput();
413
- }
414
- }
415
-
416
- function layoutText(message: string, width: number, height: number, color: number) {
417
- const lineHeight = font.charHeight + PROMPT_LINE_SPACING;
418
-
419
- const lineLength = Math.floor(width / font.charWidth);
420
- const numLines = Math.floor(height / lineHeight);
421
-
422
- let lines: string[] = [];
423
- let word: string;
424
- let line: string;
425
-
426
- let pushWord = () => {
427
- if (line) {
428
- if (line.length + word.length + 1 > lineLength) {
429
- lines.push(line);
430
- line = word;
431
- }
432
- else {
433
- line = line + " " + word;
434
- }
73
+ protected moveVertical(up: boolean): void {
74
+ super.moveVertical(up);
75
+ if (up && this.cursorRow === this.keyboardRows - 1) {
76
+ this.cursorColumn = this.keyboardColumns - 1;
435
77
  }
436
- else {
437
- line = word;
438
- }
439
-
440
- word = null;
441
78
  }
442
79
 
443
- for (let l = 0; l < message.length; l++) {
444
- const char = message.charAt(l);
445
-
446
- if (char === " ") {
447
- if (word) {
448
- pushWord();
449
- }
450
- else {
451
- word = " ";
452
- }
453
- }
454
- else if (!word) {
455
- word = char;
456
- }
457
- else {
458
- word += char;
80
+ protected getSymbolForIndex(index: number): string {
81
+ if (index < 9) {
82
+ // Calculator Layout
83
+ return "" + (3 * Math.idiv(9 - index - 1, 3) + index % 3 + 1);
84
+ } else if (index == 9) {
85
+ return "-";
86
+ } else if (index == 10) {
87
+ return "0";
88
+ } else if (index == 11) {
89
+ return ".";
90
+ } else {
91
+ return "";
459
92
  }
460
93
  }
461
-
462
- if (word) {
463
- pushWord();
464
- }
465
-
466
- if (line) {
467
- lines.push(line);
468
- }
469
-
470
- let maxLineWidth = 0;
471
- for (let m = 0; m < lines.length; m++) {
472
- maxLineWidth = Math.max(maxLineWidth, lines[m].length);
473
- }
474
-
475
- const actualWidth = maxLineWidth * font.charWidth;
476
- const actualHeight = lines.length * lineHeight;
477
-
478
- const res = image.create(actualWidth, actualHeight);
479
-
480
- for (let n = 0; n < lines.length; n++) {
481
- if ((n + 1) > numLines) break;
482
- res.print(lines[n], 0, n * lineHeight, color, font);
483
- }
484
-
485
- return res;
486
- }
487
-
488
- function getSymbolFromIndex(index: number) {
489
- if (index < 9) {
490
- // Calculator Layout
491
- return "" + (3 * Math.idiv(9 - index - 1, 3) + index % 3 + 1);
492
- } else if (index == 9) {
493
- return "-";
494
- } else if (index == 10) {
495
- return "0";
496
- } else if (index == 11) {
497
- return ".";
498
- } else {
499
- return "";
500
- }
501
94
  }
502
-
503
95
  }