jstd-web/node_modules/diagram-js/lib/features/lasso-tool/LassoTool.js

282 lines
5.6 KiB
JavaScript

import { values } from 'min-dash';
import { getEnclosedElements } from '../../util/Elements';
import {
hasSecondaryModifier
} from '../../util/Mouse';
import {
append as svgAppend,
attr as svgAttr,
create as svgCreate,
remove as svgRemove
} from 'tiny-svg';
/**
* @typedef {import('../../core/Canvas').default} Canvas
* @typedef {import('../dragging/Dragging').default} Dragging
* @typedef {import('../../core/ElementRegistry').default} ElementRegistry
* @typedef {import('../../core/EventBus').default} EventBus
* @typedef {import('../mouse/Mouse').default} Mouse
* @typedef {import('../selection/Selection').default} Selection
* @typedef {import('../tool-manager/ToolManager').default} ToolManager
*/
var LASSO_TOOL_CURSOR = 'crosshair';
/**
* @param {EventBus} eventBus
* @param {Canvas} canvas
* @param {Dragging} dragging
* @param {ElementRegistry} elementRegistry
* @param {Selection} selection
* @param {ToolManager} toolManager
* @param {Mouse} mouse
*/
export default function LassoTool(
eventBus, canvas, dragging,
elementRegistry, selection, toolManager,
mouse) {
this._selection = selection;
this._dragging = dragging;
this._mouse = mouse;
var self = this;
// lasso visuals implementation
/**
* A helper that realizes the selection box visual
*/
var visuals = {
create: function(context) {
var container = canvas.getActiveLayer(),
frame;
frame = context.frame = svgCreate('rect');
svgAttr(frame, {
class: 'djs-lasso-overlay',
width: 1,
height: 1,
x: 0,
y: 0
});
svgAppend(container, frame);
},
update: function(context) {
var frame = context.frame,
bbox = context.bbox;
svgAttr(frame, {
x: bbox.x,
y: bbox.y,
width: bbox.width,
height: bbox.height
});
},
remove: function(context) {
if (context.frame) {
svgRemove(context.frame);
}
}
};
toolManager.registerTool('lasso', {
tool: 'lasso.selection',
dragging: 'lasso'
});
eventBus.on('lasso.selection.end', function(event) {
var target = event.originalEvent.target;
// only reactive on diagram click
// on some occasions, event.hover is not set and we have to check if the target is an svg
if (!event.hover && !(target instanceof SVGElement)) {
return;
}
eventBus.once('lasso.selection.ended', function() {
self.activateLasso(event.originalEvent, true);
});
});
// lasso interaction implementation
eventBus.on('lasso.end', function(event) {
var bbox = toBBox(event);
var elements = elementRegistry.filter(function(element) {
return element;
});
self.select(elements, bbox);
});
eventBus.on('lasso.start', function(event) {
var context = event.context;
context.bbox = toBBox(event);
visuals.create(context);
});
eventBus.on('lasso.move', function(event) {
var context = event.context;
context.bbox = toBBox(event);
visuals.update(context);
});
eventBus.on('lasso.cleanup', function(event) {
var context = event.context;
visuals.remove(context);
});
// event integration
eventBus.on('element.mousedown', 1500, function(event) {
if (!hasSecondaryModifier(event)) {
return;
}
self.activateLasso(event.originalEvent);
// we've handled the event
return true;
});
}
LassoTool.$inject = [
'eventBus',
'canvas',
'dragging',
'elementRegistry',
'selection',
'toolManager',
'mouse'
];
LassoTool.prototype.activateLasso = function(event, autoActivate) {
this._dragging.init(event, 'lasso', {
autoActivate: autoActivate,
cursor: LASSO_TOOL_CURSOR,
data: {
context: {}
}
});
};
LassoTool.prototype.activateSelection = function(event, autoActivate) {
this._dragging.init(event, 'lasso.selection', {
trapClick: false,
autoActivate: autoActivate,
cursor: LASSO_TOOL_CURSOR,
data: {
context: {}
}
});
};
LassoTool.prototype.select = function(elements, bbox) {
var selectedElements = getEnclosedElements(elements, bbox);
this._selection.select(values(selectedElements));
};
LassoTool.prototype.toggle = function() {
if (this.isActive()) {
return this._dragging.cancel();
}
var mouseEvent = this._mouse.getLastMoveEvent();
this.activateSelection(mouseEvent, !!mouseEvent);
};
LassoTool.prototype.isActive = function() {
var context = this._dragging.context();
return context && /^lasso/.test(context.prefix);
};
function toBBox(event) {
var start = {
x: event.x - event.dx,
y: event.y - event.dy
};
var end = {
x: event.x,
y: event.y
};
var bbox;
if ((start.x <= end.x && start.y < end.y) ||
(start.x < end.x && start.y <= end.y)) {
bbox = {
x: start.x,
y: start.y,
width: end.x - start.x,
height: end.y - start.y
};
} else if ((start.x >= end.x && start.y < end.y) ||
(start.x > end.x && start.y <= end.y)) {
bbox = {
x: end.x,
y: start.y,
width: start.x - end.x,
height: end.y - start.y
};
} else if ((start.x <= end.x && start.y > end.y) ||
(start.x < end.x && start.y >= end.y)) {
bbox = {
x: start.x,
y: end.y,
width: end.x - start.x,
height: start.y - end.y
};
} else if ((start.x >= end.x && start.y > end.y) ||
(start.x > end.x && start.y >= end.y)) {
bbox = {
x: end.x,
y: end.y,
width: start.x - end.x,
height: start.y - end.y
};
} else {
bbox = {
x: end.x,
y: end.y,
width: 0,
height: 0
};
}
return bbox;
}