diff --git a/package.json b/package.json index 5f0e62fbe..ce2ca2a8d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "zed-software-system", "private": true, - "version": "0.19.3", + "version": "0.19.5", "type": "module", "scripts": { "sloc": "npx sloc zss", diff --git a/zss/gadget/components/tape/elements/editorinput.tsx b/zss/gadget/components/tape/elements/editorinput.tsx index 990bfdb1e..3e6a289c2 100644 --- a/zss/gadget/components/tape/elements/editorinput.tsx +++ b/zss/gadget/components/tape/elements/editorinput.tsx @@ -146,57 +146,6 @@ export function EditorInput({ onScroll={(ydelta) => movecursor(ydelta * 0.75)} /> { - trackselection(mods.shift) - if (mods.ctrl) { - useTapeEditor.setState({ cursor: coderow.start }) - } else { - const cursor = tapeeditor.cursor - (mods.alt ? 10 : 1) - useTapeEditor.setState({ cursor: clamp(cursor, 0, codeend) }) - } - }} - MOVE_RIGHT={(mods) => { - trackselection(mods.shift) - if (mods.ctrl) { - useTapeEditor.setState({ cursor: coderow.end }) - } else { - const cursor = tapeeditor.cursor + (mods.alt ? 10 : 1) - useTapeEditor.setState({ cursor: clamp(cursor, 0, codeend) }) - } - }} - MOVE_UP={(mods) => { - trackselection(mods.shift) - if (mods.ctrl) { - useTapeEditor.setState({ cursor: 0 }) - } else { - movecursor(mods.alt ? -10 : -1) - } - }} - MOVE_DOWN={(mods) => { - trackselection(mods.shift) - if (mods.ctrl) { - useTapeEditor.setState({ cursor: codeend }) - } else { - movecursor(mods.alt ? 10 : 1) - } - }} - OK_BUTTON={() => { - if (ispresent(value)) { - // insert newline ! - value.insert(tapeeditor.cursor, `\n`) - useTapeEditor.setState({ cursor: tapeeditor.cursor + 1 }) - } - }} - CANCEL_BUTTON={(mods) => { - if (mods.shift || mods.alt || mods.ctrl) { - tape_terminal_close('tape') - } else { - tape_editor_close('editor') - } - }} - MENU_BUTTON={(mods) => { - tape_terminal_inclayout('editor', !mods.shift) - }} keydown={(event) => { if (!ispresent(value)) { return @@ -207,6 +156,58 @@ export function EditorInput({ const mods = modsfromevent(event) switch (lkey) { + case 'arrowleft': + trackselection(mods.shift) + if (mods.ctrl) { + useTapeEditor.setState({ cursor: coderow.start }) + } else { + const cursor = tapeeditor.cursor - (mods.alt ? 10 : 1) + useTapeEditor.setState({ cursor: clamp(cursor, 0, codeend) }) + } + break + case 'arrowright': + trackselection(mods.shift) + if (mods.ctrl) { + useTapeEditor.setState({ cursor: coderow.end }) + } else { + const cursor = tapeeditor.cursor + (mods.alt ? 10 : 1) + useTapeEditor.setState({ cursor: clamp(cursor, 0, codeend) }) + } + break + case 'arrowup': + trackselection(mods.shift) + if (mods.ctrl) { + useTapeEditor.setState({ cursor: 0 }) + } else { + movecursor(mods.alt ? -10 : -1) + } + break + case 'arrowdown': + trackselection(mods.shift) + if (mods.ctrl) { + useTapeEditor.setState({ cursor: codeend }) + } else { + movecursor(mods.alt ? 10 : 1) + } + break + case 'enter': + if (ispresent(value)) { + // insert newline ! + value.insert(tapeeditor.cursor, `\n`) + useTapeEditor.setState({ cursor: tapeeditor.cursor + 1 }) + } + break + case 'esc': + case 'escape': + if (mods.shift || mods.alt || mods.ctrl) { + tape_terminal_close('tape') + } else { + tape_editor_close('editor') + } + break + case 'tab': + tape_terminal_inclayout('editor', !mods.shift) + break case 'delete': if (hasselection) { deleteselection() diff --git a/zss/gadget/components/tape/elements/terminalinput.tsx b/zss/gadget/components/tape/elements/terminalinput.tsx index 70c7db845..7e8bb66f1 100644 --- a/zss/gadget/components/tape/elements/terminalinput.tsx +++ b/zss/gadget/components/tape/elements/terminalinput.tsx @@ -206,97 +206,100 @@ export function TerminalInput({ }} /> tape_terminal_inclayout('tape', !mods.shift)} - MOVE_UP={(mods) => { - if (mods.ctrl) { - inputstateswitch(tapeterminal.bufferindex + 1) - } else { - trackselection(mods.shift) - useTapeTerminal.setState({ - ycursor: clamp( - Math.round(tapeterminal.ycursor + (mods.alt ? 10 : 1)), - 0, - logrowtotalheight, - ), - }) - } - }} - MOVE_DOWN={(mods) => { - if (mods.ctrl) { - inputstateswitch(tapeterminal.bufferindex - 1) - } else { - trackselection(mods.shift) - useTapeTerminal.setState({ - ycursor: clamp( - Math.round(tapeterminal.ycursor - (mods.alt ? 10 : 1)), - 0, - logrowtotalheight, - ), - }) - } - }} - MOVE_LEFT={(mods) => { - trackselection(mods.shift) - if (mods.ctrl) { - useTapeTerminal.setState({ xcursor: 0 }) - } else { - useTapeTerminal.setState({ - xcursor: clamp( - tapeterminal.xcursor - (mods.alt ? 10 : 1), - 0, - edge.right, - ), - }) - } - }} - MOVE_RIGHT={(mods) => { - trackselection(mods.shift) - if (mods.ctrl) { - useTapeTerminal.setState({ - xcursor: inputstateactive ? inputstate.length : edge.right, - }) - } else { - useTapeTerminal.setState({ - xcursor: clamp( - tapeterminal.xcursor + (mods.alt ? 10 : 1), - 0, - edge.right, - ), - }) - } - }} - OK_BUTTON={() => { - const invoke = hasselection ? inputstateselected : inputstate - if (invoke.length) { - if (inputstateactive) { - useTapeTerminal.setState({ - xcursor: 0, - bufferindex: 0, - xselect: undefined, - yselect: undefined, - buffer: [ - '', - invoke, - ...tapeterminal.buffer - .slice(1) - .filter((item) => item !== invoke), - ], - }) - vm_cli('tape', invoke, player) - } else { - resettoend() - } - } - }} - CANCEL_BUTTON={() => { - tape_terminal_close('tape') - }} keydown={(event) => { const { key } = event const lkey = key.toLowerCase() const mods = modsfromevent(event) - switch (lkey) { + case 'arrowleft': + trackselection(mods.shift) + if (mods.ctrl) { + useTapeTerminal.setState({ xcursor: 0 }) + } else { + useTapeTerminal.setState({ + xcursor: clamp( + tapeterminal.xcursor - (mods.alt ? 10 : 1), + 0, + edge.right, + ), + }) + } + break + case 'arrowright': + trackselection(mods.shift) + if (mods.ctrl) { + useTapeTerminal.setState({ + xcursor: inputstateactive ? inputstate.length : edge.right, + }) + } else { + useTapeTerminal.setState({ + xcursor: clamp( + tapeterminal.xcursor + (mods.alt ? 10 : 1), + 0, + edge.right, + ), + }) + } + break + case 'arrowup': + if (mods.ctrl) { + inputstateswitch(tapeterminal.bufferindex + 1) + } else { + trackselection(mods.shift) + useTapeTerminal.setState({ + ycursor: clamp( + Math.round(tapeterminal.ycursor + (mods.alt ? 10 : 1)), + 0, + logrowtotalheight, + ), + }) + } + break + case 'arrowdown': + if (mods.ctrl) { + inputstateswitch(tapeterminal.bufferindex - 1) + } else { + trackselection(mods.shift) + useTapeTerminal.setState({ + ycursor: clamp( + Math.round(tapeterminal.ycursor - (mods.alt ? 10 : 1)), + 0, + logrowtotalheight, + ), + }) + } + break + case 'enter': { + const invoke = hasselection ? inputstateselected : inputstate + if (invoke.length) { + if (inputstateactive) { + useTapeTerminal.setState({ + xcursor: 0, + bufferindex: 0, + xselect: undefined, + yselect: undefined, + buffer: [ + '', + invoke, + ...tapeterminal.buffer + .slice(1) + .filter((item) => item !== invoke), + ], + }) + vm_cli('tape', invoke, player) + } else { + resettoend() + } + } + break + } + case 'esc': + case 'escape': + tape_terminal_close('tape') + break + case 'tab': + tape_terminal_inclayout('tape', !mods.shift) + break case 'delete': // single line only if (inputstateactive) { diff --git a/zss/gadget/components/userinput.tsx b/zss/gadget/components/userinput.tsx index c24309b64..d3c300806 100644 --- a/zss/gadget/components/userinput.tsx +++ b/zss/gadget/components/userinput.tsx @@ -40,15 +40,25 @@ const inputstate: Record = { [INPUT.SHOOT_RIGHT]: false, } +// handle input repeat +let acc = 0 +let previous = performance.now() +const INPUT_RATE = 250 + function inputdown(input: INPUT) { // make sure to trigger input event + // when we change from false to true state if (!inputstate[input]) { + // reset input repeat + acc = 0 + // emit input event invoke(input, { alt: inputstate[INPUT.ALT], ctrl: inputstate[INPUT.CTRL], shift: inputstate[INPUT.SHIFT], }) } + // track state change inputstate[input] = true } @@ -271,19 +281,16 @@ const buttonlookup: Record = { type GamepadEvent = CustomEvent +// @ts-expect-error added by gamepad helper document.addEventListener('gamepadbuttondown', (event: GamepadEvent) => { inputdown(buttonlookup[event.detail.button]) }) +// @ts-expect-error added by gamepad helper document.addEventListener('gamepadbuttonup', (event: GamepadEvent) => { inputup(buttonlookup[event.detail.button]) }) -// handle input repeat -let acc = 0 -let previous = performance.now() -const INPUT_RATE = 250 - function inputpoll() { const now = performance.now() const delta = now - previous