@thi.ng/imgui
Version:
Immediate mode GUI with flexible state handling & data only shape output
85 lines (84 loc) • 2.2 kB
JavaScript
import { clamp0 } from "@thi.ng/math/interval";
import { Key } from "../api.js";
const WS = /\s/;
const __nextNonAlpha = (src, i) => {
const n = src.length;
while (i < n && WS.test(src[i])) i++;
for (; i < n && !WS.test(src[i]); i++) {
}
return i;
};
const __prevNonAlpha = (src, i) => {
while (i > 0 && WS.test(src[i])) i--;
for (; i > 0 && !WS.test(src[i]); i--) {
}
return i;
};
const __getNext = (gui, txt, cursor, dir) => {
cursor += dir;
return gui.isAltDown() ? (dir < 0 ? __prevNonAlpha : __nextNonAlpha)(txt, cursor) : cursor;
};
const handleTextfieldKeys = (gui, state, filter, txt, cursor, drawCursor, maxLen) => {
const txtLen = txt.length;
const move = (next, delta) => {
state.cursor = next;
if (drawCursor + delta < 0) {
state.offset = Math.max(state.offset + delta, 0);
} else if (drawCursor + delta > maxLen) {
state.offset = Math.min(
state.offset + delta,
clamp0(txtLen - maxLen)
);
}
};
const k = gui.key;
switch (k) {
case "":
break;
case Key.TAB:
gui.switchFocus();
break;
case Key.ENTER:
return txt;
case Key.BACKSPACE:
if (cursor > 0) {
const next = __getNext(gui, txt, cursor, -1);
move(next, next - cursor);
return txt.substring(0, next) + txt.substring(cursor);
}
break;
case Key.DELETE:
if (cursor < txtLen) {
const next = __getNext(gui, txt, cursor, 1);
return txt.substring(0, cursor) + txt.substring(next + 1);
}
break;
case Key.LEFT:
if (cursor > 0) {
const next = __getNext(gui, txt, cursor, -1);
move(next, next - cursor);
}
break;
case Key.RIGHT:
if (cursor < txtLen) {
const next = __getNext(gui, txt, cursor, 1);
move(next, next - cursor);
}
break;
case Key.HOME:
move(0, -cursor);
break;
case Key.END:
move(txtLen, txtLen - cursor);
break;
default: {
if (k.length === 1 && filter(k)) {
move(cursor + 1, 1);
return txt.substring(0, cursor) + k + txt.substring(cursor);
}
}
}
};
export {
handleTextfieldKeys
};