123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- import {
- getElementLineIntersection
- } from '../../layout/LayoutUtil';
- import {
- getMid
- } from '../../layout/LayoutUtil';
- var MARKER_OK = 'connect-ok',
- MARKER_NOT_OK = 'connect-not-ok';
- import {
- append as svgAppend,
- attr as svgAttr,
- create as svgCreate,
- remove as svgRemove
- } from 'tiny-svg';
- export default function Connect(
- eventBus, dragging, modeling,
- rules, canvas, graphicsFactory) {
- // TODO(nre): separate UI and events
- // rules
- function canConnect(source, target) {
- return rules.allowed('connection.create', {
- source: source,
- target: target
- });
- }
- // layouting
- function crop(start, end, source, target) {
- var sourcePath = graphicsFactory.getShapePath(source),
- targetPath = target && graphicsFactory.getShapePath(target),
- connectionPath = graphicsFactory.getConnectionPath({ waypoints: [ start, end ] });
- start = getElementLineIntersection(sourcePath, connectionPath, true) || start;
- end = (target && getElementLineIntersection(targetPath, connectionPath, false)) || end;
- return [ start, end ];
- }
- // event handlers
- eventBus.on('connect.move', function(event) {
- var context = event.context,
- source = context.source,
- target = context.target,
- visual = context.visual,
- sourcePosition = context.sourcePosition,
- endPosition,
- waypoints;
- // update connection visuals during drag
- endPosition = {
- x: event.x,
- y: event.y
- };
- waypoints = crop(sourcePosition, endPosition, source, target);
- svgAttr(visual, { 'points': [ waypoints[0].x, waypoints[0].y, waypoints[1].x, waypoints[1].y ] });
- });
- eventBus.on('connect.hover', function(event) {
- var context = event.context,
- source = context.source,
- hover = event.hover,
- canExecute;
- canExecute = context.canExecute = canConnect(source, hover);
- // simply ignore hover
- if (canExecute === null) {
- return;
- }
- context.target = hover;
- canvas.addMarker(hover, canExecute ? MARKER_OK : MARKER_NOT_OK);
- });
- eventBus.on([ 'connect.out', 'connect.cleanup' ], function(event) {
- var context = event.context;
- if (context.target) {
- canvas.removeMarker(context.target, context.canExecute ? MARKER_OK : MARKER_NOT_OK);
- }
- context.target = null;
- context.canExecute = false;
- });
- eventBus.on('connect.cleanup', function(event) {
- var context = event.context;
- if (context.visual) {
- svgRemove(context.visual);
- }
- });
- eventBus.on('connect.start', function(event) {
- var context = event.context,
- visual;
- visual = svgCreate('polyline');
- svgAttr(visual, {
- 'stroke': '#333',
- 'strokeDasharray': [ 1 ],
- 'strokeWidth': 2,
- 'pointer-events': 'none'
- });
- svgAppend(canvas.getDefaultLayer(), visual);
- context.visual = visual;
- });
- eventBus.on('connect.end', function(event) {
- var context = event.context,
- source = context.source,
- sourcePosition = context.sourcePosition,
- target = context.target,
- targetPosition = {
- x: event.x,
- y: event.y
- },
- canExecute = context.canExecute || canConnect(source, target);
- if (!canExecute) {
- return false;
- }
- var attrs = null,
- hints = {
- connectionStart: sourcePosition,
- connectionEnd: targetPosition
- };
- if (typeof canExecute === 'object') {
- attrs = canExecute;
- }
- modeling.connect(source, target, attrs, hints);
- });
- // API
- /**
- * Start connect operation.
- *
- * @param {DOMEvent} event
- * @param {djs.model.Base} source
- * @param {Point} [sourcePosition]
- * @param {Boolean} [autoActivate=false]
- */
- this.start = function(event, source, sourcePosition, autoActivate) {
- if (typeof sourcePosition !== 'object') {
- autoActivate = sourcePosition;
- sourcePosition = getMid(source);
- }
- dragging.init(event, 'connect', {
- autoActivate: autoActivate,
- data: {
- shape: source,
- context: {
- source: source,
- sourcePosition: sourcePosition
- }
- }
- });
- };
- }
- Connect.$inject = [
- 'eventBus',
- 'dragging',
- 'modeling',
- 'rules',
- 'canvas',
- 'graphicsFactory'
- ];
|