sprotty
Version:
A next-gen framework for graphical views
136 lines • 6.72 kB
JavaScript
;
/********************************************************************************
* Copyright (c) 2017-2024 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
********************************************************************************/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AbstractLayout = void 0;
const geometry_1 = require("sprotty-protocol/lib/utils/geometry");
const smodel_1 = require("../../base/model/smodel");
const model_1 = require("./model");
const inversify_1 = require("inversify");
let AbstractLayout = class AbstractLayout {
layout(container, layouter) {
const boundsData = layouter.getBoundsData(container);
const options = this.getLayoutOptions(container);
const childrenSize = this.getChildrenSize(container, options, layouter);
const maxWidth = options.paddingFactor * (options.resizeContainer
? Math.max(childrenSize.width, options.minWidth)
: Math.max(0, this.getFixedContainerBounds(container, options, layouter).width) - options.paddingLeft - options.paddingRight);
const maxHeight = options.paddingFactor * (options.resizeContainer
? Math.max(childrenSize.height, options.minHeight)
: Math.max(0, this.getFixedContainerBounds(container, options, layouter).height) - options.paddingTop - options.paddingBottom);
if (maxWidth > 0 && maxHeight > 0) {
const offset = this.layoutChildren(container, layouter, options, maxWidth, maxHeight);
boundsData.bounds = this.getFinalContainerBounds(container, offset, options, maxWidth, maxHeight);
boundsData.boundsChanged = true;
}
}
getFinalContainerBounds(container, lastOffset, options, maxWidth, maxHeight) {
return {
x: container.bounds.x,
y: container.bounds.y,
width: Math.max(options.minWidth, maxWidth + options.paddingLeft + options.paddingRight),
height: Math.max(options.minHeight, maxHeight + options.paddingTop + options.paddingBottom)
};
}
getFixedContainerBounds(container, layoutOptions, layouter) {
let currentContainer = container;
while (true) {
if ((0, model_1.isBoundsAware)(currentContainer)) {
const bounds = currentContainer.bounds;
if ((0, model_1.isLayoutContainer)(currentContainer) && layoutOptions.resizeContainer)
layouter.log.error(currentContainer, 'Resizable container found while detecting fixed bounds');
if (geometry_1.Dimension.isValid(bounds))
return bounds;
}
if (currentContainer instanceof smodel_1.SChildElementImpl) {
currentContainer = currentContainer.parent;
}
else {
layouter.log.error(currentContainer, 'Cannot detect fixed bounds');
return geometry_1.Bounds.EMPTY;
}
}
}
layoutChildren(container, layouter, containerOptions, maxWidth, maxHeight) {
let currentOffset = {
x: containerOptions.paddingLeft + 0.5 * (maxWidth - (maxWidth / containerOptions.paddingFactor)),
y: containerOptions.paddingTop + 0.5 * (maxHeight - (maxHeight / containerOptions.paddingFactor))
};
container.children.forEach(child => {
if ((0, model_1.isLayoutableChild)(child)) {
const boundsData = layouter.getBoundsData(child);
const bounds = boundsData.bounds;
const childOptions = this.getChildLayoutOptions(child, containerOptions);
if (bounds !== undefined && geometry_1.Dimension.isValid(bounds)) {
currentOffset = this.layoutChild(child, boundsData, bounds, childOptions, containerOptions, currentOffset, maxWidth, maxHeight);
}
}
});
return currentOffset;
}
getDx(hAlign, bounds, maxWidth) {
switch (hAlign) {
case 'left':
return 0;
case 'center':
return 0.5 * (maxWidth - bounds.width);
case 'right':
return maxWidth - bounds.width;
}
}
getDy(vAlign, bounds, maxHeight) {
switch (vAlign) {
case 'top':
return 0;
case 'center':
return 0.5 * (maxHeight - bounds.height);
case 'bottom':
return maxHeight - bounds.height;
}
}
getChildLayoutOptions(child, containerOptions) {
const layoutOptions = child.layoutOptions;
if (layoutOptions === undefined)
return containerOptions;
else
return this.spread(containerOptions, layoutOptions);
}
getLayoutOptions(element) {
let current = element;
const allOptions = [];
while (current !== undefined) {
const layoutOptions = current.layoutOptions;
if (layoutOptions !== undefined)
allOptions.push(layoutOptions);
if (current instanceof smodel_1.SChildElementImpl)
current = current.parent;
else
break;
}
return allOptions.reverse().reduce((a, b) => { return this.spread(a, b); }, this.getDefaultLayoutOptions());
}
};
exports.AbstractLayout = AbstractLayout;
exports.AbstractLayout = AbstractLayout = __decorate([
(0, inversify_1.injectable)()
], AbstractLayout);
//# sourceMappingURL=abstract-layout.js.map