Pārlūkot izejas kodu

Update svg position when cursor is close to bounds

Tom SPIRA 6 gadi atpakaļ
vecāks
revīzija
836177521c
1 mainītis faili ar 141 papildinājumiem un 121 dzēšanām
  1. 141 121
      hide/view/ShaderEditor.hx

+ 141 - 121
hide/view/ShaderEditor.hx

@@ -1,5 +1,6 @@
 package hide.view;
 
+import haxe.Timer;
 import h3d.shader.LineShader;
 import h3d.shader.ColorAdd;
 using hxsl.Ast.Type;
@@ -41,12 +42,13 @@ class ShaderEditor extends FileView {
 
 	static var transformMatrix : Array<Float> = [1, 0, 0, 1, 0, 0];
 	var isPanning : Bool = false;
+	var timerUpdateView : Timer;
 
 	// used for selection
 	var listOfBoxesSelected : Array<Box> = [];
 	var recSelection : JQuery;
-	var startRecSelection : h2d.col.IPoint;
-	var firstClickDrag : h2d.col.IPoint;
+	var startRecSelection : h2d.col.Point;
+	var lastClickDrag : h2d.col.Point;
 
 	// used to build edge
 	static var NODE_TRIGGER_NEAR = 2000.0;
@@ -136,7 +138,7 @@ class ShaderEditor extends FileView {
 			closeAddMenu();
 
 			if (e.button == 0) {
-				startRecSelection = new IPoint(e.offsetX, e.offsetY);
+				startRecSelection = new Point(lX(e.clientX), lY(e.clientY));
 				if (currentEdge != null) {
 					currentEdge.elt.removeClass("selected");
 					currentEdge = null;
@@ -145,101 +147,22 @@ class ShaderEditor extends FileView {
 				clearSelectionBoxes();
 			}
 			if (e.button == 1) {
-				firstClickDrag = new IPoint(e.clientX, e.clientY);
+				lastClickDrag = new Point(lX(e.clientX), lY(e.clientY));
 				isPanning = true;
 			}
 		});
 
-		parent.on("mouseover", function(e) {
-			if (isCreatingLink != None)
-				updateViewPosition();
-			if (currentEdge != null)
-				updateViewPosition();
-			if (startRecSelection != null)
-				updateViewPosition();
-		});
-
 		parent.on("mousemove", function(e : js.jquery.Event) {
 			e.preventDefault();
 			e.cancelBubble=true;
     		e.returnValue=false;
-
-			if (isCreatingLink != None) {
-				createLink(e);
-				return;
-			}
-			// Moving edge
-			if (currentEdge != null) {
-				// TODO: handle moving edge => disconnect closest node
-				// try to use the same code when user clicks on input node already connected and here
-			}
-			if (isPanning) {
-				pan(new Point(e.clientX - firstClickDrag.x, e.clientY - firstClickDrag.y));
-				firstClickDrag.x = e.clientX;
-				firstClickDrag.y = e.clientY;
-				return;
-			}
-			// Edit rectangle selection
-			if (startRecSelection != null) {
-				var screenOffset = editor.element.offset();
-				var endRecSelection = new h2d.col.IPoint(Std.int(e.clientX - screenOffset.left), Std.int(e.clientY - screenOffset.top));
-				var xMin = startRecSelection.x;
-				var xMax = endRecSelection.x;
-				var yMin = startRecSelection.y;
-				var yMax = endRecSelection.y;
-
-				if (startRecSelection.x > endRecSelection.x) {
-					xMin = endRecSelection.x;
-					xMax = startRecSelection.x;
-				}
-				if (startRecSelection.y > endRecSelection.y) {
-					yMin = endRecSelection.y;
-					yMax = startRecSelection.y;
-				}
-
-				if (recSelection != null) recSelection.remove();
-				recSelection = editor.rect(editor.element, xMin, yMin, xMax - xMin, yMax - yMin).addClass("rect-selection");
-
-				for (box in listOfBoxes) {
-					if (isInside(box, new IPoint(xMin, yMin), new IPoint(xMax, yMax))) {
-						box.setSelected(true);
-					} else {
-						box.setSelected(false);
-					}
-				}
-				return;
-			}
-
-			// Move selected boxes
-			if (listOfBoxesSelected.length > 0 && firstClickDrag != null) {
-				var dx = (e.clientX - firstClickDrag.x)/transformMatrix[0];
-				var dy = (e.clientY - firstClickDrag.y)/transformMatrix[3];
-
-				for (b in listOfBoxesSelected) {
-					b.setPosition(b.getX() + dx, b.getY() + dy);
-					shaderGraph.setPosition(b.getId(), b.getX(), b.getY());
-					// move edges from and to this box
-					for (edge in listOfEdges) {
-						if (edge.from == b || edge.to == b) {
-							edge.elt.remove();
-							edge.elt = createCurve(edge.nodeFrom, edge.nodeTo);
-
-							edge.elt.on("mousedown", function(e) {
-								e.stopPropagation();
-								clearSelectionBoxes();
-								this.currentEdge = edge;
-								currentEdge.elt.addClass("selected");
-							});
-						}
-					}
-				}
-				firstClickDrag.x = e.clientX;
-				firstClickDrag.y = e.clientY;
-				return;
-			}
+			mouseMoveFunction(e.clientX, e.clientY);
 		});
 
+
 		parent.on("mouseup", function(e) {
+			if(timerUpdateView != null)
+				stopUpdateViewPosition();
 			if (e.button == 0) {
 				// Stop link creation
 				if (isCreatingLink != None) {
@@ -256,7 +179,7 @@ class ShaderEditor extends FileView {
 				}
 
 				// Stop rectangle selection
-				firstClickDrag = null;
+				lastClickDrag = null;
 				startRecSelection = null;
 				if (recSelection != null) {
 					recSelection.remove();
@@ -269,7 +192,7 @@ class ShaderEditor extends FileView {
 
 			// Stop panning
 			if (e.button == 1) {
-				firstClickDrag = null;
+				lastClickDrag = null;
 				isPanning = false;
 			}
 		});
@@ -319,7 +242,7 @@ class ShaderEditor extends FileView {
 				}
 			} else if (e.keyCode == 83 && e.ctrlKey) { // CTRL+S : save
 				shaderGraph.save();
-			} else if (e.keyCode == 74 && e.ctrlKey) { // CTRL+J : test
+			} else if (e.keyCode == 74 && e.ctrlKey) { // CTRL+S : save
 				trace(shaderGraph.hasCycle());
 			}
 		});
@@ -406,6 +329,85 @@ class ShaderEditor extends FileView {
 		element.find("#preview").first().append(sceneEditor.scene.element);
 	}
 
+	function mouseMoveFunction(clientX : Int, clientY : Int) {
+		if (isCreatingLink != None) {
+			startUpdateViewPosition();
+			createLink(clientX, clientY);
+			return;
+		}
+		// Moving edge
+		if (currentEdge != null) {
+			startUpdateViewPosition();
+			// TODO: handle moving edge => disconnect closest node
+			// try to use the same code when user clicks on input node already connected and here
+		}
+		if (isPanning) {
+			pan(new Point(lX(clientX) - lastClickDrag.x, lY(clientY) - lastClickDrag.y));
+			lastClickDrag.x = lX(clientX);
+			lastClickDrag.y = lY(clientY);
+			return;
+		}
+		// Edit rectangle selection
+		if (startRecSelection != null) {
+			startUpdateViewPosition();
+			var endRecSelection = new h2d.col.Point(lX(clientX), lY(clientY));
+			var xMin = startRecSelection.x;
+			var xMax = endRecSelection.x;
+			var yMin = startRecSelection.y;
+			var yMax = endRecSelection.y;
+
+			if (startRecSelection.x > endRecSelection.x) {
+				xMin = endRecSelection.x;
+				xMax = startRecSelection.x;
+			}
+			if (startRecSelection.y > endRecSelection.y) {
+				yMin = endRecSelection.y;
+				yMax = startRecSelection.y;
+			}
+
+			if (recSelection != null) recSelection.remove();
+			recSelection = editor.rect(editorMatrix, xMin, yMin, xMax - xMin, yMax - yMin).addClass("rect-selection");
+
+			for (box in listOfBoxes) {
+				if (isInside(box, new Point(xMin, yMin), new Point(xMax, yMax))) {
+					box.setSelected(true);
+				} else {
+					box.setSelected(false);
+				}
+			}
+			return;
+		}
+
+		// Move selected boxes
+		if (listOfBoxesSelected.length > 0 && lastClickDrag != null) {
+			startUpdateViewPosition();
+			var dx = (lX(clientX) - lastClickDrag.x);
+			var dy = (lY(clientY) - lastClickDrag.y);
+
+			for (b in listOfBoxesSelected) {
+				b.setPosition(b.getX() + dx, b.getY() + dy);
+				shaderGraph.setPosition(b.getId(), b.getX(), b.getY());
+				// move edges from and to this box
+				for (edge in listOfEdges) {
+					if (edge.from == b || edge.to == b) {
+						edge.elt.remove();
+						edge.elt = createCurve(edge.nodeFrom, edge.nodeTo);
+
+						edge.elt.on("mousedown", function(e) {
+							e.stopPropagation();
+							clearSelectionBoxes();
+							this.currentEdge = edge;
+							currentEdge.elt.addClass("selected");
+						});
+					}
+				}
+			}
+			lastClickDrag.x = lX(clientX);
+			lastClickDrag.y = lY(clientY);
+			return;
+		}
+	}
+
 	function addNode(p : Point, nodeClass : Class<ShaderNode>) {
 		var node = shaderGraph.addNode(p.x, p.y, nodeClass);
 
@@ -424,7 +426,7 @@ class ShaderEditor extends FileView {
 				return;
 			e.stopPropagation();
 
-			firstClickDrag = new IPoint(e.clientX, e.clientY);
+			lastClickDrag = new Point(lX(e.clientX), lY(e.clientY));
 			if (!box.selected) {
 				if (!e.ctrlKey) {
 					// when not group selection and click on box not selected
@@ -438,7 +440,7 @@ class ShaderEditor extends FileView {
 		elt.mouseup(function(e) {
 			if (e.button != 0)
 				return;
-			firstClickDrag = null;
+			lastClickDrag = null;
 			if (listOfBoxesSelected.length == 1 && box.selected && !e.ctrlKey) {
 				clearSelectionBoxes();
 			}
@@ -493,7 +495,7 @@ class ShaderEditor extends FileView {
 								startLinkBox = edge.from;
 								setAvailableInputNodes(edge.from, edge.nodeFrom.attr("field"));
 								removeEdge(edge);
-								createLink(e);
+								createLink(e.clientX, e.clientY);
 								return;
 							}
 						}
@@ -635,16 +637,16 @@ class ShaderEditor extends FileView {
 		});
 	}
 
-	function createLink(e : js.jquery.Event) {
+	function createLink(clientX : Int, clientY : Int) {
 
 		var nearestNode = null;
 		var minDistNode = NODE_TRIGGER_NEAR;
 
 		// checking nearest box
 		var nearestBox = listOfBoxes[0];
-		var minDist = distanceToBox(nearestBox, e.clientX, e.clientY);
+		var minDist = distanceToBox(nearestBox, clientX, clientY);
 		for (i in 1...listOfBoxes.length) {
-			var tmpDist = distanceToBox(listOfBoxes[i], e.clientX, e.clientY);
+			var tmpDist = distanceToBox(listOfBoxes[i], clientX, clientY);
 			if (tmpDist < minDist) {
 				minDist = tmpDist;
 				nearestBox = listOfBoxes[i];
@@ -659,11 +661,11 @@ class ShaderEditor extends FileView {
 			}
 			if (startIndex < nearestBox.outputs.length) {
 				nearestNode = nearestBox.outputs[startIndex];
-				minDistNode = distanceToElement(nearestNode, e.clientX, e.clientY);
+				minDistNode = distanceToElement(nearestNode, clientX, clientY);
 				for (i in startIndex+1...nearestBox.outputs.length) {
 					if (!nearestBox.outputs[i].hasClass("nodeMatch"))
 						continue;
-					var tmpDist = distanceToElement(nearestBox.outputs[i], e.clientX, e.clientY);
+					var tmpDist = distanceToElement(nearestBox.outputs[i], clientX, clientY);
 					if (tmpDist < minDistNode) {
 						minDistNode = tmpDist;
 						nearestNode = nearestBox.outputs[i];
@@ -678,11 +680,11 @@ class ShaderEditor extends FileView {
 			}
 			if (startIndex < nearestBox.inputs.length) {
 				nearestNode = nearestBox.inputs[startIndex];
-				minDistNode = distanceToElement(nearestNode, e.clientX, e.clientY);
+				minDistNode = distanceToElement(nearestNode, clientX, clientY);
 				for (i in startIndex+1...nearestBox.inputs.length) {
 					if (!nearestBox.inputs[i].hasClass("nodeMatch"))
 						continue;
-					var tmpDist = distanceToElement(nearestBox.inputs[i], e.clientX, e.clientY);
+					var tmpDist = distanceToElement(nearestBox.inputs[i], clientX, clientY);
 					if (tmpDist < minDistNode) {
 						minDistNode = tmpDist;
 						nearestNode = nearestBox.inputs[i];
@@ -700,7 +702,7 @@ class ShaderEditor extends FileView {
 
 		// create edge
 		if (currentLink != null) currentLink.remove();
-		currentLink = createCurve(startLinkGrNode.find(".node"), nearestNode, minDistNode, e.clientX, e.clientY, true);
+		currentLink = createCurve(startLinkGrNode.find(".node"), nearestNode, minDistNode, clientX, clientY, true);
 
 	}
 
@@ -915,23 +917,41 @@ class ShaderEditor extends FileView {
 		}
 	}
 
-	function updateViewPosition() {
-		var PADDING_BOUNDS = 40;
-		var SPEED_BOUNDS = 1;
-		var posCursor = new Point(ide.mouseX - parent.offset().left, ide.mouseY - parent.offset().top);
-		if (posCursor.x < PADDING_BOUNDS) {
-			pan(new Point((PADDING_BOUNDS - posCursor.x)*SPEED_BOUNDS, 0));
-		}
-		if (posCursor.y < PADDING_BOUNDS) {
-			pan(new Point(0, (PADDING_BOUNDS - posCursor.y)*SPEED_BOUNDS));
-		}
-		var rightBorder = parent.width() - PADDING_BOUNDS;
-		if (posCursor.x > rightBorder) {
-			pan(new Point((rightBorder - posCursor.x)*SPEED_BOUNDS, 0));
-		}
-		var botBorder = parent.height() - PADDING_BOUNDS;
-		if (posCursor.y > botBorder) {
-			pan(new Point(0, (botBorder - posCursor.y)*SPEED_BOUNDS));
+	function startUpdateViewPosition() {
+		if (timerUpdateView != null)
+			return;
+		var PADDING_BOUNDS = 75;
+		var SPEED_BOUNDS = 0.1;
+		timerUpdateView = new Timer(10);
+		timerUpdateView.run = function() {
+			var posCursor = new Point(ide.mouseX - parent.offset().left, ide.mouseY - parent.offset().top);
+			var wasUpdated = false;
+			if (posCursor.x < PADDING_BOUNDS) {
+				pan(new Point((PADDING_BOUNDS - posCursor.x)*SPEED_BOUNDS, 0));
+				wasUpdated = true;
+			}
+			if (posCursor.y < PADDING_BOUNDS) {
+				pan(new Point(0, (PADDING_BOUNDS - posCursor.y)*SPEED_BOUNDS));
+				wasUpdated = true;
+			}
+			var rightBorder = parent.width() - PADDING_BOUNDS;
+			if (posCursor.x > rightBorder) {
+				pan(new Point((rightBorder - posCursor.x)*SPEED_BOUNDS, 0));
+				wasUpdated = true;
+			}
+			var botBorder = parent.height() - PADDING_BOUNDS;
+			if (posCursor.y > botBorder) {
+				pan(new Point(0, (botBorder - posCursor.y)*SPEED_BOUNDS));
+				wasUpdated = true;
+			}
+			mouseMoveFunction(ide.mouseX, ide.mouseY);
+		};
+	}
+
+	function stopUpdateViewPosition() {
+		if (timerUpdateView != null) {
+			timerUpdateView.stop();
+			timerUpdateView = null;
 		}
 	}
 
@@ -964,10 +984,10 @@ class ShaderEditor extends FileView {
 	}
 
 	// Useful method
-	function isInside(b : Box, min : IPoint, max : IPoint) {
-		if (max.x < gX(b.getX()) || min.x > gX(b.getX() + b.getWidth()))
+	function isInside(b : Box, min : Point, max : Point) {
+		if (max.x < b.getX() || min.x > b.getX() + b.getWidth())
 			return false;
-		if (max.y < gY(b.getY()) || min.y > gY(b.getY() + b.getHeight()))
+		if (max.y < b.getY() || min.y > b.getY() + b.getHeight())
 			return false;
 
 		return true;