Added ability to remove nodes and disconnect all edges.

This commit is contained in:
2025-04-11 16:19:35 -06:00
parent 4dbd3a3e53
commit bb93040c05
2 changed files with 54 additions and 1 deletions

BIN
Data/Sounds/Short_Beep.wav Normal file

Binary file not shown.

View File

@ -58,7 +58,7 @@ if (!window.BorealisUpdateRate) {
window.BorealisUpdateRate = 200; // Default Update Rate: 100ms window.BorealisUpdateRate = 200; // Default Update Rate: 100ms
} }
const nodeContext = require.context("./nodes", true, /\.jsx$/); const nodeContext = require.context("./nodes", true, /\.jsx$/); // Dynamically import all node components from the nodes directory
const nodeTypes = {}; const nodeTypes = {};
const categorizedNodes = {}; const categorizedNodes = {};
@ -82,6 +82,7 @@ nodeContext.keys().forEach((path) => {
function FlowEditor({ nodes, edges, setNodes, setEdges, nodeTypes }) { function FlowEditor({ nodes, edges, setNodes, setEdges, nodeTypes }) {
const reactFlowWrapper = useRef(null); const reactFlowWrapper = useRef(null);
const { project } = useReactFlow(); const { project } = useReactFlow();
const [contextMenu, setContextMenu] = useState(null); // Node Right-Click Context Menu
const onDrop = useCallback( const onDrop = useCallback(
(event) => { (event) => {
@ -150,6 +151,34 @@ function FlowEditor({ nodes, edges, setNodes, setEdges, nodeTypes }) {
[setEdges] [setEdges]
); );
const handleRightClick = (event, node) => {
event.preventDefault();
setContextMenu({
mouseX: event.clientX + 2,
mouseY: event.clientY - 6,
nodeId: node.id
});
};
const handleDisconnect = () => {
if (contextMenu?.nodeId) {
setEdges((eds) =>
eds.filter((e) => e.source !== contextMenu.nodeId && e.target !== contextMenu.nodeId)
);
}
setContextMenu(null);
};
const handleRemoveNode = () => {
if (contextMenu?.nodeId) {
setNodes((nds) => nds.filter((n) => n.id !== contextMenu.nodeId));
setEdges((eds) =>
eds.filter((e) => e.source !== contextMenu.nodeId && e.target !== contextMenu.nodeId)
);
}
setContextMenu(null);
};
useEffect(() => { useEffect(() => {
const nodeCountEl = document.getElementById("nodeCount"); const nodeCountEl = document.getElementById("nodeCount");
if (nodeCountEl) { if (nodeCountEl) {
@ -169,6 +198,7 @@ function FlowEditor({ nodes, edges, setNodes, setEdges, nodeTypes }) {
onConnect={onConnect} onConnect={onConnect}
onDrop={onDrop} onDrop={onDrop}
onDragOver={onDragOver} onDragOver={onDragOver}
onNodeContextMenu={handleRightClick}
defaultViewport={{ x: 0, y: 0, zoom: 1.5 }} defaultViewport={{ x: 0, y: 0, zoom: 1.5 }}
edgeOptions={{ edgeOptions={{
type: "smoothstep", type: "smoothstep",
@ -186,10 +216,33 @@ function FlowEditor({ nodes, edges, setNodes, setEdges, nodeTypes }) {
color="rgba(255, 255, 255, 0.2)" color="rgba(255, 255, 255, 0.2)"
/> />
</ReactFlow> </ReactFlow>
{/* Right-Click Node Menu */}
<Menu
open={Boolean(contextMenu)}
onClose={() => setContextMenu(null)}
anchorReference="anchorPosition"
anchorPosition={
contextMenu !== null
? { top: contextMenu.mouseY, left: contextMenu.mouseX }
: undefined
}
PaperProps={{
sx: {
bgcolor: "#1e1e1e",
color: "#fff",
fontSize: "13px"
}
}}
>
<MenuItem onClick={handleDisconnect}>Disconnect All Edges</MenuItem>
<MenuItem onClick={handleRemoveNode}>Remove Node</MenuItem>
</Menu>
</div> </div>
); );
} }
const darkTheme = createTheme({ const darkTheme = createTheme({
palette: { palette: {
mode: "dark", mode: "dark",