@thi.ng/imgui 3.0.2 → 3.1.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2024-10-05T12:12:32Z
3
+ - **Last updated**: 2024-10-07T12:32:11Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,20 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [3.1.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/imgui@3.1.0) (2024-10-07)
13
+
14
+ #### 🚀 Features
15
+
16
+ - clamp value args to min/max range ([ee866b1](https://github.com/thi-ng/umbrella/commit/ee866b1))
17
+ - update dial, ring, sliders and XY pad components
18
+ - ensure provided value arg is within limits
19
+ - update ramp component & RampOpts ([953f2fa](https://github.com/thi-ng/umbrella/commit/953f2fa))
20
+
21
+ #### ♻️ Refactoring
22
+
23
+ - update DropDownOpts ([fe0f080](https://github.com/thi-ng/umbrella/commit/fe0f080))
24
+ - rename `title` option => `label`
25
+
12
26
  # [3.0.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/imgui@3.0.0) (2024-10-03)
13
27
 
14
28
  #### 🛑 Breaking changes
@@ -1,3 +1,3 @@
1
1
  import type { ReadonlyVec } from "@thi.ng/vectors";
2
- export declare const dialVal: (p: ReadonlyVec, c: ReadonlyVec, startTheta: number, thetaGap: number, min: number, max: number, prec: number) => number;
2
+ export declare const dialVal: (p: ReadonlyVec, origin: ReadonlyVec, startTheta: number, thetaGap: number, min: number, max: number, prec: number) => number;
3
3
  //# sourceMappingURL=dial.d.ts.map
package/behaviors/dial.js CHANGED
@@ -3,8 +3,8 @@ import { fit } from "@thi.ng/math/fit";
3
3
  import { heading } from "@thi.ng/vectors/heading";
4
4
  import { sub2 } from "@thi.ng/vectors/sub";
5
5
  import { slider1Val } from "./slider.js";
6
- const dialVal = (p, c, startTheta, thetaGap, min, max, prec) => {
7
- let theta = heading(sub2([], p, c)) - startTheta;
6
+ const dialVal = (p, origin, startTheta, thetaGap, min, max, prec) => {
7
+ let theta = heading(sub2([], p, origin)) - startTheta;
8
8
  theta < -0.5 && (theta += TAU);
9
9
  return slider1Val(
10
10
  fit(Math.min(theta / (TAU - thetaGap)), 0, 1, min, max),
@@ -5,6 +5,6 @@ import type { IMGUI } from "../gui.js";
5
5
  export declare const isHoverSlider: (gui: IMGUI, id: string, shape: IShape, cursor?: string) => boolean;
6
6
  export declare const slider1Val: FnN4;
7
7
  export declare const slider2Val: (v: Vec, min: Vec, max: Vec, prec: number) => Vec;
8
- export declare const handleSlider1Keys: (gui: IMGUI, min: number, max: number, prec: number, val: number) => number | undefined;
9
- export declare const handleSlider2Keys: (gui: IMGUI, min: Vec, max: Vec, prec: number, val: Vec, yUp: boolean) => Vec | undefined;
8
+ export declare const handleSlider1Keys: (gui: IMGUI, min: number, max: number, prec: number, value: number) => number | undefined;
9
+ export declare const handleSlider2Keys: (gui: IMGUI, min: Vec, max: Vec, prec: number, value: Vec, yUp: boolean) => Vec | undefined;
10
10
  //# sourceMappingURL=slider.d.ts.map
@@ -17,7 +17,7 @@ const isHoverSlider = (gui, id, shape, cursor = "ew-resize") => {
17
17
  };
18
18
  const slider1Val = (x, min, max, prec) => clamp(roundTo(x, prec), min, max);
19
19
  const slider2Val = (v, min, max, prec) => clamp2(null, roundN2([], v, prec), min, max);
20
- const handleSlider1Keys = (gui, min, max, prec, val) => {
20
+ const handleSlider1Keys = (gui, min, max, prec, value) => {
21
21
  switch (gui.key) {
22
22
  case Key.TAB:
23
23
  gui.switchFocus();
@@ -25,12 +25,12 @@ const handleSlider1Keys = (gui, min, max, prec, val) => {
25
25
  case Key.UP:
26
26
  case Key.DOWN: {
27
27
  const step = (gui.key === Key.UP ? prec : -prec) * (gui.isShiftDown() ? 5 : 1);
28
- return slider1Val(val + step, min, max, prec);
28
+ return slider1Val(value + step, min, max, prec);
29
29
  }
30
30
  default:
31
31
  }
32
32
  };
33
- const handleSlider2Keys = (gui, min, max, prec, val, yUp) => {
33
+ const handleSlider2Keys = (gui, min, max, prec, value, yUp) => {
34
34
  switch (gui.key) {
35
35
  case Key.TAB:
36
36
  gui.switchFocus();
@@ -38,12 +38,12 @@ const handleSlider2Keys = (gui, min, max, prec, val, yUp) => {
38
38
  case Key.LEFT:
39
39
  case Key.RIGHT: {
40
40
  const step = (gui.key === Key.RIGHT ? prec : -prec) * (gui.isShiftDown() ? 5 : 1);
41
- return slider2Val(add2([], val, [step, 0]), min, max, prec);
41
+ return slider2Val(add2([], value, [step, 0]), min, max, prec);
42
42
  }
43
43
  case Key.UP:
44
44
  case Key.DOWN: {
45
45
  const step = (gui.key === Key.UP ? prec : -prec) * (yUp ? 1 : -1) * (gui.isShiftDown() ? 5 : 1);
46
- return slider2Val(add2([], val, [0, step]), min, max, prec);
46
+ return slider2Val(add2([], value, [0, step]), min, max, prec);
47
47
  }
48
48
  default:
49
49
  }
@@ -2,6 +2,10 @@ import type { IShape } from "@thi.ng/geom";
2
2
  import type { ComponentOpts, Hash } from "../api.js";
3
3
  import type { IMGUI } from "../gui.js";
4
4
  export interface ButtonOpts extends ComponentOpts {
5
+ /**
6
+ * Label text when button is in hover state (by default the same as
7
+ * {@link ComponentOpts.label}).
8
+ */
5
9
  labelHover?: string;
6
10
  }
7
11
  export declare const buttonH: ({ gui, layout, id, label, labelHover, info, }: ButtonOpts) => boolean;
@@ -22,5 +22,5 @@ export interface DialGroupOpts extends Omit<DialOpts, "layout" | "value" | "labe
22
22
  fmt?: Fn<number, string>;
23
23
  }
24
24
  export declare const dialGroup: (opts: DialGroupOpts) => number[] | undefined;
25
- export declare const dialRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: number, max: number, step: number, value: number, lx: number, ly: number, label?: string, fmt?: Fn<number, string>, info?: string) => Maybe<number>;
25
+ export declare const dialRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: number, max: number, step: number, value: number, labelX: number, labelY: number, label?: string, fmt?: Fn<number, string>, info?: string) => Maybe<number>;
26
26
  //# sourceMappingURL=dial.d.ts.map
@@ -3,6 +3,7 @@ import { line } from "@thi.ng/geom/line";
3
3
  import { isLayout } from "@thi.ng/layout/checks";
4
4
  import { HALF_PI, PI, TAU } from "@thi.ng/math/api";
5
5
  import { norm } from "@thi.ng/math/fit";
6
+ import { clamp } from "@thi.ng/math/interval";
6
7
  import { cartesian2 } from "@thi.ng/vectors/cartesian";
7
8
  import { hash } from "@thi.ng/vectors/hash";
8
9
  import { dialVal } from "../behaviors/dial.js";
@@ -62,7 +63,7 @@ const dialGroup = (opts) => {
62
63
  }
63
64
  return res !== void 0 ? [idx, res] : void 0;
64
65
  };
65
- const dialRaw = (gui, id, x, y, w, h, min, max, step, value, lx, ly, label, fmt, info) => {
66
+ const dialRaw = (gui, id, x, y, w, h, min, max, step, value, labelX, labelY, label, fmt, info) => {
66
67
  const r = Math.min(w, h) / 2;
67
68
  const pos = [x + w / 2, y + h / 2];
68
69
  const thetaGap = PI / 2;
@@ -72,7 +73,7 @@ const dialRaw = (gui, id, x, y, w, h, min, max, step, value, lx, ly, label, fmt,
72
73
  const bgShape = gui.resource(id, key, () => circle(pos, r, {}));
73
74
  const hover = isHoverSlider(gui, id, bgShape, "pointer");
74
75
  const draw = gui.draw;
75
- let v = value;
76
+ let v = clamp(value, min, max);
76
77
  let res;
77
78
  if (hover) {
78
79
  gui.hotID = id;
@@ -102,8 +103,8 @@ const dialRaw = (gui, id, x, y, w, h, min, max, step, value, lx, ly, label, fmt,
102
103
  id,
103
104
  key,
104
105
  v,
105
- x + lx,
106
- y + ly,
106
+ x + labelX,
107
+ y + labelY,
107
108
  label,
108
109
  fmt
109
110
  );
@@ -1,12 +1,12 @@
1
1
  import type { Maybe } from "@thi.ng/api";
2
2
  import { type ComponentOpts } from "../api.js";
3
- export interface DropDownOpts extends ComponentOpts {
3
+ export interface DropDownOpts extends Omit<ComponentOpts, "label"> {
4
4
  /**
5
5
  * Index of selected item.
6
6
  */
7
7
  value: number;
8
8
  items: string[];
9
- title: string;
9
+ label: string;
10
10
  }
11
- export declare const dropdown: ({ gui, layout, id, value, items, title, info, }: DropDownOpts) => Maybe<number>;
11
+ export declare const dropdown: ({ gui, layout, id, value, items, label, info, }: DropDownOpts) => Maybe<number>;
12
12
  //# sourceMappingURL=dropdown.d.ts.map
@@ -11,7 +11,7 @@ const dropdown = ({
11
11
  id,
12
12
  value,
13
13
  items,
14
- title,
14
+ label,
15
15
  info
16
16
  }) => {
17
17
  const open = gui.state(id, () => false);
@@ -28,7 +28,7 @@ const dropdown = ({
28
28
  gui,
29
29
  layout: box,
30
30
  id: `${id}-title`,
31
- label: title,
31
+ label,
32
32
  info
33
33
  });
34
34
  draw && gui.add(
@@ -71,7 +71,7 @@ const dropdown = ({
71
71
  layout: box,
72
72
  id: `${id}-${value}`,
73
73
  label: items[value],
74
- labelHover: title,
74
+ labelHover: label,
75
75
  info
76
76
  })) {
77
77
  gui.setState(id, true);
@@ -11,8 +11,17 @@ export interface RadioOpts extends Omit<ComponentOpts, "label" | "info"> {
11
11
  * positioned next to it.
12
12
  */
13
13
  square?: boolean;
14
+ /**
15
+ * Index of selected radio item
16
+ */
14
17
  value: number;
18
+ /**
19
+ * Radio item labels
20
+ */
15
21
  label: string[];
22
+ /**
23
+ * Radio item tooltips
24
+ */
16
25
  info?: string[];
17
26
  }
18
27
  export declare const radio: ({ gui, layout, id, horizontal, square, value, label, info, }: RadioOpts) => Maybe<number>;
@@ -3,7 +3,18 @@ import type { Ramp } from "@thi.ng/ramp";
3
3
  import { type ComponentOpts } from "../api.js";
4
4
  export interface RampOpts extends Omit<ComponentOpts, "label"> {
5
5
  ramp: Ramp<number>;
6
+ /**
7
+ * User defined interpolation mode. Only used to compute internal hash of
8
+ * ramp curve geometry, i.e. if the {@link RampOpts.ramp} interpolation
9
+ * method changes, so should this mode value.
10
+ */
6
11
  mode?: number;
12
+ /**
13
+ * Normalized snap/selection tolerance for ramp control point positions
14
+ *
15
+ * @defaultValue 0.05
16
+ */
17
+ eps?: number;
7
18
  }
8
- export declare const ramp: ({ gui, layout, id, ramp, mode, info }: RampOpts) => Maybe<Ramp<number>>;
19
+ export declare const ramp: ({ gui, layout, id, ramp, mode, info, eps, }: RampOpts) => Maybe<Ramp<number>>;
9
20
  //# sourceMappingURL=ramp.d.ts.map
@@ -15,7 +15,15 @@ import { Key } from "../api.js";
15
15
  import { isHoverSlider } from "../behaviors/slider.js";
16
16
  import { layoutBox } from "../layout.js";
17
17
  import { tooltipRaw } from "./tooltip.js";
18
- const ramp = ({ gui, layout, id, ramp: ramp2, mode = 0, info }) => {
18
+ const ramp = ({
19
+ gui,
20
+ layout,
21
+ id,
22
+ ramp: ramp2,
23
+ mode = 0,
24
+ info,
25
+ eps = 0.05
26
+ }) => {
19
27
  const { x, y, w, h } = layoutBox(layout);
20
28
  const maxX = x + w;
21
29
  const maxY = y + h;
@@ -33,7 +41,7 @@ const ramp = ({ gui, layout, id, ramp: ramp2, mode = 0, info }) => {
33
41
  const focused = gui.requestFocus(id);
34
42
  if (hover) {
35
43
  sel = clamp01_2(null, fit2([], gui.mouse, pos, maxPos, ZERO2, ONE2));
36
- selID = ramp2.closestIndex(sel[0], 0.05);
44
+ selID = ramp2.closestIndex(sel[0], eps);
37
45
  if (gui.isMouseDown()) {
38
46
  gui.activeID = id;
39
47
  if (selID >= 0) {
@@ -42,12 +50,12 @@ const ramp = ({ gui, layout, id, ramp: ramp2, mode = 0, info }) => {
42
50
  ramp2.setStopAt(
43
51
  roundTo(sel[0], 1e-3),
44
52
  roundTo(sel[1], 1e-3),
45
- 0.05
53
+ eps
46
54
  );
47
55
  }
48
56
  res = ramp2;
49
57
  }
50
- if (focused && selID >= 0 && handleRampKeys(gui, ramp2, selID)) {
58
+ if (focused && selID >= 0 && __handleRampKeys(gui, ramp2, selID)) {
51
59
  res = ramp2;
52
60
  }
53
61
  info && gui.draw && tooltipRaw(gui, info);
@@ -66,7 +74,7 @@ const ramp = ({ gui, layout, id, ramp: ramp2, mode = 0, info }) => {
66
74
  [
67
75
  [x, maxY],
68
76
  mix2([], pos, maxPos, [0, stops[0][1]]),
69
- ...rampVertices(ramp2, pos, maxPos),
77
+ ...__rampVertices(ramp2, pos, maxPos),
70
78
  mix2([], pos, maxPos, [1, stops[stops.length - 1][1]]),
71
79
  [maxX, maxY]
72
80
  ],
@@ -98,8 +106,8 @@ const ramp = ({ gui, layout, id, ramp: ramp2, mode = 0, info }) => {
98
106
  gui.lastID = id;
99
107
  return res;
100
108
  };
101
- const rampVertices = (ramp2, pos, maxPos, numSamples = 100) => map((p) => mix2(p, pos, maxPos, p), ramp2.samples(numSamples));
102
- const handleRampKeys = (gui, ramp2, selID) => {
109
+ const __rampVertices = (ramp2, pos, maxPos, numSamples = 100) => map((p) => mix2(p, pos, maxPos, p), ramp2.samples(numSamples));
110
+ const __handleRampKeys = (gui, ramp2, selID) => {
103
111
  switch (gui.key) {
104
112
  case Key.TAB:
105
113
  gui.switchFocus();
@@ -23,5 +23,5 @@ export interface RingGroupOpts extends Omit<RingOpts, "layout" | "value" | "labe
23
23
  info?: string[];
24
24
  }
25
25
  export declare const ringGroup: (opts: RingGroupOpts) => number[] | undefined;
26
- export declare const ringRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: number, max: number, prec: number, val: number, thetaGap: number, rscale: number, lx: number, ly: number, label?: string, fmt?: Fn<number, string>, info?: string) => Maybe<number>;
26
+ export declare const ringRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: number, max: number, step: number, value: number, thetaGap: number, rscale: number, labelX: number, labelY: number, label?: string, fmt?: Fn<number, string>, info?: string) => Maybe<number>;
27
27
  //# sourceMappingURL=ring.d.ts.map
@@ -3,6 +3,7 @@ import { polygon } from "@thi.ng/geom/polygon";
3
3
  import { isLayout } from "@thi.ng/layout/checks";
4
4
  import { HALF_PI, PI, TAU } from "@thi.ng/math/api";
5
5
  import { fitClamped, norm } from "@thi.ng/math/fit";
6
+ import { clamp } from "@thi.ng/math/interval";
6
7
  import { mix } from "@thi.ng/math/mix";
7
8
  import { map } from "@thi.ng/transducers/map";
8
9
  import { normRange } from "@thi.ng/transducers/norm-range";
@@ -82,7 +83,7 @@ const ringGroup = (opts) => {
82
83
  }
83
84
  return res !== void 0 ? [idx, res] : void 0;
84
85
  };
85
- const ringRaw = (gui, id, x, y, w, h, min, max, prec, val, thetaGap, rscale, lx, ly, label, fmt, info) => {
86
+ const ringRaw = (gui, id, x, y, w, h, min, max, step, value, thetaGap, rscale, labelX, labelY, label, fmt, info) => {
86
87
  const r = w / 2;
87
88
  const key = hash([x, y, r]);
88
89
  gui.registerID(id, key);
@@ -92,14 +93,14 @@ const ringRaw = (gui, id, x, y, w, h, min, max, prec, val, thetaGap, rscale, lx,
92
93
  const draw = gui.draw;
93
94
  const aid = gui.activeID;
94
95
  const hover = !gui.disabled && (aid === id || aid === "" && pointInRect(gui.mouse, [x, y], [w, h]));
95
- let v = val;
96
+ let v = clamp(value, min, max);
96
97
  let res;
97
98
  if (hover) {
98
99
  gui.setCursor("pointer");
99
100
  gui.hotID = id;
100
101
  if (gui.isMouseDown()) {
101
102
  gui.activeID = id;
102
- res = dialVal(gui.mouse, pos, startTheta, thetaGap, min, max, prec);
103
+ res = dialVal(gui.mouse, pos, startTheta, thetaGap, min, max, step);
103
104
  }
104
105
  info && draw && tooltipRaw(gui, info);
105
106
  }
@@ -122,8 +123,8 @@ const ringRaw = (gui, id, x, y, w, h, min, max, prec, val, thetaGap, rscale, lx,
122
123
  id,
123
124
  key,
124
125
  v,
125
- x + lx,
126
- y + ly,
126
+ x + labelX,
127
+ y + labelY,
127
128
  label,
128
129
  fmt
129
130
  );
@@ -132,7 +133,7 @@ const ringRaw = (gui, id, x, y, w, h, min, max, prec, val, thetaGap, rscale, lx,
132
133
  valShape.attribs.fill = gui.fgColor(hover);
133
134
  gui.add(bgShape, valShape, valLabel);
134
135
  }
135
- if (focused && (v = handleSlider1Keys(gui, min, max, prec, v)) !== void 0) {
136
+ if (focused && (v = handleSlider1Keys(gui, min, max, step, v)) !== void 0) {
136
137
  return v;
137
138
  }
138
139
  gui.lastID = id;
@@ -21,5 +21,5 @@ export interface SliderGroupOpts extends Omit<SliderOpts, "layout" | "value" | "
21
21
  info?: string[];
22
22
  }
23
23
  export declare const sliderHGroup: (opts: SliderGroupOpts) => number[] | undefined;
24
- export declare const sliderHRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: number, max: number, prec: number, val: number, label?: string, fmt?: Fn<number, string>, info?: string) => Maybe<number>;
24
+ export declare const sliderHRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: number, max: number, step: number, val: number, label?: string, fmt?: Fn<number, string>, info?: string) => Maybe<number>;
25
25
  //# sourceMappingURL=sliderh.d.ts.map
@@ -1,5 +1,6 @@
1
1
  import { rect } from "@thi.ng/geom/rect";
2
2
  import { fit, norm } from "@thi.ng/math/fit";
3
+ import { clamp } from "@thi.ng/math/interval";
3
4
  import { hash } from "@thi.ng/vectors/hash";
4
5
  import {
5
6
  handleSlider1Keys,
@@ -61,14 +62,14 @@ const sliderHGroup = (opts) => {
61
62
  }
62
63
  return res !== void 0 ? [idx, res] : void 0;
63
64
  };
64
- const sliderHRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info) => {
65
+ const sliderHRaw = (gui, id, x, y, w, h, min, max, step, val, label, fmt, info) => {
65
66
  const theme = gui.theme;
66
67
  const key = hash([x, y, w, h]);
67
68
  gui.registerID(id, key);
68
69
  const box = gui.resource(id, key, () => rect([x, y], [w, h], {}));
69
70
  const hover = isHoverSlider(gui, id, box);
70
71
  const draw = gui.draw;
71
- let v = val;
72
+ let v = clamp(val, min, max);
72
73
  let res;
73
74
  if (hover) {
74
75
  if (gui.isMouseDown()) {
@@ -77,7 +78,7 @@ const sliderHRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info)
77
78
  fit(gui.mouse[0], x, x + w - 1, min, max),
78
79
  min,
79
80
  max,
80
- prec
81
+ step
81
82
  );
82
83
  }
83
84
  info && draw && tooltipRaw(gui, info);
@@ -103,7 +104,7 @@ const sliderHRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info)
103
104
  valueBox.attribs.fill = gui.fgColor(hover);
104
105
  gui.add(box, valueBox, valLabel);
105
106
  }
106
- if (focused && (v = handleSlider1Keys(gui, min, max, prec, v)) !== void 0) {
107
+ if (focused && (v = handleSlider1Keys(gui, min, max, step, v)) !== void 0) {
107
108
  return v;
108
109
  }
109
110
  gui.lastID = id;
@@ -8,5 +8,5 @@ export interface SliderVGroupOpts extends Omit<SliderGroupOpts, "horizontal"> {
8
8
  rows: number;
9
9
  }
10
10
  export declare const sliderVGroup: (opts: SliderVGroupOpts) => number[] | undefined;
11
- export declare const sliderVRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: number, max: number, prec: number, val: number, label?: string, fmt?: Fn<number, string>, info?: string) => Maybe<number>;
11
+ export declare const sliderVRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: number, max: number, step: number, val: number, label?: string, fmt?: Fn<number, string>, info?: string) => Maybe<number>;
12
12
  //# sourceMappingURL=sliderv.d.ts.map
@@ -1,5 +1,6 @@
1
1
  import { rect } from "@thi.ng/geom/rect";
2
2
  import { fit, norm } from "@thi.ng/math/fit";
3
+ import { clamp } from "@thi.ng/math/interval";
3
4
  import { ZERO2 } from "@thi.ng/vectors/api";
4
5
  import { hash } from "@thi.ng/vectors/hash";
5
6
  import {
@@ -63,7 +64,7 @@ const sliderVGroup = (opts) => {
63
64
  }
64
65
  return res !== void 0 ? [idx, res] : void 0;
65
66
  };
66
- const sliderVRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info) => {
67
+ const sliderVRaw = (gui, id, x, y, w, h, min, max, step, val, label, fmt, info) => {
67
68
  const theme = gui.theme;
68
69
  const key = hash([x, y, w, h]);
69
70
  gui.registerID(id, key);
@@ -71,7 +72,7 @@ const sliderVRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info)
71
72
  const ymax = y + h;
72
73
  const hover = isHoverSlider(gui, id, box, "ns-resize");
73
74
  const draw = gui.draw;
74
- let v = val;
75
+ let v = clamp(val, min, max);
75
76
  let res;
76
77
  if (hover) {
77
78
  if (gui.isMouseDown()) {
@@ -80,7 +81,7 @@ const sliderVRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info)
80
81
  fit(gui.mouse[1], ymax - 1, y, min, max),
81
82
  min,
82
83
  max,
83
- prec
84
+ step
84
85
  );
85
86
  }
86
87
  info && draw && tooltipRaw(gui, info);
@@ -108,7 +109,7 @@ const sliderVRaw = (gui, id, x, y, w, h, min, max, prec, val, label, fmt, info)
108
109
  box.attribs.stroke = gui.focusColor(id);
109
110
  gui.add(box, valueBox, valLabel);
110
111
  }
111
- if (focused && (v = handleSlider1Keys(gui, min, max, prec, v)) !== void 0) {
112
+ if (focused && (v = handleSlider1Keys(gui, min, max, step, v)) !== void 0) {
112
113
  return v;
113
114
  }
114
115
  gui.lastID = id;
@@ -10,5 +10,5 @@ export interface ToggleOpts extends ComponentOpts {
10
10
  value: boolean;
11
11
  }
12
12
  export declare const toggle: ({ gui, layout, id, value, square, label, info, }: ToggleOpts) => Maybe<boolean>;
13
- export declare const toggleRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, lx: number, val: boolean, label?: string, info?: string) => Maybe<boolean>;
13
+ export declare const toggleRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, labelX: number, val: boolean, label?: string, info?: string) => Maybe<boolean>;
14
14
  //# sourceMappingURL=toggle.d.ts.map
@@ -26,7 +26,7 @@ const toggle = ({
26
26
  info
27
27
  );
28
28
  };
29
- const toggleRaw = (gui, id, x, y, w, h, lx, val, label, info) => {
29
+ const toggleRaw = (gui, id, x, y, w, h, labelX, val, label, info) => {
30
30
  const theme = gui.theme;
31
31
  const key = hash([x, y, w, h]);
32
32
  gui.registerID(id, key);
@@ -45,8 +45,10 @@ const toggleRaw = (gui, id, x, y, w, h, lx, val, label, info) => {
45
45
  gui.add(box);
46
46
  label && gui.add(
47
47
  textLabelRaw(
48
- [x + theme.pad + lx, y + h / 2 + theme.baseLine],
49
- gui.textColor(hover && lx > 0 && lx < w - theme.pad),
48
+ [x + theme.pad + labelX, y + h / 2 + theme.baseLine],
49
+ gui.textColor(
50
+ hover && labelX > 0 && labelX < w - theme.pad
51
+ ),
50
52
  label
51
53
  )
52
54
  );
@@ -24,5 +24,5 @@ export interface XYPadOpts extends Omit<ComponentOpts, "layout"> {
24
24
  fmt?: Fn<Vec, string>;
25
25
  }
26
26
  export declare const xyPad: ({ gui, layout, id, min, max, step, value, mode, yUp, label, info, fmt, }: XYPadOpts) => Maybe<Vec>;
27
- export declare const xyPadRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: Vec, max: Vec, prec: number, val: Vec, yUp: boolean | undefined, lx: number, ly: number, label?: string, fmt?: Fn<Vec, string>, info?: string) => Maybe<Vec>;
27
+ export declare const xyPadRaw: (gui: IMGUI, id: string, x: number, y: number, w: number, h: number, min: Vec, max: Vec, step: number, val: Vec, yUp: boolean | undefined, labelX: number, labelY: number, label?: string, fmt?: Fn<Vec, string>, info?: string) => Maybe<Vec>;
28
28
  //# sourceMappingURL=xypad.d.ts.map
@@ -1,5 +1,6 @@
1
1
  import { line } from "@thi.ng/geom/line";
2
2
  import { rect } from "@thi.ng/geom/rect";
3
+ import { clamp2 } from "@thi.ng/vectors/clamp";
3
4
  import { fit2 } from "@thi.ng/vectors/fit";
4
5
  import { hash } from "@thi.ng/vectors/hash";
5
6
  import {
@@ -52,7 +53,7 @@ const xyPad = ({
52
53
  info
53
54
  );
54
55
  };
55
- const xyPadRaw = (gui, id, x, y, w, h, min, max, prec, val, yUp = false, lx, ly, label, fmt, info) => {
56
+ const xyPadRaw = (gui, id, x, y, w, h, min, max, step, val, yUp = false, labelX, labelY, label, fmt, info) => {
56
57
  const maxX = x + w;
57
58
  const maxY = y + h;
58
59
  const pos = yUp ? [x, maxY] : [x, y];
@@ -63,7 +64,7 @@ const xyPadRaw = (gui, id, x, y, w, h, min, max, prec, val, yUp = false, lx, ly,
63
64
  const col = gui.textColor(false);
64
65
  const hover = isHoverSlider(gui, id, box, "move");
65
66
  const draw = gui.draw;
66
- let v = val;
67
+ let v = clamp2([], val, min, max);
67
68
  let res;
68
69
  if (hover) {
69
70
  if (gui.isMouseDown()) {
@@ -72,7 +73,7 @@ const xyPadRaw = (gui, id, x, y, w, h, min, max, prec, val, yUp = false, lx, ly,
72
73
  fit2([], gui.mouse, pos, maxPos, min, max),
73
74
  min,
74
75
  max,
75
- prec
76
+ step
76
77
  );
77
78
  }
78
79
  info && draw && tooltipRaw(gui, info);
@@ -93,13 +94,13 @@ const xyPadRaw = (gui, id, x, y, w, h, min, max, prec, val, yUp = false, lx, ly,
93
94
  stroke: col
94
95
  }),
95
96
  textLabelRaw(
96
- [x + lx, y + ly],
97
+ [x + labelX, y + labelY],
97
98
  col,
98
99
  (label ? label + " " : "") + (fmt ? fmt(val) : `${val[0] | 0}, ${val[1] | 0}`)
99
100
  )
100
101
  );
101
102
  }
102
- if (focused && (v = handleSlider2Keys(gui, min, max, prec, v, yUp)) !== void 0) {
103
+ if (focused && (v = handleSlider2Keys(gui, min, max, step, v, yUp)) !== void 0) {
103
104
  return v;
104
105
  }
105
106
  gui.lastID = id;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/imgui",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "Immediate mode GUI with flexible state handling & data only shape output",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -38,13 +38,13 @@
38
38
  "dependencies": {
39
39
  "@thi.ng/api": "^8.11.11",
40
40
  "@thi.ng/checks": "^3.6.13",
41
- "@thi.ng/geom": "^8.1.11",
42
- "@thi.ng/geom-isec": "^4.0.15",
43
- "@thi.ng/layout": "^3.1.3",
41
+ "@thi.ng/geom": "^8.1.12",
42
+ "@thi.ng/geom-isec": "^4.0.16",
43
+ "@thi.ng/layout": "^3.1.4",
44
44
  "@thi.ng/math": "^5.11.11",
45
- "@thi.ng/ramp": "^3.3.3",
46
- "@thi.ng/transducers": "^9.2.5",
47
- "@thi.ng/vectors": "^7.12.3"
45
+ "@thi.ng/ramp": "^3.3.4",
46
+ "@thi.ng/transducers": "^9.2.6",
47
+ "@thi.ng/vectors": "^7.12.4"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@microsoft/api-extractor": "^7.47.9",
@@ -160,5 +160,5 @@
160
160
  ],
161
161
  "year": 2019
162
162
  },
163
- "gitHead": "9a32147fce4bd1e5f98dffb04a452576f9984de8\n"
163
+ "gitHead": "241df2019d93359c34da1a11a94e416b6ea73f32\n"
164
164
  }