important progress

This commit is contained in:
Joeri Exelmans 2025-10-04 23:42:48 +02:00
parent a72653fcce
commit 9bb5157d5d
3 changed files with 26 additions and 87 deletions

View file

@ -1,21 +1,5 @@
# bun-react-template
![logo](./logo.png)
To install dependencies:
# StateBuddy
```bash
bun install
```
To start a development server:
```bash
bun dev
```
To run for production:
```bash
bun start
```
This project was created using `bun init` in bun v1.2.14. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
dependencies, bla, bla

BIN
logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

View file

@ -47,10 +47,6 @@ type DraggingState = {
lastMousePos: Vec2D;
} | null; // null means: not dragging
type ResizingState = {
lastMousePos: Vec2D;
} | null; // null means: not resizing
type SelectingState = Rect2D | null;
@ -76,7 +72,6 @@ const minStateSize = {x: 40, y: 40};
export function VisualEditor() {
const [state, setState] = useState<VisualEditorState>(onOffStateMachine);
const [dragging, setDragging] = useState<DraggingState>(null);
const [resizing, setResizing] = useState<ResizingState>(null);
const [mode, setMode] = useState<"state"|"transition"|"text">("state");
@ -107,10 +102,13 @@ export function VisualEditor() {
const currentPointer = {x: e.clientX, y: e.clientY};
if (e.button === 1) {
// ignore selection, always insert rountangle
// ignore selection, middle mouse button always inserts
setState(state => {
const newID = state.nextID.toString();
setSelection([newID]);
setSelection([{uid: newID, parts: ["bottom", "right"]}]);
setDragging({
lastMousePos: currentPointer,
});
return {
...state,
rountangles: [...state.rountangles, {
@ -122,9 +120,11 @@ export function VisualEditor() {
nextID: state.nextID+1,
};
});
setResizing({lastMousePos: currentPointer});
return;
}
else if (e.button === 0) {
if (e.button === 0) {
// left mouse button on a shape will drag that shape (and everything else that's selected). if the shape under the pointer was not in the selection then the selection is reset to contain only that shape.
const uid = e.target?.dataset.uid;
const parts: string[] = e.target?.dataset.parts?.split(' ') || [];
if (uid) {
@ -138,28 +138,20 @@ export function VisualEditor() {
if (!allPartsInSelection) {
setSelection([{uid, parts, kind: "dontcare"}]);
}
// left mouse button: select and drag
setDragging({
lastMousePos: currentPointer,
});
// // right mouse button: select and resize
// else if (e.button === 2) {
// setResizing({
// lastMousePos: currentPointer,
// });
// }
return;
}
else {
}
// otherwise, just start making a selection
setDragging(null);
setResizing(null);
setSelectingState({
topLeft: currentPointer,
size: {x: 0, y: 0},
});
setSelection([]);
}
}
};
const onMouseMove = (e: MouseEvent) => {
@ -195,31 +187,6 @@ export function VisualEditor() {
return {lastMousePos: currentPointer};
});
}
else if (resizing) {
setResizing(prevResizeState => {
const pointerDelta = subtractV2D(currentPointer, prevResizeState!.lastMousePos);
const halfPointerDelta = scaleV2D(pointerDelta, 0.5);
setState(state => ({
...state,
rountangles: state.rountangles.map(r => {
if (selection.includes(r.uid)) {
const newSize = addV2D(r.size, halfPointerDelta);
return {
...r,
size: {
x: Math.max(newSize.x, minStateSize.x),
y: Math.max(newSize.y, minStateSize.y),
},
};
}
else {
return r; // no change
}
}),
}));
return {lastMousePos: currentPointer};
});
}
else if (selectingState) {
setSelectingState(ss => {
const selectionSize = subtractV2D(currentPointer, ss!.topLeft);
@ -233,7 +200,6 @@ export function VisualEditor() {
const onMouseUp = (e: MouseEvent) => {
setDragging(null);
setResizing(null);
setSelectingState(ss => {
if (ss) {
// we were making a selection
@ -263,17 +229,6 @@ export function VisualEditor() {
uid,
parts: [...parts],
})));
// const selected = [
// ...state.rountangles.filter(rountangle =>
// isEntirelyWithin(rountangle, normalizedSS)),
// ...state.arrows.filter(arrow => isEntirelyWithin({
// topLeft: arrow.start,
// size: subtractV2D(arrow.end, arrow.start),
// }, normalizedSS)),
// ];
// setSelection(selected.map(r => r.uid));
}
return null; // no longer selecting
});
@ -290,7 +245,7 @@ export function VisualEditor() {
setSelection(selection => {
setState(state => ({
...state,
rountangles: state.rountangles.filter(r => !selection.includes(r.uid)),
rountangles: state.rountangles.filter(r => !selection.some(rs => rs.uid === r.uid)),
}));
return [];
});
@ -340,7 +295,7 @@ export function VisualEditor() {
window.removeEventListener("mousemove", onMouseMove);
window.removeEventListener("mouseup", onMouseUp);
};
}, [selectingState, dragging, resizing]);
}, [selectingState, dragging]);
return <svg width="100%" height="100%"
className="svgCanvas"
@ -383,7 +338,7 @@ export function VisualEditor() {
Left mouse button: Select/Drag.
</text>
<text x={5} y={40}>
Right mouse button: Resize.
Right mouse button: Select only.
</text>
<text x={5} y={60}>
Middle mouse button: Insert [S]tates / [T]ransitions / Te[X]t (current mode: {mode})</text>