UNPKG

sprotty

Version:

A next-gen framework for graphical views

295 lines 13.3 kB
"use strict"; /******************************************************************************** * Copyright (c) 2017-2022 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; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; Object.defineProperty(exports, "__esModule", { value: true }); exports.UpdateModelCommand = void 0; const inversify_1 = require("inversify"); const actions_1 = require("sprotty-protocol/lib/actions"); const geometry_1 = require("sprotty-protocol/lib/utils/geometry"); const animation_1 = require("../../base/animations/animation"); const command_1 = require("../../base/commands/command"); const fade_1 = require("../fade/fade"); const smodel_1 = require("../../base/model/smodel"); const move_1 = require("../move/move"); const model_1 = require("../fade/model"); const model_2 = require("../move/model"); const model_3 = require("../bounds/model"); const viewport_root_1 = require("../viewport/viewport-root"); const model_4 = require("../select/model"); const model_matching_1 = require("./model-matching"); const resize_1 = require("../bounds/resize"); const types_1 = require("../../base/types"); const model_5 = require("../viewport/model"); const routing_1 = require("../routing/routing"); const model_6 = require("../routing/model"); const smodel_utils_1 = require("../../base/model/smodel-utils"); let UpdateModelCommand = class UpdateModelCommand extends command_1.Command { constructor(action) { super(); this.action = action; } execute(context) { let newRoot; if (this.action.newRoot !== undefined) { newRoot = context.modelFactory.createRoot(this.action.newRoot); } else { newRoot = context.modelFactory.createRoot(context.root); if (this.action.matches !== undefined) this.applyMatches(newRoot, this.action.matches, context); } this.oldRoot = context.root; this.newRoot = newRoot; return this.performUpdate(this.oldRoot, this.newRoot, context); } performUpdate(oldRoot, newRoot, context) { if ((this.action.animate === undefined || this.action.animate) && oldRoot.id === newRoot.id) { let matchResult; if (this.action.matches === undefined) { const matcher = new model_matching_1.ModelMatcher(); matchResult = matcher.match(oldRoot, newRoot); } else { matchResult = this.convertToMatchResult(this.action.matches, oldRoot, newRoot); } const animationOrRoot = this.computeAnimation(newRoot, matchResult, context); if (animationOrRoot instanceof animation_1.Animation) return animationOrRoot.start(); else return animationOrRoot; } else { if (oldRoot.type === newRoot.type && geometry_1.Dimension.isValid(oldRoot.canvasBounds)) newRoot.canvasBounds = oldRoot.canvasBounds; if ((0, model_5.isViewport)(oldRoot) && (0, model_5.isViewport)(newRoot)) { newRoot.zoom = oldRoot.zoom; newRoot.scroll = oldRoot.scroll; } return newRoot; } } applyMatches(root, matches, context) { const index = root.index; for (const match of matches) { if (match.left !== undefined) { const element = index.getById(match.left.id); if (element instanceof smodel_1.SChildElementImpl) element.parent.remove(element); } } for (const match of matches) { if (match.right !== undefined) { const element = context.modelFactory.createElement(match.right); let parent; if (match.rightParentId !== undefined) parent = index.getById(match.rightParentId); if (parent instanceof smodel_1.SParentElementImpl) parent.add(element); else root.add(element); } } } convertToMatchResult(matches, leftRoot, rightRoot) { const result = {}; for (const match of matches) { const converted = {}; let id = undefined; if (match.left !== undefined) { id = match.left.id; converted.left = leftRoot.index.getById(id); converted.leftParentId = match.leftParentId; } if (match.right !== undefined) { id = match.right.id; converted.right = rightRoot.index.getById(id); converted.rightParentId = match.rightParentId; } if (id !== undefined) result[id] = converted; } return result; } computeAnimation(newRoot, matchResult, context) { const animationData = { fades: [] }; (0, model_matching_1.forEachMatch)(matchResult, (id, match) => { if (match.left !== undefined && match.right !== undefined) { // The element is still there, but may have been moved this.updateElement(match.left, match.right, animationData); } else if (match.right !== undefined) { // An element has been added const right = match.right; if ((0, model_1.isFadeable)(right)) { right.opacity = 0; animationData.fades.push({ element: right, type: 'in' }); } } else if (match.left instanceof smodel_1.SChildElementImpl) { // An element has been removed const left = match.left; if ((0, model_1.isFadeable)(left) && match.leftParentId !== undefined) { if (!(0, smodel_utils_1.containsSome)(newRoot, left)) { const parent = newRoot.index.getById(match.leftParentId); if (parent instanceof smodel_1.SParentElementImpl) { const leftCopy = context.modelFactory.createElement(left); parent.add(leftCopy); animationData.fades.push({ element: leftCopy, type: 'out' }); } } } } }); const animations = this.createAnimations(animationData, newRoot, context); if (animations.length >= 2) { return new animation_1.CompoundAnimation(newRoot, context, animations); } else if (animations.length === 1) { return animations[0]; } else { return newRoot; } } updateElement(left, right, animationData) { if ((0, model_2.isLocateable)(left) && (0, model_2.isLocateable)(right)) { const leftPos = left.position; const rightPos = right.position; if (!(0, geometry_1.almostEquals)(leftPos.x, rightPos.x) || !(0, geometry_1.almostEquals)(leftPos.y, rightPos.y)) { if (animationData.moves === undefined) animationData.moves = []; animationData.moves.push({ element: right, fromPosition: leftPos, toPosition: rightPos }); right.position = leftPos; } } if ((0, model_3.isSizeable)(left) && (0, model_3.isSizeable)(right)) { if (!geometry_1.Dimension.isValid(right.bounds)) { right.bounds = { x: right.bounds.x, y: right.bounds.y, width: left.bounds.width, height: left.bounds.height }; } else if (!(0, geometry_1.almostEquals)(left.bounds.width, right.bounds.width) || !(0, geometry_1.almostEquals)(left.bounds.height, right.bounds.height)) { if (animationData.resizes === undefined) animationData.resizes = []; animationData.resizes.push({ element: right, fromDimension: { width: left.bounds.width, height: left.bounds.height, }, toDimension: { width: right.bounds.width, height: right.bounds.height, } }); } } if (left instanceof model_6.SRoutableElementImpl && right instanceof model_6.SRoutableElementImpl && this.edgeRouterRegistry) { if (animationData.edgeMementi === undefined) animationData.edgeMementi = []; animationData.edgeMementi.push({ edge: right, before: this.takeSnapshot(left), after: this.takeSnapshot(right), }); } if ((0, model_4.isSelectable)(left) && (0, model_4.isSelectable)(right)) { right.selected = left.selected; } if (left instanceof smodel_1.SModelRootImpl && right instanceof smodel_1.SModelRootImpl) { right.canvasBounds = left.canvasBounds; } if (left instanceof viewport_root_1.ViewportRootElementImpl && right instanceof viewport_root_1.ViewportRootElementImpl) { right.scroll = left.scroll; right.zoom = left.zoom; } } takeSnapshot(edge) { const router = this.edgeRouterRegistry.get(edge.routerKind); return router.takeSnapshot(edge); } createAnimations(data, root, context) { const animations = []; if (data.fades.length > 0) { animations.push(new fade_1.FadeAnimation(root, data.fades, context, true)); } if (data.moves !== undefined && data.moves.length > 0) { const movesMap = new Map; for (const move of data.moves) { movesMap.set(move.element.id, move); } animations.push(new move_1.MoveAnimation(root, movesMap, context, false)); } if (data.resizes !== undefined && data.resizes.length > 0) { const resizesMap = new Map; for (const resize of data.resizes) { resizesMap.set(resize.element.id, resize); } animations.push(new resize_1.ResizeAnimation(root, resizesMap, context, false)); } if (data.edgeMementi !== undefined && data.edgeMementi.length > 0) { animations.push(new move_1.MorphEdgesAnimation(root, data.edgeMementi, context, false)); } return animations; } undo(context) { return this.performUpdate(this.newRoot, this.oldRoot, context); } redo(context) { return this.performUpdate(this.oldRoot, this.newRoot, context); } }; exports.UpdateModelCommand = UpdateModelCommand; UpdateModelCommand.KIND = actions_1.UpdateModelAction.KIND; __decorate([ (0, inversify_1.inject)(routing_1.EdgeRouterRegistry), (0, inversify_1.optional)(), __metadata("design:type", routing_1.EdgeRouterRegistry) ], UpdateModelCommand.prototype, "edgeRouterRegistry", void 0); exports.UpdateModelCommand = UpdateModelCommand = __decorate([ (0, inversify_1.injectable)(), __param(0, (0, inversify_1.inject)(types_1.TYPES.Action)), __metadata("design:paramtypes", [Object]) ], UpdateModelCommand); //# sourceMappingURL=update-model.js.map