take4-console 0.15.0

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 (131) hide show
  1. package/CHANGELOG.md +287 -0
  2. package/LICENSE +21 -0
  3. package/README.md +986 -0
  4. package/dist/Screen/InterfaceBuilder.d.mts +43 -0
  5. package/dist/Screen/InterfaceBuilder.d.mts.map +1 -0
  6. package/dist/Screen/InterfaceBuilder.mjs +355 -0
  7. package/dist/Screen/InterfaceBuilder.mjs.map +1 -0
  8. package/dist/Screen/Pos.d.mts +52 -0
  9. package/dist/Screen/Pos.d.mts.map +1 -0
  10. package/dist/Screen/Pos.mjs +105 -0
  11. package/dist/Screen/Pos.mjs.map +1 -0
  12. package/dist/Screen/Region.d.mts +31 -0
  13. package/dist/Screen/Region.d.mts.map +1 -0
  14. package/dist/Screen/Region.mjs +73 -0
  15. package/dist/Screen/Region.mjs.map +1 -0
  16. package/dist/Screen/RegistryHolder.d.mts +6 -0
  17. package/dist/Screen/RegistryHolder.d.mts.map +1 -0
  18. package/dist/Screen/RegistryHolder.mjs +14 -0
  19. package/dist/Screen/RegistryHolder.mjs.map +1 -0
  20. package/dist/Screen/Screen.d.mts +25 -0
  21. package/dist/Screen/Screen.d.mts.map +1 -0
  22. package/dist/Screen/Screen.mjs +100 -0
  23. package/dist/Screen/Screen.mjs.map +1 -0
  24. package/dist/Screen/Size.d.mts +23 -0
  25. package/dist/Screen/Size.d.mts.map +1 -0
  26. package/dist/Screen/Size.mjs +48 -0
  27. package/dist/Screen/Size.mjs.map +1 -0
  28. package/dist/Screen/StyleRegistry.d.mts +32 -0
  29. package/dist/Screen/StyleRegistry.d.mts.map +1 -0
  30. package/dist/Screen/StyleRegistry.mjs +80 -0
  31. package/dist/Screen/StyleRegistry.mjs.map +1 -0
  32. package/dist/Screen/Window.d.mts +121 -0
  33. package/dist/Screen/Window.d.mts.map +1 -0
  34. package/dist/Screen/Window.mjs +407 -0
  35. package/dist/Screen/Window.mjs.map +1 -0
  36. package/dist/Screen/WindowManager.d.mts +86 -0
  37. package/dist/Screen/WindowManager.d.mts.map +1 -0
  38. package/dist/Screen/WindowManager.mjs +399 -0
  39. package/dist/Screen/WindowManager.mjs.map +1 -0
  40. package/dist/Screen/controls/BarChart.d.mts +29 -0
  41. package/dist/Screen/controls/BarChart.d.mts.map +1 -0
  42. package/dist/Screen/controls/BarChart.mjs +90 -0
  43. package/dist/Screen/controls/BarChart.mjs.map +1 -0
  44. package/dist/Screen/controls/Button.d.mts +16 -0
  45. package/dist/Screen/controls/Button.d.mts.map +1 -0
  46. package/dist/Screen/controls/Button.mjs +34 -0
  47. package/dist/Screen/controls/Button.mjs.map +1 -0
  48. package/dist/Screen/controls/Checkbox.d.mts +23 -0
  49. package/dist/Screen/controls/Checkbox.d.mts.map +1 -0
  50. package/dist/Screen/controls/Checkbox.mjs +55 -0
  51. package/dist/Screen/controls/Checkbox.mjs.map +1 -0
  52. package/dist/Screen/controls/LineChart.d.mts +29 -0
  53. package/dist/Screen/controls/LineChart.d.mts.map +1 -0
  54. package/dist/Screen/controls/LineChart.mjs +172 -0
  55. package/dist/Screen/controls/LineChart.mjs.map +1 -0
  56. package/dist/Screen/controls/ListBox.d.mts +34 -0
  57. package/dist/Screen/controls/ListBox.d.mts.map +1 -0
  58. package/dist/Screen/controls/ListBox.mjs +138 -0
  59. package/dist/Screen/controls/ListBox.mjs.map +1 -0
  60. package/dist/Screen/controls/ProgressBar.d.mts +26 -0
  61. package/dist/Screen/controls/ProgressBar.d.mts.map +1 -0
  62. package/dist/Screen/controls/ProgressBar.mjs +70 -0
  63. package/dist/Screen/controls/ProgressBar.mjs.map +1 -0
  64. package/dist/Screen/controls/ProgressBarV.d.mts +22 -0
  65. package/dist/Screen/controls/ProgressBarV.d.mts.map +1 -0
  66. package/dist/Screen/controls/ProgressBarV.mjs +61 -0
  67. package/dist/Screen/controls/ProgressBarV.mjs.map +1 -0
  68. package/dist/Screen/controls/Radio.d.mts +23 -0
  69. package/dist/Screen/controls/Radio.d.mts.map +1 -0
  70. package/dist/Screen/controls/Radio.mjs +55 -0
  71. package/dist/Screen/controls/Radio.mjs.map +1 -0
  72. package/dist/Screen/controls/Sparkline.d.mts +29 -0
  73. package/dist/Screen/controls/Sparkline.d.mts.map +1 -0
  74. package/dist/Screen/controls/Sparkline.mjs +82 -0
  75. package/dist/Screen/controls/Sparkline.mjs.map +1 -0
  76. package/dist/Screen/controls/Spinner.d.mts +37 -0
  77. package/dist/Screen/controls/Spinner.d.mts.map +1 -0
  78. package/dist/Screen/controls/Spinner.mjs +87 -0
  79. package/dist/Screen/controls/Spinner.mjs.map +1 -0
  80. package/dist/Screen/controls/StatusLED.d.mts +22 -0
  81. package/dist/Screen/controls/StatusLED.d.mts.map +1 -0
  82. package/dist/Screen/controls/StatusLED.mjs +51 -0
  83. package/dist/Screen/controls/StatusLED.mjs.map +1 -0
  84. package/dist/Screen/controls/Tabs.d.mts +42 -0
  85. package/dist/Screen/controls/Tabs.d.mts.map +1 -0
  86. package/dist/Screen/controls/Tabs.mjs +126 -0
  87. package/dist/Screen/controls/Tabs.mjs.map +1 -0
  88. package/dist/Screen/controls/TextArea.d.mts +41 -0
  89. package/dist/Screen/controls/TextArea.d.mts.map +1 -0
  90. package/dist/Screen/controls/TextArea.mjs +197 -0
  91. package/dist/Screen/controls/TextArea.mjs.map +1 -0
  92. package/dist/Screen/controls/TextBox.d.mts +35 -0
  93. package/dist/Screen/controls/TextBox.d.mts.map +1 -0
  94. package/dist/Screen/controls/TextBox.mjs +135 -0
  95. package/dist/Screen/controls/TextBox.mjs.map +1 -0
  96. package/dist/Screen/types.d.mts +399 -0
  97. package/dist/Screen/types.d.mts.map +1 -0
  98. package/dist/Screen/types.mjs +22 -0
  99. package/dist/Screen/types.mjs.map +1 -0
  100. package/dist/index.d.mts +26 -0
  101. package/dist/index.d.mts.map +1 -0
  102. package/dist/index.mjs +41 -0
  103. package/dist/index.mjs.map +1 -0
  104. package/package.json +72 -0
  105. package/src/Screen/InterfaceBuilder.mts +403 -0
  106. package/src/Screen/Pos.mts +119 -0
  107. package/src/Screen/Region.mts +88 -0
  108. package/src/Screen/RegistryHolder.mts +16 -0
  109. package/src/Screen/Screen.mts +103 -0
  110. package/src/Screen/Size.mts +55 -0
  111. package/src/Screen/StyleRegistry.mts +95 -0
  112. package/src/Screen/Window.mts +439 -0
  113. package/src/Screen/WindowManager.mts +472 -0
  114. package/src/Screen/controls/BarChart.mts +109 -0
  115. package/src/Screen/controls/Button.mts +40 -0
  116. package/src/Screen/controls/Checkbox.mts +66 -0
  117. package/src/Screen/controls/LineChart.mts +202 -0
  118. package/src/Screen/controls/ListBox.mts +154 -0
  119. package/src/Screen/controls/ProgressBar.mts +88 -0
  120. package/src/Screen/controls/ProgressBarV.mts +77 -0
  121. package/src/Screen/controls/Radio.mts +66 -0
  122. package/src/Screen/controls/Sparkline.mts +101 -0
  123. package/src/Screen/controls/Spinner.mts +102 -0
  124. package/src/Screen/controls/StatusLED.mts +65 -0
  125. package/src/Screen/controls/Tabs.mts +140 -0
  126. package/src/Screen/controls/TextArea.mts +194 -0
  127. package/src/Screen/controls/TextBox.mts +139 -0
  128. package/src/Screen/types.mts +416 -0
  129. package/src/demo.mts +171 -0
  130. package/src/index.mts +105 -0
  131. package/src/layout.yaml +236 -0
