private static void OnDragging(object sender, PointerRoutedEventArgs e) #endif { var obj = sender as DependencyObject; if (!GetIsDragging(obj)) { return; } var area = GetAreaFromObject(obj); var pos = GetPositionInArea(area, e); double horizontalChange = pos.X - GetOriginalMouseX(obj); double verticalChange = pos.Y - GetOriginalMouseY(obj); // Determine whether to use snapping bool snap = GetIsSnappingPredicate(obj)(obj); bool individualSnap = false; // Snap modifier functions to apply to the primary dragged object SnapModifierFunc snapXMod = null; SnapModifierFunc snapYMod = null; // Snap modifier functions to apply to other dragged objects if they snap individually instead of moving // the same amounts as the primary object. SnapModifierFunc individualSnapXMod = null; SnapModifierFunc individualSnapYMod = null; if (snap) { snapXMod = GetXSnapModifier(obj); snapYMod = GetYSnapModifier(obj); // If objects snap to grid individually instead of moving the same amount as the primary dragged object, // use the same snap modifier on each individual object. individualSnap = GetIsIndividualSnappingPredicate(obj)(obj); if (individualSnap) { individualSnapXMod = snapXMod; individualSnapYMod = snapYMod; } } if (GetIsTagged(obj)) { // When the dragged item is a tagged item, we could be dragging a group of objects. If the dragged object is a vertex, it's // automatically the primary object of the drag. If the dragged object is an edge, prefer the source vertex, but accept the // target vertex as the primary object of the drag and start with that. var primaryDragVertex = obj as VertexControl; if (primaryDragVertex == null) { var ec = obj as EdgeControl; if (ec != null) { primaryDragVertex = ec.Source ?? ec.Target; } if (primaryDragVertex == null) { Debug.WriteLine("OnDragging() -> Tagged and dragged the wrong object?"); return; } } UpdateCoordinates(area, primaryDragVertex, horizontalChange, verticalChange, snapXMod, snapYMod); if (!individualSnap) { // When dragging groups of objects that all move the same amount (not snapping individually, but tracking with // the movement of the primary dragged object), deterrmine how much offset the primary dragged object experienced // and use that offset for the rest. horizontalChange = GraphAreaBase.GetFinalX(primaryDragVertex) - GetOriginalX(primaryDragVertex); verticalChange = GraphAreaBase.GetFinalY(primaryDragVertex) - GetOriginalY(primaryDragVertex); } foreach (var item in area.GetAllVertexControls()) { if (!ReferenceEquals(item, primaryDragVertex) && GetIsTagged(item)) { UpdateCoordinates(area, item, horizontalChange, verticalChange, individualSnapXMod, individualSnapYMod); } } } else { UpdateCoordinates(area, obj, horizontalChange, verticalChange, snapXMod, snapYMod); } e.Handled = true; }
private static void UpdateCoordinates(GraphAreaBase area, DependencyObject obj, double horizontalChange, double verticalChange, SnapModifierFunc xSnapModifier, SnapModifierFunc ySnapModifier) { if (double.IsNaN(GraphAreaBase.GetX(obj))) { GraphAreaBase.SetX(obj, 0, true); } if (double.IsNaN(GraphAreaBase.GetY(obj))) { GraphAreaBase.SetY(obj, 0, true); } //move the object var x = GetOriginalX(obj) + horizontalChange; if (xSnapModifier != null) { x = xSnapModifier(area, obj, x); } GraphAreaBase.SetX(obj, x, true); var y = GetOriginalY(obj) + verticalChange; if (ySnapModifier != null) { y = ySnapModifier(area, obj, y); } GraphAreaBase.SetY(obj, y, true); if (GetUpdateEdgesOnMove(obj)) { UpdateVertexEdges(obj as VertexControl); } //Debug.WriteLine("({0:##0.00000}, {1:##0.00000})", x, y); }
public static void SetYSnapModifier(DependencyObject obj, SnapModifierFunc value) { obj.SetValue(YSnapModifierProperty, value); }