UNPKG

@thi.ng/imgui

Version:

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

85 lines (84 loc) 2.2 kB
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 };