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.
- package/libs/azureiot/built/debug/binary.js +461 -461
- package/libs/color/built/debug/binary.js +8 -8
- package/libs/color-sensor/built/debug/binary.js +8 -8
- package/libs/controller/built/debug/binary.js +7120 -7120
- package/libs/controller---none/built/debug/binary.js +7100 -7100
- package/libs/datalogger/built/debug/binary.js +63 -63
- package/libs/edge-connector/built/debug/binary.js +8 -8
- package/libs/esp32/built/debug/binary.js +462 -462
- package/libs/game/_locales/game-jsdoc-strings.json +2 -0
- package/libs/game/_locales/game-strings.json +2 -2
- package/libs/game/built/debug/binary.js +7039 -7039
- package/libs/game/numberprompt.ts +36 -444
- package/libs/game/prompt.ts +222 -258
- package/libs/game/pxt.json +2 -0
- package/libs/game/systemKeyboard.cpp +32 -0
- package/libs/game/systemKeyboard.d.ts +23 -0
- package/libs/lcd/built/debug/binary.js +8 -8
- package/libs/light-spectrum-sensor/built/debug/binary.js +8 -8
- package/libs/lora/built/debug/binary.js +8 -8
- package/libs/matrix-keypad/built/debug/binary.js +8 -8
- package/libs/mqtt/built/debug/binary.js +176 -176
- package/libs/net/built/debug/binary.js +176 -176
- package/libs/net-game/built/debug/binary.js +19979 -18810
- package/libs/palette/built/debug/binary.js +7038 -7038
- package/libs/pixel/built/debug/binary.js +8 -8
- package/libs/power/built/debug/binary.js +8 -8
- package/libs/proximity/built/debug/binary.js +8 -8
- package/libs/radio/built/debug/binary.js +8 -8
- package/libs/radio-broadcast/built/debug/binary.js +8 -8
- package/libs/rotary-encoder/built/debug/binary.js +8 -8
- package/libs/screen/_locales/screen-jsdoc-strings.json +2 -0
- package/libs/screen/_locales/screen-strings.json +4 -0
- package/libs/screen/built/debug/binary.js +50 -50
- package/libs/screen/fieldeditors.ts +1 -0
- package/libs/screen/image.d.ts +24 -0
- package/libs/screen/image.ts +25 -0
- package/libs/servo/built/debug/binary.js +8 -8
- package/libs/sprite-scaling/built/debug/binary.js +7038 -7038
- package/libs/storyboard/built/debug/binary.js +7038 -7038
- package/package.json +1 -1
package/libs/game/prompt.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
namespace game {
|
|
2
|
+
export const _KEYBOARD_CHANGE_EVENT = 7339;
|
|
3
|
+
export const _KEYBOARD_ENTER_EVENT = 7340;
|
|
4
|
+
export const _KEYBOARD_CANCEL_EVENT = 7341;
|
|
5
|
+
|
|
2
6
|
export interface PromptTheme {
|
|
3
7
|
colorPrompt: number;
|
|
4
8
|
colorInput: number;
|
|
@@ -15,18 +19,20 @@ namespace game {
|
|
|
15
19
|
* Ask the player for a string value.
|
|
16
20
|
* @param message The message to display on the text-entry screen
|
|
17
21
|
* @param answerLength The maximum number of characters the user can enter (1 - 24)
|
|
22
|
+
* @param useSystemKeyboard Use the computer keyboard for typing if the game is being played in the simulator
|
|
18
23
|
*/
|
|
19
24
|
//% weight=10 help=game/ask-for-string
|
|
20
|
-
//% blockId=gameaskforstring
|
|
25
|
+
//% blockId=gameaskforstring
|
|
26
|
+
//% block="ask for string $message || and max length $answerLength use system keyboard $useSystemKeyboard"
|
|
21
27
|
//% message.shadow=text
|
|
22
28
|
//% message.defl=""
|
|
23
29
|
//% answerLength.defl="12"
|
|
24
30
|
//% answerLength.min=1
|
|
25
31
|
//% answerLength.max=24
|
|
26
32
|
//% group="Prompt"
|
|
27
|
-
export function askForString(message: any, answerLength = 12) {
|
|
33
|
+
export function askForString(message: any, answerLength = 12, useSystemKeyboard = false) {
|
|
28
34
|
let p = new game.Prompt();
|
|
29
|
-
const result = p.show(console.inspect(message), answerLength);
|
|
35
|
+
const result = p.show(console.inspect(message), answerLength, useSystemKeyboard);
|
|
30
36
|
return result;
|
|
31
37
|
}
|
|
32
38
|
|
|
@@ -35,8 +41,6 @@ namespace game {
|
|
|
35
41
|
const font = image.font8; // FONT8-TODO
|
|
36
42
|
//% whenUsed=true
|
|
37
43
|
const PADDING = 4;
|
|
38
|
-
//% whenUsed=true
|
|
39
|
-
const PROMPT_LINE_SPACING = 2;
|
|
40
44
|
|
|
41
45
|
//% whenUsed=true
|
|
42
46
|
const NUM_LETTERS = 26;
|
|
@@ -66,7 +70,7 @@ namespace game {
|
|
|
66
70
|
//% whenUsed=true
|
|
67
71
|
const BLANK_PADDING = 1;
|
|
68
72
|
//% whenUsed=true
|
|
69
|
-
const ROW_LEFT = PADDING +
|
|
73
|
+
const ROW_LEFT = PADDING + Math.floor((CONTENT_WIDTH - (CELL_WIDTH * ALPHABET_ROW_LENGTH)) / 2);
|
|
70
74
|
|
|
71
75
|
// Dimensions of the bottom bar
|
|
72
76
|
//% whenUsed=true
|
|
@@ -74,8 +78,6 @@ namespace game {
|
|
|
74
78
|
//% whenUsed=true
|
|
75
79
|
const BOTTOM_BAR_HEIGHT = PADDING + BOTTOM_BAR_ALPHABET_MARGIN + CELL_HEIGHT;
|
|
76
80
|
//% whenUsed=true
|
|
77
|
-
const BOTTOM_BAR_TOP = screen.height - BOTTOM_BAR_HEIGHT;
|
|
78
|
-
//% whenUsed=true
|
|
79
81
|
const BOTTOM_BAR_BUTTON_WIDTH = PADDING * 2 + font.charWidth * 3;
|
|
80
82
|
//% whenUsed=true
|
|
81
83
|
const BOTTOM_BAR_TEXT_Y = (BOTTOM_BAR_HEIGHT - font.charHeight) / 2;
|
|
@@ -100,10 +102,6 @@ namespace game {
|
|
|
100
102
|
//% whenUsed=true
|
|
101
103
|
const INPUT_TOP = ALPHABET_TOP - INPUT_HEIGHT - ALPHABET_INPUT_MARGIN;
|
|
102
104
|
|
|
103
|
-
// Dimensions of prompt message area
|
|
104
|
-
//% whenUsed=true
|
|
105
|
-
const PROMPT_HEIGHT = INPUT_TOP - CONTENT_TOP;
|
|
106
|
-
|
|
107
105
|
//% whenUsed=true
|
|
108
106
|
const lowerShiftText = "ABC";
|
|
109
107
|
//% whenUsed=true
|
|
@@ -121,20 +119,20 @@ namespace game {
|
|
|
121
119
|
answerLength: number;
|
|
122
120
|
result: string;
|
|
123
121
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
122
|
+
protected confirmPressed: boolean;
|
|
123
|
+
protected cursorRow: number;
|
|
124
|
+
protected cursorColumn: number;
|
|
125
|
+
protected upper: boolean;
|
|
126
|
+
protected useSystemKeyboard: boolean;
|
|
127
|
+
|
|
128
|
+
protected renderable: scene.Renderable;
|
|
129
|
+
protected selectionStart: number;
|
|
130
|
+
protected selectionEnd: number;
|
|
127
131
|
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
protected keyboardRows: number;
|
|
133
|
+
protected keyboardColumns: number;
|
|
130
134
|
|
|
131
|
-
private
|
|
132
|
-
private cursorRow: number;
|
|
133
|
-
private cursorColumn: number;
|
|
134
|
-
private upper: boolean;
|
|
135
|
-
private inputIndex: number;
|
|
136
|
-
private blink: boolean;
|
|
137
|
-
private frameCount: number;
|
|
135
|
+
private changeTime = 0;
|
|
138
136
|
|
|
139
137
|
constructor(theme?: PromptTheme) {
|
|
140
138
|
if (theme) {
|
|
@@ -156,22 +154,63 @@ namespace game {
|
|
|
156
154
|
this.cursorRow = 0;
|
|
157
155
|
this.cursorColumn = 0;
|
|
158
156
|
this.upper = false;
|
|
159
|
-
this.
|
|
157
|
+
this.result = "";
|
|
158
|
+
this.keyboardColumns = ALPHABET_ROW_LENGTH;
|
|
159
|
+
this.keyboardRows = NUM_ROWS;
|
|
160
|
+
this.selectionStart = 0;
|
|
161
|
+
this.selectionEnd = 0;
|
|
160
162
|
}
|
|
161
163
|
|
|
162
|
-
show(message: string, answerLength: number) {
|
|
164
|
+
show(message: string, answerLength: number, useSystemKeyboard = false) {
|
|
163
165
|
this.message = message;
|
|
164
166
|
this.answerLength = answerLength;
|
|
165
|
-
this.inputIndex = 0;
|
|
166
167
|
|
|
167
168
|
controller._setUserEventsEnabled(false);
|
|
168
169
|
game.pushScene()
|
|
169
170
|
|
|
170
|
-
this.
|
|
171
|
-
this.registerHandlers();
|
|
171
|
+
this.createRenderable();
|
|
172
172
|
this.confirmPressed = false;
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
if (useSystemKeyboard && control.deviceDalVersion() === "sim" && helpers._isSystemKeyboardSupported()) {
|
|
175
|
+
this.useSystemKeyboard = true;
|
|
176
|
+
helpers._promptForText(this.answerLength, this.numbersOnly());
|
|
177
|
+
this.selectionEnd = 0;
|
|
178
|
+
this.selectionStart = 0;
|
|
179
|
+
control.onEvent(_KEYBOARD_CHANGE_EVENT, 0, () => {
|
|
180
|
+
this.result = helpers._getTextPromptString().substr(0, this.answerLength);
|
|
181
|
+
|
|
182
|
+
this.changeTime = game.runtime();
|
|
183
|
+
|
|
184
|
+
this.selectionStart = helpers._getTextPromptSelectionStart();
|
|
185
|
+
this.selectionEnd = helpers._getTextPromptSelectionEnd();
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
let cancelled = false;
|
|
189
|
+
let finished = false;
|
|
190
|
+
|
|
191
|
+
control.onEvent(_KEYBOARD_CANCEL_EVENT, 0, () => {
|
|
192
|
+
cancelled = true;
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
control.onEvent(_KEYBOARD_ENTER_EVENT, 0, () => {
|
|
196
|
+
finished = true;
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
pauseUntil(() => cancelled || finished);
|
|
200
|
+
|
|
201
|
+
if (cancelled) {
|
|
202
|
+
this.useSystemKeyboard = false;
|
|
203
|
+
this.selectionStart = this.result.length;
|
|
204
|
+
this.selectionEnd = this.selectionStart;
|
|
205
|
+
this.registerHandlers();
|
|
206
|
+
pauseUntil(() => this.confirmPressed);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
this.useSystemKeyboard = false;
|
|
211
|
+
this.registerHandlers();
|
|
212
|
+
pauseUntil(() => this.confirmPressed);
|
|
213
|
+
}
|
|
175
214
|
|
|
176
215
|
game.popScene();
|
|
177
216
|
controller._setUserEventsEnabled(true);
|
|
@@ -179,147 +218,170 @@ namespace game {
|
|
|
179
218
|
return this.result;
|
|
180
219
|
}
|
|
181
220
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
this.drawKeyboard();
|
|
185
|
-
this.drawInputarea();
|
|
186
|
-
this.drawBottomBar();
|
|
221
|
+
protected numbersOnly() {
|
|
222
|
+
return false;
|
|
187
223
|
}
|
|
188
224
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
225
|
+
protected createRenderable() {
|
|
226
|
+
if (this.renderable) {
|
|
227
|
+
this.renderable.destroy();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const promptText = new sprites.RenderText(this.message, CONTENT_WIDTH);
|
|
231
|
+
const systemKeyboardText = new sprites.RenderText("Type your response using your keyboard and hit ENTER", CONTENT_WIDTH);
|
|
232
|
+
|
|
233
|
+
this.renderable = scene.createRenderable(-1, () => {
|
|
234
|
+
promptText.draw(screen, (screen.width >> 1) - (promptText.width >> 1), CONTENT_TOP, this.theme.colorPrompt, 0, 2)
|
|
235
|
+
this.drawInputArea();
|
|
236
|
+
|
|
237
|
+
if (!this.useSystemKeyboard) {
|
|
238
|
+
this.drawKeyboard();
|
|
239
|
+
this.drawBottomBar();
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
screen.fillRect(0, screen.height - (PADDING << 1) - systemKeyboardText.height, screen.width, screen.height, this.theme.colorBottomBackground);
|
|
244
|
+
systemKeyboardText.draw(screen, PADDING, screen.height - PADDING - systemKeyboardText.height, this.theme.colorBottomText);
|
|
245
|
+
});
|
|
193
246
|
}
|
|
194
247
|
|
|
195
|
-
|
|
248
|
+
protected drawInputArea() {
|
|
196
249
|
const answerLeft = ROW_LEFT + Math.floor(
|
|
197
250
|
((CELL_WIDTH * ALPHABET_ROW_LENGTH) -
|
|
198
251
|
CELL_WIDTH * Math.min(this.answerLength, ALPHABET_ROW_LENGTH)) / 2);
|
|
199
252
|
|
|
200
|
-
this.inputs = [];
|
|
201
253
|
for (let i = 0; i < this.answerLength; i++) {
|
|
202
|
-
const blank = image.create(CELL_WIDTH, CELL_HEIGHT);
|
|
203
|
-
this.drawInput(blank, "", this.theme.colorInput);
|
|
204
|
-
|
|
205
254
|
const col = i % ALPHABET_ROW_LENGTH;
|
|
206
255
|
const row = Math.floor(i / ALPHABET_ROW_LENGTH);
|
|
207
256
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
cursorImage.fill(this.theme.colorCursor);
|
|
218
|
-
this.cursor = sprites.create(cursorImage, -1);
|
|
219
|
-
this.cursor.z = -1;
|
|
220
|
-
this.updateCursor();
|
|
221
|
-
|
|
222
|
-
this.letters = [];
|
|
223
|
-
for (let j = 0; j < 36; j++) {
|
|
224
|
-
const letter = image.create(CELL_WIDTH, CELL_HEIGHT);
|
|
225
|
-
|
|
226
|
-
const col2 = j % ALPHABET_ROW_LENGTH;
|
|
227
|
-
const row2 = Math.floor(j / ALPHABET_ROW_LENGTH);
|
|
257
|
+
if (this.selectionStart !== this.selectionEnd && i >= this.selectionStart && i < this.selectionEnd) {
|
|
258
|
+
screen.fillRect(
|
|
259
|
+
answerLeft + col * CELL_WIDTH,
|
|
260
|
+
INPUT_TOP + row * CELL_HEIGHT,
|
|
261
|
+
CELL_WIDTH,
|
|
262
|
+
CELL_HEIGHT,
|
|
263
|
+
this.theme.colorCursor
|
|
264
|
+
);
|
|
265
|
+
}
|
|
228
266
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
267
|
+
screen.fillRect(
|
|
268
|
+
answerLeft + col * CELL_WIDTH + BLANK_PADDING,
|
|
269
|
+
INPUT_TOP + row * CELL_HEIGHT + CELL_HEIGHT - 1,
|
|
270
|
+
CELL_WIDTH - BLANK_PADDING * 2,
|
|
271
|
+
1,
|
|
272
|
+
!this.useSystemKeyboard && !this.blink() && i === this.selectionStart ? this.theme.colorInputHighlighted : this.theme.colorInput
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
if (i < this.result.length) {
|
|
276
|
+
const char = this.result.charAt(i);
|
|
277
|
+
screen.print(
|
|
278
|
+
char,
|
|
279
|
+
answerLeft + col * CELL_WIDTH + LETTER_OFFSET_X,
|
|
280
|
+
INPUT_TOP + row * CELL_HEIGHT + LETTER_OFFSET_Y,
|
|
281
|
+
this.theme.colorInputText,
|
|
282
|
+
font
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
232
286
|
|
|
233
|
-
|
|
287
|
+
// draw the blinking text cursor
|
|
288
|
+
if (this.useSystemKeyboard) {
|
|
289
|
+
if (this.selectionStart === this.selectionEnd && this.selectionStart < this.answerLength) {
|
|
290
|
+
const col = this.selectionStart % ALPHABET_ROW_LENGTH;
|
|
291
|
+
const row = Math.floor(this.selectionStart / ALPHABET_ROW_LENGTH);
|
|
292
|
+
if (!this.blink()) {
|
|
293
|
+
screen.fillRect(
|
|
294
|
+
answerLeft + col * CELL_WIDTH,
|
|
295
|
+
INPUT_TOP + row * CELL_HEIGHT,
|
|
296
|
+
1,
|
|
297
|
+
CELL_HEIGHT,
|
|
298
|
+
this.theme.colorCursor
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
234
302
|
}
|
|
235
|
-
this.updateKeyboard();
|
|
236
303
|
}
|
|
237
304
|
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
305
|
+
protected drawKeyboard() {
|
|
306
|
+
const top = screen.height - BOTTOM_BAR_HEIGHT - this.keyboardRows * CELL_HEIGHT - PADDING;
|
|
307
|
+
const left = (screen.width >> 1) - ((CELL_WIDTH * this.keyboardColumns) >> 1)
|
|
308
|
+
for (let j = 0; j < this.keyboardRows * this.keyboardColumns; j++) {
|
|
309
|
+
const col = j % this.keyboardColumns;
|
|
310
|
+
const row = Math.idiv(j, this.keyboardColumns);
|
|
311
|
+
|
|
312
|
+
if (col === this.cursorColumn && row === this.cursorRow) {
|
|
313
|
+
screen.fillRect(
|
|
314
|
+
left + col * CELL_WIDTH,
|
|
315
|
+
top + row * CELL_HEIGHT,
|
|
316
|
+
CELL_WIDTH,
|
|
317
|
+
CELL_HEIGHT,
|
|
318
|
+
this.theme.colorCursor
|
|
319
|
+
)
|
|
320
|
+
}
|
|
246
321
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
322
|
+
screen.print(
|
|
323
|
+
this.getSymbolForIndex(j),
|
|
324
|
+
left + col * CELL_WIDTH + LETTER_OFFSET_X,
|
|
325
|
+
top + row * CELL_HEIGHT + LETTER_OFFSET_Y,
|
|
326
|
+
this.theme.colorAlphabet
|
|
327
|
+
)
|
|
328
|
+
}
|
|
329
|
+
}
|
|
250
330
|
|
|
251
|
-
|
|
252
|
-
this.
|
|
253
|
-
this.
|
|
331
|
+
protected drawBottomBar() {
|
|
332
|
+
this.drawBottomBarBackground();
|
|
333
|
+
this.drawShift(this.cursorRow === 3 && !(this.cursorColumn & 1));
|
|
334
|
+
this.drawConfirm(this.cursorRow === 3 && !!(this.cursorColumn & 1));
|
|
335
|
+
}
|
|
254
336
|
|
|
255
|
-
|
|
337
|
+
protected drawBottomBarBackground() {
|
|
338
|
+
screen.fillRect(0, screen.height - BOTTOM_BAR_HEIGHT, screen.width, BOTTOM_BAR_HEIGHT, this.theme.colorBottomBackground);
|
|
256
339
|
}
|
|
257
340
|
|
|
258
|
-
|
|
259
|
-
if (
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
341
|
+
protected drawShift(highlighted: boolean) {
|
|
342
|
+
if (highlighted) {
|
|
343
|
+
screen.fillRect(
|
|
344
|
+
0,
|
|
345
|
+
screen.height - BOTTOM_BAR_HEIGHT,
|
|
346
|
+
BOTTOM_BAR_BUTTON_WIDTH,
|
|
347
|
+
BOTTOM_BAR_HEIGHT,
|
|
348
|
+
this.theme.colorCursor
|
|
349
|
+
);
|
|
264
350
|
}
|
|
265
351
|
|
|
352
|
+
let shiftText = lowerShiftText;
|
|
266
353
|
if (this.upper) {
|
|
267
|
-
|
|
354
|
+
shiftText = upperShiftText;
|
|
268
355
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
this.confirmButton.image.fill(this.theme.colorCursor);
|
|
276
|
-
}
|
|
277
|
-
else {
|
|
278
|
-
this.confirmButton.image.fill(this.theme.colorBottomBackground);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
this.confirmButton.image.print(confirmText, BOTTOM_BAR_CONFIRM_X, BOTTOM_BAR_TEXT_Y);
|
|
356
|
+
screen.print(
|
|
357
|
+
shiftText,
|
|
358
|
+
BOTTOM_BAR_SHIFT_X,
|
|
359
|
+
screen.height - BOTTOM_BAR_HEIGHT + BOTTOM_BAR_TEXT_Y,
|
|
360
|
+
this.theme.colorBottomText
|
|
361
|
+
)
|
|
282
362
|
}
|
|
283
363
|
|
|
284
|
-
|
|
285
|
-
if (
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
364
|
+
protected drawConfirm(highlighted: boolean) {
|
|
365
|
+
if (highlighted) {
|
|
366
|
+
screen.fillRect(
|
|
367
|
+
CONFIRM_BUTTON_LEFT,
|
|
368
|
+
screen.height - BOTTOM_BAR_HEIGHT,
|
|
369
|
+
BOTTOM_BAR_BUTTON_WIDTH,
|
|
370
|
+
BOTTOM_BAR_HEIGHT,
|
|
371
|
+
this.theme.colorCursor
|
|
372
|
+
);
|
|
292
373
|
}
|
|
293
|
-
}
|
|
294
374
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
else {
|
|
302
|
-
this.drawInput(u.image, "", this.theme.colorInputHighlighted)
|
|
303
|
-
}
|
|
304
|
-
}
|
|
375
|
+
screen.print(
|
|
376
|
+
confirmText,
|
|
377
|
+
CONFIRM_BUTTON_LEFT + BOTTOM_BAR_CONFIRM_X,
|
|
378
|
+
screen.height - BOTTOM_BAR_HEIGHT + BOTTOM_BAR_TEXT_Y,
|
|
379
|
+
this.theme.colorBottomText
|
|
380
|
+
)
|
|
305
381
|
}
|
|
306
382
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
for (let k = 0; k < len; k++) {
|
|
310
|
-
const img = this.letters[k].image;
|
|
311
|
-
img.fill(0);
|
|
312
|
-
img.print(getCharForIndex(k, this.upper), LETTER_OFFSET_X, LETTER_OFFSET_Y);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
private drawInput(img: Image, char: string, color: number) {
|
|
317
|
-
img.fill(0);
|
|
318
|
-
img.fillRect(BLANK_PADDING, CELL_HEIGHT - 1, CELL_WIDTH - BLANK_PADDING * 2, 1, color)
|
|
319
|
-
|
|
320
|
-
if (char) {
|
|
321
|
-
img.print(char, LETTER_OFFSET_X, LETTER_OFFSET_Y, this.theme.colorInputText, font);
|
|
322
|
-
}
|
|
383
|
+
protected getSymbolForIndex(index: number) {
|
|
384
|
+
return getCharForIndex(index, this.upper);
|
|
323
385
|
}
|
|
324
386
|
|
|
325
387
|
private registerHandlers() {
|
|
@@ -346,79 +408,56 @@ namespace game {
|
|
|
346
408
|
controller.B.onEvent(SYSTEM_KEY_DOWN, () => {
|
|
347
409
|
this.delete();
|
|
348
410
|
});
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
this.frameCount = 0;
|
|
352
|
-
this.blink = true;
|
|
353
|
-
|
|
354
|
-
game.onUpdate(() => {
|
|
355
|
-
this.frameCount = (this.frameCount + 1) % 30;
|
|
356
|
-
|
|
357
|
-
if (this.frameCount === 0) {
|
|
358
|
-
this.blink = !this.blink;
|
|
359
|
-
|
|
360
|
-
this.updateSelectedInput();
|
|
361
|
-
}
|
|
362
|
-
})
|
|
363
411
|
}
|
|
364
412
|
|
|
365
|
-
|
|
413
|
+
protected moveVertical(up: boolean) {
|
|
366
414
|
if (up) {
|
|
367
|
-
if (this.cursorRow ===
|
|
368
|
-
this.
|
|
369
|
-
this.cursorRow = 2;
|
|
415
|
+
if (this.cursorRow === this.keyboardRows) {
|
|
416
|
+
this.cursorRow = this.keyboardRows - 1;
|
|
370
417
|
|
|
371
418
|
if (this.cursorColumn % 2) {
|
|
372
|
-
this.cursorColumn =
|
|
419
|
+
this.cursorColumn = this.keyboardColumns - 1;
|
|
373
420
|
}
|
|
374
421
|
else {
|
|
375
422
|
this.cursorColumn = 0;
|
|
376
423
|
}
|
|
377
|
-
|
|
378
|
-
this.updateButtons();
|
|
379
424
|
}
|
|
380
425
|
else {
|
|
381
426
|
this.cursorRow = Math.max(0, this.cursorRow - 1);
|
|
382
427
|
}
|
|
383
428
|
}
|
|
384
429
|
else {
|
|
385
|
-
this.cursorRow = Math.min(
|
|
430
|
+
this.cursorRow = Math.min(this.keyboardRows, this.cursorRow + 1);
|
|
386
431
|
|
|
387
|
-
if (this.cursorRow ===
|
|
432
|
+
if (this.cursorRow === this.keyboardRows) {
|
|
388
433
|
// Go to closest button
|
|
389
434
|
this.cursorColumn = this.cursorColumn > 5 ? 1 : 0;
|
|
390
435
|
}
|
|
391
436
|
}
|
|
392
|
-
|
|
393
|
-
this.updateCursor();
|
|
394
437
|
}
|
|
395
438
|
|
|
396
|
-
|
|
439
|
+
protected moveHorizontal(right: boolean) {
|
|
397
440
|
if (right) {
|
|
398
|
-
this.cursorColumn = (this.cursorColumn + 1) %
|
|
441
|
+
this.cursorColumn = (this.cursorColumn + 1) % this.keyboardColumns;
|
|
399
442
|
}
|
|
400
443
|
else {
|
|
401
|
-
this.cursorColumn = (this.cursorColumn + (
|
|
444
|
+
this.cursorColumn = (this.cursorColumn + (this.keyboardColumns - 1)) % this.keyboardColumns;
|
|
402
445
|
}
|
|
403
|
-
|
|
404
|
-
this.updateCursor();
|
|
405
446
|
}
|
|
406
447
|
|
|
407
|
-
|
|
448
|
+
protected confirm() {
|
|
408
449
|
if (this.cursorRow === 3) {
|
|
409
450
|
if (this.cursorColumn % 2) {
|
|
410
451
|
this.confirmPressed = true;
|
|
411
452
|
}
|
|
412
453
|
else {
|
|
413
454
|
this.upper = !this.upper;
|
|
414
|
-
this.updateKeyboard();
|
|
415
|
-
this.updateButtons();
|
|
416
455
|
}
|
|
417
456
|
}
|
|
418
457
|
else {
|
|
419
|
-
if (this.
|
|
458
|
+
if (this.selectionStart >= this.answerLength) return;
|
|
420
459
|
|
|
421
|
-
const index = this.cursorColumn + this.cursorRow *
|
|
460
|
+
const index = this.cursorColumn + this.cursorRow * this.keyboardColumns
|
|
422
461
|
const letter = getCharForIndex(index, this.upper);
|
|
423
462
|
|
|
424
463
|
if (!this.result) {
|
|
@@ -428,102 +467,27 @@ namespace game {
|
|
|
428
467
|
this.result += letter;
|
|
429
468
|
}
|
|
430
469
|
|
|
431
|
-
|
|
470
|
+
this.changeTime = game.runtime();
|
|
471
|
+
|
|
432
472
|
this.changeInputIndex(1);
|
|
433
|
-
this.drawInput(sprite.image, letter, this.theme.colorInput);
|
|
434
473
|
}
|
|
435
474
|
}
|
|
436
475
|
|
|
437
|
-
|
|
438
|
-
if (this.
|
|
439
|
-
|
|
440
|
-
if (this.inputIndex < this.answerLength) {
|
|
441
|
-
this.drawInput(this.inputs[this.inputIndex].image, "", this.theme.colorInput);
|
|
442
|
-
}
|
|
476
|
+
protected delete() {
|
|
477
|
+
if (this.selectionStart <= 0) return;
|
|
443
478
|
|
|
444
479
|
this.result = this.result.substr(0, this.result.length - 1);
|
|
445
|
-
|
|
446
480
|
this.changeInputIndex(-1);
|
|
447
481
|
}
|
|
448
482
|
|
|
449
|
-
|
|
450
|
-
this.
|
|
451
|
-
this.
|
|
452
|
-
this.blink = false;
|
|
453
|
-
this.updateSelectedInput();
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
function layoutText(message: string, width: number, height: number, color: number) {
|
|
458
|
-
const lineHeight = font.charHeight + PROMPT_LINE_SPACING;
|
|
459
|
-
|
|
460
|
-
const lineLength = Math.floor(width / font.charWidth);
|
|
461
|
-
const numLines = Math.floor(height / lineHeight);
|
|
462
|
-
|
|
463
|
-
let lines: string[] = [];
|
|
464
|
-
let word: string;
|
|
465
|
-
let line: string;
|
|
466
|
-
|
|
467
|
-
let pushWord = () => {
|
|
468
|
-
if (line) {
|
|
469
|
-
if (line.length + word.length + 1 > lineLength) {
|
|
470
|
-
lines.push(line);
|
|
471
|
-
line = word;
|
|
472
|
-
}
|
|
473
|
-
else {
|
|
474
|
-
line = line + " " + word;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
else {
|
|
478
|
-
line = word;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
word = null;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
for (let l = 0; l < message.length; l++) {
|
|
485
|
-
const char = message.charAt(l);
|
|
486
|
-
|
|
487
|
-
if (char === " ") {
|
|
488
|
-
if (word) {
|
|
489
|
-
pushWord();
|
|
490
|
-
}
|
|
491
|
-
else {
|
|
492
|
-
word = " ";
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
else if (!word) {
|
|
496
|
-
word = char;
|
|
497
|
-
}
|
|
498
|
-
else {
|
|
499
|
-
word += char;
|
|
500
|
-
}
|
|
483
|
+
protected changeInputIndex(delta: number) {
|
|
484
|
+
this.selectionStart += delta;
|
|
485
|
+
this.selectionEnd = this.selectionStart;
|
|
501
486
|
}
|
|
502
487
|
|
|
503
|
-
|
|
504
|
-
|
|
488
|
+
protected blink() {
|
|
489
|
+
return Math.idiv(game.runtime() - this.changeTime, 500) & 1;
|
|
505
490
|
}
|
|
506
|
-
|
|
507
|
-
if (line) {
|
|
508
|
-
lines.push(line);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
let maxLineWidth = 0;
|
|
512
|
-
for (let m = 0; m < lines.length; m++) {
|
|
513
|
-
maxLineWidth = Math.max(maxLineWidth, lines[m].length);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
const actualWidth = maxLineWidth * font.charWidth;
|
|
517
|
-
const actualHeight = lines.length * lineHeight;
|
|
518
|
-
|
|
519
|
-
const res = image.create(actualWidth, actualHeight);
|
|
520
|
-
|
|
521
|
-
for (let n = 0; n < lines.length; n++) {
|
|
522
|
-
if ((n + 1) > numLines) break;
|
|
523
|
-
res.print(lines[n], 0, n * lineHeight, color, font);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
return res;
|
|
527
491
|
}
|
|
528
492
|
|
|
529
493
|
function getCharForIndex(index: number, upper: boolean) {
|