diff --git a/src/App/App.tsx b/src/App/App.tsx index e116143..4a6408e 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -32,6 +32,7 @@ export function App() { setRT([{inputEvent: null, simtime: 0, ...config}]); setRTIdx(0); setTime({kind: "paused", simtime: 0}); + scrollDownSidebar(); } function onClear() { @@ -51,12 +52,17 @@ export function App() { function appendNewConfig(inputEvent: string, simtime: number, config: BigStepOutput) { setRT([...rt.slice(0, rtIdx!+1), {inputEvent, simtime, ...config}]); setRTIdx(rtIdx!+1); - console.log('new config:', config); + // console.log('new config:', config); + scrollDownSidebar(); + } + + function scrollDownSidebar() { if (refRightSideBar.current) { const el = refRightSideBar.current; + // hack: we want to scroll to the new element, but we have to wait until it is rendered... setTimeout(() => { el.scrollIntoView({block: "end", behavior: "smooth"}); - }, 100); + }, 50); } } diff --git a/src/App/TopPanel.tsx b/src/App/TopPanel.tsx index bf9894e..4bab859 100644 --- a/src/App/TopPanel.tsx +++ b/src/App/TopPanel.tsx @@ -72,18 +72,39 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode const onKeyDown = (e: KeyboardEvent) => { if (e.key === " ") { e.preventDefault(); + if (rt) onChangePaused(time.kind !== "paused", performance.now()); }; if (e.key === "i") { e.preventDefault(); onInit(); } + if (e.key === "c") { + e.preventDefault(); + onClear(); + } + if (e.key === "Tab") { + e.preventDefault(); + onSkip(); + } + if (e.key === "s") { + e.preventDefault(); + onSlower(); + } + if (e.key === "f") { + e.preventDefault(); + onFaster(); + } + if (e.key === "`") { + e.preventDefault(); + setShowKeys(show => !show); + } }; window.addEventListener("keydown", onKeyDown); return () => { window.removeEventListener("keydown", onKeyDown); }; - }, [time, onInit]); + }, [time, onInit, timescale]); useEffect(() => { setTimeout(() => localStorage.setItem("showKeys", showKeys?"1":"0"), 100); @@ -143,6 +164,25 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode const timers: Timers = (rt?.environment.get("_timers") || []); const nextTimedTransition: [number, TimerElapseEvent] | undefined = timers[0]; + function onSkip() { + const now = performance.now(); + setTime(time => { + if (time.kind === "paused") { + return {kind: "paused", simtime: nextTimedTransition[0]}; + } + else { + return {kind: "realtime", scale: time.scale, since: {simtime: nextTimedTransition[0], wallclktime: now}}; + } + }); + } + + function onSlower() { + onTimeScaleChange((timescale/2).toString(), performance.now()); + } + function onFaster() { + onTimeScaleChange((timescale*2).toString(), performance.now()); + } + return <>
@@ -175,7 +215,9 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode I}> + C}> +   @@ -186,21 +228,19 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode   -   +   S}> - + onTimeScaleChange(e.target.value, performance.now())}/> F}> - +   -   -   @@ -210,17 +250,7 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode Tab}> - +
@@ -259,8 +289,10 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode  
+ ~}> setShowKeys(e.target.checked)}> +
diff --git a/src/index.css b/src/index.css index 9499955..c54e9a7 100644 --- a/src/index.css +++ b/src/index.css @@ -35,3 +35,7 @@ input { ::selection { background-color: rgba(0,0,255,0.2); } + +label { + user-select: none; +} \ No newline at end of file