sprotty
Version:
A next-gen framework for graphical views
131 lines • 5.05 kB
JavaScript
;
/********************************************************************************
* 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