diff --git a/src/App/App.css b/src/App/App.css index 1b05d57..3bdf30a 100644 --- a/src/App/App.css +++ b/src/App/App.css @@ -35,18 +35,26 @@ summary { text-align: "right"; } - - -.toolbar > * { +.toolbar * { vertical-align: middle; - height: 26px; } -.toolbar > input { + +.toolbar *:not(label) { + /* vertical-align: bottom; */ +} + +.toolbar input { height: 20px; } +.toolbar div { + vertical-align: bottom; +} +.toolbar button { + height: 26px; +} button.active { border: solid blue 2px; background-color: rgba(0,0,255,0.2); color: black; -} \ No newline at end of file +} diff --git a/src/App/KeyInfo.tsx b/src/App/KeyInfo.tsx new file mode 100644 index 0000000..09afde6 --- /dev/null +++ b/src/App/KeyInfo.tsx @@ -0,0 +1,16 @@ +import { Stack } from "@mui/material"; + +export function KeyInfoVisible(props: {keyInfo, children}) { + return +
+ {props.keyInfo} +
+
+ {props.children} +
+
+} + +export function KeyInfoHidden(props: {children}) { + return <>{props.children}; +} diff --git a/src/App/TopPanel.tsx b/src/App/TopPanel.tsx index 4b336e9..bf9894e 100644 --- a/src/App/TopPanel.tsx +++ b/src/App/TopPanel.tsx @@ -11,9 +11,12 @@ import SkipNextIcon from '@mui/icons-material/SkipNext'; import TrendingFlatIcon from '@mui/icons-material/TrendingFlat'; import AccessAlarmIcon from '@mui/icons-material/AccessAlarm'; import StopIcon from '@mui/icons-material/Stop'; +import UndoIcon from '@mui/icons-material/Undo'; +import RedoIcon from '@mui/icons-material/Redo'; import { formatTime } from "./util"; import { InsertMode } from "../VisualEditor/VisualEditor"; +import { KeyInfoHidden, KeyInfoVisible } from "./KeyInfo"; export type TopPanelProps = { rt?: BigStep, @@ -61,6 +64,9 @@ function HistoryIcon(props: {kind: "shallow"|"deep"}) { export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode, setMode}: TopPanelProps) { const [displayTime, setDisplayTime] = useState("0.000"); const [timescale, setTimescale] = useState(1); + const [showKeys, setShowKeys] = useState(true); + + const KeyInfo = showKeys ? KeyInfoVisible : KeyInfoHidden; useEffect(() => { const onKeyDown = (e: KeyboardEvent) => { @@ -68,12 +74,25 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode e.preventDefault(); onChangePaused(time.kind !== "paused", performance.now()); }; + if (e.key === "i") { + e.preventDefault(); + onInit(); + } }; window.addEventListener("keydown", onKeyDown); return () => { window.removeEventListener("keydown", onKeyDown); }; - }, [time]); + }, [time, onInit]); + + useEffect(() => { + setTimeout(() => localStorage.setItem("showKeys", showKeys?"1":"0"), 100); + }, [showKeys]) + + useEffect(() => { + const show = localStorage.getItem("showKeys") || "1"; + setShowKeys(show==="1") + }, []) function updateDisplayedTime() { const now = performance.now(); @@ -126,53 +145,71 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode return <>
+ +
+
+ {([ - ["and", "AND-states", ], - ["or", "OR-states", ], - ["pseudo", "pseudo-states", ], - ["shallow", "shallow history", ], - ["deep", "deep history", ], - ["transition", "transitions", ], - ["text", "text", <> T ], - ] as [InsertMode, string, ReactElement][]).map(([m, hint, buttonTxt]) => + ["and", "AND-states", , A], + ["or", "OR-states", , O], + ["pseudo", "pseudo-states", , P], + ["shallow", "shallow history", , H], + ["deep", "deep history", , <>], + ["transition", "transitions", , T], + ["text", "text", <> T , X], + ] as [InsertMode, string, ReactElement, ReactElement][]).map(([m, hint, buttonTxt, keyInfo]) => + )} + >{buttonTxt})} + +
  +
+ + I}> +   - - - - {/* onChangePaused(newValue==="paused", performance.now())} size="small"> - - - */} + Space}> + + +   + S}> + onTimeScaleChange(e.target.value, performance.now())}/> + F}> +   +   + +   +   + + Tab}> + + +
  +
+
+ {ast.inputEvents && <> {ast.inputEvents.map(({event, paramName}) => @@ -207,9 +250,20 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode }}> {event} - {paramName && <>} )} + + {paramName && <>} +  )} } +   + +
+ setShowKeys(e.target.checked)}> + +
+ +
+
; } diff --git a/src/App/shortcut_handler.ts b/src/App/shortcut_handler.ts index 730c6a1..e74228c 100644 --- a/src/App/shortcut_handler.ts +++ b/src/App/shortcut_handler.ts @@ -18,5 +18,11 @@ export function getKeyHandler(setMode: Dispatch>) { if (e.key === "x") { setMode("text"); } + if (e.key === "h") { + setMode(oldMode => { + if (oldMode === "shallow") return "deep"; + return "shallow"; + }) + } } } diff --git a/src/index.css b/src/index.css index cc58cac..9499955 100644 --- a/src/index.css +++ b/src/index.css @@ -7,3 +7,31 @@ html, body { div#root { height: 100%; } + +kbd { + display: inline-block; + padding: .12em .3em; + padding-bottom: 3px; + font-family: ui-monospace, SFMono-Regular, Menlo, monospace; + font-size: .9em; + line-height: 1; + border: 0.8px solid #aaa; + border-radius: 4px; + background: linear-gradient(#ebebeb, #fff); + box-shadow: inset 0 -2px 0 #aaa; + vertical-align: middle; + user-select: none; +} +kbd:active { transform: translateY(1px); } + + +input { + /* border: solid blue 2px; */ + accent-color: rgba(0,0,255,0.2); + + /* accent-color: blue; */ +} + +::selection { + background-color: rgba(0,0,255,0.2); +}