2020-05-19 11:43:42 +03:00

298 lines
13 KiB
JavaScript

(function() {
'use strict';
function Nodedraggingfactory(flowchartConstants) {
var nodeDropScope = {};
nodeDropScope.dropElement = null;
return function(modelservice, nodeDraggingScope, applyFunction, automaticResize, dragAnimation) {
nodeDraggingScope.shadowDragStarted = false;
nodeDraggingScope.dropElement = null;
var dragOffsets = [];
var draggedElements = [];
nodeDraggingScope.draggedNodes = [];
nodeDraggingScope.shadowElements = [];
var destinationHtmlElements = [];
var oldDisplayStyles = [];
function getCoordinate(coordinate, max) {
coordinate = Math.max(coordinate, 0);
coordinate = Math.min(coordinate, max);
return coordinate;
}
function getXCoordinate(x) {
return getCoordinate(x, modelservice.getCanvasHtmlElement().offsetWidth);
}
function getYCoordinate(y) {
return getCoordinate(y, modelservice.getCanvasHtmlElement().offsetHeight);
}
function resizeCanvas(draggedNode, nodeElement) {
if (automaticResize && !modelservice.isDropSource()) {
var canvasElement = modelservice.getCanvasHtmlElement();
if (canvasElement.offsetWidth < draggedNode.x + nodeElement.offsetWidth + flowchartConstants.canvasResizeThreshold) {
canvasElement.style.width = canvasElement.offsetWidth + flowchartConstants.canvasResizeStep + 'px';
}
if (canvasElement.offsetHeight < draggedNode.y + nodeElement.offsetHeight + flowchartConstants.canvasResizeThreshold) {
canvasElement.style.height = canvasElement.offsetHeight + flowchartConstants.canvasResizeStep + 'px';
}
}
}
return {
dragstart: function(node) {
return function(event) {
if (node.readonly) {
return;
}
dragOffsets.length = 0;
draggedElements.length = 0;
nodeDraggingScope.draggedNodes.length = 0;
nodeDraggingScope.shadowElements.length = 0;
destinationHtmlElements.length = 0;
oldDisplayStyles.length = 0;
var elements = [];
var nodes = [];
if (modelservice.nodes.isSelected(node)) {
var selectedNodes = modelservice.nodes.getSelectedNodes();
for (var i=0;i<selectedNodes.length;i++) {
var selectedNode = selectedNodes[i];
var element = angular.element(modelservice.nodes.getHtmlElement(selectedNode.id));
elements.push(element);
nodes.push(selectedNode);
}
} else {
elements.push(angular.element(event.target));
nodes.push(node);
}
var offsetsX = [];
var offsetsY = [];
for (var i=0;i<elements.length;i++) {
var element = elements[i];
offsetsX.push(parseInt(element.css('left')) - event.clientX);
offsetsY.push(parseInt(element.css('top')) - event.clientY);
}
if (modelservice.isDropSource()) {
if (nodeDropScope.dropElement) {
nodeDropScope.dropElement.parentNode.removeChild(nodeDropScope.dropElement);
nodeDropScope.dropElement = null;
}
nodeDropScope.dropElement = elements[0][0].cloneNode(true);
var offset = angular.element(modelservice.getCanvasHtmlElement()).offset();
nodeDropScope.dropElement.offsetInfo = {
offsetX: Math.round(offsetsX[0] + offset.left),
offsetY: Math.round(offsetsY[0] + offset.top)
};
nodeDropScope.dropElement.style.position = 'absolute';
nodeDropScope.dropElement.style.pointerEvents = 'none';
nodeDropScope.dropElement.style.zIndex = '9999';
document.body.appendChild(nodeDropScope.dropElement);
var dropNodeInfo = {
node: node,
dropTargetId: modelservice.getDropTargetId(),
offsetX: Math.round(offsetsX[0] + offset.left),
offsetY: Math.round(offsetsY[0] + offset.top)
};
event.originalEvent.dataTransfer.setData('text', angular.toJson(dropNodeInfo));
if (event.originalEvent.dataTransfer.setDragImage) {
//var invisibleDiv = angular.element('<div></div>')[0]; // This divs stays invisible, because it is not in the dom.
//event.originalEvent.dataTransfer.setDragImage(invisibleDiv, 0, 0);
event.originalEvent.dataTransfer.setDragImage(modelservice.getDragImage(), 0, 0);
} else {
destinationHtmlElements.push(event.target);
oldDisplayStyles.push(event.target.style.display);
event.target.style.display = 'none';
nodeDraggingScope.shadowDragStarted = true;
}
return;
}
//modelservice.deselectAll();
//modelservice.nodes.select(node);
nodeDraggingScope.draggedNodes = nodes;
for (var i=0;i<elements.length;i++) {
draggedElements.push(elements[i][0]);
dragOffsets.push(
{
x: offsetsX[i],
y: offsetsY[i]
}
);
}
if (dragAnimation == flowchartConstants.dragAnimationShadow) {
for (var i=0;i<draggedElements.length;i++) {
var dragOffset = dragOffsets[i];
var draggedNode = nodeDraggingScope.draggedNodes[i];
var shadowElement = angular.element('<div style="position: absolute; opacity: 0.7; top: '+ getYCoordinate(dragOffset.y + event.clientY) +'px; left: '+ getXCoordinate(dragOffset.x + event.clientX) +'px; "><div class="innerNode"><p style="padding: 0 15px;">'+ draggedNode.name +'</p> </div></div>');
var targetInnerNode = angular.element(draggedElements[i]).children()[0];
shadowElement.children()[0].style.backgroundColor = targetInnerNode.style.backgroundColor;
nodeDraggingScope.shadowElements.push(shadowElement);
modelservice.getCanvasHtmlElement().appendChild(nodeDraggingScope.shadowElements[i][0]);
}
}
event.originalEvent.dataTransfer.setData('text', 'Just to support firefox');
if (event.originalEvent.dataTransfer.setDragImage) {
//var invisibleDiv = angular.element('<div></div>')[0]; // This divs stays invisible, because it is not in the dom.
//event.originalEvent.dataTransfer.setDragImage(invisibleDiv, 0, 0);
event.originalEvent.dataTransfer.setDragImage(modelservice.getDragImage(), 0, 0);
} else {
for (var i=0;i<draggedElements.length;i++) {
destinationHtmlElements.push(draggedElements[i]);
oldDisplayStyles.push(destinationHtmlElements[i].style.display);
destinationHtmlElements[i].style.display = 'none'; // Internetexplorer does not support setDragImage, but it takes an screenshot, from the draggedelement and uses it as dragimage.
}
// Since angular redraws the element in the next dragover call, display: none never gets visible to the user.
if (dragAnimation == flowchartConstants.dragAnimationShadow) {
// IE Drag Fix
nodeDraggingScope.shadowDragStarted = true;
}
}
};
},
drop: function(event) {
if (modelservice.isDropSource()) {
event.preventDefault();
return false;
}
var dropNode = null;
var infoText = event.originalEvent.dataTransfer.getData('text');
if (infoText) {
var dropNodeInfo = null;
try {
dropNodeInfo = angular.fromJson(infoText);
} catch (e) {}
if (dropNodeInfo && dropNodeInfo.dropTargetId) {
if (modelservice.getCanvasHtmlElement().id &&
modelservice.getCanvasHtmlElement().id == dropNodeInfo.dropTargetId) {
dropNode = dropNodeInfo.node;
var offset = angular.element(modelservice.getCanvasHtmlElement()).offset();
var x = event.clientX - offset.left;
var y = event.clientY - offset.top;
dropNode.x = Math.round(getXCoordinate(dropNodeInfo.offsetX + x));
dropNode.y = Math.round(getYCoordinate(dropNodeInfo.offsetY + y));
}
}
}
if (dropNode) {
modelservice.dropNode(event, dropNode);
event.preventDefault();
return false;
} else if (nodeDraggingScope.draggedNodes.length) {
return applyFunction(function() {
for (var i=0;i<nodeDraggingScope.draggedNodes.length;i++) {
var draggedNode = nodeDraggingScope.draggedNodes[i];
var dragOffset = dragOffsets[i];
draggedNode.x = Math.round(getXCoordinate(dragOffset.x + event.clientX));
draggedNode.y = Math.round(getYCoordinate(dragOffset.y + event.clientY));
}
event.preventDefault();
return false;
})
}
},
dragover: function(event) {
if (nodeDropScope.dropElement) {
var offsetInfo = nodeDropScope.dropElement.offsetInfo;
nodeDropScope.dropElement.style.left = (offsetInfo.offsetX + event.clientX) + 'px';
nodeDropScope.dropElement.style.top = (offsetInfo.offsetY + event.clientY) + 'px';
if(nodeDraggingScope.shadowDragStarted) {
applyFunction(function() {
destinationHtmlElements[0].style.display = oldDisplayStyles[0];
nodeDraggingScope.shadowDragStarted = false;
});
}
event.preventDefault();
return;
}
if (modelservice.isDropSource()) {
event.preventDefault();
return;
}
if (!nodeDraggingScope.draggedNodes.length) {
event.preventDefault();
return;
}
if (dragAnimation == flowchartConstants.dragAnimationRepaint) {
if (nodeDraggingScope.draggedNodes.length) {
return applyFunction(function() {
for (var i=0;i<nodeDraggingScope.draggedNodes.length;i++) {
var draggedNode = nodeDraggingScope.draggedNodes[i];
var dragOffset = dragOffsets[i];
draggedNode.x = getXCoordinate(dragOffset.x + event.clientX);
draggedNode.y = getYCoordinate(dragOffset.y + event.clientY);
resizeCanvas(draggedNode, draggedElements[i]);
}
event.preventDefault();
return false;
});
}
} else if (dragAnimation == flowchartConstants.dragAnimationShadow) {
if (nodeDraggingScope.draggedNodes.length) {
if(nodeDraggingScope.shadowDragStarted) {
applyFunction(function() {
for (var i=0;i<nodeDraggingScope.draggedNodes.length;i++) {
destinationHtmlElements[i].style.display = oldDisplayStyles[i];
}
nodeDraggingScope.shadowDragStarted = false;
});
}
for (var i=0;i<nodeDraggingScope.draggedNodes.length;i++) {
var draggedNode = nodeDraggingScope.draggedNodes[i];
var dragOffset = dragOffsets[i];
nodeDraggingScope.shadowElements[i].css('left', getXCoordinate(dragOffset.x + event.clientX) + 'px');
nodeDraggingScope.shadowElements[i].css('top', getYCoordinate(dragOffset.y + event.clientY) + 'px');
resizeCanvas(draggedNode, draggedElements[i]);
}
event.preventDefault();
}
}
},
dragend: function(event) {
applyFunction(function() {
if (nodeDropScope.dropElement) {
nodeDropScope.dropElement.parentNode.removeChild(nodeDropScope.dropElement);
nodeDropScope.dropElement = null;
}
if (modelservice.isDropSource()) {
return;
}
if (nodeDraggingScope.shadowElements.length) {
for (var i=0;i<nodeDraggingScope.draggedNodes.length;i++) {
var draggedNode = nodeDraggingScope.draggedNodes[i];
var shadowElement = nodeDraggingScope.shadowElements[i];
draggedNode.x = parseInt(shadowElement.css('left').replace('px', ''));
draggedNode.y = parseInt(shadowElement.css('top').replace('px', ''));
modelservice.getCanvasHtmlElement().removeChild(shadowElement[0]);
}
nodeDraggingScope.shadowElements.length = 0;
}
if (nodeDraggingScope.draggedNodes.length) {
nodeDraggingScope.draggedNodes.length = 0;
draggedElements.length = 0;
dragOffsets.length = 0;
}
});
}
};
};
}
angular
.module('flowchart')
.factory('Nodedraggingfactory', Nodedraggingfactory);
}());