111 lines
2.6 KiB
JavaScript
111 lines
2.6 KiB
JavaScript
|
|
import {
|
||
|
|
isArray,
|
||
|
|
forEach
|
||
|
|
} from 'min-dash';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @typedef {import('../../core/EventBus').default} EventBus
|
||
|
|
*/
|
||
|
|
|
||
|
|
/**
|
||
|
|
* A service that offers the current selection in a diagram.
|
||
|
|
* Offers the api to control the selection, too.
|
||
|
|
*
|
||
|
|
* @class
|
||
|
|
*
|
||
|
|
* @param {EventBus} eventBus
|
||
|
|
*/
|
||
|
|
export default function Selection(eventBus, canvas) {
|
||
|
|
|
||
|
|
this._eventBus = eventBus;
|
||
|
|
this._canvas = canvas;
|
||
|
|
|
||
|
|
this._selectedElements = [];
|
||
|
|
|
||
|
|
var self = this;
|
||
|
|
|
||
|
|
eventBus.on([ 'shape.remove', 'connection.remove' ], function(e) {
|
||
|
|
var element = e.element;
|
||
|
|
self.deselect(element);
|
||
|
|
});
|
||
|
|
|
||
|
|
eventBus.on([ 'diagram.clear', 'root.set' ], function(e) {
|
||
|
|
self.select(null);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
Selection.$inject = [ 'eventBus', 'canvas' ];
|
||
|
|
|
||
|
|
|
||
|
|
Selection.prototype.deselect = function(element) {
|
||
|
|
var selectedElements = this._selectedElements;
|
||
|
|
|
||
|
|
var idx = selectedElements.indexOf(element);
|
||
|
|
|
||
|
|
if (idx !== -1) {
|
||
|
|
var oldSelection = selectedElements.slice();
|
||
|
|
|
||
|
|
selectedElements.splice(idx, 1);
|
||
|
|
|
||
|
|
this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements });
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
Selection.prototype.get = function() {
|
||
|
|
return this._selectedElements;
|
||
|
|
};
|
||
|
|
|
||
|
|
Selection.prototype.isSelected = function(element) {
|
||
|
|
return this._selectedElements.indexOf(element) !== -1;
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* This method selects one or more elements on the diagram.
|
||
|
|
*
|
||
|
|
* By passing an additional add parameter you can decide whether or not the element(s)
|
||
|
|
* should be added to the already existing selection or not.
|
||
|
|
*
|
||
|
|
* @method Selection#select
|
||
|
|
*
|
||
|
|
* @param {Object|Object[]} elements element or array of elements to be selected
|
||
|
|
* @param {boolean} [add] whether the element(s) should be appended to the current selection, defaults to false
|
||
|
|
*/
|
||
|
|
Selection.prototype.select = function(elements, add) {
|
||
|
|
var selectedElements = this._selectedElements,
|
||
|
|
oldSelection = selectedElements.slice();
|
||
|
|
|
||
|
|
if (!isArray(elements)) {
|
||
|
|
elements = elements ? [ elements ] : [];
|
||
|
|
}
|
||
|
|
|
||
|
|
var canvas = this._canvas;
|
||
|
|
|
||
|
|
var rootElement = canvas.getRootElement();
|
||
|
|
|
||
|
|
elements = elements.filter(function(element) {
|
||
|
|
var elementRoot = canvas.findRoot(element);
|
||
|
|
|
||
|
|
return rootElement === elementRoot;
|
||
|
|
});
|
||
|
|
|
||
|
|
// selection may be cleared by passing an empty array or null
|
||
|
|
// to the method
|
||
|
|
if (add) {
|
||
|
|
forEach(elements, function(element) {
|
||
|
|
if (selectedElements.indexOf(element) !== -1) {
|
||
|
|
|
||
|
|
// already selected
|
||
|
|
return;
|
||
|
|
} else {
|
||
|
|
selectedElements.push(element);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
this._selectedElements = selectedElements = elements.slice();
|
||
|
|
}
|
||
|
|
|
||
|
|
this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements });
|
||
|
|
};
|