2020-10-25 20:14:51 +00:00
|
|
|
/**
|
|
|
|
* @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<N, E>(network: IUndoRedoGraph<N,E>, 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
|
|
|
|
});
|
2020-10-30 18:30:59 +00:00
|
|
|
drag = true;
|
2020-10-25 20:14:51 +00:00
|
|
|
} 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
|
2020-10-30 18:30:59 +00:00
|
|
|
if(which === RIGHT_CLICK) {
|
2020-10-25 20:14:51 +00:00
|
|
|
selectFromDOMRect();
|
2020-10-30 18:30:59 +00:00
|
|
|
|
2020-10-25 20:14:51 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|