feat: 重写快捷键复制

This commit is contained in:
zhangshaohu 2024-06-17 22:04:27 +08:00
parent 069d1588c3
commit dfc8e770a4
2 changed files with 156 additions and 36 deletions

View File

@ -0,0 +1,119 @@
import type LogicFlow from '@logicflow/core';
import {type GraphModel} from '@logicflow/core';
import { ElMessageBox, ElMessage } from 'element-plus'
let selected:any|null = null;
function translationNodeData(nodeData:any, distance:any) {
nodeData.x += distance;
nodeData.y += distance;
if (nodeData.text) {
nodeData.text.x += distance;
nodeData.text.y += distance;
}
return nodeData;
}
function translationEdgeData(edgeData:any, distance:any) {
if (edgeData.startPoint) {
edgeData.startPoint.x += distance;
edgeData.startPoint.y += distance;
}
if (edgeData.endPoint) {
edgeData.endPoint.x += distance;
edgeData.endPoint.y += distance;
}
if (edgeData.pointsList && edgeData.pointsList.length > 0) {
edgeData.pointsList.forEach((point:any) => {
point.x += distance;
point.y += distance;
});
}
if (edgeData.text) {
edgeData.text.x += distance;
edgeData.text.y += distance;
}
return edgeData;
}
const TRANSLATION_DISTANCE = 40;
let CHILDREN_TRANSLATION_DISTANCE = 40;
export function initDefaultShortcut(lf: LogicFlow, graph: GraphModel) {
const { keyboard } = lf;
const { options: { keyboard: keyboardOptions } } = keyboard;
const copy_node=() => {
CHILDREN_TRANSLATION_DISTANCE = TRANSLATION_DISTANCE;
if (!keyboardOptions?.enabled) return true;
if (graph.textEditElement) return true;
const { guards } = lf.options;
const elements = graph.getSelectElements(false);
const enabledClone = guards && guards.beforeClone ? guards.beforeClone(elements) : true;
if (!enabledClone || (elements.nodes.length === 0 && elements.edges.length === 0)) {
selected = null;
return true;
}
selected = elements;
selected.nodes.forEach((node:any) => translationNodeData(node, TRANSLATION_DISTANCE));
selected.edges.forEach((edge:any) => translationEdgeData(edge, TRANSLATION_DISTANCE));
ElMessage.success({
message: '已复制节点',
type: 'success',
showClose: true,
duration: 1500
})
return false;
}
const paste_node=() => {
if (!keyboardOptions?.enabled) return true;
if (graph.textEditElement) return true;
if (selected && (selected.nodes || selected.edges)) {
lf.clearSelectElements();
const addElements = lf.addElements(selected, CHILDREN_TRANSLATION_DISTANCE);
if (!addElements) return true;
addElements.nodes.forEach(node => lf.selectElementById(node.id, true));
addElements.edges.forEach(edge => lf.selectElementById(edge.id, true));
selected.nodes.forEach((node:any) => translationNodeData(node, TRANSLATION_DISTANCE));
selected.edges.forEach((edge:any) => translationEdgeData(edge, TRANSLATION_DISTANCE));
CHILDREN_TRANSLATION_DISTANCE = CHILDREN_TRANSLATION_DISTANCE + TRANSLATION_DISTANCE;
}
return false;
}
const delete_node=()=>{
const defaultOptions: Object = {
showCancelButton: true,
confirmButtonText: '确定',
cancelButtonText: '取消'
}
ElMessageBox.confirm('确定删除改节点?', defaultOptions).then(() => {
if (!keyboardOptions?.enabled) return true;
if (graph.textEditElement) return true;
const elements = graph.getSelectElements(true);
lf.clearSelectElements();
elements.edges.forEach((edge:any) => lf.deleteEdge(edge.id));
elements.nodes.forEach((node:any) => lf.deleteNode(node.id));
})
return false
}
graph.eventCenter.on('copy_node', copy_node)
graph.eventCenter.on('paste_node', copy_node)
// 复制
keyboard.on(['cmd + c', 'ctrl + c'], copy_node);
// 粘贴
keyboard.on(['cmd + v', 'ctrl + v'],paste_node );
// undo
keyboard.on(['cmd + z', 'ctrl + z'], () => {
if (!keyboardOptions?.enabled) return true;
if (graph.textEditElement) return true;
lf.undo();
return false;
});
// redo
keyboard.on(['cmd + y', 'ctrl + y'], () => {
if (!keyboardOptions?.enabled) return true;
if (graph.textEditElement) return true;
lf.redo();
return false;
});
// delete
keyboard.on(['backspace'], delete_node);
}

View File

@ -12,8 +12,40 @@ import { baseNodes } from '@/workflow/common/data'
import '@logicflow/extension/lib/style/index.css'
import '@logicflow/core/dist/style/index.css'
import { ElMessageBox, ElMessage } from 'element-plus'
import {initDefaultShortcut} from '@/workflow/common/shortcut'
const nodes: any = import.meta.glob('./nodes/**/index.ts', { eager: true })
function translationNodeData(nodeData, distance) {
nodeData.x += distance;
nodeData.y += distance;
if (nodeData.text) {
nodeData.text.x += distance;
nodeData.text.y += distance;
}
return nodeData;
}
function translationEdgeData(edgeData, distance) {
if (edgeData.startPoint) {
edgeData.startPoint.x += distance;
edgeData.startPoint.y += distance;
}
if (edgeData.endPoint) {
edgeData.endPoint.x += distance;
edgeData.endPoint.y += distance;
}
if (edgeData.pointsList && edgeData.pointsList.length > 0) {
edgeData.pointsList.forEach((point) => {
point.x += distance;
point.y += distance;
});
}
if (edgeData.text) {
edgeData.text.x += distance;
edgeData.text.y += distance;
}
return edgeData;
}
defineOptions({ name: 'WorkFlow' })
type ShapeItem = {
@ -490,7 +522,8 @@ const graphData = {
}
const lf = ref()
const TRANSLATION_DISTANCE = 40;
let CHILDREN_TRANSLATION_DISTANCE = 40;
onMounted(() => {
const container: any = document.querySelector('#container')
if (container) {
@ -509,40 +542,7 @@ onMounted(() => {
},
keyboard: {
enabled: true,
shortcuts: [
{
keys: ['backspace'],
callback: (edge: any) => {
const defaultOptions: Object = {
showCancelButton: true,
confirmButtonText: '确定',
cancelButtonText: '取消'
}
const elements = lf.value.getSelectElements(true)
ElMessageBox.confirm('确定删除改节点?', defaultOptions).then((ok) => {
const elements = lf.value.getSelectElements(true)
lf.value.clearSelectElements()
elements.edges.forEach((edge: any) => {
lf.value.deleteEdge(edge.id)
})
elements.nodes.forEach((node: any) => {
lf.value.deleteNode(node.id)
})
})
}
},
{
keys: ['cmd + c', 'ctrl + c'],
callback: (edge: any) => {
ElMessage.success({
message: '已复制节点',
type: 'success',
showClose: true,
duration: 1500
})
}
}
]
},
isSilentMode: false,
container: container
@ -553,11 +553,12 @@ onMounted(() => {
strokeWidth: 1
}
})
initDefaultShortcut(lf.value,lf.value.graphModel)
lf.value.batchRegister([...Object.keys(nodes).map((key) => nodes[key].default), AppEdge])
lf.value.setDefaultEdgeType('app-edge')
lf.value.render(graphData)
lf.value.graphModel.eventCenter.on('delete_edge', (id_list: Array<string>) => {
id_list.forEach((id: string) => {
lf.value.deleteEdge(id)