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.
- package/CHANGELOG.md +287 -0
- package/LICENSE +21 -0
- package/README.md +986 -0
- package/dist/Screen/InterfaceBuilder.d.mts +43 -0
- package/dist/Screen/InterfaceBuilder.d.mts.map +1 -0
- package/dist/Screen/InterfaceBuilder.mjs +355 -0
- package/dist/Screen/InterfaceBuilder.mjs.map +1 -0
- package/dist/Screen/Pos.d.mts +52 -0
- package/dist/Screen/Pos.d.mts.map +1 -0
- package/dist/Screen/Pos.mjs +105 -0
- package/dist/Screen/Pos.mjs.map +1 -0
- package/dist/Screen/Region.d.mts +31 -0
- package/dist/Screen/Region.d.mts.map +1 -0
- package/dist/Screen/Region.mjs +73 -0
- package/dist/Screen/Region.mjs.map +1 -0
- package/dist/Screen/RegistryHolder.d.mts +6 -0
- package/dist/Screen/RegistryHolder.d.mts.map +1 -0
- package/dist/Screen/RegistryHolder.mjs +14 -0
- package/dist/Screen/RegistryHolder.mjs.map +1 -0
- package/dist/Screen/Screen.d.mts +25 -0
- package/dist/Screen/Screen.d.mts.map +1 -0
- package/dist/Screen/Screen.mjs +100 -0
- package/dist/Screen/Screen.mjs.map +1 -0
- package/dist/Screen/Size.d.mts +23 -0
- package/dist/Screen/Size.d.mts.map +1 -0
- package/dist/Screen/Size.mjs +48 -0
- package/dist/Screen/Size.mjs.map +1 -0
- package/dist/Screen/StyleRegistry.d.mts +32 -0
- package/dist/Screen/StyleRegistry.d.mts.map +1 -0
- package/dist/Screen/StyleRegistry.mjs +80 -0
- package/dist/Screen/StyleRegistry.mjs.map +1 -0
- package/dist/Screen/Window.d.mts +121 -0
- package/dist/Screen/Window.d.mts.map +1 -0
- package/dist/Screen/Window.mjs +407 -0
- package/dist/Screen/Window.mjs.map +1 -0
- package/dist/Screen/WindowManager.d.mts +86 -0
- package/dist/Screen/WindowManager.d.mts.map +1 -0
- package/dist/Screen/WindowManager.mjs +399 -0
- package/dist/Screen/WindowManager.mjs.map +1 -0
- package/dist/Screen/controls/BarChart.d.mts +29 -0
- package/dist/Screen/controls/BarChart.d.mts.map +1 -0
- package/dist/Screen/controls/BarChart.mjs +90 -0
- package/dist/Screen/controls/BarChart.mjs.map +1 -0
- package/dist/Screen/controls/Button.d.mts +16 -0
- package/dist/Screen/controls/Button.d.mts.map +1 -0
- package/dist/Screen/controls/Button.mjs +34 -0
- package/dist/Screen/controls/Button.mjs.map +1 -0
- package/dist/Screen/controls/Checkbox.d.mts +23 -0
- package/dist/Screen/controls/Checkbox.d.mts.map +1 -0
- package/dist/Screen/controls/Checkbox.mjs +55 -0
- package/dist/Screen/controls/Checkbox.mjs.map +1 -0
- package/dist/Screen/controls/LineChart.d.mts +29 -0
- package/dist/Screen/controls/LineChart.d.mts.map +1 -0
- package/dist/Screen/controls/LineChart.mjs +172 -0
- package/dist/Screen/controls/LineChart.mjs.map +1 -0
- package/dist/Screen/controls/ListBox.d.mts +34 -0
- package/dist/Screen/controls/ListBox.d.mts.map +1 -0
- package/dist/Screen/controls/ListBox.mjs +138 -0
- package/dist/Screen/controls/ListBox.mjs.map +1 -0
- package/dist/Screen/controls/ProgressBar.d.mts +26 -0
- package/dist/Screen/controls/ProgressBar.d.mts.map +1 -0
- package/dist/Screen/controls/ProgressBar.mjs +70 -0
- package/dist/Screen/controls/ProgressBar.mjs.map +1 -0
- package/dist/Screen/controls/ProgressBarV.d.mts +22 -0
- package/dist/Screen/controls/ProgressBarV.d.mts.map +1 -0
- package/dist/Screen/controls/ProgressBarV.mjs +61 -0
- package/dist/Screen/controls/ProgressBarV.mjs.map +1 -0
- package/dist/Screen/controls/Radio.d.mts +23 -0
- package/dist/Screen/controls/Radio.d.mts.map +1 -0
- package/dist/Screen/controls/Radio.mjs +55 -0
- package/dist/Screen/controls/Radio.mjs.map +1 -0
- package/dist/Screen/controls/Sparkline.d.mts +29 -0
- package/dist/Screen/controls/Sparkline.d.mts.map +1 -0
- package/dist/Screen/controls/Sparkline.mjs +82 -0
- package/dist/Screen/controls/Sparkline.mjs.map +1 -0
- package/dist/Screen/controls/Spinner.d.mts +37 -0
- package/dist/Screen/controls/Spinner.d.mts.map +1 -0
- package/dist/Screen/controls/Spinner.mjs +87 -0
- package/dist/Screen/controls/Spinner.mjs.map +1 -0
- package/dist/Screen/controls/StatusLED.d.mts +22 -0
- package/dist/Screen/controls/StatusLED.d.mts.map +1 -0
- package/dist/Screen/controls/StatusLED.mjs +51 -0
- package/dist/Screen/controls/StatusLED.mjs.map +1 -0
- package/dist/Screen/controls/Tabs.d.mts +42 -0
- package/dist/Screen/controls/Tabs.d.mts.map +1 -0
- package/dist/Screen/controls/Tabs.mjs +126 -0
- package/dist/Screen/controls/Tabs.mjs.map +1 -0
- package/dist/Screen/controls/TextArea.d.mts +41 -0
- package/dist/Screen/controls/TextArea.d.mts.map +1 -0
- package/dist/Screen/controls/TextArea.mjs +197 -0
- package/dist/Screen/controls/TextArea.mjs.map +1 -0
- package/dist/Screen/controls/TextBox.d.mts +35 -0
- package/dist/Screen/controls/TextBox.d.mts.map +1 -0
- package/dist/Screen/controls/TextBox.mjs +135 -0
- package/dist/Screen/controls/TextBox.mjs.map +1 -0
- package/dist/Screen/types.d.mts +399 -0
- package/dist/Screen/types.d.mts.map +1 -0
- package/dist/Screen/types.mjs +22 -0
- package/dist/Screen/types.mjs.map +1 -0
- package/dist/index.d.mts +26 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +41 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +72 -0
- package/src/Screen/InterfaceBuilder.mts +403 -0
- package/src/Screen/Pos.mts +119 -0
- package/src/Screen/Region.mts +88 -0
- package/src/Screen/RegistryHolder.mts +16 -0
- package/src/Screen/Screen.mts +103 -0
- package/src/Screen/Size.mts +55 -0
- package/src/Screen/StyleRegistry.mts +95 -0
- package/src/Screen/Window.mts +439 -0
- package/src/Screen/WindowManager.mts +472 -0
- package/src/Screen/controls/BarChart.mts +109 -0
- package/src/Screen/controls/Button.mts +40 -0
- package/src/Screen/controls/Checkbox.mts +66 -0
- package/src/Screen/controls/LineChart.mts +202 -0
- package/src/Screen/controls/ListBox.mts +154 -0
- package/src/Screen/controls/ProgressBar.mts +88 -0
- package/src/Screen/controls/ProgressBarV.mts +77 -0
- package/src/Screen/controls/Radio.mts +66 -0
- package/src/Screen/controls/Sparkline.mts +101 -0
- package/src/Screen/controls/Spinner.mts +102 -0
- package/src/Screen/controls/StatusLED.mts +65 -0
- package/src/Screen/controls/Tabs.mts +140 -0
- package/src/Screen/controls/TextArea.mts +194 -0
- package/src/Screen/controls/TextBox.mts +139 -0
- package/src/Screen/types.mts +416 -0
- package/src/demo.mts +171 -0
- package/src/index.mts +105 -0
- package/src/layout.yaml +236 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { BUILTIN_TEXT_CHECKED } from '../types.mjs';
|
|
2
|
+
import { Window } from '../Window.mjs';
|
|
3
|
+
import { Size } from '../Size.mjs';
|
|
4
|
+
import { getRegistry } from '../RegistryHolder.mjs';
|
|
5
|
+
/** Width of the indicator prefix: `[✓] ` = 4 columns. */
|
|
6
|
+
const INDICATOR_WIDTH = 4;
|
|
7
|
+
/** A toggle control that renders `[✓] label` (checked) or `[ ] label` (unchecked).
|
|
8
|
+
* Width is derived automatically from the label length when size is not provided.
|
|
9
|
+
* Use setChecked() / setFocused() / setDisabled() to update state. */
|
|
10
|
+
export class Checkbox extends Window {
|
|
11
|
+
checked;
|
|
12
|
+
onChange;
|
|
13
|
+
checkedStyleId;
|
|
14
|
+
/** Creates a Checkbox from window properties and optional control-specific properties.
|
|
15
|
+
* When wp.size is omitted, width is computed from wp.label automatically.
|
|
16
|
+
* Uses the global StyleRegistry set by the Screen constructor. */
|
|
17
|
+
constructor(wp, cp) {
|
|
18
|
+
const label = wp.label ?? '';
|
|
19
|
+
const size = wp.size ?? new Size(INDICATOR_WIDTH + label.length, 1);
|
|
20
|
+
super({ ...wp, size });
|
|
21
|
+
this.checked = cp?.checked ?? false;
|
|
22
|
+
this.onChange = cp?.onChange;
|
|
23
|
+
this.checkedStyleId = getRegistry().getNamed(BUILTIN_TEXT_CHECKED);
|
|
24
|
+
}
|
|
25
|
+
/** Toggles or sets the checked state. */
|
|
26
|
+
setChecked(checked) {
|
|
27
|
+
this.checked = checked;
|
|
28
|
+
}
|
|
29
|
+
/** Returns the current checked state. */
|
|
30
|
+
isChecked() {
|
|
31
|
+
return this.checked;
|
|
32
|
+
}
|
|
33
|
+
/** Processes a key press; Space toggles the checked state and fires onChange. */
|
|
34
|
+
handleKey(key) {
|
|
35
|
+
if (this.disabled)
|
|
36
|
+
return;
|
|
37
|
+
if (key === ' ' || key === 'space') {
|
|
38
|
+
this.checked = !this.checked;
|
|
39
|
+
this.onChange?.(this.checked);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/** Rebuilds the checkbox: draws indicator and label with appropriate styles. */
|
|
43
|
+
render() {
|
|
44
|
+
this.clear();
|
|
45
|
+
const indicator = this.checked ? '[✓]' : '[ ]';
|
|
46
|
+
// For indicator: use checkedStyleId when checked (and not disabled); auto-pick otherwise.
|
|
47
|
+
const indicatorStyle = (!this.disabled && this.checked) ? this.checkedStyleId : undefined;
|
|
48
|
+
// Write indicator (first 3 chars) and label separately to allow distinct colouring.
|
|
49
|
+
// Label uses auto-style (disabled/focused/normal via writeText).
|
|
50
|
+
this.writeText(indicator, { style: indicatorStyle });
|
|
51
|
+
this.writeText(` ${this.label}`, { x: INDICATOR_WIDTH - 1 });
|
|
52
|
+
super.render();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=Checkbox.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.mjs","sourceRoot":"","sources":["../../../src/Screen/controls/Checkbox.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,yDAAyD;AACzD,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B;;uEAEuE;AACvE,MAAM,OAAO,QAAS,SAAQ,MAAM;IAC3B,OAAO,CAAU;IACjB,QAAQ,CAA8B;IACtC,cAAc,CAAU;IAEhC;;uEAEmE;IACnE,YAAmB,EAAoB,EAAE,EAAuB;QAC/D,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAI,EAAE,CAAC,IAAI,IAAI,IAAI,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrE,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAEvB,IAAI,CAAC,OAAO,GAAI,EAAE,EAAE,OAAO,IAAK,KAAK,CAAC;QACtC,IAAI,CAAC,QAAQ,GAAG,EAAE,EAAE,QAAQ,CAAC;QAE7B,IAAI,CAAC,cAAc,GAAG,WAAW,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAE,CAAC;IACrE,CAAC;IAED,yCAAyC;IAClC,UAAU,CAAC,OAAgB;QACjC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,yCAAyC;IAClC,SAAS;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED,iFAAiF;IAC1E,SAAS,CAAC,GAAW;QAC3B,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO;QAC1B,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpC,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;YAC7B,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;IACF,CAAC;IAED,gFAAgF;IAChE,MAAM;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,MAAM,SAAS,GAAQ,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QACpD,0FAA0F;QAC1F,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;QAE1F,oFAAoF;QACpF,iEAAiE;QACjE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC,EAAE,eAAe,GAAG,CAAC,EAAE,CAAC,CAAC;QAE7D,KAAK,CAAC,MAAM,EAAE,CAAC;IAChB,CAAC;CACD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { LineChartProperties, WindowProperties } from '../types.mjs';
|
|
2
|
+
import { Window } from '../Window.mjs';
|
|
3
|
+
/** A read-only line chart that renders a data series using box-drawing characters.
|
|
4
|
+
* Includes a labelled Y-axis on the left and an X-axis at the bottom. */
|
|
5
|
+
export declare class LineChart extends Window {
|
|
6
|
+
private data;
|
|
7
|
+
private minValue;
|
|
8
|
+
private maxValue;
|
|
9
|
+
private lineStyleId;
|
|
10
|
+
private axisStyleId;
|
|
11
|
+
private labelStyleId;
|
|
12
|
+
/** Creates a LineChart from window properties and optional control-specific properties.
|
|
13
|
+
* Uses the global StyleRegistry set by the Screen constructor. */
|
|
14
|
+
constructor(wp: WindowProperties, cp?: LineChartProperties);
|
|
15
|
+
/** Sets the data series. Call render() afterwards. */
|
|
16
|
+
setData(data: number[]): void;
|
|
17
|
+
/** Returns the current data series. */
|
|
18
|
+
getData(): number[];
|
|
19
|
+
/** Sets the minimum Y value. Pass undefined to derive from data. Call render() afterwards. */
|
|
20
|
+
setMin(min: number | undefined): void;
|
|
21
|
+
/** Returns the configured minimum Y value, or undefined if derived from data. */
|
|
22
|
+
getMin(): number | undefined;
|
|
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=LineChart.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LineChart.d.mts","sourceRoot":"","sources":["../../../src/Screen/controls/LineChart.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAW,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAUvC;0EAC0E;AAC1E,qBAAa,SAAU,SAAQ,MAAM;IACpC,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,QAAQ,CAAqB;IAErC,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,YAAY,CAAU;IAE9B;uEACmE;gBAChD,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,mBAAmB;IAajE,sDAAsD;IAC/C,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAIpC,uCAAuC;IAChC,OAAO,IAAI,MAAM,EAAE;IAI1B,8FAA8F;IACvF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI5C,iFAAiF;IAC1E,MAAM,IAAI,MAAM,GAAG,SAAS;IAInC,8FAA8F;IACvF,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAI5C,iFAAiF;IAC1E,MAAM,IAAI,MAAM,GAAG,SAAS;IAInB,MAAM,IAAI,IAAI;CAsI9B"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Window } from '../Window.mjs';
|
|
2
|
+
import { getRegistry } from '../RegistryHolder.mjs';
|
|
3
|
+
/** Formats a Y-axis label value as a compact string. */
|
|
4
|
+
function formatYLabel(value) {
|
|
5
|
+
if (Number.isInteger(value))
|
|
6
|
+
return String(value);
|
|
7
|
+
const rounded = Math.round(value * 10) / 10;
|
|
8
|
+
return String(rounded);
|
|
9
|
+
}
|
|
10
|
+
/** A read-only line chart that renders a data series using box-drawing characters.
|
|
11
|
+
* Includes a labelled Y-axis on the left and an X-axis at the bottom. */
|
|
12
|
+
export class LineChart extends Window {
|
|
13
|
+
data;
|
|
14
|
+
minValue;
|
|
15
|
+
maxValue;
|
|
16
|
+
lineStyleId;
|
|
17
|
+
axisStyleId;
|
|
18
|
+
labelStyleId;
|
|
19
|
+
/** Creates a LineChart from window properties and optional control-specific properties.
|
|
20
|
+
* Uses the global StyleRegistry set by the Screen constructor. */
|
|
21
|
+
constructor(wp, cp) {
|
|
22
|
+
super(wp);
|
|
23
|
+
this.data = cp?.data ?? [];
|
|
24
|
+
this.minValue = cp?.min;
|
|
25
|
+
this.maxValue = cp?.max;
|
|
26
|
+
const reg = getRegistry();
|
|
27
|
+
this.lineStyleId = reg.register({ foreground: cp?.color ?? 75 });
|
|
28
|
+
this.axisStyleId = reg.register({ foreground: 245 });
|
|
29
|
+
this.labelStyleId = reg.register({ foreground: 245 });
|
|
30
|
+
}
|
|
31
|
+
/** Sets the data series. Call render() afterwards. */
|
|
32
|
+
setData(data) {
|
|
33
|
+
this.data = data;
|
|
34
|
+
}
|
|
35
|
+
/** Returns the current data series. */
|
|
36
|
+
getData() {
|
|
37
|
+
return this.data;
|
|
38
|
+
}
|
|
39
|
+
/** Sets the minimum Y value. Pass undefined to derive from data. Call render() afterwards. */
|
|
40
|
+
setMin(min) {
|
|
41
|
+
this.minValue = min;
|
|
42
|
+
}
|
|
43
|
+
/** Returns the configured minimum Y value, or undefined if derived from data. */
|
|
44
|
+
getMin() {
|
|
45
|
+
return this.minValue;
|
|
46
|
+
}
|
|
47
|
+
/** Sets the maximum Y value. Pass undefined to derive from data. Call render() afterwards. */
|
|
48
|
+
setMax(max) {
|
|
49
|
+
this.maxValue = max;
|
|
50
|
+
}
|
|
51
|
+
/** Returns the configured maximum Y value, or undefined if derived from data. */
|
|
52
|
+
getMax() {
|
|
53
|
+
return this.maxValue;
|
|
54
|
+
}
|
|
55
|
+
render() {
|
|
56
|
+
this.clear();
|
|
57
|
+
const { width, height } = this.getInnerSize();
|
|
58
|
+
const { x: ox, y: oy } = this.getInnerOffset();
|
|
59
|
+
if (width < 4 || height < 3) {
|
|
60
|
+
super.render();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// ── 1. Resolve data range ───────────────────────��───────────────────────
|
|
64
|
+
const dataMin = this.minValue ?? (this.data.length > 0 ? Math.min(...this.data) : 0);
|
|
65
|
+
const dataMax = this.maxValue ?? (this.data.length > 0 ? Math.max(...this.data) : 1);
|
|
66
|
+
const dataRange = dataMax - dataMin;
|
|
67
|
+
// ── 2. Compute Y-axis label width ────────────────────────────────────────
|
|
68
|
+
const numYLabels = Math.min(5, Math.max(2, height - 1));
|
|
69
|
+
const yLabelValues = Array.from({ length: numYLabels }, (_, k) => dataMin + (k / (numYLabels - 1)) * dataRange);
|
|
70
|
+
const yLabelStrs = yLabelValues.map(formatYLabel);
|
|
71
|
+
const maxLabelLen = Math.max(...yLabelStrs.map(s => s.length));
|
|
72
|
+
const yLabelWidth = maxLabelLen + 2; // space + label + '┤'
|
|
73
|
+
// ── 3. Plot dimensions ───────────────────────��───────────────────────────
|
|
74
|
+
const plotW = width - yLabelWidth;
|
|
75
|
+
const plotH = height - 1; // last row = X-axis
|
|
76
|
+
if (plotW < 1 || plotH < 1) {
|
|
77
|
+
super.render();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
/** Maps a value to a plot row (0 = top = dataMax). */
|
|
81
|
+
const valueToRow = (v) => {
|
|
82
|
+
if (dataRange === 0)
|
|
83
|
+
return Math.floor((plotH - 1) / 2);
|
|
84
|
+
const norm = Math.min(1, Math.max(0, (v - dataMin) / dataRange));
|
|
85
|
+
return (plotH - 1) - Math.round(norm * (plotH - 1));
|
|
86
|
+
};
|
|
87
|
+
// ── 4. Draw Y-axis ───────────────────��────────────────────────────────────
|
|
88
|
+
const yAxisAbsX = ox + yLabelWidth - 1; // column of '┤' / '│'
|
|
89
|
+
// Draw vertical line for all plot rows
|
|
90
|
+
for (let row = 0; row < plotH; row++) {
|
|
91
|
+
this.setCell(yAxisAbsX, oy + row, '│', this.axisStyleId);
|
|
92
|
+
}
|
|
93
|
+
// Overwrite with '┤' and labels at each label row
|
|
94
|
+
for (let k = 0; k < numYLabels; k++) {
|
|
95
|
+
// k=0 → bottom label (dataMin), k=numYLabels-1 → top label (dataMax)
|
|
96
|
+
const labelValue = yLabelValues[k];
|
|
97
|
+
const labelRow = valueToRow(labelValue);
|
|
98
|
+
const labelStr = yLabelStrs[k];
|
|
99
|
+
// Right-justify within maxLabelLen columns starting at ox
|
|
100
|
+
const padded = labelStr.padStart(maxLabelLen);
|
|
101
|
+
this.setCell(yAxisAbsX, oy + labelRow, '┤', this.axisStyleId);
|
|
102
|
+
for (let c = 0; c < padded.length; c++) {
|
|
103
|
+
this.setCell(ox + c, oy + labelRow, padded[c], this.labelStyleId);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ── 5. Draw X-axis ─────────────────────────���─────────────────────────���────
|
|
107
|
+
const xAxisAbsY = oy + plotH;
|
|
108
|
+
for (let col = 0; col < plotW; col++) {
|
|
109
|
+
const absX = ox + yLabelWidth + col;
|
|
110
|
+
this.setCell(absX, xAxisAbsY, col === 0 ? '┼' : '─', this.axisStyleId);
|
|
111
|
+
}
|
|
112
|
+
// Y-axis bottom corner
|
|
113
|
+
this.setCell(yAxisAbsX, xAxisAbsY, '┼', this.axisStyleId);
|
|
114
|
+
// ── 6. Plot the line ──────────────────────────────────────────────────────
|
|
115
|
+
if (this.data.length === 0) {
|
|
116
|
+
super.render();
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Build an interpolated row index for every plot column. With more
|
|
120
|
+
// columns than data points, this upsamples the series; with fewer,
|
|
121
|
+
// it averages between adjacent samples.
|
|
122
|
+
const dataRow = new Array(plotW);
|
|
123
|
+
if (this.data.length === 1) {
|
|
124
|
+
const r0 = valueToRow(this.data[0]);
|
|
125
|
+
for (let c = 0; c < plotW; c++)
|
|
126
|
+
dataRow[c] = r0;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
for (let c = 0; c < plotW; c++) {
|
|
130
|
+
const t = (c / (plotW - 1)) * (this.data.length - 1);
|
|
131
|
+
const i0 = Math.floor(t);
|
|
132
|
+
const i1 = Math.min(i0 + 1, this.data.length - 1);
|
|
133
|
+
const frac = t - i0;
|
|
134
|
+
const v = this.data[i0] * (1 - frac) + this.data[i1] * frac;
|
|
135
|
+
dataRow[c] = valueToRow(v);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/** Draws a single line cell in plot space. */
|
|
139
|
+
const plot = (col, row, ch) => {
|
|
140
|
+
this.setCell(ox + yLabelWidth + col, oy + row, ch, this.lineStyleId);
|
|
141
|
+
};
|
|
142
|
+
// Each column either holds a flat horizontal segment or a self-contained
|
|
143
|
+
// vertical step bridging the previous column's row to this column's row.
|
|
144
|
+
// The first column has no incoming step.
|
|
145
|
+
plot(0, dataRow[0], '─');
|
|
146
|
+
for (let c = 1; c < plotW; c++) {
|
|
147
|
+
const inRow = dataRow[c - 1];
|
|
148
|
+
const outRow = dataRow[c];
|
|
149
|
+
if (inRow === outRow) {
|
|
150
|
+
plot(c, outRow, '─');
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
const top = Math.min(inRow, outRow);
|
|
154
|
+
const bot = Math.max(inRow, outRow);
|
|
155
|
+
if (outRow < inRow) {
|
|
156
|
+
// Going up: line enters from left at the bottom, exits right at the top.
|
|
157
|
+
plot(c, bot, '╯'); // LEFT + TOP
|
|
158
|
+
plot(c, top, '╭'); // BOTTOM + RIGHT
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Going down: line enters from left at the top, exits right at the bottom.
|
|
162
|
+
plot(c, top, '╮'); // LEFT + BOTTOM
|
|
163
|
+
plot(c, bot, '╰'); // TOP + RIGHT
|
|
164
|
+
}
|
|
165
|
+
for (let row = top + 1; row < bot; row++) {
|
|
166
|
+
plot(c, row, '│');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
super.render();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=LineChart.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LineChart.mjs","sourceRoot":"","sources":["../../../src/Screen/controls/LineChart.mts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ListBoxProperties, WindowProperties } from '../types.mjs';
|
|
2
|
+
import { Window } from '../Window.mjs';
|
|
3
|
+
/** A scrollable list of single-line items. The selected item is highlighted and may
|
|
4
|
+
* be moved with arrow keys, PgUp/PgDn, and Home/End. Emits onChange whenever the
|
|
5
|
+
* selection index changes via keyboard. Appearance follows the same built-in style
|
|
6
|
+
* naming scheme as the other focusable controls. */
|
|
7
|
+
export declare class ListBox extends Window {
|
|
8
|
+
private items;
|
|
9
|
+
private selectedIndex;
|
|
10
|
+
private scrollTop;
|
|
11
|
+
private onChange?;
|
|
12
|
+
private selectedStyleId;
|
|
13
|
+
private focusedSelStyle;
|
|
14
|
+
/** Creates a ListBox from window properties and optional control-specific properties.
|
|
15
|
+
* Uses the global StyleRegistry set by the Screen constructor. */
|
|
16
|
+
constructor(wp: WindowProperties, cp?: ListBoxProperties);
|
|
17
|
+
/** Replaces the list items. Resets selection to 0 (or -1 if empty) and scrolls to top. */
|
|
18
|
+
setItems(items: string[]): void;
|
|
19
|
+
/** Returns the current list items. */
|
|
20
|
+
getItems(): string[];
|
|
21
|
+
/** Sets the selected index. Clamped to valid range; -1 allowed only when items is empty. */
|
|
22
|
+
setSelectedIndex(index: number): void;
|
|
23
|
+
/** Returns the currently selected index, or -1 when the list is empty. */
|
|
24
|
+
getSelectedIndex(): number;
|
|
25
|
+
/** Returns the currently selected item string, or undefined when nothing is selected. */
|
|
26
|
+
getSelectedItem(): string | undefined;
|
|
27
|
+
/** Processes a key press: arrow keys, Home/End, PgUp/PgDn move the selection. */
|
|
28
|
+
handleKey(key: string): void;
|
|
29
|
+
/** Adjusts scrollTop so that the selected index remains within the visible window. */
|
|
30
|
+
private ensureVisible;
|
|
31
|
+
/** Rebuilds the list: renders visible rows with styles. */
|
|
32
|
+
render(): void;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=ListBox.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListBox.d.mts","sourceRoot":"","sources":["../../../src/Screen/controls/ListBox.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAW,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAGvC;;;qDAGqD;AACrD,qBAAa,OAAQ,SAAQ,MAAM;IAClC,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,CAAwC;IACzD,OAAO,CAAC,eAAe,CAAW;IAClC,OAAO,CAAC,eAAe,CAAW;IAElC;uEACmE;gBAChD,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,iBAAiB;IAiB/D,0FAA0F;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAMtC,sCAAsC;IAC/B,QAAQ,IAAI,MAAM,EAAE;IAI3B,4FAA4F;IACrF,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAS5C,0EAA0E;IACnE,gBAAgB,IAAI,MAAM;IAIjC,yFAAyF;IAClF,eAAe,IAAI,MAAM,GAAG,SAAS;IAK5C,iFAAiF;IAC1E,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAqCnC,sFAAsF;IACtF,OAAO,CAAC,aAAa;IAYrB,2DAA2D;IAC3C,MAAM,IAAI,IAAI;CAiC9B"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Window } from '../Window.mjs';
|
|
2
|
+
import { getRegistry } from '../RegistryHolder.mjs';
|
|
3
|
+
/** A scrollable list of single-line items. The selected item is highlighted and may
|
|
4
|
+
* be moved with arrow keys, PgUp/PgDn, and Home/End. Emits onChange whenever the
|
|
5
|
+
* selection index changes via keyboard. Appearance follows the same built-in style
|
|
6
|
+
* naming scheme as the other focusable controls. */
|
|
7
|
+
export class ListBox extends Window {
|
|
8
|
+
items;
|
|
9
|
+
selectedIndex;
|
|
10
|
+
scrollTop;
|
|
11
|
+
onChange;
|
|
12
|
+
selectedStyleId;
|
|
13
|
+
focusedSelStyle;
|
|
14
|
+
/** Creates a ListBox from window properties and optional control-specific properties.
|
|
15
|
+
* Uses the global StyleRegistry set by the Screen constructor. */
|
|
16
|
+
constructor(wp, cp) {
|
|
17
|
+
super({
|
|
18
|
+
...wp,
|
|
19
|
+
defaultBorder: { top: true, right: true, bottom: true, left: true, style: 'single' },
|
|
20
|
+
});
|
|
21
|
+
this.items = cp?.items ?? [];
|
|
22
|
+
this.onChange = cp?.onChange;
|
|
23
|
+
this.scrollTop = 0;
|
|
24
|
+
this.selectedIndex = cp?.selectedIndex ?? (this.items.length > 0 ? 0 : -1);
|
|
25
|
+
// Selected row: muted highlight when unfocused, bright inverse when focused.
|
|
26
|
+
const reg = getRegistry();
|
|
27
|
+
this.selectedStyleId = reg.register({ background: 238, foreground: 252 });
|
|
28
|
+
this.focusedSelStyle = reg.register({ background: 75, foreground: 231, bold: true });
|
|
29
|
+
}
|
|
30
|
+
/** Replaces the list items. Resets selection to 0 (or -1 if empty) and scrolls to top. */
|
|
31
|
+
setItems(items) {
|
|
32
|
+
this.items = items;
|
|
33
|
+
this.selectedIndex = items.length > 0 ? 0 : -1;
|
|
34
|
+
this.scrollTop = 0;
|
|
35
|
+
}
|
|
36
|
+
/** Returns the current list items. */
|
|
37
|
+
getItems() {
|
|
38
|
+
return this.items;
|
|
39
|
+
}
|
|
40
|
+
/** Sets the selected index. Clamped to valid range; -1 allowed only when items is empty. */
|
|
41
|
+
setSelectedIndex(index) {
|
|
42
|
+
if (this.items.length === 0) {
|
|
43
|
+
this.selectedIndex = -1;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
this.selectedIndex = Math.max(0, Math.min(this.items.length - 1, index));
|
|
47
|
+
this.ensureVisible();
|
|
48
|
+
}
|
|
49
|
+
/** Returns the currently selected index, or -1 when the list is empty. */
|
|
50
|
+
getSelectedIndex() {
|
|
51
|
+
return this.selectedIndex;
|
|
52
|
+
}
|
|
53
|
+
/** Returns the currently selected item string, or undefined when nothing is selected. */
|
|
54
|
+
getSelectedItem() {
|
|
55
|
+
if (this.selectedIndex < 0 || this.selectedIndex >= this.items.length)
|
|
56
|
+
return undefined;
|
|
57
|
+
return this.items[this.selectedIndex];
|
|
58
|
+
}
|
|
59
|
+
/** Processes a key press: arrow keys, Home/End, PgUp/PgDn move the selection. */
|
|
60
|
+
handleKey(key) {
|
|
61
|
+
if (this.disabled || this.items.length === 0)
|
|
62
|
+
return;
|
|
63
|
+
const prev = this.selectedIndex;
|
|
64
|
+
const pageSz = Math.max(1, this.getInnerSize().height);
|
|
65
|
+
switch (key) {
|
|
66
|
+
case '\x1b[A': // Up arrow
|
|
67
|
+
this.selectedIndex = Math.max(0, this.selectedIndex - 1);
|
|
68
|
+
break;
|
|
69
|
+
case '\x1b[B': // Down arrow
|
|
70
|
+
this.selectedIndex = Math.min(this.items.length - 1, this.selectedIndex + 1);
|
|
71
|
+
break;
|
|
72
|
+
case '\x1b[H': // Home
|
|
73
|
+
case '\x1b[1~':
|
|
74
|
+
this.selectedIndex = 0;
|
|
75
|
+
break;
|
|
76
|
+
case '\x1b[F': // End
|
|
77
|
+
case '\x1b[4~':
|
|
78
|
+
this.selectedIndex = this.items.length - 1;
|
|
79
|
+
break;
|
|
80
|
+
case '\x1b[5~': // PgUp
|
|
81
|
+
this.selectedIndex = Math.max(0, this.selectedIndex - pageSz);
|
|
82
|
+
break;
|
|
83
|
+
case '\x1b[6~': // PgDn
|
|
84
|
+
this.selectedIndex = Math.min(this.items.length - 1, this.selectedIndex + pageSz);
|
|
85
|
+
break;
|
|
86
|
+
default:
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.ensureVisible();
|
|
90
|
+
if (this.selectedIndex !== prev) {
|
|
91
|
+
this.onChange?.(this.selectedIndex, this.items[this.selectedIndex]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** Adjusts scrollTop so that the selected index remains within the visible window. */
|
|
95
|
+
ensureVisible() {
|
|
96
|
+
const visibleRows = Math.max(1, this.getInnerSize().height);
|
|
97
|
+
if (this.selectedIndex < this.scrollTop) {
|
|
98
|
+
this.scrollTop = this.selectedIndex;
|
|
99
|
+
}
|
|
100
|
+
else if (this.selectedIndex >= this.scrollTop + visibleRows) {
|
|
101
|
+
this.scrollTop = this.selectedIndex - visibleRows + 1;
|
|
102
|
+
}
|
|
103
|
+
// Clamp scrollTop so we don't leave trailing empty rows unless necessary.
|
|
104
|
+
const maxScroll = Math.max(0, this.items.length - visibleRows);
|
|
105
|
+
this.scrollTop = Math.max(0, Math.min(maxScroll, this.scrollTop));
|
|
106
|
+
}
|
|
107
|
+
/** Rebuilds the list: renders visible rows with styles. */
|
|
108
|
+
render() {
|
|
109
|
+
this.clear();
|
|
110
|
+
const { width, height } = this.getInnerSize();
|
|
111
|
+
if (width < 1 || height < 1) {
|
|
112
|
+
super.render();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.ensureVisible();
|
|
116
|
+
const visibleCount = Math.min(height, this.items.length - this.scrollTop);
|
|
117
|
+
for (let row = 0; row < visibleCount; row++) {
|
|
118
|
+
const itemIndex = this.scrollTop + row;
|
|
119
|
+
const rawText = this.items[itemIndex];
|
|
120
|
+
// Truncate to fit width; pad with spaces so the highlight covers the whole row.
|
|
121
|
+
const text = rawText.length > width ? rawText.slice(0, width) : rawText;
|
|
122
|
+
const padded = text + ' '.repeat(width - text.length);
|
|
123
|
+
let style;
|
|
124
|
+
if (this.disabled) {
|
|
125
|
+
style = this.disabledStyleId;
|
|
126
|
+
}
|
|
127
|
+
else if (itemIndex === this.selectedIndex) {
|
|
128
|
+
style = this.focused ? this.focusedSelStyle : this.selectedStyleId;
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
style = this.normalStyleId;
|
|
132
|
+
}
|
|
133
|
+
this.writeText(padded, { x: 0, y: row, style });
|
|
134
|
+
}
|
|
135
|
+
super.render();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=ListBox.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListBox.mjs","sourceRoot":"","sources":["../../../src/Screen/controls/ListBox.mts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ProgressBarProperties, WindowProperties } from '../types.mjs';
|
|
2
|
+
import { Window } from '../Window.mjs';
|
|
3
|
+
/** A horizontal read-only progress bar that fills left-to-right using block characters.
|
|
4
|
+
* Displays an optional centred percentage label over the bar. */
|
|
5
|
+
export declare class ProgressBar extends Window {
|
|
6
|
+
private value;
|
|
7
|
+
private max;
|
|
8
|
+
private showLabel;
|
|
9
|
+
private fillStyleId;
|
|
10
|
+
private emptyStyleId;
|
|
11
|
+
private labelStyleId;
|
|
12
|
+
/** Creates a ProgressBar from window properties and optional control-specific properties.
|
|
13
|
+
* Recommended height: 1 (no border) or 3 (with border).
|
|
14
|
+
* Uses the global StyleRegistry set by the Screen constructor. */
|
|
15
|
+
constructor(wp: WindowProperties, cp?: ProgressBarProperties);
|
|
16
|
+
/** Sets the current value (clamped to 0–max). Call render() afterwards. */
|
|
17
|
+
setValue(value: number): void;
|
|
18
|
+
/** Returns the current value. */
|
|
19
|
+
getValue(): number;
|
|
20
|
+
/** Sets the maximum value (minimum 1). Call render() afterwards. */
|
|
21
|
+
setMax(max: number): void;
|
|
22
|
+
/** Returns the maximum value. */
|
|
23
|
+
getMax(): number;
|
|
24
|
+
render(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=ProgressBar.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProgressBar.d.mts","sourceRoot":"","sources":["../../../src/Screen/controls/ProgressBar.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAW,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAQvC;kEACkE;AAClE,qBAAa,WAAY,SAAQ,MAAM;IACtC,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,GAAG,CAAe;IAC1B,OAAO,CAAC,SAAS,CAAU;IAE3B,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,YAAY,CAAU;IAE9B;;uEAEmE;gBAChD,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,qBAAqB;IAanE,2EAA2E;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIpC,iCAAiC;IAC1B,QAAQ,IAAI,MAAM;IAIzB,oEAAoE;IAC7D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKhC,iCAAiC;IAC1B,MAAM,IAAI,MAAM;IAIP,MAAM,IAAI,IAAI;CA8B9B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Window } from '../Window.mjs';
|
|
2
|
+
import { getRegistry } from '../RegistryHolder.mjs';
|
|
3
|
+
/** Character used for the filled portion of the bar. */
|
|
4
|
+
const CHAR_FILL = '█';
|
|
5
|
+
/** Character used for the empty portion of the bar. */
|
|
6
|
+
const CHAR_EMPTY = '░';
|
|
7
|
+
/** A horizontal read-only progress bar that fills left-to-right using block characters.
|
|
8
|
+
* Displays an optional centred percentage label over the bar. */
|
|
9
|
+
export class ProgressBar extends Window {
|
|
10
|
+
value;
|
|
11
|
+
max;
|
|
12
|
+
showLabel;
|
|
13
|
+
fillStyleId;
|
|
14
|
+
emptyStyleId;
|
|
15
|
+
labelStyleId;
|
|
16
|
+
/** Creates a ProgressBar from window properties and optional control-specific properties.
|
|
17
|
+
* Recommended height: 1 (no border) or 3 (with border).
|
|
18
|
+
* Uses the global StyleRegistry set by the Screen constructor. */
|
|
19
|
+
constructor(wp, cp) {
|
|
20
|
+
super(wp);
|
|
21
|
+
this.max = Math.max(1, cp?.max ?? 100);
|
|
22
|
+
this.value = Math.max(0, Math.min(cp?.value ?? 0, this.max));
|
|
23
|
+
this.showLabel = cp?.showLabel ?? true;
|
|
24
|
+
const reg = getRegistry();
|
|
25
|
+
this.fillStyleId = reg.register({ background: cp?.fillColor ?? 75 });
|
|
26
|
+
this.emptyStyleId = reg.register({ background: cp?.emptyColor ?? 237 });
|
|
27
|
+
this.labelStyleId = reg.register({ foreground: 255, bold: true });
|
|
28
|
+
}
|
|
29
|
+
/** Sets the current value (clamped to 0–max). Call render() afterwards. */
|
|
30
|
+
setValue(value) {
|
|
31
|
+
this.value = Math.max(0, Math.min(value, this.max));
|
|
32
|
+
}
|
|
33
|
+
/** Returns the current value. */
|
|
34
|
+
getValue() {
|
|
35
|
+
return this.value;
|
|
36
|
+
}
|
|
37
|
+
/** Sets the maximum value (minimum 1). Call render() afterwards. */
|
|
38
|
+
setMax(max) {
|
|
39
|
+
this.max = Math.max(1, max);
|
|
40
|
+
this.value = Math.min(this.value, this.max);
|
|
41
|
+
}
|
|
42
|
+
/** Returns the maximum value. */
|
|
43
|
+
getMax() {
|
|
44
|
+
return this.max;
|
|
45
|
+
}
|
|
46
|
+
render() {
|
|
47
|
+
this.clear();
|
|
48
|
+
const { width, height } = this.getInnerSize();
|
|
49
|
+
const { x: ox, y: oy } = this.getInnerOffset();
|
|
50
|
+
if (width < 1 || height < 1) {
|
|
51
|
+
super.render();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const ratio = this.max > 0 ? Math.min(1, Math.max(0, this.value / this.max)) : 0;
|
|
55
|
+
const filledCols = Math.round(ratio * width);
|
|
56
|
+
const barRow = Math.floor(height / 2);
|
|
57
|
+
for (let x = 0; x < width; x++) {
|
|
58
|
+
const isFilled = x < filledCols;
|
|
59
|
+
this.setCell(ox + x, oy + barRow, isFilled ? CHAR_FILL : CHAR_EMPTY, isFilled ? this.fillStyleId : this.emptyStyleId);
|
|
60
|
+
}
|
|
61
|
+
if (this.showLabel) {
|
|
62
|
+
const pct = Math.round(ratio * 100);
|
|
63
|
+
const text = `${pct}%`;
|
|
64
|
+
const labelX = Math.max(0, Math.floor((width - text.length) / 2));
|
|
65
|
+
this.writeText(text, { x: labelX, y: barRow, style: this.labelStyleId });
|
|
66
|
+
}
|
|
67
|
+
super.render();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=ProgressBar.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProgressBar.mjs","sourceRoot":"","sources":["../../../src/Screen/controls/ProgressBar.mts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ProgressBarVProperties, WindowProperties } from '../types.mjs';
|
|
2
|
+
import { Window } from '../Window.mjs';
|
|
3
|
+
/** A vertical read-only progress bar that fills from the bottom upward using block characters. */
|
|
4
|
+
export declare class ProgressBarV extends Window {
|
|
5
|
+
private value;
|
|
6
|
+
private max;
|
|
7
|
+
private fillStyleId;
|
|
8
|
+
private emptyStyleId;
|
|
9
|
+
/** Creates a ProgressBarV from window properties and optional control-specific properties.
|
|
10
|
+
* Uses the global StyleRegistry set by the Screen constructor. */
|
|
11
|
+
constructor(wp: WindowProperties, cp?: ProgressBarVProperties);
|
|
12
|
+
/** Sets the current value (clamped to 0–max). Call render() afterwards. */
|
|
13
|
+
setValue(value: number): void;
|
|
14
|
+
/** Returns the current value. */
|
|
15
|
+
getValue(): number;
|
|
16
|
+
/** Sets the maximum value (minimum 1). Call render() afterwards. */
|
|
17
|
+
setMax(max: number): void;
|
|
18
|
+
/** Returns the maximum value. */
|
|
19
|
+
getMax(): number;
|
|
20
|
+
render(): void;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=ProgressBarV.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProgressBarV.d.mts","sourceRoot":"","sources":["../../../src/Screen/controls/ProgressBarV.mts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,gBAAgB,EAAW,MAAM,cAAc,CAAC;AACtF,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAQvC,kGAAkG;AAClG,qBAAa,YAAa,SAAQ,MAAM;IACvC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,GAAG,CAAW;IAEtB,OAAO,CAAC,WAAW,CAAW;IAC9B,OAAO,CAAC,YAAY,CAAU;IAE9B;uEACmE;gBAChD,EAAE,EAAE,gBAAgB,EAAE,EAAE,CAAC,EAAE,sBAAsB;IAWpE,2EAA2E;IACpE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIpC,iCAAiC;IAC1B,QAAQ,IAAI,MAAM;IAIzB,oEAAoE;IAC7D,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKhC,iCAAiC;IAC1B,MAAM,IAAI,MAAM;IAIP,MAAM,IAAI,IAAI;CAyB9B"}
|