better dialogs

This commit is contained in:
Joeri Exelmans 2025-10-19 21:30:45 +02:00
parent ff32e6d000
commit c2dd27afa5
4 changed files with 39 additions and 12 deletions

View file

@ -1,10 +1,19 @@
import logo from "../../artwork/logo.svg";
export function About() {
return <div style={{backgroundColor: 'white', width: 500, padding: 4}}>
return <div style={{width: 500, padding: 4}}>
<p><img src={logo}/></p>
<p>StateBuddy is an <a target="_blank" href="https://deemz.org/git/research/statebuddy">open source</a> tool for <a target="_blank" href="https://dl.acm.org/doi/10.1016/0167-6423(87)90035-9">Statechart</a> editing, simulation, debugging and testing environment, inspired by <a target="_blank" href="https://dl.acm.org/doi/10.1145/3417990.3421401">CouchEdit</a>.</p>
<p>It was originally created for teaching Statecharts to university students, but likely is a useful tool for other purposes as well.</p>
<p>Commercial use: <a href="mailto:joeri.exelmans@gmail.com">e&#x2011;mail me</a> for permission.</p>
<p>StateBuddy is an <a target="_blank" href="https://deemz.org/git/research/statebuddy">open source</a> tool for <a target="_blank" href="https://dl.acm.org/doi/10.1016/0167-6423(87)90035-9">Statechart</a> editing, simulation, (omniscient) debugging and testing.</p>
<p>It was originally created for teaching Statecharts to university students.</p>
<p>The main novelty is in the way you deal with the visual concrete syntax: You just draw boxes, arrows and text. Connectedness or insideness are continuously figured out by a parser, but they do not influence what you can do with the shapes, which IMO is much more intuitive than editors that try to "help" you. This idea comes from <a target="_blank" href="https://dl.acm.org/doi/10.1145/3417990.3421401">CouchEdit</a>, which was in turn influenced by the very old tool <a target="_blank" href="https://en.wikipedia.org/wiki/I-Logix#History">StateMate</a>.</p>
<p>Unique to StateBuddy is that sides of boxes, and endpoints of arrows can be independently selected for many boxes/arrows simultaneously, making editing even more powerful while remaining highly intuitive to both novice and expert users.</p>
<p>No commercial use without my written permission.</p>
<p>Contact: <a href="mailto:joeri.exelmans@gmail.com">joeri.exelmans@gmail.com</a></p>
</div>;
}

View file

@ -58,3 +58,22 @@ button.active {
background-color: rgba(0,0,255,0.2);
color: black;
}
.modalInner {
position: relative;
top: 50%;
transform: translateY(-50%);
text-align: center;
display: inline-block;
background-color: white;
}
.modalOuter {
width: 100%;
height: 100%;
position:absolute;
text-align: center;
background-color: rgba(200,200,200,0.7);
/* backdrop-filter: blur(2px) */
}

View file

@ -149,10 +149,9 @@ export function App() {
return <>
{/* Modal dialog */}
{modal && <div
onMouseDown={() => setModal(null)}
style={{width: '100%', height: '100%', position:'absolute', textAlign: 'center', backgroundColor: 'rgba(127,127,127,0.5)' }}>
<div
style={{position: 'relative', top: '50%', transform: 'translateY(-50%)', textAlign: 'center', display: 'inline-block'}}>
className="modalOuter"
onMouseDown={() => setModal(null)}>
<div className="modalInner">
<span onMouseDown={e => e.stopPropagation()}>
{modal}
</span>

View file

@ -1,6 +1,6 @@
import { Dispatch, ReactElement, SetStateAction, useState } from "react";
import { parse as parseLabel, SyntaxError } from "../statecharts/label_parser";
import { parse as parseLabel } from "../statecharts/label_parser";
export function TextDialog(props: {setModal: Dispatch<SetStateAction<ReactElement|null>>, text: string, done: (newText: string|undefined) => void}) {
const [text, setText] = useState(props.text);
@ -26,12 +26,12 @@ export function TextDialog(props: {setModal: Dispatch<SetStateAction<ReactElemen
error = e.message;
}
return <div onKeyDown={onKeyDown} style={{backgroundColor:'white', padding: 4, width: 520}}>
Edit text label:<br/>
return <div onKeyDown={onKeyDown} style={{padding: 4, width: 520}}>
Text label:<br/>
<textarea autoFocus style={{fontFamily: 'Roboto', width:500, height: 100}} onChange={e=>setText(e.target.value)}>{text}</textarea>
<br/>
<span style={{color: 'var(--error-color)'}}>{error}</span><br/>
<p><kbd>Enter</kbd> to confirm. <kbd>Escape</kbd> to cancel.
<p><kbd>Enter</kbd> to confirm. <kbd>Esc</kbd> to cancel.
</p>
(Tip: <kbd>Shift</kbd>+<kbd>Enter</kbd> to insert newline.)
</div>;