/* * Activiti Modeler component part of the Activiti project * Copyright 2005-2014 Alfresco Software, Ltd. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Controller for morph shape selection */ var KisBpmShapeSelectionCtrl = [ '$rootScope', '$scope', '$timeout', '$translate', function($rootScope, $scope, $timeout, $translate) { $scope.selectedMorphShapes = []; $scope.availableMorphShapes = []; for (var i = 0; i < $scope.morphShapes.length; i++) { if ($scope.morphShapes[i].id != $scope.currentSelectedShape.getStencil().idWithoutNs()) { $scope.availableMorphShapes.push($scope.morphShapes[i]); } } // Config for grid $scope.gridOptions = { data: 'availableMorphShapes', enableRowReordering: true, headerRowHeight: 28, multiSelect: false, keepLastSelected : false, selectedItems: $scope.selectedMorphShapes, columnDefs: [{ field: 'objectId', displayName: 'Icon', width: 50, cellTemplate: 'editor-app/popups/icon-template.html?version=' + Date.now() }, { field: 'name', displayName: 'Name'}] }; // Click handler for save button $scope.select = function() { if ($scope.selectedMorphShapes.length > 0) { var MorphTo = ORYX.Core.Command.extend({ construct: function(shape, stencil, facade){ this.shape = shape; this.stencil = stencil; this.facade = facade; }, execute: function(){ var shape = this.shape; var stencil = this.stencil; var resourceId = shape.resourceId; // Serialize all attributes var serialized = shape.serialize(); stencil.properties().each((function(prop) { if(prop.readonly()) { serialized = serialized.reject(function(serProp) { return serProp.name==prop.id(); }); } }).bind(this)); // Get shape if already created, otherwise create a new shape if (this.newShape){ newShape = this.newShape; this.facade.getCanvas().add(newShape); } else { newShape = this.facade.createShape({ type: stencil.id(), namespace: stencil.namespace(), resourceId: resourceId }); } // calculate new bounds using old shape's upperLeft and new shape's width/height var boundsObj = serialized.find(function(serProp){ return (serProp.prefix === "oryx" && serProp.name === "bounds"); }); var changedBounds = null; if (!this.facade.getRules().preserveBounds(shape.getStencil())) { var bounds = boundsObj.value.split(","); if (parseInt(bounds[0], 10) > parseInt(bounds[2], 10)) { // if lowerRight comes first, swap array items var tmp = bounds[0]; bounds[0] = bounds[2]; bounds[2] = tmp; tmp = bounds[1]; bounds[1] = bounds[3]; bounds[3] = tmp; } bounds[2] = parseInt(bounds[0], 10) + newShape.bounds.width(); bounds[3] = parseInt(bounds[1], 10) + newShape.bounds.height(); boundsObj.value = bounds.join(","); } else { var height = shape.bounds.height(); var width = shape.bounds.width(); // consider the minimum and maximum size of // the new shape if (newShape.minimumSize) { if (shape.bounds.height() < newShape.minimumSize.height) { height = newShape.minimumSize.height; } if (shape.bounds.width() < newShape.minimumSize.width) { width = newShape.minimumSize.width; } } if(newShape.maximumSize) { if(shape.bounds.height() > newShape.maximumSize.height) { height = newShape.maximumSize.height; } if(shape.bounds.width() > newShape.maximumSize.width) { width = newShape.maximumSize.width; } } changedBounds = { a : { x: shape.bounds.a.x, y: shape.bounds.a.y }, b : { x: shape.bounds.a.x + width, y: shape.bounds.a.y + height } }; } var oPos = shape.bounds.center(); if(changedBounds !== null) { newShape.bounds.set(changedBounds); } // Set all related dockers this.setRelatedDockers(shape, newShape); // store DOM position of old shape var parentNode = shape.node.parentNode; var nextSibling = shape.node.nextSibling; // Delete the old shape this.facade.deleteShape(shape); // Deserialize the new shape - Set all attributes newShape.deserialize(serialized); /* * Change color to default if unchanged * 23.04.2010 */ if(shape.getStencil().property("oryx-bgcolor") && shape.properties["oryx-bgcolor"] && shape.getStencil().property("oryx-bgcolor").value().toUpperCase()== shape.properties["oryx-bgcolor"].toUpperCase()){ if(newShape.getStencil().property("oryx-bgcolor")){ newShape.setProperty("oryx-bgcolor", newShape.getStencil().property("oryx-bgcolor").value()); } } if(changedBounds !== null) { newShape.bounds.set(changedBounds); } if(newShape.getStencil().type()==="edge" || (newShape.dockers.length==0 || !newShape.dockers[0].getDockedShape())) { newShape.bounds.centerMoveTo(oPos); } if(newShape.getStencil().type()==="node" && (newShape.dockers.length==0 || !newShape.dockers[0].getDockedShape())) { this.setRelatedDockers(newShape, newShape); } // place at the DOM position of the old shape if(nextSibling) parentNode.insertBefore(newShape.node, nextSibling); else parentNode.appendChild(newShape.node); // Set selection this.facade.setSelection([newShape]); this.facade.getCanvas().update(); this.facade.updateSelection(); this.newShape = newShape; }, rollback: function(){ if (!this.shape || !this.newShape || !this.newShape.parent) {return;} // Append shape to the parent this.newShape.parent.add(this.shape); // Set dockers this.setRelatedDockers(this.newShape, this.shape); // Delete new shape this.facade.deleteShape(this.newShape); // Set selection this.facade.setSelection([this.shape]); // Update this.facade.getCanvas().update(); this.facade.updateSelection(); }, /** * Set all incoming and outgoing edges from the shape to the new shape * @param {Shape} shape * @param {Shape} newShape */ setRelatedDockers: function(shape, newShape){ if(shape.getStencil().type()==="node") { (shape.incoming||[]).concat(shape.outgoing||[]) .each(function(i) { i.dockers.each(function(docker) { if (docker.getDockedShape() == shape) { var rPoint = Object.clone(docker.referencePoint); // Move reference point per percent var rPointNew = { x: rPoint.x*newShape.bounds.width()/shape.bounds.width(), y: rPoint.y*newShape.bounds.height()/shape.bounds.height() }; docker.setDockedShape(newShape); // Set reference point and center to new position docker.setReferencePoint(rPointNew); if(i instanceof ORYX.Core.Edge) { docker.bounds.centerMoveTo(rPointNew); } else { var absXY = shape.absoluteXY(); docker.bounds.centerMoveTo({x:rPointNew.x+absXY.x, y:rPointNew.y+absXY.y}); //docker.bounds.moveBy({x:rPointNew.x-rPoint.x, y:rPointNew.y-rPoint.y}); } } }); }); // for attached events if(shape.dockers.length>0&&shape.dockers.first().getDockedShape()) { newShape.dockers.first().setDockedShape(shape.dockers.first().getDockedShape()); newShape.dockers.first().setReferencePoint(Object.clone(shape.dockers.first().referencePoint)); } } else { // is edge newShape.dockers.first().setDockedShape(shape.dockers.first().getDockedShape()); newShape.dockers.first().setReferencePoint(shape.dockers.first().referencePoint); newShape.dockers.last().setDockedShape(shape.dockers.last().getDockedShape()); newShape.dockers.last().setReferencePoint(shape.dockers.last().referencePoint); } } }); var stencil = undefined; var stencilSets = $scope.editor.getStencilSets().values(); var stencilId = $scope.selectedMorphShapes[0].id; if ($scope.selectedMorphShapes[0].genericTaskId) { stencilId = $scope.selectedMorphShapes[0].genericTaskId; } for (var i = 0; i < stencilSets.length; i++) { var stencilSet = stencilSets[i]; var nodes = stencilSet.nodes(); for (var j = 0; j < nodes.length; j++) { if (nodes[j].idWithoutNs() === stencilId) { stencil = nodes[j]; break; } } } if (!stencil) return; // Create and execute command (for undo/redo) var command = new MorphTo($scope.currentSelectedShape, stencil, $scope.editor); $scope.editor.executeCommands([command]); } $scope.close(); }; $scope.cancel = function() { $scope.$hide(); }; // Close button handler $scope.close = function() { $scope.$hide(); }; }];