From 4c64b29a63d50641a6e8ab7dc62169ca5620713d Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 12 Jan 2024 18:20:16 -0500 Subject: [PATCH 1/2] Use screenToFlowPosition() instead of project() --- .../RepresentativeNodeWrapper.tsx | 15 ++++++++++----- src/renderer/contexts/GlobalNodeState.tsx | 12 +++++++++--- src/renderer/helpers/copyAndPaste.ts | 10 +++++----- src/renderer/hooks/usePaneNodeSearchMenu.tsx | 11 +++-------- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/renderer/components/NodeSelectorPanel/RepresentativeNodeWrapper.tsx b/src/renderer/components/NodeSelectorPanel/RepresentativeNodeWrapper.tsx index ee0e3ff5f..08a8b30b1 100644 --- a/src/renderer/components/NodeSelectorPanel/RepresentativeNodeWrapper.tsx +++ b/src/renderer/components/NodeSelectorPanel/RepresentativeNodeWrapper.tsx @@ -103,11 +103,16 @@ export const RepresentativeNodeWrapper = memo( const createNodeFromSelector = useCallback(() => { if (!reactFlowWrapper.current) return; - const { height: wHeight, width } = reactFlowWrapper.current.getBoundingClientRect(); - - const position = reactFlowInstance.project({ - x: width / 2, - y: wHeight / 2, + const { + height: wHeight, + width, + x, + y, + } = reactFlowWrapper.current.getBoundingClientRect(); + + const position = reactFlowInstance.screenToFlowPosition({ + x: (width + x) / 2, + y: (wHeight + y) / 2, }); createNode({ diff --git a/src/renderer/contexts/GlobalNodeState.tsx b/src/renderer/contexts/GlobalNodeState.tsx index 5b213c869..98d2d4943 100644 --- a/src/renderer/contexts/GlobalNodeState.tsx +++ b/src/renderer/contexts/GlobalNodeState.tsx @@ -181,7 +181,7 @@ export const GlobalProvider = memo( setNodes: rfSetNodes, setEdges: rfSetEdges, viewportInitialized, - project, + screenToFlowPosition, } = useReactFlow(); const currentViewport = useViewport(); @@ -1231,8 +1231,14 @@ export const GlobalProvider = memo( copyToClipboard(getNodes(), getEdges()); }, [getNodes, getEdges]); const pasteFn = useCallback(() => { - pasteFromClipboard(changeNodes, changeEdges, createNode, project, reactFlowWrapper); - }, [changeNodes, changeEdges, createNode, project, reactFlowWrapper]); + pasteFromClipboard( + changeNodes, + changeEdges, + createNode, + screenToFlowPosition, + reactFlowWrapper + ); + }, [changeNodes, changeEdges, createNode, screenToFlowPosition, reactFlowWrapper]); const selectAllFn = useCallback(() => { changeNodes((nodes) => nodes.map((n) => ({ ...n, selected: true }))); changeEdges((edges) => edges.map((e) => ({ ...e, selected: true }))); diff --git a/src/renderer/helpers/copyAndPaste.ts b/src/renderer/helpers/copyAndPaste.ts index 133048018..3297e0b74 100644 --- a/src/renderer/helpers/copyAndPaste.ts +++ b/src/renderer/helpers/copyAndPaste.ts @@ -56,7 +56,7 @@ export const pasteFromClipboard = ( setNodes: SetState[]>, setEdges: SetState[]>, createNode: (proto: NodeProto, parentId?: string) => void, - project: Project, + screenToFlowPosition: Project, reactFlowWrapper: React.RefObject ) => { const availableFormats = clipboard.availableFormats(); @@ -114,14 +114,14 @@ export const pasteFromClipboard = ( let positionX = 0; let positionY = 0; if (reactFlowWrapper.current) { - const { height, width } = + const { height, width, x, y } = reactFlowWrapper.current.getBoundingClientRect(); - positionX = width / 2; - positionY = height / 2; + positionX = (width + x) / 2; + positionY = (height + y) / 2; } createNode({ nodeType: 'regularNode', - position: project({ x: positionX, y: positionY }), + position: screenToFlowPosition({ x: positionX, y: positionY }), data: { schemaId: 'chainner:image:load' as SchemaId, inputData: { diff --git a/src/renderer/hooks/usePaneNodeSearchMenu.tsx b/src/renderer/hooks/usePaneNodeSearchMenu.tsx index 3853e93e7..f92a40339 100644 --- a/src/renderer/hooks/usePaneNodeSearchMenu.tsx +++ b/src/renderer/hooks/usePaneNodeSearchMenu.tsx @@ -393,7 +393,7 @@ export const usePaneNodeSearchMenu = ( const [connectingFrom, setConnectingFrom] = useState(null); const [, setGlobalConnectingFrom] = useConnectingFrom; - const { getNode, project, getNodes, getEdges } = useReactFlow(); + const { getNode, screenToFlowPosition, getNodes, getEdges } = useReactFlow(); const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 }); @@ -428,12 +428,8 @@ export const usePaneNodeSearchMenu = ( const onSchemaSelect = useCallback( (schema: NodeSchema, target: ConnectionTarget) => { - const reactFlowBounds = wrapperRef.current!.getBoundingClientRect(); const { x, y } = mousePosition; - const projPosition = project({ - x: x - reactFlowBounds.left, - y: y - reactFlowBounds.top, - }); + const projPosition = screenToFlowPosition({ x, y }); const nodeId = createUniqueId(); createNode({ id: nodeId, @@ -483,9 +479,8 @@ export const usePaneNodeSearchMenu = ( createNode, functionDefinitions, mousePosition, - project, + screenToFlowPosition, setGlobalConnectingFrom, - wrapperRef, ] ); From de605970422af72918054168b7b3d38f07eb1fec Mon Sep 17 00:00:00 2001 From: Joey Ballentine Date: Fri, 12 Jan 2024 18:48:53 -0500 Subject: [PATCH 2/2] remove unused var --- src/renderer/components/ReactFlowBox.tsx | 2 +- src/renderer/hooks/usePaneNodeSearchMenu.tsx | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/renderer/components/ReactFlowBox.tsx b/src/renderer/components/ReactFlowBox.tsx index 6dc29291d..2bada8c03 100644 --- a/src/renderer/components/ReactFlowBox.tsx +++ b/src/renderer/components/ReactFlowBox.tsx @@ -412,7 +412,7 @@ export const ReactFlowBox = memo(({ wrapperRef, nodeTypes, edgeTypes }: ReactFlo // [setEdges] // ); - const { onConnectStart, onConnectStop, onPaneContextMenu } = usePaneNodeSearchMenu(wrapperRef); + const { onConnectStart, onConnectStop, onPaneContextMenu } = usePaneNodeSearchMenu(); const [selectedNodes, setSelectedNodes] = useState[]>([]); const selectionMenu = useNodesMenu(selectedNodes); diff --git a/src/renderer/hooks/usePaneNodeSearchMenu.tsx b/src/renderer/hooks/usePaneNodeSearchMenu.tsx index f92a40339..63e735d47 100644 --- a/src/renderer/hooks/usePaneNodeSearchMenu.tsx +++ b/src/renderer/hooks/usePaneNodeSearchMenu.tsx @@ -379,9 +379,7 @@ interface Position { readonly y: number; } -export const usePaneNodeSearchMenu = ( - wrapperRef: React.RefObject -): UsePaneNodeSearchMenuValue => { +export const usePaneNodeSearchMenu = (): UsePaneNodeSearchMenuValue => { const typeState = useContextSelector(GlobalVolatileContext, (c) => c.typeState); const useConnectingFrom = useContextSelector(GlobalVolatileContext, (c) => c.useConnectingFrom); const { createNode, createConnection } = useContext(GlobalContext);