@thi.ng/imgui
Version:
Immediate mode GUI with flexible state handling & data only shape output
118 lines (117 loc) • 2.68 kB
JavaScript
import { rect } from "@thi.ng/geom/rect";
import { fit, norm } from "@thi.ng/math/fit";
import { clamp } from "@thi.ng/math/interval";
import { hash } from "@thi.ng/vectors/hash";
import {
handleSlider1Keys,
isHoverSlider,
slider1Val
} from "../behaviors/slider.js";
import { valHash } from "../hash.js";
import { layoutBox } from "../layout.js";
import { textLabelRaw } from "./textlabel.js";
import { tooltipRaw } from "./tooltip.js";
const sliderH = ({
gui,
layout,
id,
min,
max,
step,
value,
label,
info,
fmt
}) => {
const box = layoutBox(layout);
return sliderHRaw(
gui,
id,
box.x,
box.y,
box.w,
box.h,
min,
max,
step,
value,
label,
fmt,
info
);
};
const sliderHGroup = (opts) => {
const { layout, id, value, label, info } = opts;
const n = value.length;
const nested = opts.horizontal ? layout.nest(n, [n, 1]) : layout.nest(1, [1, n]);
let res;
let idx = -1;
for (let i = 0; i < n; i++) {
const v = sliderH({
...opts,
layout: nested,
id: `${id}-${i}`,
value: value[i],
label: label[i],
info: info?.[i]
});
if (v !== void 0) {
res = v;
idx = i;
}
}
return res !== void 0 ? [idx, res] : void 0;
};
const sliderHRaw = (gui, id, x, y, w, h, min, max, step, val, label, fmt, info) => {
const theme = gui.theme;
const key = hash([x, y, w, h]);
gui.registerID(id, key);
const box = gui.resource(id, key, () => rect([x, y], [w, h], {}));
const hover = isHoverSlider(gui, id, box);
const draw = gui.draw;
let v = clamp(val, min, max);
let res;
if (hover) {
if (gui.isMouseDown()) {
gui.activeID = id;
res = slider1Val(
fit(gui.mouse[0], x, x + w - 1, min, max),
min,
max,
step
);
}
info && draw && tooltipRaw(gui, info);
}
const focused = gui.requestFocus(id);
if (draw) {
const valueBox = gui.resource(
id,
v,
() => rect([x, y], [1 + norm(v, min, max) * (w - 1), h], {})
);
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)
)
);
box.attribs.fill = gui.bgColor(hover || focused);
box.attribs.stroke = gui.focusColor(id);
valueBox.attribs.fill = gui.fgColor(hover);
gui.add(box, valueBox, valLabel);
}
if (focused && (v = handleSlider1Keys(gui, min, max, step, v)) !== void 0) {
return v;
}
gui.lastID = id;
return res;
};
export {
sliderH,
sliderHGroup,
sliderHRaw
};