UNPKG

sprotty

Version:

A next-gen framework for graphical views

131 lines 5.05 kB
"use strict"; /******************************************************************************** * Copyright (c) 2021 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.getModelBounds = exports.getProjectedBounds = exports.getProjections = exports.isProjectable = void 0; const geometry_1 = require("sprotty-protocol/lib/utils/geometry"); const object_1 = require("sprotty-protocol/lib/utils/object"); const smodel_utils_1 = require("../../base/model/smodel-utils"); const model_1 = require("../bounds/model"); function isProjectable(arg) { return (0, object_1.hasOwnProperty)(arg, 'projectionCssClasses'); } exports.isProjectable = isProjectable; /** * Gather all projections of elements contained in the given parent element. */ function getProjections(parent) { let result; for (const child of parent.children) { if (isProjectable(child) && child.projectionCssClasses.length > 0) { const projectedBounds = getProjectedBounds(child); if (projectedBounds) { const projection = { elementId: child.id, projectedBounds, cssClasses: child.projectionCssClasses }; if (result) { result.push(projection); } else { result = [projection]; } } } if (child.children.length > 0) { const childProj = getProjections(child); if (childProj) { if (result) { result.push(...childProj); } else { result = childProj; } } } } return result; } exports.getProjections = getProjections; /** * Compute the projected bounds of the given model element, that is the absolute position in the diagram. */ function getProjectedBounds(model) { const parent = model.parent; if (model.projectedBounds) { let bounds = model.projectedBounds; if ((0, model_1.isBoundsAware)(parent)) { bounds = (0, smodel_utils_1.transformToRootBounds)(parent, bounds); } return bounds; } else if ((0, model_1.isBoundsAware)(model)) { let bounds = model.bounds; bounds = (0, smodel_utils_1.transformToRootBounds)(parent, bounds); return bounds; } return undefined; } exports.getProjectedBounds = getProjectedBounds; const MAX_COORD = 1000000000; /** * Determine the total bounds of a model; this takes the viewport into consideration * so it can be shown in the projections. */ function getModelBounds(model) { let minX = MAX_COORD; let minY = MAX_COORD; let maxX = -MAX_COORD; let maxY = -MAX_COORD; const bounds = (0, model_1.isBoundsAware)(model) ? model.bounds : undefined; if (bounds && geometry_1.Dimension.isValid(bounds)) { // Get the bounds directly from the model if it returns a valid size minX = bounds.x; minY = bounds.y; maxX = minX + bounds.width; maxY = minY + bounds.height; } else { // Determine the min. / max coordinates of top-level model elements // Note that this approach is slower, so provide valid bounds to speed up the process. for (const element of model.children) { if ((0, model_1.isBoundsAware)(element)) { const b = element.bounds; minX = Math.min(minX, b.x); minY = Math.min(minY, b.y); maxX = Math.max(maxX, b.x + b.width); maxY = Math.max(maxY, b.y + b.height); } } } // Enlarge the bounds by the current viewport to ensure it always fits into the projection minX = Math.min(minX, model.scroll.x); minY = Math.min(minY, model.scroll.y); maxX = Math.max(maxX, model.scroll.x + model.canvasBounds.width / model.zoom); maxY = Math.max(maxY, model.scroll.y + model.canvasBounds.height / model.zoom); if (minX < maxX && minY < maxY) { return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }; } return undefined; } exports.getModelBounds = getModelBounds; //# sourceMappingURL=model.js.map