cl
2024-05-23 ba1a7a9ef126296e2798e313dc5b43f775a1123c
提交 | 用户 | 时间
71e81e 1 /*
2  * Activiti Modeler component part of the Activiti project
3  * Copyright 2005-2014 Alfresco Software, Ltd. All rights reserved.
4  * 
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19
20 /*
21  * Controller for morph shape selection
22  */
23
24 var KisBpmShapeSelectionCtrl = [ '$rootScope', '$scope', '$timeout', '$translate', function($rootScope, $scope, $timeout, $translate) {
25
26     $scope.selectedMorphShapes = [];
27     
28     $scope.availableMorphShapes = [];
29
30     for (var i = 0; i < $scope.morphShapes.length; i++)
31     {
32         if ($scope.morphShapes[i].id != $scope.currentSelectedShape.getStencil().idWithoutNs())
33         {
34             $scope.availableMorphShapes.push($scope.morphShapes[i]);
35         }
36     }
37         
38     // Config for grid
39     $scope.gridOptions = {
40         data: 'availableMorphShapes',
41         enableRowReordering: true,
42         headerRowHeight: 28,
43         multiSelect: false,
44         keepLastSelected : false,
45         selectedItems: $scope.selectedMorphShapes,
46         columnDefs: [{ field: 'objectId', displayName: 'Icon', width: 50, cellTemplate: 'editor-app/popups/icon-template.html?version=' + Date.now() },
47             { field: 'name', displayName: 'Name'}]
48     };
49
50     // Click handler for save button
51     $scope.select = function() {
52
53         if ($scope.selectedMorphShapes.length > 0) 
54         {
55             var MorphTo = ORYX.Core.Command.extend({
56                 construct: function(shape, stencil, facade){
57                     this.shape = shape;
58                     this.stencil = stencil;
59                     this.facade = facade;
60                 },
61                 execute: function(){
62                     
63                     var shape = this.shape;
64                     var stencil = this.stencil;
65                     var resourceId = shape.resourceId;
66                     
67                     // Serialize all attributes
68                     var serialized = shape.serialize();
69                     stencil.properties().each((function(prop) {
70                         if(prop.readonly()) {
71                             serialized = serialized.reject(function(serProp) {
72                                 return serProp.name==prop.id();
73                             });
74                         }
75                     }).bind(this));
76             
77                     // Get shape if already created, otherwise create a new shape
78                     if (this.newShape){
79                         newShape = this.newShape;
80                         this.facade.getCanvas().add(newShape);
81                     } else {
82                         newShape = this.facade.createShape({
83                                         type: stencil.id(),
84                                         namespace: stencil.namespace(),
85                                         resourceId: resourceId
86                                     });
87                     }
88                     
89                     // calculate new bounds using old shape's upperLeft and new shape's width/height
90                     var boundsObj = serialized.find(function(serProp){
91                         return (serProp.prefix === "oryx" && serProp.name === "bounds");
92                     });
93                     
94                     var changedBounds = null;
95                     
96                     if (!this.facade.getRules().preserveBounds(shape.getStencil())) {
97                         
98                         var bounds = boundsObj.value.split(",");
99                         if (parseInt(bounds[0], 10) > parseInt(bounds[2], 10)) { // if lowerRight comes first, swap array items
100                             var tmp = bounds[0];
101                             bounds[0] = bounds[2];
102                             bounds[2] = tmp;
103                             tmp = bounds[1];
104                             bounds[1] = bounds[3];
105                             bounds[3] = tmp;
106                         }
107                         bounds[2] = parseInt(bounds[0], 10) + newShape.bounds.width();
108                         bounds[3] = parseInt(bounds[1], 10) + newShape.bounds.height();
109                         boundsObj.value = bounds.join(",");
110                         
111                     }  else {
112                         
113                         var height = shape.bounds.height();
114                         var width  = shape.bounds.width();
115                         
116                         // consider the minimum and maximum size of
117                         // the new shape
118                         
119                         if (newShape.minimumSize) {
120                             if (shape.bounds.height() < newShape.minimumSize.height) {
121                                 height = newShape.minimumSize.height;
122                             }
123                             
124                             
125                             if (shape.bounds.width() < newShape.minimumSize.width) {
126                                 width = newShape.minimumSize.width;
127                             }
128                         }
129                         
130                         if(newShape.maximumSize) {
131                             if(shape.bounds.height() > newShape.maximumSize.height) {
132                                 height = newShape.maximumSize.height;
133                             }    
134                             
135                             if(shape.bounds.width() > newShape.maximumSize.width) {
136                                 width = newShape.maximumSize.width;
137                             }
138                         }
139                         
140                         changedBounds = {
141                             a : {
142                                 x: shape.bounds.a.x,
143                                 y: shape.bounds.a.y
144                             },
145                             b : {
146                                 x: shape.bounds.a.x + width,
147                                 y: shape.bounds.a.y + height
148                             }                        
149                         };
150                         
151                     }
152                     
153                     var oPos = shape.bounds.center();
154                     if(changedBounds !== null) {
155                         newShape.bounds.set(changedBounds);
156                     }
157                     
158                     // Set all related dockers
159                     this.setRelatedDockers(shape, newShape);
160                     
161                     // store DOM position of old shape
162                     var parentNode = shape.node.parentNode;
163                     var nextSibling = shape.node.nextSibling;
164                     
165                     // Delete the old shape
166                     this.facade.deleteShape(shape);
167                     
168                     // Deserialize the new shape - Set all attributes
169                     newShape.deserialize(serialized);
170                     /*
171                      * Change color to default if unchanged
172                      * 23.04.2010
173                      */
174                     if(shape.getStencil().property("oryx-bgcolor") 
175                             && shape.properties["oryx-bgcolor"]
176                             && shape.getStencil().property("oryx-bgcolor").value().toUpperCase()== shape.properties["oryx-bgcolor"].toUpperCase()){
177                             if(newShape.getStencil().property("oryx-bgcolor")){
178                                 newShape.setProperty("oryx-bgcolor", newShape.getStencil().property("oryx-bgcolor").value());
179                             }
180                     }    
181                     if(changedBounds !== null) {
182                         newShape.bounds.set(changedBounds);
183                     }
184                     
185                     if(newShape.getStencil().type()==="edge" || (newShape.dockers.length==0 || !newShape.dockers[0].getDockedShape())) {
186                         newShape.bounds.centerMoveTo(oPos);
187                     } 
188                     
189                     if(newShape.getStencil().type()==="node" && (newShape.dockers.length==0 || !newShape.dockers[0].getDockedShape())) {
190                         this.setRelatedDockers(newShape, newShape);
191                         
192                     }
193                     
194                     // place at the DOM position of the old shape
195                     if(nextSibling) parentNode.insertBefore(newShape.node, nextSibling);
196                     else parentNode.appendChild(newShape.node);
197                     
198                     // Set selection
199                     this.facade.setSelection([newShape]);
200                     this.facade.getCanvas().update();
201                     this.facade.updateSelection();
202                     this.newShape = newShape;
203                     
204                 },
205                 rollback: function(){
206                     
207                     if (!this.shape || !this.newShape || !this.newShape.parent) {return;}
208                     
209                     // Append shape to the parent
210                     this.newShape.parent.add(this.shape);
211                     // Set dockers
212                     this.setRelatedDockers(this.newShape, this.shape);
213                     // Delete new shape
214                     this.facade.deleteShape(this.newShape);
215                     // Set selection
216                     this.facade.setSelection([this.shape]);
217                     // Update
218                     this.facade.getCanvas().update();
219                     this.facade.updateSelection();
220                 },
221                 
222                 /**
223                  * Set all incoming and outgoing edges from the shape to the new shape
224                  * @param {Shape} shape
225                  * @param {Shape} newShape
226                  */
227                 setRelatedDockers: function(shape, newShape){
228                     
229                     if(shape.getStencil().type()==="node") {
230                         
231                         (shape.incoming||[]).concat(shape.outgoing||[])
232                             .each(function(i) { 
233                                 i.dockers.each(function(docker) {
234                                     if (docker.getDockedShape() == shape) {
235                                         var rPoint = Object.clone(docker.referencePoint);
236                                         // Move reference point per percent
237
238                                         var rPointNew = {
239                                             x: rPoint.x*newShape.bounds.width()/shape.bounds.width(),
240                                             y: rPoint.y*newShape.bounds.height()/shape.bounds.height()
241                                         };
242
243                                         docker.setDockedShape(newShape);
244                                         // Set reference point and center to new position
245                                         docker.setReferencePoint(rPointNew);
246                                         if(i instanceof ORYX.Core.Edge) {
247                                             docker.bounds.centerMoveTo(rPointNew);
248                                         } else {
249                                             var absXY = shape.absoluteXY();
250                                             docker.bounds.centerMoveTo({x:rPointNew.x+absXY.x, y:rPointNew.y+absXY.y});
251                                             //docker.bounds.moveBy({x:rPointNew.x-rPoint.x, y:rPointNew.y-rPoint.y});
252                                         }
253                                     }
254                                 });    
255                             });
256                         
257                         // for attached events
258                         if(shape.dockers.length>0&&shape.dockers.first().getDockedShape()) {
259                             newShape.dockers.first().setDockedShape(shape.dockers.first().getDockedShape());
260                             newShape.dockers.first().setReferencePoint(Object.clone(shape.dockers.first().referencePoint));
261                         }
262                     
263                     } else { // is edge
264                         newShape.dockers.first().setDockedShape(shape.dockers.first().getDockedShape());
265                         newShape.dockers.first().setReferencePoint(shape.dockers.first().referencePoint);
266                         newShape.dockers.last().setDockedShape(shape.dockers.last().getDockedShape());
267                         newShape.dockers.last().setReferencePoint(shape.dockers.last().referencePoint);
268                     }
269                 }
270             });
271             
272             var stencil = undefined;
273             var stencilSets = $scope.editor.getStencilSets().values();
274             
275             var stencilId = $scope.selectedMorphShapes[0].id;
276             if ($scope.selectedMorphShapes[0].genericTaskId)
277             {
278                 stencilId = $scope.selectedMorphShapes[0].genericTaskId;
279             }
280             
281             for (var i = 0; i < stencilSets.length; i++)
282             {
283                 var stencilSet = stencilSets[i];
284                 var nodes = stencilSet.nodes();
285                 for (var j = 0; j < nodes.length; j++)
286                 {
287                     if (nodes[j].idWithoutNs() === stencilId)
288                     {
289                         stencil = nodes[j];
290                         break;
291                     }
292                 }
293             }
294             
295             if (!stencil) return;
296             
297             // Create and execute command (for undo/redo)            
298             var command = new MorphTo($scope.currentSelectedShape, stencil, $scope.editor);
299             $scope.editor.executeCommands([command]);
300         }
301
302         $scope.close();
303     };
304
305     $scope.cancel = function() {
306         $scope.$hide();
307     };
308
309     // Close button handler
310     $scope.close = function() {
311         $scope.$hide();
312     };
313
314 }];