important progress
This commit is contained in:
parent
a72653fcce
commit
9bb5157d5d
3 changed files with 26 additions and 87 deletions
22
README.md
22
README.md
|
|
@ -1,21 +1,5 @@
|
||||||
# bun-react-template
|

|
||||||
|
|
||||||
To install dependencies:
|
# StateBuddy
|
||||||
|
|
||||||
```bash
|
dependencies, bla, bla
|
||||||
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.
|
|
||||||
BIN
logo.png
Normal file
BIN
logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 57 KiB |
|
|
@ -47,10 +47,6 @@ type DraggingState = {
|
||||||
lastMousePos: Vec2D;
|
lastMousePos: Vec2D;
|
||||||
} | null; // null means: not dragging
|
} | null; // null means: not dragging
|
||||||
|
|
||||||
type ResizingState = {
|
|
||||||
lastMousePos: Vec2D;
|
|
||||||
} | null; // null means: not resizing
|
|
||||||
|
|
||||||
type SelectingState = Rect2D | null;
|
type SelectingState = Rect2D | null;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -76,7 +72,6 @@ const minStateSize = {x: 40, y: 40};
|
||||||
export function VisualEditor() {
|
export function VisualEditor() {
|
||||||
const [state, setState] = useState<VisualEditorState>(onOffStateMachine);
|
const [state, setState] = useState<VisualEditorState>(onOffStateMachine);
|
||||||
const [dragging, setDragging] = useState<DraggingState>(null);
|
const [dragging, setDragging] = useState<DraggingState>(null);
|
||||||
const [resizing, setResizing] = useState<ResizingState>(null);
|
|
||||||
|
|
||||||
const [mode, setMode] = useState<"state"|"transition"|"text">("state");
|
const [mode, setMode] = useState<"state"|"transition"|"text">("state");
|
||||||
|
|
||||||
|
|
@ -107,10 +102,13 @@ export function VisualEditor() {
|
||||||
const currentPointer = {x: e.clientX, y: e.clientY};
|
const currentPointer = {x: e.clientX, y: e.clientY};
|
||||||
|
|
||||||
if (e.button === 1) {
|
if (e.button === 1) {
|
||||||
// ignore selection, always insert rountangle
|
// ignore selection, middle mouse button always inserts
|
||||||
setState(state => {
|
setState(state => {
|
||||||
const newID = state.nextID.toString();
|
const newID = state.nextID.toString();
|
||||||
setSelection([newID]);
|
setSelection([{uid: newID, parts: ["bottom", "right"]}]);
|
||||||
|
setDragging({
|
||||||
|
lastMousePos: currentPointer,
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
rountangles: [...state.rountangles, {
|
rountangles: [...state.rountangles, {
|
||||||
|
|
@ -122,9 +120,11 @@ export function VisualEditor() {
|
||||||
nextID: state.nextID+1,
|
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 uid = e.target?.dataset.uid;
|
||||||
const parts: string[] = e.target?.dataset.parts?.split(' ') || [];
|
const parts: string[] = e.target?.dataset.parts?.split(' ') || [];
|
||||||
if (uid) {
|
if (uid) {
|
||||||
|
|
@ -138,28 +138,20 @@ export function VisualEditor() {
|
||||||
if (!allPartsInSelection) {
|
if (!allPartsInSelection) {
|
||||||
setSelection([{uid, parts, kind: "dontcare"}]);
|
setSelection([{uid, parts, kind: "dontcare"}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// left mouse button: select and drag
|
|
||||||
setDragging({
|
setDragging({
|
||||||
lastMousePos: currentPointer,
|
lastMousePos: currentPointer,
|
||||||
});
|
});
|
||||||
// // right mouse button: select and resize
|
return;
|
||||||
// else if (e.button === 2) {
|
|
||||||
// setResizing({
|
|
||||||
// lastMousePos: currentPointer,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
|
|
||||||
|
// otherwise, just start making a selection
|
||||||
setDragging(null);
|
setDragging(null);
|
||||||
setResizing(null);
|
|
||||||
setSelectingState({
|
setSelectingState({
|
||||||
topLeft: currentPointer,
|
topLeft: currentPointer,
|
||||||
size: {x: 0, y: 0},
|
size: {x: 0, y: 0},
|
||||||
});
|
});
|
||||||
setSelection([]);
|
setSelection([]);
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMouseMove = (e: MouseEvent) => {
|
const onMouseMove = (e: MouseEvent) => {
|
||||||
|
|
@ -195,31 +187,6 @@ export function VisualEditor() {
|
||||||
return {lastMousePos: currentPointer};
|
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) {
|
else if (selectingState) {
|
||||||
setSelectingState(ss => {
|
setSelectingState(ss => {
|
||||||
const selectionSize = subtractV2D(currentPointer, ss!.topLeft);
|
const selectionSize = subtractV2D(currentPointer, ss!.topLeft);
|
||||||
|
|
@ -233,7 +200,6 @@ export function VisualEditor() {
|
||||||
|
|
||||||
const onMouseUp = (e: MouseEvent) => {
|
const onMouseUp = (e: MouseEvent) => {
|
||||||
setDragging(null);
|
setDragging(null);
|
||||||
setResizing(null);
|
|
||||||
setSelectingState(ss => {
|
setSelectingState(ss => {
|
||||||
if (ss) {
|
if (ss) {
|
||||||
// we were making a selection
|
// we were making a selection
|
||||||
|
|
@ -263,17 +229,6 @@ export function VisualEditor() {
|
||||||
uid,
|
uid,
|
||||||
parts: [...parts],
|
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
|
return null; // no longer selecting
|
||||||
});
|
});
|
||||||
|
|
@ -290,7 +245,7 @@ export function VisualEditor() {
|
||||||
setSelection(selection => {
|
setSelection(selection => {
|
||||||
setState(state => ({
|
setState(state => ({
|
||||||
...state,
|
...state,
|
||||||
rountangles: state.rountangles.filter(r => !selection.includes(r.uid)),
|
rountangles: state.rountangles.filter(r => !selection.some(rs => rs.uid === r.uid)),
|
||||||
}));
|
}));
|
||||||
return [];
|
return [];
|
||||||
});
|
});
|
||||||
|
|
@ -340,7 +295,7 @@ export function VisualEditor() {
|
||||||
window.removeEventListener("mousemove", onMouseMove);
|
window.removeEventListener("mousemove", onMouseMove);
|
||||||
window.removeEventListener("mouseup", onMouseUp);
|
window.removeEventListener("mouseup", onMouseUp);
|
||||||
};
|
};
|
||||||
}, [selectingState, dragging, resizing]);
|
}, [selectingState, dragging]);
|
||||||
|
|
||||||
return <svg width="100%" height="100%"
|
return <svg width="100%" height="100%"
|
||||||
className="svgCanvas"
|
className="svgCanvas"
|
||||||
|
|
@ -383,7 +338,7 @@ export function VisualEditor() {
|
||||||
Left mouse button: Select/Drag.
|
Left mouse button: Select/Drag.
|
||||||
</text>
|
</text>
|
||||||
<text x={5} y={40}>
|
<text x={5} y={40}>
|
||||||
Right mouse button: Resize.
|
Right mouse button: Select only.
|
||||||
</text>
|
</text>
|
||||||
<text x={5} y={60}>
|
<text x={5} y={60}>
|
||||||
Middle mouse button: Insert [S]tates / [T]ransitions / Te[X]t (current mode: {mode})</text>
|
Middle mouse button: Insert [S]tates / [T]ransitions / Te[X]t (current mode: {mode})</text>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue