You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							318 lines
						
					
					
						
							11 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							318 lines
						
					
					
						
							11 KiB
						
					
					
				| /* Licensed under the Apache License, Version 2.0 (the "License"); | |
|  * you may not use this file except in compliance with the License. | |
|  * You may obtain a copy of the License at | |
|  *  | |
|  *      http://www.apache.org/licenses/LICENSE-2.0 | |
|  *  | |
|  * Unless required by applicable law or agreed to in writing, software | |
|  * distributed under the License is distributed on an "AS IS" BASIS, | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
|  * See the License for the specific language governing permissions and | |
|  * limitations under the License. | |
|  */ | |
| 
 | |
| /* | |
|  * Controller for morph shape selection | |
|  */ | |
| 
 | |
| angular.module('flowableModeler').controller('FlowableBpmShapeSelectionCtrl', | |
|     [ '$rootScope', '$scope', '$timeout', '$translate', 'editorManager', function($rootScope, $scope, $timeout, $translate, editorManager) { | |
| 
 | |
|     $scope.currentSelectedMorph = undefined; | |
|      | |
|     $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: $scope.availableMorphShapes, | |
|         headerRowHeight: 28, | |
|         enableRowSelection: true, | |
|         enableRowHeaderSelection: false, | |
|         multiSelect: false, | |
|         modifierKeysToMultiSelect: false, | |
|         enableHorizontalScrollbar: 0, | |
| 		enableColumnMenus: false, | |
| 		enableSorting: false, | |
|         columnDefs: [{ field: 'objectId', displayName: 'Icon', width: 50, cellTemplate: 'editor-app/popups/icon-template.html?version=' + Date.now() }, | |
|             { field: 'name', displayName: 'Name', cellTemplate: '<div class="ui-grid-cell-contents">{{"" + row.entity[col.field] | translate}}</div>'}] | |
|     }; | |
|      | |
|     $scope.gridOptions.onRegisterApi = function(gridApi) { | |
|         //set gridApi on scope | |
|         $scope.gridApi = gridApi; | |
|         gridApi.selection.on.rowSelectionChanged($scope, function(row) { | |
|             if (row.isSelected) { | |
|                 $scope.currentSelectedMorph = row.entity; | |
|             } else { | |
|                 $scope.currentSelectedMorph = undefined; | |
|             } | |
|         }); | |
|     }; | |
| 
 | |
|     // Click handler for save button | |
|     $scope.select = function() { | |
| 
 | |
|         if ($scope.currentSelectedMorph) { | |
|         	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 = editorManager.getStencilSets().values(); | |
|         	 | |
|         	var stencilId = $scope.currentSelectedMorph.id; | |
|         	if ($scope.currentSelectedMorph.genericTaskId) { | |
|         		stencilId = $scope.currentSelectedMorph.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, editorManager.getEditor()); | |
|     		editorManager.executeCommands([command]); | |
|         } | |
| 
 | |
|         $scope.close(); | |
|     }; | |
| 
 | |
|     $scope.cancel = function() { | |
|     	$scope.$hide(); | |
|     }; | |
| 
 | |
|     // Close button handler | |
|     $scope.close = function() { | |
|     	$scope.$hide(); | |
|     }; | |
| 
 | |
| }]); |