diff --git a/src/App/App.tsx b/src/App/App.tsx index 4a6408e..743d7fa 100644 --- a/src/App/App.tsx +++ b/src/App/App.tsx @@ -56,6 +56,28 @@ export function App() { scrollDownSidebar(); } + function onBack() { + setTime(() => { + if (rtIdx !== undefined) { + if (rtIdx > 0) + return { + kind: "paused", + simtime: rt[rtIdx-1].simtime, + } + } + return { kind: "paused", simtime: 0 }; + }); + setRTIdx(rtIdx => { + if (rtIdx !== undefined) { + if (rtIdx > 0) + return rtIdx - 1; + else + return 0; + } + else return undefined; + }) + } + function scrollDownSidebar() { if (refRightSideBar.current) { const el = refRightSideBar.current; @@ -128,15 +150,21 @@ export function App() { borderBottom: 1, borderColor: "divider", alignItems: 'center', + flex: '0 0 content', }}> - + {/* main */} - + {/* right sidebar */} @@ -145,7 +173,6 @@ export function App() { borderLeft: 1, borderColor: "divider", flex: '0 0 content', - height: 'calc(100vh-32px)', overflow: "auto", }}> @@ -155,7 +182,9 @@ export function App() { - + ; diff --git a/src/App/BottomPanel.css b/src/App/BottomPanel.css index ceb412e..bbe185e 100644 --- a/src/App/BottomPanel.css +++ b/src/App/BottomPanel.css @@ -1,3 +1,9 @@ .errorStatus { - color: rgb(230,0,0); + /* background-color: rgb(230,0,0); */ + background-color: var(--error-color); + color: white; +} + +.bottom { + background-color: lightyellow; } \ No newline at end of file diff --git a/src/App/BottomPanel.tsx b/src/App/BottomPanel.tsx index f7cde46..b892f8a 100644 --- a/src/App/BottomPanel.tsx +++ b/src/App/BottomPanel.tsx @@ -1,10 +1,22 @@ +import { useEffect, useState } from "react"; import { TraceableError } from "../statecharts/parser"; import "./BottomPanel.css"; export function BottomPanel(props: {errors: TraceableError[]}) { - return
-
{ - props.errors.length>0 && <>{props.errors.length} errors {props.errors.map(({message})=>message).join(',')}}
+ const [greeting, setGreeting] = useState("Welcome to StateBuddy, buddy!"); + + useEffect(() => { + setTimeout(() => { + setGreeting(""); + }, 2000); + }, []); + + return
+ <>{greeting} + {props.errors.length > 0 && +
+ {props.errors.length>0 && <>{props.errors.length} errors: {props.errors.map(({message})=>message).join(', ')}} +
}
; } \ No newline at end of file diff --git a/src/App/KeyInfo.tsx b/src/App/KeyInfo.tsx index 09afde6..9e7fc73 100644 --- a/src/App/KeyInfo.tsx +++ b/src/App/KeyInfo.tsx @@ -2,10 +2,10 @@ import { Stack } from "@mui/material"; export function KeyInfoVisible(props: {keyInfo, children}) { return -
+
{props.keyInfo}
-
+
{props.children}
diff --git a/src/App/TopPanel.tsx b/src/App/TopPanel.tsx index 4bab859..bdc046a 100644 --- a/src/App/TopPanel.tsx +++ b/src/App/TopPanel.tsx @@ -8,7 +8,7 @@ import PauseIcon from '@mui/icons-material/Pause'; import PlayArrowIcon from '@mui/icons-material/PlayArrow'; import BoltIcon from '@mui/icons-material/Bolt'; import SkipNextIcon from '@mui/icons-material/SkipNext'; -import TrendingFlatIcon from '@mui/icons-material/TrendingFlat'; +import SkipPreviousIcon from '@mui/icons-material/SkipPrevious';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'; @@ -20,11 +20,13 @@ import { KeyInfoHidden, KeyInfoVisible } from "./KeyInfo"; export type TopPanelProps = { rt?: BigStep, + rtIdx?: number, time: TimeMode, setTime: Dispatch>, onInit: () => void, onClear: () => void, onRaise: (e: string, p: any) => void, + onBack: () => void, ast: Statechart, mode: InsertMode, setMode: Dispatch>, @@ -61,7 +63,7 @@ function HistoryIcon(props: {kind: "shallow"|"deep"}) { } -export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode, setMode}: TopPanelProps) { +export function TopPanel({rt, rtIdx, time, setTime, onInit, onClear, onRaise, onBack, ast, mode, setMode}: TopPanelProps) { const [displayTime, setDisplayTime] = useState("0.000"); const [timescale, setTimescale] = useState(1); const [showKeys, setShowKeys] = useState(true); @@ -99,6 +101,10 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode e.preventDefault(); setShowKeys(show => !show); } + if (e.key === "Backspace") { + e.preventDefault(); + onBack(); + } }; window.addEventListener("keydown", onKeyDown); return () => { @@ -186,9 +192,20 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode return <>
-
+
+ Ctrl+Z}> + + + Ctrl+Shift+Z}> + + +
+ +   + +
{([ ["and", "AND-states", , A], ["or", "OR-states", , O], @@ -205,7 +222,6 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode className={mode===m ? "active":""} onClick={() => setMode(m)} >{buttonTxt})} -
  @@ -221,7 +237,7 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode   - Space}> + Space toggles}> @@ -253,6 +269,12 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode +   + Backspace}> + + +
  @@ -291,7 +313,7 @@ export function TopPanel({rt, time, setTime, onInit, onClear, onRaise, ast, mode
~}> setShowKeys(e.target.checked)}> - +
diff --git a/src/VisualEditor/VisualEditor.css b/src/VisualEditor/VisualEditor.css index f9d982e..619125a 100644 --- a/src/VisualEditor/VisualEditor.css +++ b/src/VisualEditor/VisualEditor.css @@ -39,19 +39,12 @@ /* fill: rgba(0, 0, 255, 0.2); */ } .rountangle.error { - stroke: rgb(230,0,0); + stroke: var(--error-color); } .rountangle.active { - /* fill: rgb(255, 140, 0); */ - /* fill-opacity: 0.2; */ - /* stroke: rgb(100, 149, 237); */ - /* stroke: */ stroke: rgb(192, 125, 0); fill:rgb(255, 251, 244); - /* fill: lightgrey; */ - /* color: white; */ - filter: drop-shadow( 0px 0px 3px rgba(192, 125, 0, 0.856)); - /* stroke-width: 3px; */ + filter: drop-shadow( 0px 0px 3px rgba(192, 125, 0, 0.85)); } .selected:hover:not(:active) { @@ -166,7 +159,7 @@ text.helper:hover { } .arrow.error { - stroke: rgb(230,0,0); + stroke: var(--error-color); } .arrow.fired { stroke: rgb(192, 125, 0); @@ -174,7 +167,7 @@ text.helper:hover { } text.error, tspan.error { - fill: rgb(230,0,0); + fill: var(--error-color); font-weight: 600; } diff --git a/src/VisualEditor/VisualEditor.tsx b/src/VisualEditor/VisualEditor.tsx index d5d6c80..3f657dc 100644 --- a/src/VisualEditor/VisualEditor.tsx +++ b/src/VisualEditor/VisualEditor.tsx @@ -314,7 +314,8 @@ export function VisualEditor({ast, setAST, rt, errors, setErrors, mode, highligh const onMouseMove = (e: {pageX: number, pageY: number}) => { const currentPointer = getCurrentPointer(e); if (dragging) { - const pointerDelta = subtractV2D(currentPointer, dragging.lastMousePos); + // const pointerDelta = subtractV2D(currentPointer, dragging.lastMousePos); + const pointerDelta = {x: e.movementX, y: e.movementY}; setState(state => ({ ...state, rountangles: state.rountangles.map(r => { diff --git a/src/index.css b/src/index.css index c54e9a7..cf0a025 100644 --- a/src/index.css +++ b/src/index.css @@ -4,6 +4,11 @@ html, body { font-family: Roboto, sans-serif; } +body { + /* --error-color: darkred; */ + --error-color: rgb(163, 0, 0); +} + div#root { height: 100%; } @@ -18,7 +23,7 @@ kbd { border: 0.8px solid #aaa; border-radius: 4px; background: linear-gradient(#ebebeb, #fff); - box-shadow: inset 0 -2px 0 #aaa; + box-shadow: inset 0 -1.5px 0 #aaa; vertical-align: middle; user-select: none; } @@ -38,4 +43,4 @@ input { label { user-select: none; -} \ No newline at end of file +}