@thi.ng/imgui 2.2.12 → 2.2.14

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.
@@ -12,87 +12,131 @@ import { dialVal } from "../behaviors/dial.js";
12
12
  import { handleSlider1Keys } from "../behaviors/slider.js";
13
13
  import { dialValueLabel } from "./textlabel.js";
14
14
  import { tooltipRaw } from "./tooltip.js";
15
- const ringHeight = (w, thetaGap) => (w / 2) * (1 + Math.sin(HALF_PI + thetaGap / 2));
16
- const arcVerts = (o, r, start, end, thetaRes = 12) => r > 1
17
- ? map((t) => cartesian2(null, [r, mix(start, end, t)], o), normRange(Math.max(1, Math.abs(end - start) / (PI / thetaRes)) | 0))
18
- : [o];
19
- export const ring = (gui, layout, id, min, max, prec, val, thetaGap, rscale, label, fmt, info) => {
20
- let h;
21
- let box;
22
- if (isLayout(layout)) {
23
- h = ringHeight(layout.cellW, thetaGap);
24
- box = layout.next([1, layout.rowsForHeight(h) + 1]);
25
- }
26
- else {
27
- h = ringHeight(layout.cw, thetaGap);
28
- box = layout;
29
- }
30
- return ringRaw(gui, id, box.x, box.y, box.w, h, min, max, prec, val, thetaGap, rscale, 0, h + box.ch / 2 + gui.theme.baseLine, label, fmt, info);
15
+ const ringHeight = (w, thetaGap) => w / 2 * (1 + Math.sin(HALF_PI + thetaGap / 2));
16
+ const arcVerts = (o, r, start, end, thetaRes = 12) => r > 1 ? map(
17
+ (t) => cartesian2(null, [r, mix(start, end, t)], o),
18
+ normRange(
19
+ Math.max(1, Math.abs(end - start) / (PI / thetaRes)) | 0
20
+ )
21
+ ) : [o];
22
+ const ring = (gui, layout, id, min, max, prec, val, thetaGap, rscale, label, fmt, info) => {
23
+ let h;
24
+ let box;
25
+ if (isLayout(layout)) {
26
+ h = ringHeight(layout.cellW, thetaGap);
27
+ box = layout.next([1, layout.rowsForHeight(h) + 1]);
28
+ } else {
29
+ h = ringHeight(layout.cw, thetaGap);
30
+ box = layout;
31
+ }
32
+ return ringRaw(
33
+ gui,
34
+ id,
35
+ box.x,
36
+ box.y,
37
+ box.w,
38
+ h,
39
+ min,
40
+ max,
41
+ prec,
42
+ val,
43
+ thetaGap,
44
+ rscale,
45
+ 0,
46
+ h + box.ch / 2 + gui.theme.baseLine,
47
+ label,
48
+ fmt,
49
+ info
50
+ );
31
51
  };
32
- export const ringGroup = (gui, layout, id, min, max, prec, horizontal, thetaGap, rscale, vals, label, fmt, info = []) => {
33
- const n = vals.length;
34
- const nested = horizontal
35
- ? layout.nest(n, [n, 1])
36
- : layout.nest(1, [
37
- 1,
38
- (layout.rowsForHeight(ringHeight(layout.cellW, thetaGap)) + 1) *
39
- n,
40
- ]);
41
- let res;
42
- let idx = -1;
43
- for (let i = 0; i < n; i++) {
44
- const v = ring(gui, nested, `${id}-${i}`, min, max, prec, vals[i], thetaGap, rscale, label[i], fmt, info[i]);
45
- if (v !== undefined) {
46
- res = v;
47
- idx = i;
48
- }
52
+ const ringGroup = (gui, layout, id, min, max, prec, horizontal, thetaGap, rscale, vals, label, fmt, info = []) => {
53
+ const n = vals.length;
54
+ const nested = horizontal ? layout.nest(n, [n, 1]) : layout.nest(1, [
55
+ 1,
56
+ (layout.rowsForHeight(ringHeight(layout.cellW, thetaGap)) + 1) * n
57
+ ]);
58
+ let res;
59
+ let idx = -1;
60
+ for (let i = 0; i < n; i++) {
61
+ const v = ring(
62
+ gui,
63
+ nested,
64
+ `${id}-${i}`,
65
+ min,
66
+ max,
67
+ prec,
68
+ vals[i],
69
+ thetaGap,
70
+ rscale,
71
+ label[i],
72
+ fmt,
73
+ info[i]
74
+ );
75
+ if (v !== void 0) {
76
+ res = v;
77
+ idx = i;
49
78
  }
50
- return res !== undefined ? [idx, res] : undefined;
79
+ }
80
+ return res !== void 0 ? [idx, res] : void 0;
51
81
  };
52
- export const ringRaw = (gui, id, x, y, w, h, min, max, prec, val, thetaGap, rscale, lx, ly, label, fmt, info) => {
53
- const r = w / 2;
54
- const key = hash([x, y, r]);
55
- gui.registerID(id, key);
56
- const pos = [x + r, y + r];
57
- const startTheta = HALF_PI + thetaGap / 2;
58
- const endTheta = HALF_PI + TAU - thetaGap / 2;
59
- const draw = gui.draw;
60
- const aid = gui.activeID;
61
- const hover = !gui.disabled &&
62
- (aid === id || (aid === "" && pointInRect(gui.mouse, [x, y], [w, h])));
63
- let v = val;
64
- let res;
65
- if (hover) {
66
- gui.setCursor("pointer");
67
- gui.hotID = id;
68
- if (gui.isMouseDown()) {
69
- gui.activeID = id;
70
- res = dialVal(gui.mouse, pos, startTheta, thetaGap, min, max, prec);
71
- }
72
- info && draw && tooltipRaw(gui, info);
73
- }
74
- const focused = gui.requestFocus(id);
75
- if (draw) {
76
- const valTheta = startTheta + (TAU - thetaGap) * norm(v, min, max);
77
- const r2 = r * rscale;
78
- // adaptive arc resolution
79
- const numV = fitClamped(r, 15, 80, 12, 30);
80
- const shape = (max) => () => polygon([
81
- ...arcVerts(pos, r, startTheta, max, numV),
82
- ...arcVerts(pos, r2, max, startTheta, numV),
83
- ], {});
84
- const bgShape = gui.resource(id, key, shape(endTheta));
85
- const valShape = gui.resource(id, v, shape(valTheta));
86
- const valLabel = dialValueLabel(gui, id, key, v, x + lx, y + ly, label, fmt);
87
- bgShape.attribs.fill = gui.bgColor(hover || focused);
88
- bgShape.attribs.stroke = gui.focusColor(id);
89
- valShape.attribs.fill = gui.fgColor(hover);
90
- gui.add(bgShape, valShape, valLabel);
82
+ const ringRaw = (gui, id, x, y, w, h, min, max, prec, val, thetaGap, rscale, lx, ly, label, fmt, info) => {
83
+ const r = w / 2;
84
+ const key = hash([x, y, r]);
85
+ gui.registerID(id, key);
86
+ const pos = [x + r, y + r];
87
+ const startTheta = HALF_PI + thetaGap / 2;
88
+ const endTheta = HALF_PI + TAU - thetaGap / 2;
89
+ const draw = gui.draw;
90
+ const aid = gui.activeID;
91
+ const hover = !gui.disabled && (aid === id || aid === "" && pointInRect(gui.mouse, [x, y], [w, h]));
92
+ let v = val;
93
+ let res;
94
+ if (hover) {
95
+ gui.setCursor("pointer");
96
+ gui.hotID = id;
97
+ if (gui.isMouseDown()) {
98
+ gui.activeID = id;
99
+ res = dialVal(gui.mouse, pos, startTheta, thetaGap, min, max, prec);
91
100
  }
92
- if (focused &&
93
- (v = handleSlider1Keys(gui, min, max, prec, v)) !== undefined) {
94
- return v;
95
- }
96
- gui.lastID = id;
97
- return res;
101
+ info && draw && tooltipRaw(gui, info);
102
+ }
103
+ const focused = gui.requestFocus(id);
104
+ if (draw) {
105
+ const valTheta = startTheta + (TAU - thetaGap) * norm(v, min, max);
106
+ const r2 = r * rscale;
107
+ const numV = fitClamped(r, 15, 80, 12, 30);
108
+ const shape = (max2) => () => polygon(
109
+ [
110
+ ...arcVerts(pos, r, startTheta, max2, numV),
111
+ ...arcVerts(pos, r2, max2, startTheta, numV)
112
+ ],
113
+ {}
114
+ );
115
+ const bgShape = gui.resource(id, key, shape(endTheta));
116
+ const valShape = gui.resource(id, v, shape(valTheta));
117
+ const valLabel = dialValueLabel(
118
+ gui,
119
+ id,
120
+ key,
121
+ v,
122
+ x + lx,
123
+ y + ly,
124
+ label,
125
+ fmt
126
+ );
127
+ bgShape.attribs.fill = gui.bgColor(hover || focused);
128
+ bgShape.attribs.stroke = gui.focusColor(id);
129
+ valShape.attribs.fill = gui.fgColor(hover);
130
+ gui.add(bgShape, valShape, valLabel);
131
+ }
132
+ if (focused && (v = handleSlider1Keys(gui, min, max, prec, v)) !== void 0) {
133
+ return v;
134
+ }
135
+ gui.lastID = id;
136
+ return res;
137
+ };
138
+ export {
139
+ ring,
140
+ ringGroup,
141
+ ringRaw
98
142
  };
@@ -1,58 +1,108 @@
1
1
  import { rect } from "@thi.ng/geom/rect";
2
2
  import { fit, norm } from "@thi.ng/math/fit";
3
3
  import { hash } from "@thi.ng/vectors/hash";
4
- import { handleSlider1Keys, isHoverSlider, slider1Val, } from "../behaviors/slider.js";
4
+ import {
5
+ handleSlider1Keys,
6
+ isHoverSlider,
7
+ slider1Val
8
+ } from "../behaviors/slider.js";
5
9
  import { valHash } from "../hash.js";
6
10
  import { layoutBox } from "../layout.js";
7
11
  import { textLabelRaw } from "./textlabel.js";
8
12
  import { tooltipRaw } from "./tooltip.js";
9
- export const sliderH = (gui, layout, id, min, max, prec, val, label, fmt, info) => {
10
- const box = layoutBox(layout);
11
- return sliderHRaw(gui, id, box.x, box.y, box.w, box.h, min, max, prec, val, label, fmt, info);
13
+ const sliderH = (gui, layout, id, min, max, prec, val, label, fmt, info) => {
14
+ const box = layoutBox(layout);
15
+ return sliderHRaw(
16
+ gui,
17
+ id,
18
+ box.x,
19
+ box.y,
20
+ box.w,
21
+ box.h,
22
+ min,
23
+ max,
24
+ prec,
25
+ val,
26
+ label,
27
+ fmt,
28
+ info
29
+ );
12
30
  };
13
- export const sliderHGroup = (gui, layout, id, min, max, prec, horizontal, vals, label, fmt, info = []) => {
14
- const n = vals.length;
15
- const nested = horizontal ? layout.nest(n, [n, 1]) : layout.nest(1, [1, n]);
16
- let res;
17
- let idx = -1;
18
- for (let i = 0; i < n; i++) {
19
- const v = sliderH(gui, nested, `${id}-${i}`, min, max, prec, vals[i], label[i], fmt, info[i]);
20
- if (v !== undefined) {
21
- res = v;
22
- idx = i;
23
- }
31
+ const sliderHGroup = (gui, layout, id, min, max, prec, horizontal, vals, label, fmt, info = []) => {
32
+ const n = vals.length;
33
+ const nested = horizontal ? layout.nest(n, [n, 1]) : layout.nest(1, [1, n]);
34
+ let res;
35
+ let idx = -1;
36
+ for (let i = 0; i < n; i++) {
37
+ const v = sliderH(
38
+ gui,
39
+ nested,
40
+ `${id}-${i}`,
41
+ min,
42
+ max,
43
+ prec,
44
+ vals[i],
45
+ label[i],
46
+ fmt,
47
+ info[i]
48
+ );
49
+ if (v !== void 0) {
50
+ res = v;
51
+ idx = i;
24
52
  }
25
- return res !== undefined ? [idx, res] : undefined;
53
+ }
54
+ return res !== void 0 ? [idx, res] : void 0;
26
55
  };
27
- export const sliderHRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info) => {
28
- const theme = gui.theme;
29
- const key = hash([x, y, w, h]);
30
- gui.registerID(id, key);
31
- const box = gui.resource(id, key, () => rect([x, y], [w, h], {}));
32
- const hover = isHoverSlider(gui, id, box);
33
- const draw = gui.draw;
34
- let v = val;
35
- let res;
36
- if (hover) {
37
- if (gui.isMouseDown()) {
38
- gui.activeID = id;
39
- res = slider1Val(fit(gui.mouse[0], x, x + w - 1, min, max), min, max, prec);
40
- }
41
- info && draw && tooltipRaw(gui, info);
56
+ const sliderHRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info) => {
57
+ const theme = gui.theme;
58
+ const key = hash([x, y, w, h]);
59
+ gui.registerID(id, key);
60
+ const box = gui.resource(id, key, () => rect([x, y], [w, h], {}));
61
+ const hover = isHoverSlider(gui, id, box);
62
+ const draw = gui.draw;
63
+ let v = val;
64
+ let res;
65
+ if (hover) {
66
+ if (gui.isMouseDown()) {
67
+ gui.activeID = id;
68
+ res = slider1Val(
69
+ fit(gui.mouse[0], x, x + w - 1, min, max),
70
+ min,
71
+ max,
72
+ prec
73
+ );
42
74
  }
43
- const focused = gui.requestFocus(id);
44
- if (draw) {
45
- const valueBox = gui.resource(id, v, () => rect([x, y], [1 + norm(v, min, max) * (w - 1), h], {}));
46
- const valLabel = gui.resource(id, valHash(key, v, gui.disabled), () => textLabelRaw([x + theme.pad, y + h / 2 + theme.baseLine], gui.textColor(false), (label ? label + " " : "") + (fmt ? fmt(v) : v)));
47
- box.attribs.fill = gui.bgColor(hover || focused);
48
- box.attribs.stroke = gui.focusColor(id);
49
- valueBox.attribs.fill = gui.fgColor(hover);
50
- gui.add(box, valueBox, valLabel);
51
- }
52
- if (focused &&
53
- (v = handleSlider1Keys(gui, min, max, prec, v)) !== undefined) {
54
- return v;
55
- }
56
- gui.lastID = id;
57
- return res;
75
+ info && draw && tooltipRaw(gui, info);
76
+ }
77
+ const focused = gui.requestFocus(id);
78
+ if (draw) {
79
+ const valueBox = gui.resource(
80
+ id,
81
+ v,
82
+ () => rect([x, y], [1 + norm(v, min, max) * (w - 1), h], {})
83
+ );
84
+ const valLabel = gui.resource(
85
+ id,
86
+ valHash(key, v, gui.disabled),
87
+ () => textLabelRaw(
88
+ [x + theme.pad, y + h / 2 + theme.baseLine],
89
+ gui.textColor(false),
90
+ (label ? label + " " : "") + (fmt ? fmt(v) : v)
91
+ )
92
+ );
93
+ box.attribs.fill = gui.bgColor(hover || focused);
94
+ box.attribs.stroke = gui.focusColor(id);
95
+ valueBox.attribs.fill = gui.fgColor(hover);
96
+ gui.add(box, valueBox, valLabel);
97
+ }
98
+ if (focused && (v = handleSlider1Keys(gui, min, max, prec, v)) !== void 0) {
99
+ return v;
100
+ }
101
+ gui.lastID = id;
102
+ return res;
103
+ };
104
+ export {
105
+ sliderH,
106
+ sliderHGroup,
107
+ sliderHRaw
58
108
  };
@@ -2,65 +2,112 @@ import { rect } from "@thi.ng/geom/rect";
2
2
  import { fit, norm } from "@thi.ng/math/fit";
3
3
  import { ZERO2 } from "@thi.ng/vectors/api";
4
4
  import { hash } from "@thi.ng/vectors/hash";
5
- import { handleSlider1Keys, isHoverSlider, slider1Val, } from "../behaviors/slider.js";
5
+ import {
6
+ handleSlider1Keys,
7
+ isHoverSlider,
8
+ slider1Val
9
+ } from "../behaviors/slider.js";
6
10
  import { valHash } from "../hash.js";
7
11
  import { layoutBox } from "../layout.js";
8
12
  import { textLabelRaw, textTransformV } from "./textlabel.js";
9
13
  import { tooltipRaw } from "./tooltip.js";
10
- export const sliderV = (gui, layout, id, min, max, prec, val, rows, label, fmt, info) => {
11
- const box = layoutBox(layout, [1, rows]);
12
- return sliderVRaw(gui, id, box.x, box.y, box.w, box.h, min, max, prec, val, label, fmt, info);
14
+ const sliderV = (gui, layout, id, min, max, prec, val, rows, label, fmt, info) => {
15
+ const box = layoutBox(layout, [1, rows]);
16
+ return sliderVRaw(
17
+ gui,
18
+ id,
19
+ box.x,
20
+ box.y,
21
+ box.w,
22
+ box.h,
23
+ min,
24
+ max,
25
+ prec,
26
+ val,
27
+ label,
28
+ fmt,
29
+ info
30
+ );
13
31
  };
14
- export const sliderVGroup = (gui, layout, id, min, max, prec, vals, rows, label, fmt, info = []) => {
15
- const n = vals.length;
16
- const nested = layout.nest(n, [1, rows]);
17
- let res;
18
- let idx = -1;
19
- for (let i = 0; i < n; i++) {
20
- const v = sliderV(gui, nested, `${id}-${i}`, min, max, prec, vals[i], rows, label[i], fmt, info[i]);
21
- if (v !== undefined) {
22
- res = v;
23
- idx = i;
24
- }
32
+ const sliderVGroup = (gui, layout, id, min, max, prec, vals, rows, label, fmt, info = []) => {
33
+ const n = vals.length;
34
+ const nested = layout.nest(n, [1, rows]);
35
+ let res;
36
+ let idx = -1;
37
+ for (let i = 0; i < n; i++) {
38
+ const v = sliderV(
39
+ gui,
40
+ nested,
41
+ `${id}-${i}`,
42
+ min,
43
+ max,
44
+ prec,
45
+ vals[i],
46
+ rows,
47
+ label[i],
48
+ fmt,
49
+ info[i]
50
+ );
51
+ if (v !== void 0) {
52
+ res = v;
53
+ idx = i;
25
54
  }
26
- return res !== undefined ? [idx, res] : undefined;
55
+ }
56
+ return res !== void 0 ? [idx, res] : void 0;
27
57
  };
28
- export const sliderVRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info) => {
29
- const theme = gui.theme;
30
- const key = hash([x, y, w, h]);
31
- gui.registerID(id, key);
32
- const box = gui.resource(id, key, () => rect([x, y], [w, h], {}));
33
- const ymax = y + h;
34
- const hover = isHoverSlider(gui, id, box, "ns-resize");
35
- const draw = gui.draw;
36
- let v = val;
37
- let res;
38
- if (hover) {
39
- if (gui.isMouseDown()) {
40
- gui.activeID = id;
41
- res = slider1Val(fit(gui.mouse[1], ymax - 1, y, min, max), min, max, prec);
42
- }
43
- info && draw && tooltipRaw(gui, info);
58
+ const sliderVRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info) => {
59
+ const theme = gui.theme;
60
+ const key = hash([x, y, w, h]);
61
+ gui.registerID(id, key);
62
+ const box = gui.resource(id, key, () => rect([x, y], [w, h], {}));
63
+ const ymax = y + h;
64
+ const hover = isHoverSlider(gui, id, box, "ns-resize");
65
+ const draw = gui.draw;
66
+ let v = val;
67
+ let res;
68
+ if (hover) {
69
+ if (gui.isMouseDown()) {
70
+ gui.activeID = id;
71
+ res = slider1Val(
72
+ fit(gui.mouse[1], ymax - 1, y, min, max),
73
+ min,
74
+ max,
75
+ prec
76
+ );
44
77
  }
45
- const focused = gui.requestFocus(id);
46
- if (draw) {
47
- const valueBox = gui.resource(id, v, () => {
48
- const nh = norm(v, min, max) * (h - 1);
49
- return rect([x, ymax - nh], [w, nh], {});
50
- });
51
- const valLabel = gui.resource(id, valHash(key, v, gui.disabled), () => textLabelRaw(ZERO2, {
52
- transform: textTransformV(theme, x, y, w, h),
53
- fill: gui.textColor(false),
54
- }, (label ? label + " " : "") + (fmt ? fmt(v) : v)));
55
- valueBox.attribs.fill = gui.fgColor(hover);
56
- box.attribs.fill = gui.bgColor(hover || focused);
57
- box.attribs.stroke = gui.focusColor(id);
58
- gui.add(box, valueBox, valLabel);
59
- }
60
- if (focused &&
61
- (v = handleSlider1Keys(gui, min, max, prec, v)) !== undefined) {
62
- return v;
63
- }
64
- gui.lastID = id;
65
- return res;
78
+ info && draw && tooltipRaw(gui, info);
79
+ }
80
+ const focused = gui.requestFocus(id);
81
+ if (draw) {
82
+ const valueBox = gui.resource(id, v, () => {
83
+ const nh = norm(v, min, max) * (h - 1);
84
+ return rect([x, ymax - nh], [w, nh], {});
85
+ });
86
+ const valLabel = gui.resource(
87
+ id,
88
+ valHash(key, v, gui.disabled),
89
+ () => textLabelRaw(
90
+ ZERO2,
91
+ {
92
+ transform: textTransformV(theme, x, y, w, h),
93
+ fill: gui.textColor(false)
94
+ },
95
+ (label ? label + " " : "") + (fmt ? fmt(v) : v)
96
+ )
97
+ );
98
+ valueBox.attribs.fill = gui.fgColor(hover);
99
+ box.attribs.fill = gui.bgColor(hover || focused);
100
+ box.attribs.stroke = gui.focusColor(id);
101
+ gui.add(box, valueBox, valLabel);
102
+ }
103
+ if (focused && (v = handleSlider1Keys(gui, min, max, prec, v)) !== void 0) {
104
+ return v;
105
+ }
106
+ gui.lastID = id;
107
+ return res;
108
+ };
109
+ export {
110
+ sliderV,
111
+ sliderVGroup,
112
+ sliderVRaw
66
113
  };
@@ -6,52 +6,91 @@ import { handleTextfieldKeys } from "../behaviors/text.js";
6
6
  import { layoutBox } from "../layout.js";
7
7
  import { textLabelRaw } from "./textlabel.js";
8
8
  import { tooltipRaw } from "./tooltip.js";
9
- export const textField = (gui, layout, id, label, filter = () => true, info) => {
10
- const box = layoutBox(layout);
11
- return textFieldRaw(gui, id, box.x, box.y, box.w, box.h, label, filter, info);
9
+ const textField = (gui, layout, id, label, filter = () => true, info) => {
10
+ const box = layoutBox(layout);
11
+ return textFieldRaw(
12
+ gui,
13
+ id,
14
+ box.x,
15
+ box.y,
16
+ box.w,
17
+ box.h,
18
+ label,
19
+ filter,
20
+ info
21
+ );
12
22
  };
13
- export const textFieldRaw = (gui, id, x, y, w, h, txt, filter = () => true, info) => {
14
- const theme = gui.theme;
15
- const cw = theme.charWidth;
16
- const pad = theme.pad;
17
- const maxLen = Math.max(1, ((w - pad * 2) / cw) | 0);
18
- const txtLen = txt.length;
19
- const state = gui.state(id, () => ({ cursor: 0, offset: 0 }));
20
- const drawTxt = txt.substring(state.offset, state.offset + maxLen);
21
- const key = hash([x, y, w, h]);
22
- gui.registerID(id, key);
23
- const box = gui.resource(id, key, () => rect([x, y], [w, h], {}));
24
- const hover = isHoverSlider(gui, id, box, "text");
25
- const draw = gui.draw;
26
- if (hover) {
27
- if (gui.isMouseDown()) {
28
- gui.activeID = id;
29
- state.cursor = Math.min(Math.round(fitClamped(gui.mouse[0], x + pad, x + w - pad, state.offset, state.offset + maxLen)), txtLen);
30
- }
31
- info && draw && tooltipRaw(gui, info);
23
+ const textFieldRaw = (gui, id, x, y, w, h, txt, filter = () => true, info) => {
24
+ const theme = gui.theme;
25
+ const cw = theme.charWidth;
26
+ const pad = theme.pad;
27
+ const maxLen = Math.max(1, (w - pad * 2) / cw | 0);
28
+ const txtLen = txt.length;
29
+ const state = gui.state(id, () => ({ cursor: 0, offset: 0 }));
30
+ const drawTxt = txt.substring(state.offset, state.offset + maxLen);
31
+ const key = hash([x, y, w, h]);
32
+ gui.registerID(id, key);
33
+ const box = gui.resource(id, key, () => rect([x, y], [w, h], {}));
34
+ const hover = isHoverSlider(gui, id, box, "text");
35
+ const draw = gui.draw;
36
+ if (hover) {
37
+ if (gui.isMouseDown()) {
38
+ gui.activeID = id;
39
+ state.cursor = Math.min(
40
+ Math.round(
41
+ fitClamped(
42
+ gui.mouse[0],
43
+ x + pad,
44
+ x + w - pad,
45
+ state.offset,
46
+ state.offset + maxLen
47
+ )
48
+ ),
49
+ txtLen
50
+ );
32
51
  }
33
- const focused = gui.requestFocus(id);
52
+ info && draw && tooltipRaw(gui, info);
53
+ }
54
+ const focused = gui.requestFocus(id);
55
+ if (draw) {
56
+ box.attribs.fill = gui.bgColor(focused || hover);
57
+ box.attribs.stroke = gui.focusColor(id);
58
+ gui.add(
59
+ box,
60
+ textLabelRaw(
61
+ [x + pad, y + h / 2 + theme.baseLine],
62
+ gui.textColor(focused),
63
+ drawTxt
64
+ )
65
+ );
66
+ }
67
+ if (focused) {
68
+ const { cursor, offset } = state;
69
+ const drawCursor = Math.min(cursor - offset, maxLen);
34
70
  if (draw) {
35
- box.attribs.fill = gui.bgColor(focused || hover);
36
- box.attribs.stroke = gui.focusColor(id);
37
- gui.add(box, textLabelRaw([x + pad, y + h / 2 + theme.baseLine], gui.textColor(focused), drawTxt));
71
+ const xx = x + pad + drawCursor * cw;
72
+ gui.time * theme.cursorBlink % 1 < 0.5 && gui.add([
73
+ "line",
74
+ { stroke: theme.cursor },
75
+ [xx, y + 4],
76
+ [xx, y + h - 4]
77
+ ]);
38
78
  }
39
- if (focused) {
40
- const { cursor, offset } = state;
41
- const drawCursor = Math.min(cursor - offset, maxLen);
42
- if (draw) {
43
- const xx = x + pad + drawCursor * cw;
44
- (gui.time * theme.cursorBlink) % 1 < 0.5 &&
45
- gui.add([
46
- "line",
47
- { stroke: theme.cursor },
48
- [xx, y + 4],
49
- [xx, y + h - 4],
50
- ]);
51
- }
52
- const res = handleTextfieldKeys(gui, state, filter, txt, cursor, drawCursor, maxLen);
53
- if (res !== undefined)
54
- return res;
55
- }
56
- gui.lastID = id;
79
+ const res = handleTextfieldKeys(
80
+ gui,
81
+ state,
82
+ filter,
83
+ txt,
84
+ cursor,
85
+ drawCursor,
86
+ maxLen
87
+ );
88
+ if (res !== void 0)
89
+ return res;
90
+ }
91
+ gui.lastID = id;
92
+ };
93
+ export {
94
+ textField,
95
+ textFieldRaw
57
96
  };