UNPKG

sprotty

Version:

A next-gen framework for graphical views

154 lines 6.18 kB
"use strict"; /******************************************************************************** * Copyright (c) 2018 TypeFox and others. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * This Source Code may also be made available under the following Secondary * Licenses when the conditions for such availability set forth in the Eclipse * Public License v. 2.0 are satisfied: GNU General Public License, version 2 * with the GNU Classpath Exception which is available at * https://www.gnu.org/software/classpath/license.html. * * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ Object.defineProperty(exports, "__esModule", { value: true }); exports.edgeInProgressTargetHandleID = exports.edgeInProgressID = exports.SDanglingAnchorImpl = exports.SRoutingHandleImpl = exports.SConnectableElementImpl = exports.getRouteBounds = exports.getAbsoluteRouteBounds = exports.isConnectable = exports.connectableFeature = exports.SRoutableElementImpl = void 0; const geometry_1 = require("sprotty-protocol/lib/utils/geometry"); const smodel_1 = require("../../base/model/smodel"); const model_1 = require("../bounds/model"); const delete_1 = require("../edit/delete"); const model_2 = require("../select/model"); const model_3 = require("../hover/model"); const model_4 = require("../move/model"); class SRoutableElementImpl extends smodel_1.SChildElementImpl { constructor() { super(...arguments); this.routingPoints = []; } get source() { return this.index.getById(this.sourceId); } get target() { return this.index.getById(this.targetId); } get bounds() { // this should also work for splines, which have the convex hull property return this.routingPoints.reduce((bounds, routingPoint) => geometry_1.Bounds.combine(bounds, { x: routingPoint.x, y: routingPoint.y, width: 0, height: 0 }), geometry_1.Bounds.EMPTY); } } exports.SRoutableElementImpl = SRoutableElementImpl; exports.connectableFeature = Symbol('connectableFeature'); function isConnectable(element) { return element.hasFeature(exports.connectableFeature) && element.canConnect; } exports.isConnectable = isConnectable; function getAbsoluteRouteBounds(model, route = model.routingPoints) { let bounds = getRouteBounds(route); let current = model; while (current instanceof smodel_1.SChildElementImpl) { const parent = current.parent; bounds = parent.localToParent(bounds); current = parent; } return bounds; } exports.getAbsoluteRouteBounds = getAbsoluteRouteBounds; function getRouteBounds(route) { const bounds = { x: NaN, y: NaN, width: 0, height: 0 }; for (const point of route) { if (isNaN(bounds.x)) { bounds.x = point.x; bounds.y = point.y; } else { if (point.x < bounds.x) { bounds.width += bounds.x - point.x; bounds.x = point.x; } else if (point.x > bounds.x + bounds.width) { bounds.width = point.x - bounds.x; } if (point.y < bounds.y) { bounds.height += bounds.y - point.y; bounds.y = point.y; } else if (point.y > bounds.y + bounds.height) { bounds.height = point.y - bounds.y; } } } return bounds; } exports.getRouteBounds = getRouteBounds; /** * A connectable element is one that can have outgoing and incoming edges, i.e. it can be the source * or target element of an edge. There are two kinds of connectable elements: nodes (`SNode`) and * ports (`SPort`). A node represents a main entity, while a port is a connection point inside a node. */ class SConnectableElementImpl extends model_1.SShapeElementImpl { constructor() { super(...arguments); this.strokeWidth = 0; } get anchorKind() { return undefined; } /** * The incoming edges of this connectable element. They are resolved by the index, which must * be an `SGraphIndex` for efficient lookup. */ get incomingEdges() { const allEdges = this.index.all().filter(e => e instanceof SRoutableElementImpl); return allEdges.filter(e => e.targetId === this.id); } /** * The outgoing edges of this connectable element. They are resolved by the index, which must * be an `SGraphIndex` for efficient lookup. */ get outgoingEdges() { const allEdges = this.index.all().filter(e => e instanceof SRoutableElementImpl); return allEdges.filter(e => e.sourceId === this.id); } canConnect(routable, role) { return true; } } exports.SConnectableElementImpl = SConnectableElementImpl; class SRoutingHandleImpl extends smodel_1.SChildElementImpl { constructor() { super(...arguments); /** Whether the routing point is being dragged. */ this.editMode = false; this.hoverFeedback = false; this.selected = false; } /** * SRoutingHandles are created using the constructor, so we hard-wire the * default features */ hasFeature(feature) { return SRoutingHandleImpl.DEFAULT_FEATURES.indexOf(feature) !== -1; } } exports.SRoutingHandleImpl = SRoutingHandleImpl; SRoutingHandleImpl.DEFAULT_FEATURES = [model_2.selectFeature, model_4.moveFeature, model_3.hoverFeedbackFeature]; class SDanglingAnchorImpl extends SConnectableElementImpl { constructor() { super(); this.type = 'dangling-anchor'; this.size = { width: 0, height: 0 }; } } exports.SDanglingAnchorImpl = SDanglingAnchorImpl; SDanglingAnchorImpl.DEFAULT_FEATURES = [delete_1.deletableFeature]; exports.edgeInProgressID = 'edge-in-progress'; exports.edgeInProgressTargetHandleID = exports.edgeInProgressID + '-target-anchor'; //# sourceMappingURL=model.js.map