void AddToCreatingNodes(Node endNode) { if (CreatingNodes.Count == 0) { CreatingNodes.Add(endNode); return; } Node prevNode = CreatingNodes.Last(); Vector relativeVector = new Vector(endNode.X - prevNode.X, endNode.Y - prevNode.Y); double relativeVectorLength = relativeVector.Length(); if (relativeVectorLength < 1e-6) { return; } relativeVector /= relativeVectorLength; List <KeyValuePair <double, Node> > nodesOnLine = new List <KeyValuePair <double, Node> >(); foreach (Node node in Graph.Nodes) { Vector testVector = new Vector(node.X - prevNode.X, node.Y - prevNode.Y); if (Math.Abs(testVector * relativeVector) < 1e-6) { double length = relativeVector ^ testVector; if (length > 1e-6 && length < relativeVectorLength - 1e-6) // point on line { nodesOnLine.Add(new KeyValuePair <double, Node>(length, node)); } } } nodesOnLine.Sort((x1, x2) => x1.Key.CompareTo(x2.Key)); foreach (KeyValuePair <double, Node> pair in nodesOnLine) { if (!CreatingNodes.Contains(pair.Value)) { CreatingNodes.Add(pair.Value); } } if (!CreatingNodes.Contains(endNode)) { CreatingNodes.Add(endNode); } }
internal bool MouseDown(int x, int y, MouseButtons button, bool ctrlKey, bool altKey, bool shiftKey) // Return true if copy operation is performed { bool copyPerformed = false; if (IsCreatingMode) { if (button == MouseButtons.Left) // Add { Node addNode; if (HoveredObjects.Count > 0 && HoveredObjects[0] is Node node) { if (CreatingNodes.Contains(node)) { if (CreatingNodes.Last() == node) { CreatingNodes.RemoveAt(CreatingNodes.Count - 1); } else if (CreatingNodes.First() == node) { AddToCreatingNodes(node); SubmitCreatingNodes(); } return(false); } addNode = node; } else { Vector pos = new Vector(x, y).MapFromScreen(Scale, Origin); addNode = new Node(pos.X, pos.Y); } AddToCreatingNodes(addNode); return(false); } else if (button == MouseButtons.Right) // Exit { SubmitCreatingNodes(); return(false); } } if (altKey && PasteMode && SampleDecorator != null) // Create and paste { GraphEditManager.BeforePreformEdit(Graph, "Create Graph Elements"); Vector pos = new Vector(x, y).MapFromScreen(Scale, Origin); Node addNode = new Node(pos.X, pos.Y); addNode.Hidden = true; addNode.Decorator = SampleDecorator.Clone() as Decorator; if (!shiftKey && addNode.Decorator is TransformableDecorator transformableDecorator) { transformableDecorator.ExtraScale = (1 - Graph.MetaData.EdgeWidth) / Graph.MetaData.EdgeWidth; } GraphManipulation.AddShape(Graph, new List <Node>() { addNode }); } else if (HoveredObjects.Count > 0 && button != MouseButtons.Middle) { List <GraphElement> objectToKeep = new List <GraphElement>(); if (ctrlKey || shiftKey) { foreach (GraphElement selectedObject in SelectedObjects) { if (shiftKey || !HoveredObjects.Contains(selectedObject)) { objectToKeep.Add(selectedObject); } } } foreach (GraphElement havoredObject in HoveredObjects) { if (!SelectedObjects.Contains(havoredObject)) { objectToKeep.Add(havoredObject); } } SelectedObjects.Clear(); if (ColorPaintingMode) // Paint mode { foreach (GraphElement element in objectToKeep) { Color TryApplyColor(Color oldColor, Color newColor, string hint) { if (oldColor != newColor) { GraphEditManager.BeforePreformEdit(Graph, string.Format(Resources.Lang.Undo_Paint, hint, newColor.ToString())); } return(newColor); } if (element is Node) { if (element.Decorator is PuzzleGraph.Decorators.StartDecorator startDecorator) { if (button == MouseButtons.Right) // Color picking { PaintingModeControl.Color = startDecorator.Color; } else // Apply color { startDecorator.Color = TryApplyColor(startDecorator.Color, PaintingModeControl.Color, "start point"); } } else if (element.Decorator is PuzzleGraph.Decorators.EndDecorator endDecorator) { if (button == MouseButtons.Right) // Color picking { PaintingModeControl.Color = endDecorator.Color; } else // Apply color { endDecorator.Color = TryApplyColor(endDecorator.Color, PaintingModeControl.Color, "end point"); } } } else if (element is Face face) { if (button == MouseButtons.Right) // Color picking { PaintingModeControl.Color = face.GraphElementColor; } else // Apply color { face.GraphElementColor = TryApplyColor(face.GraphElementColor, PaintingModeControl.Color, "face"); } } else if (element is Edge edge) { if (button == MouseButtons.Right) // Color picking { PaintingModeControl.Color = edge.GraphElementColor; } else // Apply color { edge.GraphElementColor = TryApplyColor(edge.GraphElementColor, PaintingModeControl.Color, "edge"); } } } } else if (button == MouseButtons.Right) // Copy { if (objectToKeep.Count > 0) { if (ctrlKey && objectToKeep[0].Decorator is PuzzleGraph.Decorators.CombinedDecorator combinedDecorator) // Combine mode { ChooseSampleDecorator(combinedDecorator.Second, true); objectToKeep[0].Decorator = combinedDecorator.First; } else { ChooseSampleDecorator(objectToKeep[0].Decorator, true); } copyPerformed = true; } } else { if (!PasteMode) // Selection mode { SelectedObjects.AddRange(objectToKeep); if (shiftKey) { nodesToMove = new List <Node>(); foreach (GraphElement element in SelectedObjects) { if (element is Node selectedNode) { nodesToMove.Add(selectedNode); } else if (element is Edge selectedEdge) { nodesToMove.Add(selectedEdge.Start); nodesToMove.Add(selectedEdge.End); } else if (element is Face selectedFace) { nodesToMove.AddRange(selectedFace.Nodes); } } if (nodesToMove.Count > 0) { GraphEditManager.BeforePreformEdit(Graph, "Move Nodes"); ElementMoveStartPosition = new Vector(x, y); } } else { ElementMoveStartPosition = null; } } else // Paste mode { foreach (GraphElement element in objectToKeep) { if (ctrlKey && element.Decorator != null) // Combine mode { CombineDecorators(SampleDecorator, element); } else { ApplyDecoratorToObject(SampleDecorator, element); } } } } HoveredObjects.Clear(); if (SelectedObjects.Count > 0) { TetrisIndexToTemplateView(SelectedObjects[0].Decorator); } } else { mouseDownPosition = new Vector(x, y); IsDragging = true; } return(copyPerformed); }