private void OnPreviewLeftMouseDown(object sender, MouseButtonEventArgs e) { Point mouseScreenPoint = e.GetPosition(mapControl).ToMapsui(); var draggingFeature = GetFeaturesAtScreenPoint(mouseScreenPoint).OfType <DraggingFeature>().FirstOrDefault(); if (draggingFeature == null && insertionPreviewFeature != null) { int insertedIndex = insertionPreviewFeature.Index; Point insertedVertex = insertionPreviewFeature.Vertex; draggingFeature = InsertVertex(insertedIndex, insertedVertex); draggingLayer.TryRemove(insertionPreviewFeature); insertionPreviewFeature = null; } if (draggingFeature != null) { // Preventing map panning e.Handled = true; this.draggingFeature = draggingFeature; Point mouseWorldPoint = ScreenPointToGlobal(mouseScreenPoint); draggingOffset = mouseWorldPoint - draggingFeature.Vertex; return; } }
protected override void EndImpl() { UnsubscribeMouseEvents(); draggingLayer.Clear(); draggingLayer.Refresh(); insertionPreviewFeature = null; editedObject = null; }
private void OnPreviewMouseMove(object sender, MouseEventArgs e) { if (draggingFeature != null) { Point mousePoint = ScreenPointToGlobal(e.GetPosition(mapControl).ToMapsui()); draggingFeature.Vertex = mousePoint - draggingOffset; draggingLayer.Refresh(); targetLayer.Refresh(); } else { Point mouseScreenPoint = e.GetPosition(mapControl).ToMapsui(); if (GetFeaturesAtScreenPoint(mouseScreenPoint).OfType <DraggingFeature>().Any()) { TryRemoveInsertionPreviewFeature(); return; } Point mouseWorldPoint = ScreenPointToGlobal(mouseScreenPoint); Point previewPoint; int index; GetInsertionPreviewPoint(mouseScreenPoint, mouseWorldPoint, out previewPoint, out index); if (previewPoint != null) { UpdateInsertionPreviewFeature(previewPoint, index); } else { TryRemoveInsertionPreviewFeature(); } } ///////// Helper local funcs void TryRemoveInsertionPreviewFeature() { if (insertionPreviewFeature != null) { draggingLayer.TryRemove(insertionPreviewFeature); insertionPreviewFeature = null; draggingLayer.Refresh(); } } void UpdateInsertionPreviewFeature(Point previewPoint, int index) { if (insertionPreviewFeature == null) { insertionPreviewFeature = new InsertionPreviewFeature(editedObject, previewPoint, index); draggingLayer.Add(insertionPreviewFeature); } insertionPreviewFeature.Update(previewPoint, index); draggingLayer.Refresh(); } void GetInsertionPreviewPoint(Point mouseScreenPoint, Point mouseWorldPoint, out Point previewPoint, out int index) { IList <Point> vertices = editedObject.Vertices; previewPoint = null; index = -1; double minDistance = double.PositiveInfinity; int prevI, i; if (editedObject.AreVerticesLooped) { prevI = vertices.Count - 1; i = 0; } else { // The branch above allows to insert points between end and start vertices. // If the shape is not like a ring, we should be able to to this prevI = 0; i = 1; } for (; i < vertices.Count; i++) { Point closestPoint = GetClosestPoint(mouseWorldPoint, vertices[prevI], vertices[i]); Point screenPerpBase = GlobalPointToScreen(closestPoint); double screenDistance = screenPerpBase.Distance(mouseScreenPoint); if (screenDistance < VertexInsertionDistance && screenDistance < minDistance) { minDistance = screenDistance; previewPoint = closestPoint; index = i; } prevI = i; } } ///////// End helper local funcs }