Compare commits
No commits in common. "694380aa183b8e1c0f68cc766d7712c6979a0e1c" and "45cfc6f1f8bb738c9af03a893819df3324f21696" have entirely different histories.
694380aa18
...
45cfc6f1f8
4 changed files with 36 additions and 60 deletions
|
|
@ -44,10 +44,8 @@ export function App() {
|
||||||
const [rtIdx, setRTIdx] = useState<number|undefined>();
|
const [rtIdx, setRTIdx] = useState<number|undefined>();
|
||||||
const [time, setTime] = useState<TimeMode>({kind: "paused", simtime: 0});
|
const [time, setTime] = useState<TimeMode>({kind: "paused", simtime: 0});
|
||||||
const [modal, setModal] = useState<ReactElement|null>(null);
|
const [modal, setModal] = useState<ReactElement|null>(null);
|
||||||
|
|
||||||
const [plantName, setPlantName] = usePersistentState("plant", "dummy");
|
const [plantName, setPlantName] = usePersistentState("plant", "dummy");
|
||||||
const [zoom, setZoom] = usePersistentState("zoom", 1);
|
const [zoom, setZoom] = usePersistentState("zoom", 1);
|
||||||
const [showKeys, setShowKeys] = usePersistentState("shortcuts", true);
|
|
||||||
|
|
||||||
const plant = plants.find(([pn, p]) => pn === plantName)![1];
|
const plant = plants.find(([pn, p]) => pn === plantName)![1];
|
||||||
|
|
||||||
|
|
@ -251,7 +249,7 @@ export function App() {
|
||||||
>
|
>
|
||||||
<TopPanel
|
<TopPanel
|
||||||
rt={rtIdx === undefined ? undefined : rt[rtIdx]}
|
rt={rtIdx === undefined ? undefined : rt[rtIdx]}
|
||||||
{...{rtIdx, ast, time, setTime, onUndo, onRedo, onInit, onClear, onRaise, onBack, mode, setMode, setModal, zoom, setZoom, showKeys, setShowKeys}}
|
{...{rtIdx, ast, time, setTime, onUndo, onRedo, onInit, onClear, onRaise, onBack, mode, setMode, setModal, zoom, setZoom}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
{/* Below the top bar: Editor */}
|
{/* Below the top bar: Editor */}
|
||||||
|
|
@ -283,7 +281,7 @@ export function App() {
|
||||||
</PersistentDetails>
|
</PersistentDetails>
|
||||||
<PersistentDetails localStorageKey="showInputEvents" initiallyOpen={true}>
|
<PersistentDetails localStorageKey="showInputEvents" initiallyOpen={true}>
|
||||||
<summary>input events</summary>
|
<summary>input events</summary>
|
||||||
<ShowInputEvents inputEvents={ast.inputEvents} onRaise={onRaise} disabled={rtIdx===undefined} showKeys={showKeys}/>
|
<ShowInputEvents inputEvents={ast.inputEvents} onRaise={onRaise} disabled={rtIdx===undefined}/>
|
||||||
</PersistentDetails>
|
</PersistentDetails>
|
||||||
<PersistentDetails localStorageKey="showInternalEvents" initiallyOpen={true}>
|
<PersistentDetails localStorageKey="showInternalEvents" initiallyOpen={true}>
|
||||||
<summary>internal events</summary>
|
<summary>internal events</summary>
|
||||||
|
|
|
||||||
|
|
@ -72,60 +72,38 @@ export function ShowAST(props: {root: ConcreteState | PseudoState, transitions:
|
||||||
}
|
}
|
||||||
|
|
||||||
import BoltIcon from '@mui/icons-material/Bolt';
|
import BoltIcon from '@mui/icons-material/Bolt';
|
||||||
import { KeyInfoHidden, KeyInfoVisible } from "./KeyInfo";
|
|
||||||
import { useEffect } from "react";
|
|
||||||
|
|
||||||
export function ShowInputEvents({inputEvents, onRaise, disabled, showKeys}: {inputEvents: EventTrigger[], onRaise: (e: string, p: any) => void, disabled: boolean, showKeys: boolean}) {
|
export function ShowInputEvents({inputEvents, onRaise, disabled}: {inputEvents: EventTrigger[], onRaise: (e: string, p: any) => void, disabled: boolean}) {
|
||||||
const raiseHandlers = inputEvents.map(({event}) => {
|
return inputEvents.map(({event, paramName}) =>
|
||||||
return () => {
|
<div key={event+'/'+paramName} className="toolbarGroup">
|
||||||
// @ts-ignore
|
<button
|
||||||
const param = document.getElementById(`input-${event}-param`)?.value;
|
className="inputEvent"
|
||||||
let paramParsed;
|
title={`raise this input event`}
|
||||||
try {
|
disabled={disabled}
|
||||||
if (param) {
|
onClick={() => {
|
||||||
paramParsed = JSON.parse(param); // may throw
|
// @ts-ignore
|
||||||
}
|
const param = document.getElementById(`input-${event}-param`)?.value;
|
||||||
}
|
let paramParsed;
|
||||||
catch (e) {
|
try {
|
||||||
alert("invalid json");
|
if (param) {
|
||||||
return;
|
paramParsed = JSON.parse(param); // may throw
|
||||||
}
|
}
|
||||||
onRaise(event, paramParsed);
|
}
|
||||||
};
|
catch (e) {
|
||||||
});
|
alert("invalid json");
|
||||||
const onKeyDown = (e: KeyboardEvent) => {
|
return;
|
||||||
const n = (parseInt(e.key)+9) % 10;
|
}
|
||||||
if (raiseHandlers[n] !== undefined) {
|
onRaise(event, paramParsed);
|
||||||
raiseHandlers[n]();
|
}}>
|
||||||
e.stopPropagation();
|
<BoltIcon fontSize="small"/>
|
||||||
e.preventDefault();
|
{event}
|
||||||
}
|
</button>
|
||||||
}
|
|
||||||
useEffect(() => {
|
|
||||||
window.addEventListener("keydown", onKeyDown);
|
|
||||||
return () => window.removeEventListener("keydown", onKeyDown);
|
|
||||||
}, [raiseHandlers]);
|
|
||||||
const KeyInfo = showKeys ? KeyInfoVisible : KeyInfoHidden;
|
|
||||||
return inputEvents.map(({event, paramName}, i) => {
|
|
||||||
const shortcut = (i+1)%10;
|
|
||||||
const KI = (i <= 10) ? KeyInfo : KeyInfoHidden;
|
|
||||||
return <div key={event+'/'+paramName} className="toolbarGroup">
|
|
||||||
<KI keyInfo={<kbd>{shortcut}</kbd>}>
|
|
||||||
<button
|
|
||||||
className="inputEvent"
|
|
||||||
title={`raise this input event`}
|
|
||||||
disabled={disabled}
|
|
||||||
onClick={raiseHandlers[i]}>
|
|
||||||
<BoltIcon fontSize="small"/>
|
|
||||||
{event}
|
|
||||||
</button>
|
|
||||||
</KI>
|
|
||||||
{paramName &&
|
{paramName &&
|
||||||
<><input id={`input-${event}-param`} style={{width: 20}} placeholder={paramName}/></>
|
<><input id={`input-${event}-param`} style={{width: 20}} placeholder={paramName}/></>
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>;
|
</div>
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ShowInternalEvents(props: {internalEvents: EventTrigger[]}) {
|
export function ShowInternalEvents(props: {internalEvents: EventTrigger[]}) {
|
||||||
|
|
|
||||||
|
|
@ -43,13 +43,12 @@ export type TopPanelProps = {
|
||||||
setModal: Dispatch<SetStateAction<ReactElement|null>>,
|
setModal: Dispatch<SetStateAction<ReactElement|null>>,
|
||||||
zoom: number,
|
zoom: number,
|
||||||
setZoom: Dispatch<SetStateAction<number>>,
|
setZoom: Dispatch<SetStateAction<number>>,
|
||||||
showKeys: boolean,
|
|
||||||
setShowKeys: Dispatch<SetStateAction<boolean>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TopPanel({rt, rtIdx, time, setTime, onUndo, onRedo, onInit, onClear, onRaise, onBack, ast, mode, setMode, setModal, zoom, setZoom, showKeys, setShowKeys}: TopPanelProps) {
|
export function TopPanel({rt, rtIdx, time, setTime, onUndo, onRedo, onInit, onClear, onRaise, onBack, ast, mode, setMode, setModal, zoom, setZoom}: TopPanelProps) {
|
||||||
const [displayTime, setDisplayTime] = useState("0.000");
|
const [displayTime, setDisplayTime] = useState("0.000");
|
||||||
const [timescale, setTimescale] = useState(1);
|
const [timescale, setTimescale] = useState(1);
|
||||||
|
const [showKeys, setShowKeys] = usePersistentState("shortcuts", true);
|
||||||
|
|
||||||
const KeyInfo = showKeys ? KeyInfoVisible : KeyInfoHidden;
|
const KeyInfo = showKeys ? KeyInfoVisible : KeyInfoHidden;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import imgNote from "./noteSmall.png";
|
import imgNote from "./noteSmall.png";
|
||||||
import imgWatch from "./watch.png";
|
import imgWatch from "./watch.png";
|
||||||
|
import imgWatchLight from "./watch-light.png";
|
||||||
import digitalFont from "./digital-font.ttf";
|
import digitalFont from "./digital-font.ttf";
|
||||||
import { Plant } from "../Plant";
|
import { Plant } from "../Plant";
|
||||||
import { RaisedEvent } from "@/statecharts/runtime_types";
|
import { RaisedEvent } from "@/statecharts/runtime_types";
|
||||||
|
|
@ -37,10 +38,10 @@ export function DigitalWatch({light, h, m, s, alarm, callbacks}: DigitalWatchPro
|
||||||
}
|
}
|
||||||
`}</style>
|
`}</style>
|
||||||
<svg version="1.1" width="222" height="236" style={{userSelect: 'none'}}>
|
<svg version="1.1" width="222" height="236" style={{userSelect: 'none'}}>
|
||||||
<image width="222" height="236" xlinkHref={imgWatch}/>
|
{light ?
|
||||||
|
<image width="222" height="236" xlinkHref={imgWatchLight}/>
|
||||||
{light &&
|
: <image width="222" height="236" xlinkHref={imgWatch}/>
|
||||||
<rect x={52} y={98} width={120} height={52} fill="#deeaffff" rx={5} ry={5} />}
|
}
|
||||||
|
|
||||||
<text x="111" y="126" dominantBaseline="middle" textAnchor="middle" fontFamily="digital-font" fontSize={28} style={{whiteSpace:'preserve'}}>{hhmmss}</text>
|
<text x="111" y="126" dominantBaseline="middle" textAnchor="middle" fontFamily="digital-font" fontSize={28} style={{whiteSpace:'preserve'}}>{hhmmss}</text>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue