@opentui/core 0.1.23 → 0.1.25
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/3d.js +1 -1
- package/3d.js.map +1 -1
- package/Renderable.d.ts +32 -23
- package/ansi.d.ts +2 -17
- package/buffer.d.ts +3 -1
- package/{index-a6ydv6yb.js → index-6kvgbzah.js} +1279 -618
- package/index-6kvgbzah.js.map +39 -0
- package/index.d.ts +1 -0
- package/index.js +376 -151
- package/index.js.map +11 -11
- package/lib/KeyHandler.d.ts +10 -3
- package/lib/env.d.ts +41 -0
- package/lib/index.d.ts +1 -1
- package/lib/parse.keypress-kitty.d.ts +2 -0
- package/lib/parse.keypress.d.ts +11 -1
- package/lib/renderable.validations.d.ts +12 -0
- package/package.json +14 -12
- package/renderables/ASCIIFont.d.ts +1 -1
- package/renderables/Input.d.ts +2 -2
- package/renderables/ScrollBox.d.ts +3 -1
- package/renderables/Slider.d.ts +24 -11
- package/renderables/Text.d.ts +18 -3
- package/renderables/TextNode.d.ts +13 -4
- package/renderer.d.ts +17 -2
- package/testing/mock-keys.d.ts +1 -0
- package/testing/mock-mouse.d.ts +38 -0
- package/testing/test-renderer.d.ts +16 -3
- package/testing.d.ts +3 -0
- package/testing.js +353 -0
- package/testing.js.map +12 -0
- package/text-buffer.d.ts +8 -9
- package/types.d.ts +5 -0
- package/utils.d.ts +2 -0
- package/zig.d.ts +16 -10
- package/index-a6ydv6yb.js.map +0 -37
- package/lib/TrackedNode.d.ts +0 -36
- /package/{singleton.d.ts → lib/singleton.d.ts} +0 -0
package/index.js
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
KeyHandler,
|
|
14
14
|
LayoutEvents,
|
|
15
15
|
LogLevel,
|
|
16
|
-
MeasureMode,
|
|
17
16
|
MouseButton,
|
|
18
17
|
MouseEvent,
|
|
19
18
|
MouseParser,
|
|
@@ -28,7 +27,6 @@ import {
|
|
|
28
27
|
TerminalConsole,
|
|
29
28
|
TextAttributes,
|
|
30
29
|
TextBuffer,
|
|
31
|
-
TrackedNode,
|
|
32
30
|
bg,
|
|
33
31
|
bgBlack,
|
|
34
32
|
bgBlue,
|
|
@@ -56,16 +54,19 @@ import {
|
|
|
56
54
|
coordinateToCharacterIndex,
|
|
57
55
|
createCliRenderer,
|
|
58
56
|
createTextAttributes,
|
|
59
|
-
createTrackedNode,
|
|
60
57
|
cyan,
|
|
61
58
|
delegate,
|
|
62
59
|
dim,
|
|
60
|
+
env,
|
|
61
|
+
envRegistry,
|
|
62
|
+
exports_src,
|
|
63
63
|
fg,
|
|
64
64
|
fonts,
|
|
65
|
+
generateEnvColored,
|
|
66
|
+
generateEnvMarkdown,
|
|
65
67
|
getBorderFromSides,
|
|
66
68
|
getBorderSides,
|
|
67
69
|
getCharacterPositions,
|
|
68
|
-
getKeyHandler,
|
|
69
70
|
getObjectsInViewport,
|
|
70
71
|
green,
|
|
71
72
|
h,
|
|
@@ -73,15 +74,7 @@ import {
|
|
|
73
74
|
hexToRgb,
|
|
74
75
|
hsvToRgb,
|
|
75
76
|
instantiate,
|
|
76
|
-
isDimensionType,
|
|
77
|
-
isFlexBasisType,
|
|
78
|
-
isMarginType,
|
|
79
|
-
isOverflowType,
|
|
80
|
-
isPaddingType,
|
|
81
|
-
isPositionType,
|
|
82
|
-
isPositionTypeType,
|
|
83
77
|
isRenderable,
|
|
84
|
-
isSizeType,
|
|
85
78
|
isStyledText,
|
|
86
79
|
isVNode,
|
|
87
80
|
isValidPercentage,
|
|
@@ -108,6 +101,7 @@ import {
|
|
|
108
101
|
parseUnit,
|
|
109
102
|
parseWrap,
|
|
110
103
|
red,
|
|
104
|
+
registerEnvVar,
|
|
111
105
|
renderFontToFrameBuffer,
|
|
112
106
|
resolveRenderLib,
|
|
113
107
|
reverse,
|
|
@@ -117,10 +111,11 @@ import {
|
|
|
117
111
|
stringToStyledText,
|
|
118
112
|
t,
|
|
119
113
|
underline,
|
|
114
|
+
visualizeRenderableTree,
|
|
120
115
|
white,
|
|
121
116
|
wrapWithDelegates,
|
|
122
117
|
yellow
|
|
123
|
-
} from "./index-
|
|
118
|
+
} from "./index-6kvgbzah.js";
|
|
124
119
|
// src/post/filters.ts
|
|
125
120
|
function applyScanlines(buffer, strength = 0.8, step = 2) {
|
|
126
121
|
const width = buffer.width;
|
|
@@ -1378,7 +1373,7 @@ class BoxRenderable extends Renderable {
|
|
|
1378
1373
|
};
|
|
1379
1374
|
}
|
|
1380
1375
|
applyYogaBorders() {
|
|
1381
|
-
const node = this.
|
|
1376
|
+
const node = this.yogaNode;
|
|
1382
1377
|
node.setBorder(Edge.Left, this.borderSides.left ? 1 : 0);
|
|
1383
1378
|
node.setBorder(Edge.Right, this.borderSides.right ? 1 : 0);
|
|
1384
1379
|
node.setBorder(Edge.Top, this.borderSides.top ? 1 : 0);
|
|
@@ -1386,7 +1381,7 @@ class BoxRenderable extends Renderable {
|
|
|
1386
1381
|
this.requestRender();
|
|
1387
1382
|
}
|
|
1388
1383
|
applyYogaGap(options) {
|
|
1389
|
-
const node = this.
|
|
1384
|
+
const node = this.yogaNode;
|
|
1390
1385
|
if (isGapType(options.gap)) {
|
|
1391
1386
|
node.setGap(Gutter.All, options.gap);
|
|
1392
1387
|
}
|
|
@@ -1399,19 +1394,19 @@ class BoxRenderable extends Renderable {
|
|
|
1399
1394
|
}
|
|
1400
1395
|
set gap(gap) {
|
|
1401
1396
|
if (isGapType(gap)) {
|
|
1402
|
-
this.
|
|
1397
|
+
this.yogaNode.setGap(Gutter.All, gap);
|
|
1403
1398
|
this.requestRender();
|
|
1404
1399
|
}
|
|
1405
1400
|
}
|
|
1406
1401
|
set rowGap(rowGap) {
|
|
1407
1402
|
if (isGapType(rowGap)) {
|
|
1408
|
-
this.
|
|
1403
|
+
this.yogaNode.setGap(Gutter.Row, rowGap);
|
|
1409
1404
|
this.requestRender();
|
|
1410
1405
|
}
|
|
1411
1406
|
}
|
|
1412
1407
|
set columnGap(columnGap) {
|
|
1413
1408
|
if (isGapType(columnGap)) {
|
|
1414
|
-
this.
|
|
1409
|
+
this.yogaNode.setGap(Gutter.Column, columnGap);
|
|
1415
1410
|
this.requestRender();
|
|
1416
1411
|
}
|
|
1417
1412
|
}
|
|
@@ -1437,7 +1432,7 @@ class FrameBufferRenderable extends Renderable {
|
|
|
1437
1432
|
this.requestRender();
|
|
1438
1433
|
}
|
|
1439
1434
|
renderSelf(buffer) {
|
|
1440
|
-
if (!this.visible)
|
|
1435
|
+
if (!this.visible || this.isDestroyed)
|
|
1441
1436
|
return;
|
|
1442
1437
|
buffer.drawFrameBuffer(this.x, this.y, this.frameBuffer);
|
|
1443
1438
|
}
|
|
@@ -1465,16 +1460,16 @@ function styledTextToTextNodes(styledText) {
|
|
|
1465
1460
|
|
|
1466
1461
|
class TextNodeRenderable extends BaseRenderable {
|
|
1467
1462
|
[BrandedTextNodeRenderable] = true;
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1463
|
+
_fg;
|
|
1464
|
+
_bg;
|
|
1465
|
+
_attributes;
|
|
1471
1466
|
_children = [];
|
|
1472
1467
|
parent = null;
|
|
1473
1468
|
constructor(options) {
|
|
1474
1469
|
super(options);
|
|
1475
|
-
this.
|
|
1476
|
-
this.
|
|
1477
|
-
this.
|
|
1470
|
+
this._fg = options.fg ? parseColor(options.fg) : undefined;
|
|
1471
|
+
this._bg = options.bg ? parseColor(options.bg) : undefined;
|
|
1472
|
+
this._attributes = options.attributes ?? 0;
|
|
1478
1473
|
}
|
|
1479
1474
|
get children() {
|
|
1480
1475
|
return this._children;
|
|
@@ -1528,6 +1523,13 @@ class TextNodeRenderable extends BaseRenderable {
|
|
|
1528
1523
|
}
|
|
1529
1524
|
throw new Error("TextNodeRenderable only accepts strings, TextNodeRenderable instances, or StyledText instances");
|
|
1530
1525
|
}
|
|
1526
|
+
replace(obj, index) {
|
|
1527
|
+
this._children[index] = obj;
|
|
1528
|
+
if (typeof obj !== "string") {
|
|
1529
|
+
obj.parent = this;
|
|
1530
|
+
}
|
|
1531
|
+
this.requestRender();
|
|
1532
|
+
}
|
|
1531
1533
|
insertBefore(child, anchorNode) {
|
|
1532
1534
|
if (!anchorNode || !isTextNodeRenderable(anchorNode)) {
|
|
1533
1535
|
throw new Error("Anchor must be a TextNodeRenderable");
|
|
@@ -1569,9 +1571,9 @@ class TextNodeRenderable extends BaseRenderable {
|
|
|
1569
1571
|
}
|
|
1570
1572
|
mergeStyles(parentStyle) {
|
|
1571
1573
|
return {
|
|
1572
|
-
fg: this.
|
|
1573
|
-
bg: this.
|
|
1574
|
-
attributes: this.
|
|
1574
|
+
fg: this._fg ?? parentStyle.fg,
|
|
1575
|
+
bg: this._bg ?? parentStyle.bg,
|
|
1576
|
+
attributes: this._attributes | parentStyle.attributes
|
|
1575
1577
|
};
|
|
1576
1578
|
}
|
|
1577
1579
|
gatherWithInheritedStyle(parentStyle = { fg: undefined, bg: undefined, attributes: 0 }) {
|
|
@@ -1618,13 +1620,46 @@ class TextNodeRenderable extends BaseRenderable {
|
|
|
1618
1620
|
getRenderable(id) {
|
|
1619
1621
|
return this._children.find((child) => typeof child !== "string" && child.id === id);
|
|
1620
1622
|
}
|
|
1623
|
+
get fg() {
|
|
1624
|
+
return this._fg;
|
|
1625
|
+
}
|
|
1626
|
+
set fg(fg2) {
|
|
1627
|
+
if (!fg2) {
|
|
1628
|
+
this._fg = undefined;
|
|
1629
|
+
this.requestRender();
|
|
1630
|
+
return;
|
|
1631
|
+
}
|
|
1632
|
+
this._fg = parseColor(fg2);
|
|
1633
|
+
this.requestRender();
|
|
1634
|
+
}
|
|
1635
|
+
set bg(bg2) {
|
|
1636
|
+
if (!bg2) {
|
|
1637
|
+
this._bg = undefined;
|
|
1638
|
+
this.requestRender();
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
this._bg = parseColor(bg2);
|
|
1642
|
+
this.requestRender();
|
|
1643
|
+
}
|
|
1644
|
+
get bg() {
|
|
1645
|
+
return this._bg;
|
|
1646
|
+
}
|
|
1647
|
+
set attributes(attributes) {
|
|
1648
|
+
this._attributes = attributes;
|
|
1649
|
+
this.requestRender();
|
|
1650
|
+
}
|
|
1651
|
+
get attributes() {
|
|
1652
|
+
return this._attributes;
|
|
1653
|
+
}
|
|
1621
1654
|
}
|
|
1622
1655
|
|
|
1623
1656
|
class RootTextNodeRenderable extends TextNodeRenderable {
|
|
1624
1657
|
ctx;
|
|
1625
|
-
|
|
1658
|
+
textParent;
|
|
1659
|
+
constructor(ctx, options, textParent) {
|
|
1626
1660
|
super(options);
|
|
1627
1661
|
this.ctx = ctx;
|
|
1662
|
+
this.textParent = textParent;
|
|
1628
1663
|
}
|
|
1629
1664
|
requestRender() {
|
|
1630
1665
|
this.markDirty();
|
|
@@ -1636,14 +1671,17 @@ class RootTextNodeRenderable extends TextNodeRenderable {
|
|
|
1636
1671
|
class TextRenderable extends Renderable {
|
|
1637
1672
|
selectable = true;
|
|
1638
1673
|
_text;
|
|
1674
|
+
_hasManualStyledText = false;
|
|
1639
1675
|
_defaultFg;
|
|
1640
1676
|
_defaultBg;
|
|
1641
1677
|
_defaultAttributes;
|
|
1642
1678
|
_selectionBg;
|
|
1643
1679
|
_selectionFg;
|
|
1680
|
+
_wrap = false;
|
|
1681
|
+
_wrapMode = "word";
|
|
1644
1682
|
lastLocalSelection = null;
|
|
1645
1683
|
textBuffer;
|
|
1646
|
-
_lineInfo = { lineStarts: [], lineWidths: [] };
|
|
1684
|
+
_lineInfo = { lineStarts: [], lineWidths: [], maxLineWidth: 0 };
|
|
1647
1685
|
rootTextNode;
|
|
1648
1686
|
_defaultOptions = {
|
|
1649
1687
|
content: "",
|
|
@@ -1652,32 +1690,41 @@ class TextRenderable extends Renderable {
|
|
|
1652
1690
|
selectionBg: undefined,
|
|
1653
1691
|
selectionFg: undefined,
|
|
1654
1692
|
selectable: true,
|
|
1655
|
-
attributes: 0
|
|
1693
|
+
attributes: 0,
|
|
1694
|
+
wrap: true,
|
|
1695
|
+
wrapMode: "word"
|
|
1656
1696
|
};
|
|
1657
1697
|
constructor(ctx, options) {
|
|
1658
1698
|
super(ctx, options);
|
|
1659
1699
|
const content = options.content ?? this._defaultOptions.content;
|
|
1660
1700
|
const styledText = typeof content === "string" ? stringToStyledText(content) : content;
|
|
1661
1701
|
this._text = styledText;
|
|
1702
|
+
this._hasManualStyledText = !!options.content;
|
|
1662
1703
|
this._defaultFg = parseColor(options.fg ?? this._defaultOptions.fg);
|
|
1663
1704
|
this._defaultBg = parseColor(options.bg ?? this._defaultOptions.bg);
|
|
1664
1705
|
this._defaultAttributes = options.attributes ?? this._defaultOptions.attributes;
|
|
1665
1706
|
this._selectionBg = options.selectionBg ? parseColor(options.selectionBg) : this._defaultOptions.selectionBg;
|
|
1666
1707
|
this._selectionFg = options.selectionFg ? parseColor(options.selectionFg) : this._defaultOptions.selectionFg;
|
|
1667
1708
|
this.selectable = options.selectable ?? this._defaultOptions.selectable;
|
|
1668
|
-
this.
|
|
1709
|
+
this._wrap = options.wrap ?? this._defaultOptions.wrap;
|
|
1710
|
+
this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
|
|
1711
|
+
this.textBuffer = TextBuffer.create(this._ctx.widthMethod);
|
|
1712
|
+
this.textBuffer.setWrapMode(this._wrapMode);
|
|
1713
|
+
this.setupMeasureFunc();
|
|
1669
1714
|
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
1670
1715
|
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
1671
1716
|
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
1672
|
-
this.setupMeasureFunc();
|
|
1673
1717
|
this.rootTextNode = new RootTextNodeRenderable(ctx, {
|
|
1674
1718
|
id: `${this.id}-root`,
|
|
1675
1719
|
fg: this._defaultFg,
|
|
1676
1720
|
bg: this._defaultBg,
|
|
1677
1721
|
attributes: this._defaultAttributes
|
|
1678
|
-
});
|
|
1722
|
+
}, this);
|
|
1679
1723
|
this.updateTextBuffer(styledText);
|
|
1680
1724
|
this._text.mount(this);
|
|
1725
|
+
if (this._wrap && this.width > 0) {
|
|
1726
|
+
this.updateWrapWidth(this.width);
|
|
1727
|
+
}
|
|
1681
1728
|
this.updateTextInfo();
|
|
1682
1729
|
}
|
|
1683
1730
|
updateTextBuffer(styledText) {
|
|
@@ -1697,7 +1744,11 @@ class TextRenderable extends Renderable {
|
|
|
1697
1744
|
get chunks() {
|
|
1698
1745
|
return this._text.chunks;
|
|
1699
1746
|
}
|
|
1747
|
+
get textNode() {
|
|
1748
|
+
return this.rootTextNode;
|
|
1749
|
+
}
|
|
1700
1750
|
set content(value) {
|
|
1751
|
+
this._hasManualStyledText = true;
|
|
1701
1752
|
const styledText = typeof value === "string" ? stringToStyledText(value) : value;
|
|
1702
1753
|
if (this._text !== styledText) {
|
|
1703
1754
|
this._text = styledText;
|
|
@@ -1711,9 +1762,11 @@ class TextRenderable extends Renderable {
|
|
|
1711
1762
|
}
|
|
1712
1763
|
set fg(value) {
|
|
1713
1764
|
const newColor = parseColor(value ?? this._defaultOptions.fg);
|
|
1765
|
+
this.rootTextNode.fg = newColor;
|
|
1714
1766
|
if (this._defaultFg !== newColor) {
|
|
1715
1767
|
this._defaultFg = newColor;
|
|
1716
1768
|
this.textBuffer.setDefaultFg(this._defaultFg);
|
|
1769
|
+
this.rootTextNode.fg = newColor;
|
|
1717
1770
|
this.requestRender();
|
|
1718
1771
|
}
|
|
1719
1772
|
}
|
|
@@ -1748,9 +1801,11 @@ class TextRenderable extends Renderable {
|
|
|
1748
1801
|
}
|
|
1749
1802
|
set bg(value) {
|
|
1750
1803
|
const newColor = parseColor(value ?? this._defaultOptions.bg);
|
|
1804
|
+
this.rootTextNode.bg = newColor;
|
|
1751
1805
|
if (this._defaultBg !== newColor) {
|
|
1752
1806
|
this._defaultBg = newColor;
|
|
1753
1807
|
this.textBuffer.setDefaultBg(this._defaultBg);
|
|
1808
|
+
this.rootTextNode.bg = newColor;
|
|
1754
1809
|
this.requestRender();
|
|
1755
1810
|
}
|
|
1756
1811
|
}
|
|
@@ -1761,6 +1816,27 @@ class TextRenderable extends Renderable {
|
|
|
1761
1816
|
if (this._defaultAttributes !== value) {
|
|
1762
1817
|
this._defaultAttributes = value;
|
|
1763
1818
|
this.textBuffer.setDefaultAttributes(this._defaultAttributes);
|
|
1819
|
+
this.rootTextNode.attributes = value;
|
|
1820
|
+
this.requestRender();
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
get wrap() {
|
|
1824
|
+
return this._wrap;
|
|
1825
|
+
}
|
|
1826
|
+
set wrap(value) {
|
|
1827
|
+
if (this._wrap !== value) {
|
|
1828
|
+
this._wrap = value;
|
|
1829
|
+
this.textBuffer.setWrapWidth(this._wrap ? this.width : null);
|
|
1830
|
+
this.requestRender();
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
get wrapMode() {
|
|
1834
|
+
return this._wrapMode;
|
|
1835
|
+
}
|
|
1836
|
+
set wrapMode(value) {
|
|
1837
|
+
if (this._wrapMode !== value) {
|
|
1838
|
+
this._wrapMode = value;
|
|
1839
|
+
this.textBuffer.setWrapMode(this._wrapMode);
|
|
1764
1840
|
this.requestRender();
|
|
1765
1841
|
}
|
|
1766
1842
|
}
|
|
@@ -1780,40 +1856,42 @@ class TextRenderable extends Renderable {
|
|
|
1780
1856
|
return this.textBuffer.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
|
|
1781
1857
|
}
|
|
1782
1858
|
updateTextInfo() {
|
|
1783
|
-
const lineInfo = this.textBuffer.lineInfo;
|
|
1784
|
-
this._lineInfo.lineStarts = lineInfo.lineStarts;
|
|
1785
|
-
this._lineInfo.lineWidths = lineInfo.lineWidths;
|
|
1786
1859
|
if (this.lastLocalSelection) {
|
|
1787
1860
|
const changed = this.updateLocalSelection(this.lastLocalSelection);
|
|
1788
1861
|
if (changed) {
|
|
1789
1862
|
this.requestRender();
|
|
1790
1863
|
}
|
|
1791
1864
|
}
|
|
1792
|
-
this.
|
|
1865
|
+
this.yogaNode.markDirty();
|
|
1793
1866
|
this.requestRender();
|
|
1794
1867
|
}
|
|
1868
|
+
updateLineInfo() {
|
|
1869
|
+
const lineInfo = this.textBuffer.lineInfo;
|
|
1870
|
+
this._lineInfo.lineStarts = lineInfo.lineStarts;
|
|
1871
|
+
this._lineInfo.lineWidths = lineInfo.lineWidths;
|
|
1872
|
+
this._lineInfo.maxLineWidth = lineInfo.maxLineWidth;
|
|
1873
|
+
}
|
|
1874
|
+
updateWrapWidth(width) {
|
|
1875
|
+
this.textBuffer.setWrapWidth(width);
|
|
1876
|
+
this.updateLineInfo();
|
|
1877
|
+
}
|
|
1795
1878
|
setupMeasureFunc() {
|
|
1796
1879
|
const measureFunc = (width, widthMode, height, heightMode) => {
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
} else if (widthMode === MeasureMode.AtMost) {
|
|
1804
|
-
measuredWidth = Math.min(maxLineWidth, width);
|
|
1805
|
-
}
|
|
1806
|
-
if (heightMode === MeasureMode.Exactly) {
|
|
1807
|
-
measuredHeight = height;
|
|
1808
|
-
} else if (heightMode === MeasureMode.AtMost) {
|
|
1809
|
-
measuredHeight = Math.min(numLines, height);
|
|
1880
|
+
if (this._wrap) {
|
|
1881
|
+
if (this.width !== width) {
|
|
1882
|
+
this.updateWrapWidth(width);
|
|
1883
|
+
}
|
|
1884
|
+
} else {
|
|
1885
|
+
this.updateLineInfo();
|
|
1810
1886
|
}
|
|
1887
|
+
const measuredWidth = this._lineInfo.maxLineWidth;
|
|
1888
|
+
const measuredHeight = this._lineInfo.lineStarts.length;
|
|
1811
1889
|
return {
|
|
1812
1890
|
width: Math.max(1, measuredWidth),
|
|
1813
1891
|
height: Math.max(1, measuredHeight)
|
|
1814
1892
|
};
|
|
1815
1893
|
};
|
|
1816
|
-
this.
|
|
1894
|
+
this.yogaNode.setMeasureFunc(measureFunc);
|
|
1817
1895
|
}
|
|
1818
1896
|
insertChunk(chunk, index) {
|
|
1819
1897
|
this.textBuffer.insertChunkGroup(index ?? this.textBuffer.chunkGroupCount, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
|
|
@@ -1837,14 +1915,15 @@ class TextRenderable extends Renderable {
|
|
|
1837
1915
|
this.clearChunks(this._text);
|
|
1838
1916
|
}
|
|
1839
1917
|
updateTextFromNodes() {
|
|
1840
|
-
if (this.rootTextNode.isDirty) {
|
|
1918
|
+
if (this.rootTextNode.isDirty && !this._hasManualStyledText) {
|
|
1841
1919
|
const chunks = this.rootTextNode.gatherWithInheritedStyle({
|
|
1842
1920
|
fg: this._defaultFg,
|
|
1843
1921
|
bg: this._defaultBg,
|
|
1844
1922
|
attributes: this._defaultAttributes
|
|
1845
1923
|
});
|
|
1846
1924
|
this.textBuffer.setStyledText(new StyledText(chunks));
|
|
1847
|
-
this.
|
|
1925
|
+
this.updateLineInfo();
|
|
1926
|
+
this.yogaNode.markDirty();
|
|
1848
1927
|
}
|
|
1849
1928
|
}
|
|
1850
1929
|
add(obj, index) {
|
|
@@ -1860,6 +1939,9 @@ class TextRenderable extends Renderable {
|
|
|
1860
1939
|
this.rootTextNode.insertBefore(obj, anchor);
|
|
1861
1940
|
return this.rootTextNode.children.indexOf(obj);
|
|
1862
1941
|
}
|
|
1942
|
+
getTextChildren() {
|
|
1943
|
+
return this.rootTextNode.getChildren();
|
|
1944
|
+
}
|
|
1863
1945
|
clear() {
|
|
1864
1946
|
this.rootTextNode.clear();
|
|
1865
1947
|
const emptyStyledText = stringToStyledText("");
|
|
@@ -1894,9 +1976,9 @@ class TextRenderable extends Renderable {
|
|
|
1894
1976
|
getSelection() {
|
|
1895
1977
|
return this.textBuffer.getSelection();
|
|
1896
1978
|
}
|
|
1897
|
-
|
|
1979
|
+
onLifecyclePass = () => {
|
|
1898
1980
|
this.updateTextFromNodes();
|
|
1899
|
-
}
|
|
1981
|
+
};
|
|
1900
1982
|
render(buffer, deltaTime) {
|
|
1901
1983
|
if (!this.visible)
|
|
1902
1984
|
return;
|
|
@@ -1937,6 +2019,7 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
|
|
|
1937
2019
|
const text = options.text || "";
|
|
1938
2020
|
const measurements = measureText({ text, font });
|
|
1939
2021
|
super(ctx, {
|
|
2022
|
+
flexShrink: 0,
|
|
1940
2023
|
...options,
|
|
1941
2024
|
width: measurements.width || 1,
|
|
1942
2025
|
height: measurements.height || 1,
|
|
@@ -2030,6 +2113,8 @@ class ASCIIFontRenderable extends FrameBufferRenderable {
|
|
|
2030
2113
|
this.renderFontToBuffer();
|
|
2031
2114
|
}
|
|
2032
2115
|
renderFontToBuffer() {
|
|
2116
|
+
if (this.isDestroyed)
|
|
2117
|
+
return;
|
|
2033
2118
|
this.frameBuffer.clear(this._bg);
|
|
2034
2119
|
renderFontToFrameBuffer(this.frameBuffer, {
|
|
2035
2120
|
text: this._text,
|
|
@@ -2976,43 +3061,71 @@ var defaultTrackBackgroundColor = RGBA.fromHex("#252527");
|
|
|
2976
3061
|
|
|
2977
3062
|
class SliderRenderable extends Renderable {
|
|
2978
3063
|
orientation;
|
|
2979
|
-
|
|
2980
|
-
|
|
3064
|
+
_value;
|
|
3065
|
+
_min;
|
|
3066
|
+
_max;
|
|
3067
|
+
_viewPortSize;
|
|
2981
3068
|
_backgroundColor;
|
|
2982
3069
|
_foregroundColor;
|
|
2983
3070
|
_onChange;
|
|
2984
3071
|
constructor(ctx, options) {
|
|
2985
|
-
super(ctx, options);
|
|
3072
|
+
super(ctx, { flexShrink: 0, ...options });
|
|
2986
3073
|
this.orientation = options.orientation;
|
|
2987
|
-
this.
|
|
2988
|
-
this.
|
|
3074
|
+
this._min = options.min ?? 0;
|
|
3075
|
+
this._max = options.max ?? 100;
|
|
3076
|
+
this._value = options.value ?? this._min;
|
|
3077
|
+
this._viewPortSize = options.viewPortSize ?? Math.max(1, (this._max - this._min) * 0.1);
|
|
2989
3078
|
this._onChange = options.onChange;
|
|
2990
3079
|
this._backgroundColor = options.backgroundColor ? parseColor(options.backgroundColor) : defaultTrackBackgroundColor;
|
|
2991
3080
|
this._foregroundColor = options.foregroundColor ? parseColor(options.foregroundColor) : defaultThumbBackgroundColor;
|
|
2992
3081
|
this.setupMouseHandling();
|
|
2993
3082
|
}
|
|
2994
|
-
get
|
|
2995
|
-
return this.
|
|
3083
|
+
get value() {
|
|
3084
|
+
return this._value;
|
|
2996
3085
|
}
|
|
2997
|
-
set
|
|
2998
|
-
const clamped = Math.max(
|
|
2999
|
-
if (clamped !== this.
|
|
3000
|
-
this.
|
|
3086
|
+
set value(newValue) {
|
|
3087
|
+
const clamped = Math.max(this._min, Math.min(this._max, newValue));
|
|
3088
|
+
if (clamped !== this._value) {
|
|
3089
|
+
this._value = clamped;
|
|
3090
|
+
this._onChange?.(clamped);
|
|
3091
|
+
this.emit("change", { value: clamped });
|
|
3001
3092
|
this.requestRender();
|
|
3002
3093
|
}
|
|
3003
3094
|
}
|
|
3004
|
-
get
|
|
3005
|
-
return this.
|
|
3095
|
+
get min() {
|
|
3096
|
+
return this._min;
|
|
3006
3097
|
}
|
|
3007
|
-
set
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
this.
|
|
3011
|
-
|
|
3012
|
-
|
|
3098
|
+
set min(newMin) {
|
|
3099
|
+
if (newMin !== this._min) {
|
|
3100
|
+
this._min = newMin;
|
|
3101
|
+
if (this._value < newMin) {
|
|
3102
|
+
this.value = newMin;
|
|
3103
|
+
}
|
|
3013
3104
|
this.requestRender();
|
|
3014
3105
|
}
|
|
3015
3106
|
}
|
|
3107
|
+
get max() {
|
|
3108
|
+
return this._max;
|
|
3109
|
+
}
|
|
3110
|
+
set max(newMax) {
|
|
3111
|
+
if (newMax !== this._max) {
|
|
3112
|
+
this._max = newMax;
|
|
3113
|
+
if (this._value > newMax) {
|
|
3114
|
+
this.value = newMax;
|
|
3115
|
+
}
|
|
3116
|
+
this.requestRender();
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
set viewPortSize(size) {
|
|
3120
|
+
const clampedSize = Math.max(0.01, Math.min(size, this._max - this._min));
|
|
3121
|
+
if (clampedSize !== this._viewPortSize) {
|
|
3122
|
+
this._viewPortSize = clampedSize;
|
|
3123
|
+
this.requestRender();
|
|
3124
|
+
}
|
|
3125
|
+
}
|
|
3126
|
+
get viewPortSize() {
|
|
3127
|
+
return this._viewPortSize;
|
|
3128
|
+
}
|
|
3016
3129
|
get backgroundColor() {
|
|
3017
3130
|
return this._backgroundColor;
|
|
3018
3131
|
}
|
|
@@ -3027,69 +3140,183 @@ class SliderRenderable extends Renderable {
|
|
|
3027
3140
|
this._foregroundColor = parseColor(value);
|
|
3028
3141
|
this.requestRender();
|
|
3029
3142
|
}
|
|
3143
|
+
calculateDragOffsetVirtual(event) {
|
|
3144
|
+
const trackStart = this.orientation === "vertical" ? this.y : this.x;
|
|
3145
|
+
const mousePos = (this.orientation === "vertical" ? event.y : event.x) - trackStart;
|
|
3146
|
+
const virtualMousePos = Math.max(0, Math.min((this.orientation === "vertical" ? this.height : this.width) * 2, mousePos * 2));
|
|
3147
|
+
const virtualThumbStart = this.getVirtualThumbStart();
|
|
3148
|
+
const virtualThumbSize = this.getVirtualThumbSize();
|
|
3149
|
+
return Math.max(0, Math.min(virtualThumbSize, virtualMousePos - virtualThumbStart));
|
|
3150
|
+
}
|
|
3030
3151
|
setupMouseHandling() {
|
|
3031
3152
|
let isDragging = false;
|
|
3032
|
-
let
|
|
3153
|
+
let dragOffsetVirtual = 0;
|
|
3033
3154
|
this.onMouseDown = (event) => {
|
|
3034
3155
|
event.stopPropagation();
|
|
3035
3156
|
event.preventDefault();
|
|
3036
|
-
|
|
3037
|
-
const
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3157
|
+
const thumb = this.getThumbRect();
|
|
3158
|
+
const inThumb = event.x >= thumb.x && event.x < thumb.x + thumb.width && event.y >= thumb.y && event.y < thumb.y + thumb.height;
|
|
3159
|
+
if (inThumb) {
|
|
3160
|
+
isDragging = true;
|
|
3161
|
+
dragOffsetVirtual = this.calculateDragOffsetVirtual(event);
|
|
3041
3162
|
} else {
|
|
3042
|
-
|
|
3163
|
+
this.updateValueFromMouseDirect(event);
|
|
3164
|
+
isDragging = true;
|
|
3165
|
+
dragOffsetVirtual = this.calculateDragOffsetVirtual(event);
|
|
3043
3166
|
}
|
|
3044
|
-
this.updatePositionFromMouse(event, relativeStartPos);
|
|
3045
3167
|
};
|
|
3046
3168
|
this.onMouseDrag = (event) => {
|
|
3047
3169
|
if (!isDragging)
|
|
3048
3170
|
return;
|
|
3049
3171
|
event.stopPropagation();
|
|
3050
|
-
this.
|
|
3172
|
+
this.updateValueFromMouseWithOffset(event, dragOffsetVirtual);
|
|
3051
3173
|
};
|
|
3052
|
-
this.onMouseUp = () => {
|
|
3174
|
+
this.onMouseUp = (event) => {
|
|
3175
|
+
if (isDragging) {
|
|
3176
|
+
this.updateValueFromMouseWithOffset(event, dragOffsetVirtual);
|
|
3177
|
+
}
|
|
3053
3178
|
isDragging = false;
|
|
3054
3179
|
};
|
|
3055
3180
|
}
|
|
3056
|
-
|
|
3181
|
+
updateValueFromMouseDirect(event) {
|
|
3057
3182
|
const trackStart = this.orientation === "vertical" ? this.y : this.x;
|
|
3058
3183
|
const trackSize = this.orientation === "vertical" ? this.height : this.width;
|
|
3059
3184
|
const mousePos = this.orientation === "vertical" ? event.y : event.x;
|
|
3060
|
-
const
|
|
3061
|
-
const
|
|
3062
|
-
const
|
|
3063
|
-
const
|
|
3064
|
-
this.
|
|
3065
|
-
|
|
3066
|
-
|
|
3185
|
+
const relativeMousePos = mousePos - trackStart;
|
|
3186
|
+
const clampedMousePos = Math.max(0, Math.min(trackSize, relativeMousePos));
|
|
3187
|
+
const ratio = trackSize === 0 ? 0 : clampedMousePos / trackSize;
|
|
3188
|
+
const range = this._max - this._min;
|
|
3189
|
+
const newValue = this._min + ratio * range;
|
|
3190
|
+
this.value = newValue;
|
|
3191
|
+
}
|
|
3192
|
+
updateValueFromMouseWithOffset(event, offsetVirtual) {
|
|
3193
|
+
const trackStart = this.orientation === "vertical" ? this.y : this.x;
|
|
3067
3194
|
const trackSize = this.orientation === "vertical" ? this.height : this.width;
|
|
3068
|
-
const
|
|
3069
|
-
|
|
3195
|
+
const mousePos = this.orientation === "vertical" ? event.y : event.x;
|
|
3196
|
+
const virtualTrackSize = trackSize * 2;
|
|
3197
|
+
const relativeMousePos = mousePos - trackStart;
|
|
3198
|
+
const clampedMousePos = Math.max(0, Math.min(trackSize, relativeMousePos));
|
|
3199
|
+
const virtualMousePos = clampedMousePos * 2;
|
|
3200
|
+
const virtualThumbSize = this.getVirtualThumbSize();
|
|
3201
|
+
const maxThumbStart = Math.max(0, virtualTrackSize - virtualThumbSize);
|
|
3202
|
+
let desiredThumbStart = virtualMousePos - offsetVirtual;
|
|
3203
|
+
desiredThumbStart = Math.max(0, Math.min(maxThumbStart, desiredThumbStart));
|
|
3204
|
+
const ratio = maxThumbStart === 0 ? 0 : desiredThumbStart / maxThumbStart;
|
|
3205
|
+
const range = this._max - this._min;
|
|
3206
|
+
const newValue = this._min + ratio * range;
|
|
3207
|
+
this.value = newValue;
|
|
3070
3208
|
}
|
|
3071
3209
|
getThumbRect() {
|
|
3072
|
-
const
|
|
3210
|
+
const virtualThumbSize = this.getVirtualThumbSize();
|
|
3211
|
+
const virtualThumbStart = this.getVirtualThumbStart();
|
|
3212
|
+
const realThumbStart = Math.floor(virtualThumbStart / 2);
|
|
3213
|
+
const realThumbSize = Math.ceil((virtualThumbStart + virtualThumbSize) / 2) - realThumbStart;
|
|
3073
3214
|
if (this.orientation === "vertical") {
|
|
3074
3215
|
return {
|
|
3075
3216
|
x: this.x,
|
|
3076
|
-
y: this.y +
|
|
3217
|
+
y: this.y + realThumbStart,
|
|
3077
3218
|
width: this.width,
|
|
3078
|
-
height:
|
|
3219
|
+
height: Math.max(1, realThumbSize)
|
|
3079
3220
|
};
|
|
3080
3221
|
} else {
|
|
3081
3222
|
return {
|
|
3082
|
-
x: this.x +
|
|
3223
|
+
x: this.x + realThumbStart,
|
|
3083
3224
|
y: this.y,
|
|
3084
|
-
width:
|
|
3225
|
+
width: Math.max(1, realThumbSize),
|
|
3085
3226
|
height: this.height
|
|
3086
3227
|
};
|
|
3087
3228
|
}
|
|
3088
3229
|
}
|
|
3089
3230
|
renderSelf(buffer) {
|
|
3231
|
+
if (this.orientation === "horizontal") {
|
|
3232
|
+
this.renderHorizontal(buffer);
|
|
3233
|
+
} else {
|
|
3234
|
+
this.renderVertical(buffer);
|
|
3235
|
+
}
|
|
3236
|
+
}
|
|
3237
|
+
renderHorizontal(buffer) {
|
|
3238
|
+
const virtualThumbSize = this.getVirtualThumbSize();
|
|
3239
|
+
const virtualThumbStart = this.getVirtualThumbStart();
|
|
3240
|
+
const virtualThumbEnd = virtualThumbStart + virtualThumbSize;
|
|
3241
|
+
buffer.fillRect(this.x, this.y, this.width, this.height, this._backgroundColor);
|
|
3242
|
+
const realStartCell = Math.floor(virtualThumbStart / 2);
|
|
3243
|
+
const realEndCell = Math.ceil(virtualThumbEnd / 2) - 1;
|
|
3244
|
+
const startX = Math.max(0, realStartCell);
|
|
3245
|
+
const endX = Math.min(this.width - 1, realEndCell);
|
|
3246
|
+
for (let realX = startX;realX <= endX; realX++) {
|
|
3247
|
+
const virtualCellStart = realX * 2;
|
|
3248
|
+
const virtualCellEnd = virtualCellStart + 2;
|
|
3249
|
+
const thumbStartInCell = Math.max(virtualThumbStart, virtualCellStart);
|
|
3250
|
+
const thumbEndInCell = Math.min(virtualThumbEnd, virtualCellEnd);
|
|
3251
|
+
const coverage = thumbEndInCell - thumbStartInCell;
|
|
3252
|
+
let char = " ";
|
|
3253
|
+
if (coverage >= 2) {
|
|
3254
|
+
char = "\u2588";
|
|
3255
|
+
} else {
|
|
3256
|
+
const isLeftHalf = thumbStartInCell === virtualCellStart;
|
|
3257
|
+
if (isLeftHalf) {
|
|
3258
|
+
char = "\u258C";
|
|
3259
|
+
} else {
|
|
3260
|
+
char = "\u2590";
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
for (let y = 0;y < this.height; y++) {
|
|
3264
|
+
buffer.setCellWithAlphaBlending(this.x + realX, this.y + y, char, this._foregroundColor, this._backgroundColor);
|
|
3265
|
+
}
|
|
3266
|
+
}
|
|
3267
|
+
}
|
|
3268
|
+
renderVertical(buffer) {
|
|
3269
|
+
const virtualThumbSize = this.getVirtualThumbSize();
|
|
3270
|
+
const virtualThumbStart = this.getVirtualThumbStart();
|
|
3271
|
+
const virtualThumbEnd = virtualThumbStart + virtualThumbSize;
|
|
3090
3272
|
buffer.fillRect(this.x, this.y, this.width, this.height, this._backgroundColor);
|
|
3091
|
-
const
|
|
3092
|
-
|
|
3273
|
+
const realStartCell = Math.floor(virtualThumbStart / 2);
|
|
3274
|
+
const realEndCell = Math.ceil(virtualThumbEnd / 2) - 1;
|
|
3275
|
+
const startY = Math.max(0, realStartCell);
|
|
3276
|
+
const endY = Math.min(this.height - 1, realEndCell);
|
|
3277
|
+
for (let realY = startY;realY <= endY; realY++) {
|
|
3278
|
+
const virtualCellStart = realY * 2;
|
|
3279
|
+
const virtualCellEnd = virtualCellStart + 2;
|
|
3280
|
+
const thumbStartInCell = Math.max(virtualThumbStart, virtualCellStart);
|
|
3281
|
+
const thumbEndInCell = Math.min(virtualThumbEnd, virtualCellEnd);
|
|
3282
|
+
const coverage = thumbEndInCell - thumbStartInCell;
|
|
3283
|
+
let char = " ";
|
|
3284
|
+
if (coverage >= 2) {
|
|
3285
|
+
char = "\u2588";
|
|
3286
|
+
} else if (coverage > 0) {
|
|
3287
|
+
const virtualPositionInCell = thumbStartInCell - virtualCellStart;
|
|
3288
|
+
if (virtualPositionInCell === 0) {
|
|
3289
|
+
char = "\u2580";
|
|
3290
|
+
} else {
|
|
3291
|
+
char = "\u2584";
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
for (let x = 0;x < this.width; x++) {
|
|
3295
|
+
buffer.setCellWithAlphaBlending(this.x + x, this.y + realY, char, this._foregroundColor, this._backgroundColor);
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
}
|
|
3299
|
+
getVirtualThumbSize() {
|
|
3300
|
+
const virtualTrackSize = this.orientation === "vertical" ? this.height * 2 : this.width * 2;
|
|
3301
|
+
const range = this._max - this._min;
|
|
3302
|
+
if (range === 0)
|
|
3303
|
+
return virtualTrackSize;
|
|
3304
|
+
const viewportSize = Math.max(1, this._viewPortSize);
|
|
3305
|
+
const contentSize = range + viewportSize;
|
|
3306
|
+
if (contentSize <= viewportSize)
|
|
3307
|
+
return virtualTrackSize;
|
|
3308
|
+
const thumbRatio = viewportSize / contentSize;
|
|
3309
|
+
const calculatedSize = Math.floor(virtualTrackSize * thumbRatio);
|
|
3310
|
+
return Math.max(1, Math.min(calculatedSize, virtualTrackSize));
|
|
3311
|
+
}
|
|
3312
|
+
getVirtualThumbStart() {
|
|
3313
|
+
const virtualTrackSize = this.orientation === "vertical" ? this.height * 2 : this.width * 2;
|
|
3314
|
+
const range = this._max - this._min;
|
|
3315
|
+
if (range === 0)
|
|
3316
|
+
return 0;
|
|
3317
|
+
const valueRatio = (this._value - this._min) / range;
|
|
3318
|
+
const virtualThumbSize = this.getVirtualThumbSize();
|
|
3319
|
+
return Math.round(valueRatio * (virtualTrackSize - virtualThumbSize));
|
|
3093
3320
|
}
|
|
3094
3321
|
}
|
|
3095
3322
|
|
|
@@ -3132,6 +3359,7 @@ class ScrollBarRenderable extends Renderable {
|
|
|
3132
3359
|
return;
|
|
3133
3360
|
this._scrollSize = value;
|
|
3134
3361
|
this.recalculateVisibility();
|
|
3362
|
+
this.updateSliderFromScrollState();
|
|
3135
3363
|
this.scrollPosition = this.scrollPosition;
|
|
3136
3364
|
}
|
|
3137
3365
|
set scrollPosition(value) {
|
|
@@ -3139,15 +3367,15 @@ class ScrollBarRenderable extends Renderable {
|
|
|
3139
3367
|
if (newPosition !== this._scrollPosition) {
|
|
3140
3368
|
this._scrollPosition = newPosition;
|
|
3141
3369
|
this.updateSliderFromScrollState();
|
|
3142
|
-
this._onChange?.(newPosition);
|
|
3143
|
-
this.emit("change", { position: newPosition });
|
|
3144
3370
|
}
|
|
3145
3371
|
}
|
|
3146
3372
|
set viewportSize(value) {
|
|
3147
3373
|
if (value === this.viewportSize)
|
|
3148
3374
|
return;
|
|
3149
3375
|
this._viewportSize = value;
|
|
3376
|
+
this.slider.viewPortSize = Math.max(1, this._viewportSize);
|
|
3150
3377
|
this.recalculateVisibility();
|
|
3378
|
+
this.updateSliderFromScrollState();
|
|
3151
3379
|
this.scrollPosition = this.scrollPosition;
|
|
3152
3380
|
}
|
|
3153
3381
|
get showArrows() {
|
|
@@ -3170,16 +3398,22 @@ class ScrollBarRenderable extends Renderable {
|
|
|
3170
3398
|
this._onChange = options.onChange;
|
|
3171
3399
|
this.orientation = orientation;
|
|
3172
3400
|
this._showArrows = showArrows;
|
|
3401
|
+
const scrollRange = Math.max(0, this._scrollSize - this._viewportSize);
|
|
3402
|
+
const defaultStepSize = Math.max(1, this._viewportSize);
|
|
3403
|
+
const stepSize = trackOptions?.viewPortSize ?? defaultStepSize;
|
|
3173
3404
|
this.slider = new SliderRenderable(ctx, {
|
|
3174
3405
|
orientation,
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3406
|
+
min: 0,
|
|
3407
|
+
max: scrollRange,
|
|
3408
|
+
value: this._scrollPosition,
|
|
3409
|
+
viewPortSize: stepSize,
|
|
3410
|
+
onChange: (value) => {
|
|
3411
|
+
this._scrollPosition = Math.round(value);
|
|
3178
3412
|
this._onChange?.(this._scrollPosition);
|
|
3179
3413
|
this.emit("change", { position: this._scrollPosition });
|
|
3180
3414
|
},
|
|
3181
3415
|
...orientation === "vertical" ? {
|
|
3182
|
-
width: 2,
|
|
3416
|
+
width: Math.max(1, Math.min(2, this.width)),
|
|
3183
3417
|
height: "100%",
|
|
3184
3418
|
marginLeft: "auto"
|
|
3185
3419
|
} : {
|
|
@@ -3258,17 +3492,10 @@ class ScrollBarRenderable extends Renderable {
|
|
|
3258
3492
|
this.requestRender();
|
|
3259
3493
|
}
|
|
3260
3494
|
updateSliderFromScrollState() {
|
|
3261
|
-
const trackSize = this.orientation === "vertical" ? this.slider.height : this.slider.width;
|
|
3262
3495
|
const scrollRange = Math.max(0, this._scrollSize - this._viewportSize);
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
} else {
|
|
3267
|
-
const sizeRatio = this._viewportSize / this._scrollSize;
|
|
3268
|
-
this.slider.thumbSize = Math.max(1, Math.round(sizeRatio * trackSize));
|
|
3269
|
-
const positionRatio = this._scrollPosition / scrollRange;
|
|
3270
|
-
this.slider.thumbPosition = Math.max(0, Math.min(1, positionRatio));
|
|
3271
|
-
}
|
|
3496
|
+
this.slider.min = 0;
|
|
3497
|
+
this.slider.max = scrollRange;
|
|
3498
|
+
this.slider.value = Math.min(this._scrollPosition, scrollRange);
|
|
3272
3499
|
}
|
|
3273
3500
|
scrollBy(delta, unit = "absolute") {
|
|
3274
3501
|
const multiplier = unit === "viewport" ? this.viewportSize : unit === "content" ? this.scrollSize : unit === "step" ? this.scrollStep ?? 1 : 1;
|
|
@@ -3338,10 +3565,10 @@ class ArrowRenderable extends Renderable {
|
|
|
3338
3565
|
this._backgroundColor = options.backgroundColor ? parseColor(options.backgroundColor) : RGBA.fromValues(0, 0, 0, 0);
|
|
3339
3566
|
this._attributes = options.attributes ?? 0;
|
|
3340
3567
|
this._arrowChars = {
|
|
3341
|
-
up: "\
|
|
3342
|
-
down: "\
|
|
3343
|
-
left: "
|
|
3344
|
-
right: "
|
|
3568
|
+
up: "\u25B2",
|
|
3569
|
+
down: "\u25BC",
|
|
3570
|
+
left: "\u25C0",
|
|
3571
|
+
right: "\u25B6",
|
|
3345
3572
|
...options.arrowChars
|
|
3346
3573
|
};
|
|
3347
3574
|
if (!options.width) {
|
|
@@ -3547,13 +3774,12 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
3547
3774
|
horizontalScrollbarOptions,
|
|
3548
3775
|
stickyScroll = false,
|
|
3549
3776
|
stickyStart,
|
|
3777
|
+
scrollX = false,
|
|
3778
|
+
scrollY = true,
|
|
3550
3779
|
...options
|
|
3551
3780
|
}) {
|
|
3552
3781
|
super(ctx, {
|
|
3553
|
-
flexShrink: 1,
|
|
3554
|
-
flexGrow: 1,
|
|
3555
3782
|
flexDirection: "row",
|
|
3556
|
-
flexWrap: "wrap",
|
|
3557
3783
|
alignItems: "stretch",
|
|
3558
3784
|
...options,
|
|
3559
3785
|
...rootOptions
|
|
@@ -3564,10 +3790,6 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
3564
3790
|
this.wrapper = new BoxRenderable(ctx, {
|
|
3565
3791
|
flexDirection: "column",
|
|
3566
3792
|
flexGrow: 1,
|
|
3567
|
-
flexShrink: 1,
|
|
3568
|
-
flexBasis: "auto",
|
|
3569
|
-
maxHeight: "100%",
|
|
3570
|
-
maxWidth: "100%",
|
|
3571
3793
|
...wrapperOptions,
|
|
3572
3794
|
id: `scroll-box-wrapper-${this.internalId}`
|
|
3573
3795
|
});
|
|
@@ -3575,11 +3797,7 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
3575
3797
|
this.viewport = new BoxRenderable(ctx, {
|
|
3576
3798
|
flexDirection: "column",
|
|
3577
3799
|
flexGrow: 1,
|
|
3578
|
-
|
|
3579
|
-
flexBasis: "auto",
|
|
3580
|
-
maxHeight: "100%",
|
|
3581
|
-
maxWidth: "100%",
|
|
3582
|
-
overflow: "scroll",
|
|
3800
|
+
overflow: "hidden",
|
|
3583
3801
|
onSizeChange: () => {
|
|
3584
3802
|
this.recalculateBarProps();
|
|
3585
3803
|
},
|
|
@@ -3589,8 +3807,9 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
3589
3807
|
this.wrapper.add(this.viewport);
|
|
3590
3808
|
this.content = new ContentRenderable(ctx, this.viewport, {
|
|
3591
3809
|
alignSelf: "flex-start",
|
|
3592
|
-
|
|
3593
|
-
|
|
3810
|
+
flexShrink: 0,
|
|
3811
|
+
...scrollX ? { minWidth: "100%" } : { minWidth: "100%", maxWidth: "100%" },
|
|
3812
|
+
...scrollY ? { minHeight: "100%" } : { minHeight: "100%", maxHeight: "100%" },
|
|
3594
3813
|
onSizeChange: () => {
|
|
3595
3814
|
this.recalculateBarProps();
|
|
3596
3815
|
},
|
|
@@ -3609,6 +3828,8 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
3609
3828
|
orientation: "vertical",
|
|
3610
3829
|
onChange: (position) => {
|
|
3611
3830
|
this.content.translateY = -position;
|
|
3831
|
+
this._hasManualScroll = true;
|
|
3832
|
+
this.updateStickyState();
|
|
3612
3833
|
}
|
|
3613
3834
|
});
|
|
3614
3835
|
super.add(this.verticalScrollBar);
|
|
@@ -3623,6 +3844,8 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
3623
3844
|
orientation: "horizontal",
|
|
3624
3845
|
onChange: (position) => {
|
|
3625
3846
|
this.content.translateX = -position;
|
|
3847
|
+
this._hasManualScroll = true;
|
|
3848
|
+
this.updateStickyState();
|
|
3626
3849
|
}
|
|
3627
3850
|
});
|
|
3628
3851
|
this.wrapper.add(this.horizontalScrollBar);
|
|
@@ -3689,10 +3912,14 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
3689
3912
|
}
|
|
3690
3913
|
}
|
|
3691
3914
|
handleKeyPress(key) {
|
|
3692
|
-
if (this.verticalScrollBar.handleKeyPress(key))
|
|
3915
|
+
if (this.verticalScrollBar.handleKeyPress(key)) {
|
|
3916
|
+
this._hasManualScroll = true;
|
|
3693
3917
|
return true;
|
|
3694
|
-
|
|
3918
|
+
}
|
|
3919
|
+
if (this.horizontalScrollBar.handleKeyPress(key)) {
|
|
3920
|
+
this._hasManualScroll = true;
|
|
3695
3921
|
return true;
|
|
3922
|
+
}
|
|
3696
3923
|
return false;
|
|
3697
3924
|
}
|
|
3698
3925
|
startAutoScroll(mouseX, mouseY) {
|
|
@@ -3824,6 +4051,9 @@ class ScrollBoxRenderable extends BoxRenderable {
|
|
|
3824
4051
|
}
|
|
3825
4052
|
}
|
|
3826
4053
|
}
|
|
4054
|
+
process.nextTick(() => {
|
|
4055
|
+
this.requestRender();
|
|
4056
|
+
});
|
|
3827
4057
|
}
|
|
3828
4058
|
set rootOptions(options) {
|
|
3829
4059
|
Object.assign(this, options);
|
|
@@ -3936,6 +4166,7 @@ export {
|
|
|
3936
4166
|
wrapWithDelegates,
|
|
3937
4167
|
white,
|
|
3938
4168
|
vstyles,
|
|
4169
|
+
visualizeRenderableTree,
|
|
3939
4170
|
underline,
|
|
3940
4171
|
t,
|
|
3941
4172
|
stringToStyledText,
|
|
@@ -3945,6 +4176,7 @@ export {
|
|
|
3945
4176
|
reverse,
|
|
3946
4177
|
resolveRenderLib,
|
|
3947
4178
|
renderFontToFrameBuffer,
|
|
4179
|
+
registerEnvVar,
|
|
3948
4180
|
red,
|
|
3949
4181
|
parseWrap,
|
|
3950
4182
|
parseUnit,
|
|
@@ -3968,36 +4200,29 @@ export {
|
|
|
3968
4200
|
maybeMakeRenderable,
|
|
3969
4201
|
magenta,
|
|
3970
4202
|
italic,
|
|
3971
|
-
isValidPercentage,
|
|
3972
4203
|
isVNode,
|
|
3973
4204
|
isTextNodeRenderable,
|
|
3974
4205
|
isStyledText,
|
|
3975
|
-
isSizeType,
|
|
3976
4206
|
isRenderable,
|
|
3977
|
-
isPositionTypeType,
|
|
3978
|
-
isPositionType,
|
|
3979
|
-
isPaddingType,
|
|
3980
|
-
isOverflowType,
|
|
3981
|
-
isMarginType,
|
|
3982
|
-
isFlexBasisType,
|
|
3983
|
-
isDimensionType,
|
|
3984
4207
|
instantiate,
|
|
3985
4208
|
hsvToRgb,
|
|
3986
4209
|
hexToRgb,
|
|
3987
4210
|
hastToStyledText,
|
|
3988
4211
|
h,
|
|
3989
4212
|
green,
|
|
3990
|
-
getKeyHandler,
|
|
3991
4213
|
getCharacterPositions,
|
|
3992
4214
|
getBorderSides,
|
|
3993
4215
|
getBorderFromSides,
|
|
4216
|
+
generateEnvMarkdown,
|
|
4217
|
+
generateEnvColored,
|
|
3994
4218
|
fonts,
|
|
3995
4219
|
fg,
|
|
4220
|
+
envRegistry,
|
|
4221
|
+
env,
|
|
3996
4222
|
engine,
|
|
3997
4223
|
dim,
|
|
3998
4224
|
delegate,
|
|
3999
4225
|
cyan,
|
|
4000
|
-
createTrackedNode,
|
|
4001
4226
|
createTimeline,
|
|
4002
4227
|
createTextAttributes,
|
|
4003
4228
|
createCliRenderer,
|
|
@@ -4033,9 +4258,9 @@ export {
|
|
|
4033
4258
|
applyGrayscale,
|
|
4034
4259
|
applyChromaticAberration,
|
|
4035
4260
|
applyAsciiArt,
|
|
4261
|
+
exports_src as Yoga,
|
|
4036
4262
|
VignetteEffect,
|
|
4037
4263
|
VRenderable,
|
|
4038
|
-
TrackedNode,
|
|
4039
4264
|
Timeline,
|
|
4040
4265
|
TextRenderable,
|
|
4041
4266
|
TextNodeRenderable,
|
|
@@ -4091,5 +4316,5 @@ export {
|
|
|
4091
4316
|
ASCIIFont
|
|
4092
4317
|
};
|
|
4093
4318
|
|
|
4094
|
-
//# debugId=
|
|
4319
|
+
//# debugId=9C915E7AEEBC51B664756E2164756E21
|
|
4095
4320
|
//# sourceMappingURL=index.js.map
|