better looks

This commit is contained in:
Joeri Exelmans 2025-10-19 19:21:17 +02:00
parent f992dcb5f6
commit 20a36825d4
7 changed files with 71 additions and 22 deletions

View file

@ -18,3 +18,32 @@ details {
width: fit-content; width: fit-content;
border-radius: 10px; border-radius: 10px;
} }
.outputEvent {
border: 1px black solid;
border-radius: 6px;
margin-left: 4px;
padding-left: 2px;
padding-right: 2px;
background-color: rgb(230, 249, 255);
}
.activeState {
border: rgb(192, 125, 0);
background-color:rgb(255, 251, 244);
filter: drop-shadow( 0px 0px 3px rgba(192, 125, 0, 0.856));
border-radius: 6px;
margin-left: 4px;
padding-left: 2px;
padding-right: 2px;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 0;
margin-bottom: -3px;
padding: 0;
}

View file

@ -12,7 +12,7 @@ import "./App.css";
import { Box, Stack } from "@mui/material"; import { Box, Stack } from "@mui/material";
import { TopPanel } from "./TopPanel"; import { TopPanel } from "./TopPanel";
import { RTHistory } from "./RTHistory"; import { RTHistory } from "./RTHistory";
import { ShowAST } from "./ShowAST"; import { ShowAST, ShowOutputEvents } from "./ShowAST";
import { TraceableError } from "../statecharts/parser"; import { TraceableError } from "../statecharts/parser";
import { getKeyHandler } from "./shortcut_handler"; import { getKeyHandler } from "./shortcut_handler";
import { BottomPanel } from "./BottomPanel"; import { BottomPanel } from "./BottomPanel";
@ -142,6 +142,8 @@ export function App() {
const highlightTransitions = (rtIdx === undefined) ? [] : rt[rtIdx].firedTransitions; const highlightTransitions = (rtIdx === undefined) ? [] : rt[rtIdx].firedTransitions;
console.log(ast);
return <Stack sx={{height:'100vh'}}> return <Stack sx={{height:'100vh'}}>
{/* Top bar */} {/* Top bar */}
<Box <Box
@ -157,9 +159,12 @@ export function App() {
{...{rtIdx, ast, time, setTime, onInit, onClear, onRaise, onBack, mode, setMode}} {...{rtIdx, ast, time, setTime, onInit, onClear, onRaise, onBack, mode, setMode}}
/> />
</Box> </Box>
{/* Everything below the top bar */}
<Stack direction="row" sx={{ <Stack direction="row" sx={{
overflow: 'auto', overflow: 'auto',
}}> }}>
{/* main */} {/* main */}
<Box sx={{ <Box sx={{
flexGrow:1, flexGrow:1,
@ -167,6 +172,7 @@ export function App() {
}}> }}>
<VisualEditor {...{ast, setAST, rt: rt.at(rtIdx!), setRT, errors, setErrors, mode, highlightActive, highlightTransitions}}/> <VisualEditor {...{ast, setAST, rt: rt.at(rtIdx!), setRT, errors, setErrors, mode, highlightActive, highlightTransitions}}/>
</Box> </Box>
{/* right sidebar */} {/* right sidebar */}
<Box <Box
sx={{ sx={{
@ -174,8 +180,10 @@ export function App() {
borderColor: "divider", borderColor: "divider",
flex: '0 0 content', flex: '0 0 content',
overflow: "auto", overflow: "auto",
maxWidth: 350,
}}> }}>
<ShowAST {...{...ast, rt: rt.at(rtIdx!), highlightActive}}/> <ShowAST {...{...ast, rt: rt.at(rtIdx!), highlightActive}}/>
<ShowOutputEvents outputEvents={ast.outputEvents}/>
<br/> <br/>
<div ref={refRightSideBar}> <div ref={refRightSideBar}>
<RTHistory {...{ast, rt, rtIdx, setTime, setRTIdx, refRightSideBar}}/> <RTHistory {...{ast, rt, rtIdx, setTime, setRTIdx, refRightSideBar}}/>

View file

@ -5,5 +5,7 @@
} }
.bottom { .bottom {
border-top: 1px lightgrey solid;
background-color: lightyellow; background-color: lightyellow;
/* background-color: rgb(255, 251, 244); */
} }

View file

@ -6,7 +6,7 @@ import "./BottomPanel.css";
import head from "../head.svg" ; import head from "../head.svg" ;
export function BottomPanel(props: {errors: TraceableError[]}) { export function BottomPanel(props: {errors: TraceableError[]}) {
const [greeting, setGreeting] = useState(<><img src={head}/>&emsp;"Welcome to StateBuddy, buddy!"</>); const [greeting, setGreeting] = useState(<b><img src={head}/>&emsp;"Welcome to StateBuddy, buddy!"</b>);
useEffect(() => { useEffect(() => {
setTimeout(() => { setTimeout(() => {

View file

@ -21,13 +21,14 @@ export function RTHistory({rt, rtIdx, ast, setRTIdx, setTime, refRightSideBar}:
return <div> return <div>
{rt.map((r, idx) => <> {rt.map((r, idx) => <>
<hr/>
<div className={"runtimeState"+(idx===rtIdx?" active":"")} onClick={() => gotoRt(idx, r.simtime)}> <div className={"runtimeState"+(idx===rtIdx?" active":"")} onClick={() => gotoRt(idx, r.simtime)}>
<div>({formatTime(r.simtime)}, {r.inputEvent || "<init>"})</div> <div>{formatTime(r.simtime)}, {r.inputEvent || "<init>"}</div>
<ShowMode mode={r.mode} statechart={ast}/> <ShowMode mode={r.mode} statechart={ast}/>
<ShowEnvironment environment={r.environment}/> <ShowEnvironment environment={r.environment}/>
{r.outputEvents.length>0 && <div> {r.outputEvents.length>0 && <>^
{r.outputEvents.map((e:RaisedEvent) => '^'+e.name).join(', ')} {r.outputEvents.map((e:RaisedEvent) => <span className="outputEvent">{e.name}</span>)}
</div>} </>}
</div></>)} </div></>)}
</div>; </div>;
} }
@ -43,8 +44,8 @@ function ShowEnvironment(props: {environment: Environment}) {
function ShowMode(props: {mode: Mode, statechart: Statechart}) { function ShowMode(props: {mode: Mode, statechart: Statechart}) {
const activeLeafs = getActiveLeafs(props.mode, props.statechart); const activeLeafs = getActiveLeafs(props.mode, props.statechart);
return <div>mode: {[...activeLeafs].map(uid => return <div>{[...activeLeafs].map(uid =>
stateDescription(props.statechart.uid2State.get(uid)!)).join(", ")}</div>; <span className="activeState">{stateDescription(props.statechart.uid2State.get(uid)!)}</span>)}</div>;
} }
function getActiveLeafs(mode: Mode, sc: Statechart) { function getActiveLeafs(mode: Mode, sc: Statechart) {

View file

@ -25,7 +25,7 @@ export function ShowExpr(props: {expr: Expression}) {
export function ShowAction(props: {action: Action}) { export function ShowAction(props: {action: Action}) {
if (props.action.kind === "raise") { if (props.action.kind === "raise") {
return <>^{props.action.event}</>; return <>^<span className="outputEvent">{props.action.event}</span></>;
} }
else if (props.action.kind === "assignment") { else if (props.action.kind === "assignment") {
return <>{props.action.lhs} = <ShowExpr expr={props.action.rhs}/>;</>; return <>{props.action.lhs} = <ShowExpr expr={props.action.rhs}/>;</>;
@ -59,3 +59,12 @@ export function ShowAST(props: {root: ConcreteState | PseudoState, transitions:
} }
</details> </details>
} }
export function ShowOutputEvents(props: {outputEvents: Set<string>}) {
return <div style={{whiteSpace: 'wrap'}}>
out:
{[...props.outputEvents].map(eventName => {
return <><span className="outputEvent">{eventName}</span> </>;
})}
</div>;
}

View file

@ -286,18 +286,18 @@ export function parseStatechart(state: VisualEditorState, conns: Connections): [
} }
} }
// // raise-actions // raise-actions
// for (const action of parsed.actions) { for (const action of parsed.actions) {
// if (action.kind === "raise") { if (action.kind === "raise") {
// const {event} = action; const {event} = action;
// if (event.startsWith("_")) { if (event.startsWith("_")) {
// internalEvents.add(event); // internalEvents.add(event);
// } }
// else { else {
// outputEvents.add(event); outputEvents.add(event);
// } }
// } }
// } }
// collect variables // collect variables
variables = variables.union(findVariables(parsed.guard)); variables = variables.union(findVariables(parsed.guard));