/** * @author Martin Karkowski * @email m.karkowski@zema.de * @create date 2020-03-12 14:17:14 * @modify date 2020-03-12 14:17:14 * @desc [description] */ import { IUndoRedoGraph } from '../interfaces/IGraph'; // Handle the right clic rectangle selection of nodes // ======== // Everything is in there /** * Handle the right clic rectangle selection of nodes * @param network The Network, which should be used for Selection Boxes */ export function makeMeMultiSelect(network: IUndoRedoGraph, DELAY = 200) { const NO_CLICK = 0; const RIGHT_CLICK = 3; // Disable default right-click dropdown menu const container = network.network.body.container; // States let drag = false; let DOMRect: any = {}; // Selector const canvasify = (DOMx, DOMy) => { const { x, y } = network.network.DOMtoCanvas({ x: DOMx, y: DOMy }); return [x, y]; }; const correctRange = (start, end) => start < end ? [start, end] : [end, start]; const selectFromDOMRect = () => { const [sX, sY] = canvasify(DOMRect.startX, DOMRect.startY); const [eX, eY] = canvasify(DOMRect.endX, DOMRect.endY); const [startX, endX] = correctRange(sX, eX); const [startY, endY] = correctRange(sY, eY); const nodes = network.nodes.filter(node => { return (network.network.findNode(node.id).length == 1 && startX <= node.x && node.x <= endX && startY <= node.y && node.y <= endY) }).map(node => node.id); network.network.selectNodes(nodes); } let start_pos: {layerX: number, layerY: number } | null = null; let mouse_pos: {layerX: number, layerY: number } | null = null; // Listeners const org_onmousedown = container.onmousedown; container.onmousedown = function(event){ const { which, layerX, layerY } = event; // Store the Initial Position start_pos = { layerX, layerY } // When mousedown, save the initial rectangle state if(which === RIGHT_CLICK) { Object.assign(DOMRect, { startX: layerX, startY: layerY, endX: layerX, endY: layerY }); drag = true; } else if (typeof org_onmousedown === 'function') { org_onmousedown(event); } }; const org_onmousemove = container.onmousemove; container.onmousemove = function(event){ const { which, layerX, layerY } = event; // Store the Mouse Position mouse_pos = { layerX, layerY } // When mousedown, save the initial rectangle state // Make selection rectangle disappear when accidently mouseupped outside 'container' if(which === NO_CLICK && drag) { drag = false; network.network.redraw(); } // When mousemove, update the rectangle state else if(drag) { Object.assign(DOMRect, { endX: layerX, endY: layerY }); network.network.redraw(); } else if (typeof org_onmousemove === 'function'){ org_onmousemove(event); } } const org_onmouseup = container.onmouseup; container.onmouseup = function(event){ const { which, pageX, pageY } = event; // When mousedown, save the initial rectangle state if(which === RIGHT_CLICK) { selectFromDOMRect(); setTimeout(()=> { drag = false; network.network.redraw(); }) } else if (typeof org_onmouseup === 'function') { org_onmouseup(event); } }; network.on('oncontext', (params) => { params.event.preventDefault(); if ( drag ) { params.event.prevent = true; } }) // Drawer network.on('afterDrawing', ctx => { if(drag) { const [startX, startY] = canvasify(DOMRect.startX, DOMRect.startY); const [endX, endY] = canvasify(DOMRect.endX, DOMRect.endY); ctx.setLineDash([5]); ctx.strokeStyle = 'rgba(78, 146, 237, 0.75)'; ctx.strokeRect(startX, startY, endX - startX, endY - startY); ctx.setLineDash([]); ctx.fillStyle = 'rgba(151, 194, 252, 0.45)'; ctx.fillRect(startX, startY, endX - startX, endY - startY); } }); };