UNPKG

@thi.ng/imgui

Version:

Immediate mode GUI with flexible state handling & data only shape output

123 lines (122 loc) 2.82 kB
import { rect } from "@thi.ng/geom/rect"; import { fit, norm } from "@thi.ng/math/fit"; import { clamp } from "@thi.ng/math/interval"; import { ZERO2 } from "@thi.ng/vectors/api"; 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, textTransformV } from "./textlabel.js"; import { tooltipRaw } from "./tooltip.js"; const sliderV = ({ gui, layout, id, rows, min, max, step, value, label, info, fmt }) => { const box = layoutBox(layout, [1, rows]); return sliderVRaw( gui, id, box.x, box.y, box.w, box.h, min, max, step, value, label, fmt, info ); }; const sliderVGroup = (opts) => { const { id, value, label, info } = opts; const n = value.length; const layout = opts.layout.nest(n, [1, opts.rows]); let res; let idx = -1; for (let i = 0; i < n; i++) { const v = sliderV({ ...opts, layout, 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 sliderVRaw = (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 ymax = y + h; const hover = isHoverSlider(gui, id, box, "ns-resize"); 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[1], ymax - 1, y, min, max), min, max, step ); } info && draw && tooltipRaw(gui, info); } const focused = gui.requestFocus(id); if (draw) { const valueBox = gui.resource(id, v, () => { const nh = norm(v, min, max) * (h - 1); return rect([x, ymax - nh], [w, nh], {}); }); const valLabel = gui.resource( id, valHash(key, v, gui.disabled), () => textLabelRaw( ZERO2, { transform: textTransformV(theme, x, y, w, h), fill: gui.textColor(false) }, (label ? label + " " : "") + (fmt ? fmt(v) : v) ) ); valueBox.attribs.fill = gui.fgColor(hover); box.attribs.fill = gui.bgColor(hover || focused); box.attribs.stroke = gui.focusColor(id); gui.add(box, valueBox, valLabel); } if (focused && (v = handleSlider1Keys(gui, min, max, step, v)) !== void 0) { return v; } gui.lastID = id; return res; }; export { sliderV, sliderVGroup, sliderVRaw };