UNPKG

sprotty

Version:

A next-gen framework for graphical views

178 lines 6.74 kB
"use strict"; /******************************************************************************** * Copyright (c) 2017-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.SShapeElementImpl = exports.findChildrenAtPosition = exports.getAbsoluteClientBounds = exports.getAbsoluteBounds = exports.isAlignable = exports.isSizeable = exports.isLayoutableChild = exports.isLayoutContainer = exports.isBoundsAware = exports.alignFeature = exports.layoutableChildFeature = exports.layoutContainerFeature = exports.boundsFeature = void 0; const geometry_1 = require("sprotty-protocol/lib/utils/geometry"); const smodel_1 = require("../../base/model/smodel"); const smodel_utils_1 = require("../../base/model/smodel-utils"); const browser_1 = require("../../utils/browser"); exports.boundsFeature = Symbol('boundsFeature'); exports.layoutContainerFeature = Symbol('layoutContainerFeature'); exports.layoutableChildFeature = Symbol('layoutableChildFeature'); exports.alignFeature = Symbol('alignFeature'); function isBoundsAware(element) { return 'bounds' in element; } exports.isBoundsAware = isBoundsAware; function isLayoutContainer(element) { return isBoundsAware(element) && element.hasFeature(exports.layoutContainerFeature) && 'layout' in element; } exports.isLayoutContainer = isLayoutContainer; function isLayoutableChild(element) { return isBoundsAware(element) && element.hasFeature(exports.layoutableChildFeature); } exports.isLayoutableChild = isLayoutableChild; function isSizeable(element) { return element.hasFeature(exports.boundsFeature) && isBoundsAware(element); } exports.isSizeable = isSizeable; function isAlignable(element) { return element.hasFeature(exports.alignFeature) && 'alignment' in element; } exports.isAlignable = isAlignable; function getAbsoluteBounds(element) { const boundsAware = (0, smodel_utils_1.findParentByFeature)(element, isBoundsAware); if (boundsAware !== undefined) { let bounds = boundsAware.bounds; let current = boundsAware; while (current instanceof smodel_1.SChildElementImpl) { const parent = current.parent; bounds = parent.localToParent(bounds); current = parent; } return bounds; } else if (element instanceof smodel_1.SModelRootImpl) { const canvasBounds = element.canvasBounds; return { x: 0, y: 0, width: canvasBounds.width, height: canvasBounds.height }; } else { return geometry_1.Bounds.EMPTY; } } exports.getAbsoluteBounds = getAbsoluteBounds; /** * Returns the "client-absolute" bounds of the specified `element`. * * The client-absolute bounds are relative to the entire browser page. * * @param element The element to get the bounds for. * @param domHelper The dom helper to obtain the SVG element's id. * @param viewerOptions The viewer options to obtain sprotty's container div id. */ function getAbsoluteClientBounds(element, domHelper, viewerOptions) { let x = 0; let y = 0; let width = 0; let height = 0; const svgElementId = domHelper.createUniqueDOMElementId(element); const svgElement = document.getElementById(svgElementId); if (svgElement) { const rect = svgElement.getBoundingClientRect(); const scroll = (0, browser_1.getWindowScroll)(); x = rect.left + scroll.x; y = rect.top + scroll.y; width = rect.width; height = rect.height; } let container = document.getElementById(viewerOptions.baseDiv); if (container) { while (container.offsetParent instanceof HTMLElement && (container = container.offsetParent)) { x -= container.offsetLeft; y -= container.offsetTop; } } return { x, y, width, height }; } exports.getAbsoluteClientBounds = getAbsoluteClientBounds; function findChildrenAtPosition(parent, point) { const matches = []; doFindChildrenAtPosition(parent, point, matches); return matches; } exports.findChildrenAtPosition = findChildrenAtPosition; function doFindChildrenAtPosition(parent, point, matches) { parent.children.forEach(child => { if (isBoundsAware(child) && geometry_1.Bounds.includes(child.bounds, point)) matches.push(child); if (child instanceof smodel_1.SParentElementImpl) { const newPoint = child.parentToLocal(point); doFindChildrenAtPosition(child, newPoint, matches); } }); } /** * Abstract class for elements with a position and a size. */ class SShapeElementImpl extends smodel_1.SChildElementImpl { constructor() { super(...arguments); this.position = geometry_1.Point.ORIGIN; this.size = geometry_1.Dimension.EMPTY; } get bounds() { return { x: this.position.x, y: this.position.y, width: this.size.width, height: this.size.height }; } set bounds(newBounds) { this.position = { x: newBounds.x, y: newBounds.y }; this.size = { width: newBounds.width, height: newBounds.height }; } localToParent(point) { const result = { x: point.x + this.position.x, y: point.y + this.position.y, width: -1, height: -1 }; if ((0, geometry_1.isBounds)(point)) { result.width = point.width; result.height = point.height; } return result; } parentToLocal(point) { const result = { x: point.x - this.position.x, y: point.y - this.position.y, width: -1, height: -1 }; if ((0, geometry_1.isBounds)(point)) { result.width = point.width; result.height = point.height; } return result; } } exports.SShapeElementImpl = SShapeElementImpl; //# sourceMappingURL=model.js.map