@@ -0,0 +1,399 @@
1
+ // ── Key parsing ───────────────────────────────────────────────────────────────
2
+ /**
3
+ * Parses a raw stdin Buffer into an array of key strings.
4
+ * Regular characters are emitted as-is; escape sequences (CSI, SS3) are
5
+ * captured as multi-character strings (e.g. '\x1b[A' for the up arrow).
6
+ */
7
+ function parseKeys(data) {
8
+ const keys = [];
9
+ let i = 0;
10
+ while (i < data.length) {
11
+ const byte = data[i];
12
+ if (byte !== 0x1b) {
13
+ // UTF-8 multi-byte character start (0xC2–0xF4).
14
+ if (byte >= 0xc2 && byte <= 0xf4) {
15
+ const len = byte >= 0xf0 ? 4 : byte >= 0xe0 ? 3 : 2;
16
+ const end = Math.min(i + len, data.length);
17
+ keys.push(data.subarray(i, end).toString('utf8'));
18
+ i = end;
19
+ }
20
+ else {
21
+ keys.push(String.fromCharCode(byte));
22
+ i++;
23
+ }
24
+ continue;
25
+ }
26
+ // Escape byte (0x1B).
27
+ if (i + 1 >= data.length) {
28
+ keys.push('\x1b');
29
+ i++;
30
+ continue;
31
+ }
32
+ const next = data[i + 1];
33
+ if (next === 0x5b) {
34
+ // CSI sequence: ESC [ <params> <final>
35
+ // Final byte is in range 0x40–0x7E.
36
+ let j = i + 2;
37
+ while (j < data.length && (data[j] < 0x40 || data[j] > 0x7e))
38
+ j++;
39
+ if (j < data.length) {
40
+ keys.push(data.subarray(i, j + 1).toString('utf8'));
41
+ i = j + 1;
42
+ }
43
+ else {
44
+ keys.push('\x1b');
45
+ i++;
46
+ }
47
+ }
48
+ else if (next === 0x4f) {
49
+ // SS3 sequence: ESC O <char> (F1–F4).
50
+ if (i + 2 < data.length) {
51
+ keys.push(data.subarray(i, i + 3).toString('utf8'));
52
+ i += 3;
53
+ }
54
+ else {
55
+ keys.push('\x1b');
56
+ i++;
57
+ }
58
+ }
59
+ else {
60
+ // Lone ESC (or unrecognised Alt combo — emit just ESC).
61
+ keys.push('\x1b');
62
+ i++;
63
+ }
64
+ }
65
+ return keys;
66
+ }
67
+ /**
68
+ * Attempts to parse an SGR mouse escape sequence.
69
+ * SGR format: \x1b[<btn;x;yM (press) or \x1b[<btn;x;ym (release / move).
70
+ * Returns null if the key string is not a mouse sequence.
71
+ */
72
+ function parseMouseEvent(key) {
73
+ const m = key.match(/^\x1b\[<(\d+);(\d+);(\d+)([Mm])$/);
74
+ if (!m)
75
+ return null;
76
+ const raw = parseInt(m[1], 10);
77
+ const x = parseInt(m[2], 10) - 1; // terminal uses 1-based coords
78
+ const y = parseInt(m[3], 10) - 1;
79
+ const press = m[4] === 'M';
80
+ const isMove = (raw & 32) !== 0;
81
+ return {
82
+ type: isMove ? 'move' : press ? 'press' : 'release',
83
+ button: raw & 3,
84
+ x,
85
+ y,
86
+ shift: (raw & 4) !== 0,
87
+ alt: (raw & 8) !== 0,
88
+ ctrl: (raw & 16) !== 0,
89
+ };
90
+ }
91
+ // ── WindowManager ─────────────────────────────────────────────────────────────
92
+ /** Manages the application input loop, focus, and modal dialogs.
93
+ *
94
+ * Usage:
95
+ * 1. Create a Screen and add windows/controls to it.
96
+ * 2. Instantiate WindowManager and call register() for each focusable control.
97
+ * 3. Call run() to start the event loop.
98
+ *
99
+ * Focus is cycled with Tab / Shift-Tab. Keys are dispatched to the focused
100
+ * control's handleKey() method. Ctrl+C (or a configured exitKey) stops the loop.
101
+ */
102
+ export class WindowManager {
103
+ screen;
104
+ exitKeys;
105
+ onExit;
106
+ onKey;
107
+ onMouse;
108
+ mouseEnabled;
109
+ mainEntries;
110
+ mainFocusIndex;
111
+ dialogStack;
112
+ running;
113
+ /** Bound reference kept so we can remove the listener in stop(). */
114
+ boundHandleInput;
115
+ /** Bound SIGTERM handler for clean shutdown. */
116
+ boundSigterm;
117
+ /** Creates a WindowManager for the given Screen.
118
+ * Does not start the input loop; call run() to begin. */
119
+ constructor(screen, options) {
120
+ this.screen = screen;
121
+ this.exitKeys = options?.exitKeys ?? ['\x03']; // Ctrl+C
122
+ this.onExit = options?.onExit;
123
+ this.onKey = options?.onKey;
124
+ this.onMouse = options?.onMouse;
125
+ this.mouseEnabled = options?.mouse ?? false;
126
+ this.mainEntries = [];
127
+ this.mainFocusIndex = -1;
128
+ this.dialogStack = [];
129
+ this.running = false;
130
+ this.boundHandleInput = this.handleInput.bind(this);
131
+ this.boundSigterm = () => this.stop();
132
+ }
133
+ // ── Registration ───────────────────────────────────────────────────────────
134
+ /** Registers a focusable control for Tab-cycling in the main (non-dialog) context.
135
+ * Pass the chain of parent Windows so the absolute screen position can be computed
136
+ * for mouse hit-testing (innermost parent first, outermost last is NOT required —
137
+ * just pass them in nesting order from the control outward). */
138
+ register(control, ...parents) {
139
+ const absX = parents.reduce((acc, p) => acc + p.x, 0) + control.x;
140
+ const absY = parents.reduce((acc, p) => acc + p.y, 0) + control.y;
141
+ this.mainEntries.push({ control, absX, absY });
142
+ }
143
+ /** Removes a previously registered control from the main focus list. */
144
+ unregister(control) {
145
+ const idx = this.mainEntries.findIndex(e => e.control === control);
146
+ if (idx !== -1)
147
+ this.mainEntries.splice(idx, 1);
148
+ if (this.mainFocusIndex >= this.mainEntries.length) {
149
+ this.mainFocusIndex = this.mainEntries.length - 1;
150
+ }
151
+ }
152
+ // ── Focus ──────────────────────────────────────────────────────────────────
153
+ /** Returns the currently focused control, or null if no control has focus. */
154
+ getFocused() {
155
+ const entries = this.activeEntries();
156
+ const idx = this.getActiveFocusIndex();
157
+ return idx >= 0 ? entries[idx].control : null;
158
+ }
159
+ /** Moves focus to the given control if it belongs to the active context and is enabled. */
160
+ setFocus(control) {
161
+ const entries = this.activeEntries();
162
+ const idx = entries.findIndex(e => e.control === control);
163
+ if (idx === -1 || entries[idx].control.isDisabled())
164
+ return;
165
+ this.blurCurrent();
166
+ this.setActiveFocusIndex(idx);
167
+ control.setFocused(true);
168
+ }
169
+ // ── Dialog ─────────────────────────────────────────────────────────────────
170
+ /** Opens a modal dialog: blurs the current context, adds the dialog Window to
171
+ * the Screen, and activates a new focus context for the provided controls.
172
+ *
173
+ * @param dialog - The Window to display (will be added to Screen via addChild).
174
+ * @param controls - Array of { control, parents? } entries within the dialog.
175
+ * parents are Windows between the dialog and the control, used
176
+ * to compute absolute screen positions for mouse hit-testing. */
177
+ openDialog(dialog, controls) {
178
+ this.blurCurrent();
179
+ this.screen.addChild(dialog);
180
+ const entries = controls.map(({ control, parents = [] }) => ({
181
+ control,
182
+ absX: dialog.x + parents.reduce((acc, p) => acc + p.x, 0) + control.x,
183
+ absY: dialog.y + parents.reduce((acc, p) => acc + p.y, 0) + control.y,
184
+ }));
185
+ this.dialogStack.push({ dialog, entries, focusIndex: -1 });
186
+ this.initializeFocus();
187
+ this.renderFrame();
188
+ }
189
+ /** Closes the topmost modal dialog, removes it from the Screen, and restores
190
+ * the previous focus context. */
191
+ closeDialog() {
192
+ const level = this.dialogStack.pop();
193
+ if (!level)
194
+ return;
195
+ // Blur whichever control had focus inside the dialog.
196
+ const idx = level.focusIndex;
197
+ if (idx >= 0 && idx < level.entries.length) {
198
+ level.entries[idx].control.setFocused(false);
199
+ }
200
+ this.screen.removeChild(level.dialog);
201
+ // Re-focus whatever was focused in the restored context.
202
+ const entries = this.activeEntries();
203
+ const fi = this.getActiveFocusIndex();
204
+ if (fi >= 0 && fi < entries.length) {
205
+ entries[fi].control.setFocused(true);
206
+ }
207
+ this.renderFrame();
208
+ }
209
+ // ── Lifecycle ──────────────────────────────────────────────────────────────
210
+ /** Starts the input loop: enables raw mode, optional mouse tracking, and renders
211
+ * the initial frame. The method returns immediately; events are handled
212
+ * asynchronously via stdin. */
213
+ run() {
214
+ if (this.running)
215
+ return;
216
+ this.running = true;
217
+ if (process.stdin.isTTY) {
218
+ process.stdin.setRawMode(true);
219
+ }
220
+ process.stdin.resume();
221
+ process.stdin.on('data', this.boundHandleInput);
222
+ process.once('SIGTERM', this.boundSigterm);
223
+ process.stdout.write('\x1b[?1049h'); // switch to alternate screen buffer
224
+ if (this.mouseEnabled) {
225
+ // Enable button-press tracking + SGR extended coordinates.
226
+ process.stdout.write('\x1b[?1000h\x1b[?1006h');
227
+ }
228
+ process.stdout.write('\x1b[?25l'); // hide cursor
229
+ this.initializeFocus();
230
+ this.renderFrame();
231
+ }
232
+ /** Stops the input loop, restores terminal state, and fires the onExit callback.
233
+ * Safe to call even when the loop was not started (skips terminal teardown). */
234
+ stop() {
235
+ const wasRunning = this.running;
236
+ this.running = false;
237
+ if (wasRunning) {
238
+ process.stdin.off('data', this.boundHandleInput);
239
+ if (process.stdin.isTTY) {
240
+ process.stdin.setRawMode(false);
241
+ }
242
+ process.stdin.pause();
243
+ process.off('SIGTERM', this.boundSigterm);
244
+ if (this.mouseEnabled) {
245
+ process.stdout.write('\x1b[?1006l\x1b[?1000l');
246
+ }
247
+ process.stdout.write('\x1b[?25h'); // show cursor
248
+ process.stdout.write('\x1b[?1049l'); // restore normal screen buffer
249
+ }
250
+ this.onExit?.();
251
+ }
252
+ // ── Input handling ─────────────────────────────────────────────────────────
253
+ /** Processes a raw stdin Buffer. Exposed as public so tests can drive it directly
254
+ * without needing a real TTY. Tab / Shift-Tab navigation works even before run()
255
+ * because moveFocus() handles the "no current focus" case. Dispatching to a
256
+ * control triggers lazy focus initialization so the key reaches the right target. */
257
+ handleInput(data) {
258
+ for (const key of parseKeys(data)) {
259
+ // Check for mouse event first (SGR sequence starting with \x1b[<).
260
+ if (this.mouseEnabled) {
261
+ const mouse = parseMouseEvent(key);
262
+ if (mouse) {
263
+ this.onMouse?.(mouse);
264
+ this.handleMouseEvent(mouse);
265
+ continue;
266
+ }
267
+ }
268
+ this.onKey?.(key);
269
+ // Exit keys.
270
+ if (this.exitKeys.includes(key)) {
271
+ this.stop();
272
+ return;
273
+ }
274
+ // Focus navigation – moveFocus handles index -1 correctly.
275
+ if (key === '\t') {
276
+ this.moveFocus(1);
277
+ this.renderFrame();
278
+ continue;
279
+ }
280
+ if (key === '\x1b[Z') { // Shift-Tab
281
+ this.moveFocus(-1);
282
+ this.renderFrame();
283
+ continue;
284
+ }
285
+ // Dispatch to focused control.
286
+ // Lazy init here so Tab tests can rely on -1 start without double-move.
287
+ if (this.getActiveFocusIndex() < 0) {
288
+ this.initializeFocus();
289
+ }
290
+ const entries = this.activeEntries();
291
+ const fi = this.getActiveFocusIndex();
292
+ const entry = entries[fi];
293
+ if (entry?.control.handleKey) {
294
+ entry.control.handleKey(key);
295
+ this.renderFrame();
296
+ }
297
+ }
298
+ }
299
+ // ── Private helpers ────────────────────────────────────────────────────────
300
+ /** Returns the FocusEntry array for the active context (topmost dialog or main). */
301
+ activeEntries() {
302
+ if (this.dialogStack.length > 0) {
303
+ return this.dialogStack[this.dialogStack.length - 1].entries;
304
+ }
305
+ return this.mainEntries;
306
+ }
307
+ /** Returns the focus index for the active context. */
308
+ getActiveFocusIndex() {
309
+ if (this.dialogStack.length > 0) {
310
+ return this.dialogStack[this.dialogStack.length - 1].focusIndex;
311
+ }
312
+ return this.mainFocusIndex;
313
+ }
314
+ /** Sets the focus index for the active context. */
315
+ setActiveFocusIndex(index) {
316
+ if (this.dialogStack.length > 0) {
317
+ this.dialogStack[this.dialogStack.length - 1].focusIndex = index;
318
+ }
319
+ else {
320
+ this.mainFocusIndex = index;
321
+ }
322
+ }
323
+ /** Removes focus from the currently focused control without moving it elsewhere. */
324
+ blurCurrent() {
325
+ const entries = this.activeEntries();
326
+ const fi = this.getActiveFocusIndex();
327
+ if (fi >= 0 && fi < entries.length) {
328
+ entries[fi].control.setFocused(false);
329
+ }
330
+ }
331
+ /** Finds the first already-focused (or first non-disabled) control and focuses it. */
332
+ initializeFocus() {
333
+ const entries = this.activeEntries();
334
+ if (entries.length === 0)
335
+ return;
336
+ // Prefer a control that is already marked as focused.
337
+ for (let i = 0; i < entries.length; i++) {
338
+ if (entries[i].control.isFocused() && !entries[i].control.isDisabled()) {
339
+ this.setActiveFocusIndex(i);
340
+ return;
341
+ }
342
+ }
343
+ // Otherwise focus the first enabled control.
344
+ for (let i = 0; i < entries.length; i++) {
345
+ if (!entries[i].control.isDisabled()) {
346
+ this.setActiveFocusIndex(i);
347
+ entries[i].control.setFocused(true);
348
+ return;
349
+ }
350
+ }
351
+ }
352
+ /** Moves focus by delta (+1 for Tab, -1 for Shift-Tab), skipping disabled controls. */
353
+ moveFocus(delta) {
354
+ const entries = this.activeEntries();
355
+ if (entries.length === 0)
356
+ return;
357
+ const current = this.getActiveFocusIndex();
358
+ // Blur current control.
359
+ if (current >= 0 && current < entries.length) {
360
+ entries[current].control.setFocused(false);
361
+ }
362
+ const count = entries.length;
363
+ let next = current < 0 ? (delta > 0 ? -1 : count) : current;
364
+ let attempts = 0;
365
+ do {
366
+ next = ((next + delta) % count + count) % count;
367
+ attempts++;
368
+ } while (entries[next].control.isDisabled() && attempts <= count);
369
+ if (!entries[next].control.isDisabled()) {
370
+ this.setActiveFocusIndex(next);
371
+ entries[next].control.setFocused(true);
372
+ }
373
+ }
374
+ /** Handles a parsed mouse event: left click moves focus to the clicked control. */
375
+ handleMouseEvent(event) {
376
+ if (event.type !== 'press' || event.button !== 0)
377
+ return;
378
+ const entries = this.activeEntries();
379
+ for (let i = 0; i < entries.length; i++) {
380
+ const { control, absX, absY } = entries[i];
381
+ if (control.isDisabled())
382
+ continue;
383
+ const { width, height } = control.getSize();
384
+ if (event.x >= absX && event.x < absX + width &&
385
+ event.y >= absY && event.y < absY + height) {
386
+ this.blurCurrent();
387
+ this.setActiveFocusIndex(i);
388
+ control.setFocused(true);
389
+ this.renderFrame();
390
+ return;
391
+ }
392
+ }
393
+ }
394
+ /** Renders a frame to the screen. */
395
+ renderFrame() {
396
+ this.screen.render();
397
+ }
398
+ }
399
+ //# sourceMappingURL=WindowManager.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WindowManager.mjs","sourceRoot":"","sources":["../../src/Screen/WindowManager.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { BarChartProperties, WindowProperties } from '../types.mjs';
2
+ import { Window } from '../Window.mjs';
3
+ /** A read-only vertical bar chart. Each bar fills from the bottom upward using block characters.
4
+ * The last row of the inner area is reserved for single-character bar labels. */
5
+ export declare class BarChart extends Window {
6
+ private data;
7
+ private labels;
8
+ private max;
9
+ private barWidth;
10
+ private barStyleId;
11
+ private labelStyleId;
12
+ /** Creates a BarChart from window properties and optional control-specific properties.
13
+ * Uses the global StyleRegistry set by the Screen constructor. */
14
+ constructor(wp: WindowProperties, cp?: BarChartProperties);
15
+ /** Sets the data values. Call render() afterwards. */
16
+ setData(data: number[]): void;
17
+ /** Returns the current data values. */
18
+ getData(): number[];
19
+ /** Sets the bar labels. Call render() afterwards. */
20
+ setLabels(labels: string[]): void;
21
+ /** Returns the current bar labels. */
22
+ getLabels(): string[];
23
+ /** Sets the maximum Y value. Pass undefined to derive from data. Call render() afterwards. */
24
+ setMax(max: number | undefined): void;
25
+ /** Returns the configured maximum Y value, or undefined if derived from data. */
26
+ getMax(): number | undefined;
27
+ render(): void;
28
+ }
29
+ //# sourceMappingURL=BarChart.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BarChart.d.mts","sourceRoot":"","sources":["../../../src/Screen/controls/BarChart.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAW,MAAM,cAAc,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAMvC;kFACkF;AAClF,qBAAa,QAAS,SAAQ,MAAM;IACnC,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,GAAG,CAA0B;IACrC,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,YAAY,CAAU;IAE9B;uEACmE;gBAChD,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,kBAAkB;IAahE,sDAAsD;IAC/C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAIpC,uCAAuC;IAChC,OAAO,IAAI,MAAM,EAAE;IAI1B,qDAAqD;IAC9C,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAIxC,sCAAsC;IAC/B,SAAS,IAAI,MAAM,EAAE;IAI5B,8FAA8F;IACvF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI5C,iFAAiF;IAC1E,MAAM,IAAI,MAAM,GAAG,SAAS;IAInB,MAAM,IAAI,IAAI;CA6C9B"}
@@ -0,0 +1,90 @@
1
+ import { Window } from '../Window.mjs';
2
+ import { getRegistry } from '../RegistryHolder.mjs';
3
+ /** Character used for bar cells. */
4
+ const CHAR_BAR = '█';
5
+ /** A read-only vertical bar chart. Each bar fills from the bottom upward using block characters.
6
+ * The last row of the inner area is reserved for single-character bar labels. */
7
+ export class BarChart extends Window {
8
+ data;
9
+ labels;
10
+ max;
11
+ barWidth;
12
+ barStyleId;
13
+ labelStyleId;
14
+ /** Creates a BarChart from window properties and optional control-specific properties.
15
+ * Uses the global StyleRegistry set by the Screen constructor. */
16
+ constructor(wp, cp) {
17
+ super(wp);
18
+ this.data = cp?.data ?? [];
19
+ this.labels = cp?.labels ?? [];
20
+ this.max = cp?.max;
21
+ this.barWidth = Math.max(1, cp?.barWidth ?? 1);
22
+ const reg = getRegistry();
23
+ this.barStyleId = reg.register({ foreground: cp?.barColor ?? 75 });
24
+ this.labelStyleId = reg.register({ foreground: 245 });
25
+ }
26
+ /** Sets the data values. Call render() afterwards. */
27
+ setData(data) {
28
+ this.data = data;
29
+ }
30
+ /** Returns the current data values. */
31
+ getData() {
32
+ return this.data;
33
+ }
34
+ /** Sets the bar labels. Call render() afterwards. */
35
+ setLabels(labels) {
36
+ this.labels = labels;
37
+ }
38
+ /** Returns the current bar labels. */
39
+ getLabels() {
40
+ return this.labels;
41
+ }
42
+ /** Sets the maximum Y value. Pass undefined to derive from data. Call render() afterwards. */
43
+ setMax(max) {
44
+ this.max = max;
45
+ }
46
+ /** Returns the configured maximum Y value, or undefined if derived from data. */
47
+ getMax() {
48
+ return this.max;
49
+ }
50
+ render() {
51
+ this.clear();
52
+ const { width, height } = this.getInnerSize();
53
+ const { x: ox, y: oy } = this.getInnerOffset();
54
+ if (this.data.length === 0 || width < 1 || height < 2) {
55
+ super.render();
56
+ return;
57
+ }
58
+ const dataMax = this.max ?? Math.max(...this.data, 0);
59
+ const plotH = height - 1; // last row is label row
60
+ const barStep = this.barWidth + 1;
61
+ for (let i = 0; i < this.data.length; i++) {
62
+ const startCol = i * barStep;
63
+ if (startCol + this.barWidth > width)
64
+ break;
65
+ const norm = dataMax > 0 ? Math.min(1, Math.max(0, this.data[i] / dataMax)) : 0;
66
+ const filledRows = Math.round(norm * plotH);
67
+ // Draw bar cells
68
+ for (let row = 0; row < plotH; row++) {
69
+ const isFilled = row >= (plotH - filledRows);
70
+ for (let col = 0; col < this.barWidth; col++) {
71
+ const absX = ox + startCol + col;
72
+ if (absX - ox >= width)
73
+ break;
74
+ this.setCell(absX, oy + row, isFilled ? CHAR_BAR : ' ', isFilled ? this.barStyleId : 0);
75
+ }
76
+ }
77
+ // Draw label in the bottom row (truncated to barWidth)
78
+ const rawLabel = this.labels[i] ?? '';
79
+ for (let col = 0; col < this.barWidth; col++) {
80
+ const absX = ox + startCol + col;
81
+ if (absX - ox >= width)
82
+ break;
83
+ const ch = col < rawLabel.length ? rawLabel[col] : ' ';
84
+ this.setCell(absX, oy + plotH, ch, this.labelStyleId);
85
+ }
86
+ }
87
+ super.render();
88
+ }
89
+ }
90
+ //# sourceMappingURL=BarChart.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BarChart.mjs","sourceRoot":"","sources":["../../../src/Screen/controls/BarChart.mts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { ButtonProperties, WindowProperties } from '../types.mjs';
2
+ import { Window } from '../Window.mjs';
3
+ /** A clickable button that renders a centred label inside a rounded border.
4
+ * Visual state (normal / focused / disabled) is controlled via setters.
5
+ * Appearance can be customised by overriding the built-in named styles via Screen.setBuiltinStyle(). */
6
+ export declare class Button extends Window {
7
+ private onPress?;
8
+ /** Creates a Button from window properties and optional control-specific properties.
9
+ * Uses the global StyleRegistry set by the Screen constructor. */
10
+ constructor(wp: WindowProperties, cp?: ButtonProperties);
11
+ /** Processes a key press; Enter or Space triggers the onPress callback. */
12
+ handleKey(key: string): void;
13
+ /** Rebuilds the button: writes centred label with appropriate style, then composites. */
14
+ render(): void;
15
+ }
16
+ //# sourceMappingURL=Button.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.d.mts","sourceRoot":"","sources":["../../../src/Screen/controls/Button.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC;;yGAEyG;AACzG,qBAAa,MAAO,SAAQ,MAAM;IACjC,OAAO,CAAC,OAAO,CAAC,CAAa;IAE7B;uEACmE;gBAChD,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,gBAAgB;IAS9D,2EAA2E;IACpE,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOnC,yFAAyF;IACzE,MAAM,IAAI,IAAI;CAU9B"}
@@ -0,0 +1,34 @@
1
+ import { Window } from '../Window.mjs';
2
+ /** A clickable button that renders a centred label inside a rounded border.
3
+ * Visual state (normal / focused / disabled) is controlled via setters.
4
+ * Appearance can be customised by overriding the built-in named styles via Screen.setBuiltinStyle(). */
5
+ export class Button extends Window {
6
+ onPress;
7
+ /** Creates a Button from window properties and optional control-specific properties.
8
+ * Uses the global StyleRegistry set by the Screen constructor. */
9
+ constructor(wp, cp) {
10
+ super({
11
+ ...wp,
12
+ defaultBorder: { top: true, right: true, bottom: true, left: true, style: 'rounded' },
13
+ });
14
+ this.onPress = cp?.onPress;
15
+ }
16
+ /** Processes a key press; Enter or Space triggers the onPress callback. */
17
+ handleKey(key) {
18
+ if (this.disabled)
19
+ return;
20
+ if (key === '\r' || key === '\n' || key === ' ' || key === 'enter' || key === 'space') {
21
+ this.onPress?.();
22
+ }
23
+ }
24
+ /** Rebuilds the button: writes centred label with appropriate style, then composites. */
25
+ render() {
26
+ this.clear();
27
+ const { width, height } = this.getInnerSize();
28
+ const labelX = Math.max(0, Math.floor((width - this.label.length) / 2));
29
+ const labelY = Math.floor(height / 2);
30
+ this.writeText(this.label, { x: labelX, y: labelY });
31
+ super.render();
32
+ }
33
+ }
34
+ //# sourceMappingURL=Button.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.mjs","sourceRoot":"","sources":["../../../src/Screen/controls/Button.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC;;yGAEyG;AACzG,MAAM,OAAO,MAAO,SAAQ,MAAM;IACzB,OAAO,CAAc;IAE7B;uEACmE;IACnE,YAAmB,EAAoB,EAAE,EAAqB;QAC7D,KAAK,CAAC;YACL,GAAG,EAAE;YACL,aAAa,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE;SACrF,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,GAAG,EAAE,EAAE,OAAO,CAAC;IAC5B,CAAC;IAED,2EAA2E;IACpE,SAAS,CAAC,GAAW;QAC3B,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACvF,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAClB,CAAC;IACF,CAAC;IAED,yFAAyF;IACzE,MAAM;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAErD,KAAK,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;CACD"}
@@ -0,0 +1,23 @@
1
+ import type { CheckboxProperties, WindowProperties } from '../types.mjs';
2
+ import { Window } from '../Window.mjs';
3
+ /** A toggle control that renders `[✓] label` (checked) or `[ ] label` (unchecked).
4
+ * Width is derived automatically from the label length when size is not provided.
5
+ * Use setChecked() / setFocused() / setDisabled() to update state. */
6
+ export declare class Checkbox extends Window {
7
+ private checked;
8
+ private onChange?;
9
+ private checkedStyleId;
10
+ /** Creates a Checkbox from window properties and optional control-specific properties.
11
+ * When wp.size is omitted, width is computed from wp.label automatically.
12
+ * Uses the global StyleRegistry set by the Screen constructor. */
13
+ constructor(wp: WindowProperties, cp?: CheckboxProperties);
14
+ /** Toggles or sets the checked state. */
15
+ setChecked(checked: boolean): void;
16
+ /** Returns the current checked state. */
17
+ isChecked(): boolean;
18
+ /** Processes a key press; Space toggles the checked state and fires onChange. */
19
+ handleKey(key: string): void;
20
+ /** Rebuilds the checkbox: draws indicator and label with appropriate styles. */
21
+ render(): void;
22
+ }
23
+ //# sourceMappingURL=Checkbox.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Checkbox.d.mts","sourceRoot":"","sources":["../../../src/Screen/controls/Checkbox.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAW,MAAM,cAAc,CAAC;AAElF,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAOvC;;uEAEuE;AACvE,qBAAa,QAAS,SAAQ,MAAM;IACnC,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAC,CAA6B;IAC9C,OAAO,CAAC,cAAc,CAAU;IAEhC;;uEAEmE;gBAChD,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,kBAAkB;IAWhE,yCAAyC;IAClC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIzC,yCAAyC;IAClC,SAAS,IAAI,OAAO;IAI3B,iFAAiF;IAC1E,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAQnC,gFAAgF;IAChE,MAAM,IAAI,IAAI;CAc9B"}