@thi.ng/imgui 2.2.13 → 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.
- package/CHANGELOG.md +1 -1
- package/README.md +1 -1
- package/api.js +94 -84
- package/behaviors/button.js +26 -22
- package/behaviors/dial.js +12 -4
- package/behaviors/slider.js +46 -43
- package/behaviors/text.js +75 -70
- package/components/button.js +64 -41
- package/components/dial.js +102 -52
- package/components/dropdown.js +62 -64
- package/components/icon-button.js +40 -31
- package/components/radial-menu.js +43 -37
- package/components/radio.js +19 -14
- package/components/ring.js +123 -79
- package/components/sliderh.js +96 -46
- package/components/sliderv.js +100 -53
- package/components/textfield.js +83 -44
- package/components/textlabel.js +28 -14
- package/components/toggle.js +45 -38
- package/components/tooltip.js +16 -6
- package/components/xypad.js +89 -73
- package/events.js +36 -47
- package/gui.js +400 -415
- package/hash.js +17 -45
- package/layout.js +4 -1
- package/package.json +16 -13
package/components/textlabel.js
CHANGED
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
import { isPlainObject } from "@thi.ng/checks/is-plain-object";
|
|
2
2
|
import { valHash } from "../hash.js";
|
|
3
3
|
import { layoutBox } from "../layout.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
const textLabel = (gui, layout, label, pad = false) => {
|
|
5
|
+
const theme = gui.theme;
|
|
6
|
+
const { x, y, h } = layoutBox(layout);
|
|
7
|
+
gui.draw && gui.add([
|
|
8
|
+
"text",
|
|
9
|
+
{ fill: gui.textColor(false) },
|
|
10
|
+
[x + (pad ? theme.pad : 0), y + h / 2 + theme.baseLine],
|
|
11
|
+
label
|
|
12
|
+
]);
|
|
13
|
+
};
|
|
14
|
+
const textLabelRaw = (p, attribs, label) => ["text", isPlainObject(attribs) ? attribs : { fill: attribs }, p, label];
|
|
15
|
+
const textTransformH = (theme, x, y, _, h) => [1, 0, 0, 1, x + theme.pad, y + h / 2 + theme.baseLine];
|
|
16
|
+
const textTransformV = (theme, x, y, w, h) => [0, -1, 1, 0, x + w / 2 + theme.baseLine, y + h - theme.pad];
|
|
17
|
+
const dialValueLabel = (gui, id, key, v, x, y, label, fmt) => gui.resource(
|
|
18
|
+
id,
|
|
19
|
+
valHash(key, v, gui.disabled),
|
|
20
|
+
() => textLabelRaw(
|
|
21
|
+
[x, y],
|
|
22
|
+
gui.textColor(false),
|
|
23
|
+
(label ? label + " " : "") + (fmt ? fmt(v) : v)
|
|
24
|
+
)
|
|
25
|
+
);
|
|
26
|
+
export {
|
|
27
|
+
dialValueLabel,
|
|
28
|
+
textLabel,
|
|
29
|
+
textLabelRaw,
|
|
30
|
+
textTransformH,
|
|
31
|
+
textTransformV
|
|
14
32
|
};
|
|
15
|
-
export const textLabelRaw = (p, attribs, label) => ["text", isPlainObject(attribs) ? attribs : { fill: attribs }, p, label];
|
|
16
|
-
export const textTransformH = (theme, x, y, _, h) => [1, 0, 0, 1, x + theme.pad, y + h / 2 + theme.baseLine];
|
|
17
|
-
export const textTransformV = (theme, x, y, w, h) => [0, -1, 1, 0, x + w / 2 + theme.baseLine, y + h - theme.pad];
|
|
18
|
-
export const dialValueLabel = (gui, id, key, v, x, y, label, fmt) => gui.resource(id, valHash(key, v, gui.disabled), () => textLabelRaw([x, y], gui.textColor(false), (label ? label + " " : "") + (fmt ? fmt(v) : v)));
|
package/components/toggle.js
CHANGED
|
@@ -3,43 +3,50 @@ import { hash } from "@thi.ng/vectors/hash";
|
|
|
3
3
|
import { handleButtonKeys, hoverButton } from "../behaviors/button.js";
|
|
4
4
|
import { layoutBox } from "../layout.js";
|
|
5
5
|
import { textLabelRaw } from "./textlabel.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const { x, y, w, h } = layoutBox(layout);
|
|
21
|
-
return toggleRaw(gui, id, x, y, square ? h : w, h, square ? h : 0, val, label, info);
|
|
6
|
+
const toggle = (gui, layout, id, val, square, label, info) => {
|
|
7
|
+
const { x, y, w, h } = layoutBox(layout);
|
|
8
|
+
return toggleRaw(
|
|
9
|
+
gui,
|
|
10
|
+
id,
|
|
11
|
+
x,
|
|
12
|
+
y,
|
|
13
|
+
square ? h : w,
|
|
14
|
+
h,
|
|
15
|
+
square ? h : 0,
|
|
16
|
+
val,
|
|
17
|
+
label,
|
|
18
|
+
info
|
|
19
|
+
);
|
|
22
20
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
21
|
+
const toggleRaw = (gui, id, x, y, w, h, lx, val, label, info) => {
|
|
22
|
+
const theme = gui.theme;
|
|
23
|
+
const key = hash([x, y, w, h]);
|
|
24
|
+
gui.registerID(id, key);
|
|
25
|
+
let res;
|
|
26
|
+
const box = gui.resource(id, key, () => rect([x, y], [w, h]));
|
|
27
|
+
const hover = hoverButton(gui, id, box, info);
|
|
28
|
+
const focused = gui.requestFocus(id);
|
|
29
|
+
let changed = !gui.buttons && gui.hotID === id && gui.activeID === id;
|
|
30
|
+
focused && (changed = handleButtonKeys(gui) || changed);
|
|
31
|
+
changed && (res = val = !val);
|
|
32
|
+
if (gui.draw) {
|
|
33
|
+
box.attribs = {
|
|
34
|
+
fill: val ? gui.fgColor(hover) : gui.bgColor(hover),
|
|
35
|
+
stroke: gui.focusColor(id)
|
|
36
|
+
};
|
|
37
|
+
gui.add(box);
|
|
38
|
+
label && gui.add(
|
|
39
|
+
textLabelRaw(
|
|
40
|
+
[x + theme.pad + lx, y + h / 2 + theme.baseLine],
|
|
41
|
+
gui.textColor(hover && lx > 0 && lx < w - theme.pad),
|
|
42
|
+
label
|
|
43
|
+
)
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
gui.lastID = id;
|
|
47
|
+
return res;
|
|
48
|
+
};
|
|
49
|
+
export {
|
|
50
|
+
toggle,
|
|
51
|
+
toggleRaw
|
|
45
52
|
};
|
package/components/tooltip.js
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { rect } from "@thi.ng/geom/rect";
|
|
2
2
|
import { add2 } from "@thi.ng/vectors/add";
|
|
3
3
|
import { textLabelRaw } from "./textlabel.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
const tooltipRaw = (gui, tooltip) => {
|
|
5
|
+
const theme = gui.theme;
|
|
6
|
+
const p = add2(null, [0, 10], gui.mouse);
|
|
7
|
+
gui.addOverlay(
|
|
8
|
+
rect(p, [tooltip.length * theme.charWidth + theme.pad, 20], {
|
|
9
|
+
fill: theme.bgTooltip
|
|
10
|
+
}),
|
|
11
|
+
textLabelRaw(
|
|
12
|
+
add2(null, [4, 10 + theme.baseLine], p),
|
|
13
|
+
theme.textTooltip,
|
|
14
|
+
tooltip
|
|
15
|
+
)
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
tooltipRaw
|
|
10
20
|
};
|
package/components/xypad.js
CHANGED
|
@@ -2,81 +2,97 @@ import { line } from "@thi.ng/geom/line";
|
|
|
2
2
|
import { rect } from "@thi.ng/geom/rect";
|
|
3
3
|
import { fit2 } from "@thi.ng/vectors/fit";
|
|
4
4
|
import { hash } from "@thi.ng/vectors/hash";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
handleSlider2Keys,
|
|
7
|
+
isHoverSlider,
|
|
8
|
+
slider2Val
|
|
9
|
+
} from "../behaviors/slider.js";
|
|
6
10
|
import { textLabelRaw } from "./textlabel.js";
|
|
7
11
|
import { tooltipRaw } from "./tooltip.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
box = layout.next([1, rows + 1]);
|
|
38
|
-
box.h -= ch + gap;
|
|
39
|
-
}
|
|
40
|
-
return xyPadRaw(gui, id, box.x, box.y, box.w, box.h, min, max, prec, val, yUp, 0, box.h + gap + ch / 2 + gui.theme.baseLine, label, fmt, info);
|
|
12
|
+
const xyPad = (gui, layout, id, min, max, prec, val, mode, yUp, label, fmt, info) => {
|
|
13
|
+
let box;
|
|
14
|
+
const ch = layout.cellH;
|
|
15
|
+
const gap = layout.gap;
|
|
16
|
+
if (mode === -2) {
|
|
17
|
+
box = layout.nextSquare();
|
|
18
|
+
} else {
|
|
19
|
+
let rows = (mode > 0 ? mode : layout.cellW / (ch + gap)) | 0;
|
|
20
|
+
box = layout.next([1, rows + 1]);
|
|
21
|
+
box.h -= ch + gap;
|
|
22
|
+
}
|
|
23
|
+
return xyPadRaw(
|
|
24
|
+
gui,
|
|
25
|
+
id,
|
|
26
|
+
box.x,
|
|
27
|
+
box.y,
|
|
28
|
+
box.w,
|
|
29
|
+
box.h,
|
|
30
|
+
min,
|
|
31
|
+
max,
|
|
32
|
+
prec,
|
|
33
|
+
val,
|
|
34
|
+
yUp,
|
|
35
|
+
0,
|
|
36
|
+
box.h + gap + ch / 2 + gui.theme.baseLine,
|
|
37
|
+
label,
|
|
38
|
+
fmt,
|
|
39
|
+
info
|
|
40
|
+
);
|
|
41
41
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
box.attribs = {
|
|
65
|
-
fill: gui.bgColor(hover || focused),
|
|
66
|
-
stroke: gui.focusColor(id),
|
|
67
|
-
};
|
|
68
|
-
const { 0: cx, 1: cy } = fit2([], v, min, max, pos, maxPos);
|
|
69
|
-
gui.add(box, line([x, cy], [maxX, cy], {
|
|
70
|
-
stroke: col,
|
|
71
|
-
}), line([cx, y], [cx, maxY], {
|
|
72
|
-
stroke: col,
|
|
73
|
-
}), textLabelRaw([x + lx, y + ly], col, (label ? label + " " : "") +
|
|
74
|
-
(fmt ? fmt(val) : `${val[0] | 0}, ${val[1] | 0}`)));
|
|
42
|
+
const xyPadRaw = (gui, id, x, y, w, h, min, max, prec, val, yUp = false, lx, ly, label, fmt, info) => {
|
|
43
|
+
const maxX = x + w;
|
|
44
|
+
const maxY = y + h;
|
|
45
|
+
const pos = yUp ? [x, maxY] : [x, y];
|
|
46
|
+
const maxPos = yUp ? [maxX, y] : [maxX, maxY];
|
|
47
|
+
const key = hash([x, y, w, h]);
|
|
48
|
+
gui.registerID(id, key);
|
|
49
|
+
const box = gui.resource(id, key, () => rect([x, y], [w, h]));
|
|
50
|
+
const col = gui.textColor(false);
|
|
51
|
+
const hover = isHoverSlider(gui, id, box, "move");
|
|
52
|
+
const draw = gui.draw;
|
|
53
|
+
let v = val;
|
|
54
|
+
let res;
|
|
55
|
+
if (hover) {
|
|
56
|
+
if (gui.isMouseDown()) {
|
|
57
|
+
gui.activeID = id;
|
|
58
|
+
res = slider2Val(
|
|
59
|
+
fit2([], gui.mouse, pos, maxPos, min, max),
|
|
60
|
+
min,
|
|
61
|
+
max,
|
|
62
|
+
prec
|
|
63
|
+
);
|
|
75
64
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
65
|
+
info && draw && tooltipRaw(gui, info);
|
|
66
|
+
}
|
|
67
|
+
const focused = gui.requestFocus(id);
|
|
68
|
+
if (draw) {
|
|
69
|
+
box.attribs = {
|
|
70
|
+
fill: gui.bgColor(hover || focused),
|
|
71
|
+
stroke: gui.focusColor(id)
|
|
72
|
+
};
|
|
73
|
+
const { 0: cx, 1: cy } = fit2([], v, min, max, pos, maxPos);
|
|
74
|
+
gui.add(
|
|
75
|
+
box,
|
|
76
|
+
line([x, cy], [maxX, cy], {
|
|
77
|
+
stroke: col
|
|
78
|
+
}),
|
|
79
|
+
line([cx, y], [cx, maxY], {
|
|
80
|
+
stroke: col
|
|
81
|
+
}),
|
|
82
|
+
textLabelRaw(
|
|
83
|
+
[x + lx, y + ly],
|
|
84
|
+
col,
|
|
85
|
+
(label ? label + " " : "") + (fmt ? fmt(val) : `${val[0] | 0}, ${val[1] | 0}`)
|
|
86
|
+
)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
if (focused && (v = handleSlider2Keys(gui, min, max, prec, v, yUp)) !== void 0) {
|
|
90
|
+
return v;
|
|
91
|
+
}
|
|
92
|
+
gui.lastID = id;
|
|
93
|
+
return res;
|
|
94
|
+
};
|
|
95
|
+
export {
|
|
96
|
+
xyPad,
|
|
97
|
+
xyPadRaw
|
|
82
98
|
};
|
package/events.js
CHANGED
|
@@ -1,49 +1,38 @@
|
|
|
1
1
|
import { MouseButton } from "./api.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
ontouchcancel: touchEnd,
|
|
39
|
-
});
|
|
40
|
-
window.addEventListener("keydown", (e) => {
|
|
41
|
-
gui.setKey(e);
|
|
42
|
-
if (e.key === "Tab") {
|
|
43
|
-
e.preventDefault();
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
window.addEventListener("keyup", (e) => {
|
|
47
|
-
gui.setKey(e);
|
|
48
|
-
});
|
|
2
|
+
const useDefaultEventHandlers = (gui) => {
|
|
3
|
+
const pos = (e) => {
|
|
4
|
+
const b = e.target.getBoundingClientRect();
|
|
5
|
+
const t = e.changedTouches ? e.changedTouches[0] : e;
|
|
6
|
+
return [t.clientX - b.left, t.clientY - b.top];
|
|
7
|
+
};
|
|
8
|
+
const touchActive = (e) => {
|
|
9
|
+
gui.setMouse(pos(e), MouseButton.LEFT);
|
|
10
|
+
};
|
|
11
|
+
const touchEnd = (e) => {
|
|
12
|
+
gui.setMouse(pos(e), 0);
|
|
13
|
+
};
|
|
14
|
+
const mouseActive = (e) => {
|
|
15
|
+
gui.setMouse(pos(e), e.buttons);
|
|
16
|
+
};
|
|
17
|
+
Object.assign(gui.attribs, {
|
|
18
|
+
onmousemove: mouseActive,
|
|
19
|
+
onmousedown: mouseActive,
|
|
20
|
+
onmouseup: mouseActive,
|
|
21
|
+
ontouchstart: touchActive,
|
|
22
|
+
ontouchmove: touchActive,
|
|
23
|
+
ontouchend: touchEnd,
|
|
24
|
+
ontouchcancel: touchEnd
|
|
25
|
+
});
|
|
26
|
+
window.addEventListener("keydown", (e) => {
|
|
27
|
+
gui.setKey(e);
|
|
28
|
+
if (e.key === "Tab") {
|
|
29
|
+
e.preventDefault();
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
window.addEventListener("keyup", (e) => {
|
|
33
|
+
gui.setKey(e);
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
export {
|
|
37
|
+
useDefaultEventHandlers
|
|
49
38
|
};
|