mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): copy/paste input edges when copying node
- Copy edges to selected nodes on copy - If pasted with `ctrl/meta-shift-v`, also paste the input edges
This commit is contained in:
parent
575ecb4028
commit
32dff2c4e3
@ -231,6 +231,15 @@ export const Flow = memo(() => {
|
||||
);
|
||||
useHotkeys(['Ctrl+v', 'Meta+v'], onPasteHotkey);
|
||||
|
||||
const onPasteWithEdgesToNodesHotkey = useCallback(
|
||||
(e: KeyboardEvent) => {
|
||||
e.preventDefault();
|
||||
pasteSelection(true);
|
||||
},
|
||||
[pasteSelection]
|
||||
);
|
||||
useHotkeys(['Ctrl+shift+v', 'Meta+shift+v'], onPasteWithEdgesToNodesHotkey);
|
||||
|
||||
const onUndoHotkey = useCallback(() => {
|
||||
if (mayUndo) {
|
||||
dispatch(undo());
|
||||
|
@ -4,10 +4,12 @@ import {
|
||||
$copiedEdges,
|
||||
$copiedNodes,
|
||||
$cursorPos,
|
||||
$edgesToCopiedNodes,
|
||||
selectionPasted,
|
||||
selectNodesSlice,
|
||||
} from 'features/nodes/store/nodesSlice';
|
||||
import { findUnoccupiedPosition } from 'features/nodes/store/util/findUnoccupiedPosition';
|
||||
import { isEqual, uniqWith } from 'lodash-es';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
const copySelection = () => {
|
||||
@ -16,17 +18,24 @@ const copySelection = () => {
|
||||
const { nodes, edges } = selectNodesSlice(getState());
|
||||
const selectedNodes = nodes.filter((node) => node.selected);
|
||||
const selectedEdges = edges.filter((edge) => edge.selected);
|
||||
const edgesToSelectedNodes = edges.filter((edge) => selectedNodes.some((node) => node.id === edge.target));
|
||||
$copiedNodes.set(selectedNodes);
|
||||
$copiedEdges.set(selectedEdges);
|
||||
$edgesToCopiedNodes.set(edgesToSelectedNodes);
|
||||
};
|
||||
|
||||
const pasteSelection = () => {
|
||||
const pasteSelection = (withEdgesToCopiedNodes?: boolean) => {
|
||||
const { getState, dispatch } = getStore();
|
||||
const currentNodes = selectNodesSlice(getState()).nodes;
|
||||
const cursorPos = $cursorPos.get();
|
||||
|
||||
const copiedNodes = deepClone($copiedNodes.get());
|
||||
const copiedEdges = deepClone($copiedEdges.get());
|
||||
let copiedEdges = deepClone($copiedEdges.get());
|
||||
|
||||
if (withEdgesToCopiedNodes) {
|
||||
const edgesToCopiedNodes = deepClone($edgesToCopiedNodes.get());
|
||||
copiedEdges = uniqWith([...copiedEdges, ...edgesToCopiedNodes], isEqual);
|
||||
}
|
||||
|
||||
// Calculate an offset to reposition nodes to surround the cursor position, maintaining relative positioning
|
||||
const xCoords = copiedNodes.map((node) => node.position.x);
|
||||
|
@ -498,6 +498,7 @@ export const $cursorPos = atom<XYPosition | null>(null);
|
||||
export const $templates = atom<Templates>({});
|
||||
export const $copiedNodes = atom<AnyNode[]>([]);
|
||||
export const $copiedEdges = atom<InvocationNodeEdge[]>([]);
|
||||
export const $edgesToCopiedNodes = atom<InvocationNodeEdge[]>([]);
|
||||
export const $pendingConnection = atom<PendingConnection | null>(null);
|
||||
export const $isUpdatingEdge = atom(false);
|
||||
export const $viewport = atom<Viewport>({ x: 0, y: 0, zoom: 1 });
|
||||
|
Loading…
Reference in New Issue
Block a user