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
			| 
											1 year ago
										 | /* 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(); | ||
|  |     }; | ||
|  | 
 | ||
|  | }]); |