private static void OnDragStarted(object sender, PointerRoutedEventArgs e) #endif { var obj = sender as DependencyObject; //we are starting the drag SetIsDragging(obj, true); // Save the position of the mouse to the start position var area = GetAreaFromObject(obj); var pos = GetPositionInArea(area, e); SetOriginalMouseX(obj, pos.X); SetOriginalMouseY(obj, pos.Y); // Save the position of the dragged object to its starting position SetOriginalX(obj, GraphAreaBase.GetFinalX(obj)); SetOriginalY(obj, GraphAreaBase.GetFinalY(obj)); // Save starting position of all tagged elements if (GetIsTagged(obj)) { foreach (var item in area.GetAllVertexControls()) { if (GetIsTagged(item)) { SetOriginalX(item, GraphAreaBase.GetFinalX(item)); SetOriginalY(item, GraphAreaBase.GetFinalY(item)); } } } //capture the mouse #if WPF var element = obj as IInputElement; if (element != null) { element.CaptureMouse(); element.MouseMove -= OnDragging; element.MouseMove += OnDragging; } //else throw new GX_InvalidDataException("The control must be a descendent of the FrameworkElement or FrameworkContentElement!"); e.Handled = false; #elif METRO var element = obj as FrameworkElement; if (element != null) { element.CapturePointer(e.Pointer); element.PointerMoved += OnDragging; } e.Handled = true; #endif }
/// <summary> /// Get control position on the GraphArea panel in attached coords X and Y (GraphX type version) /// </summary> /// <param name="final"></param> /// <param name="round"></param> internal Measure.Point GetPositionGraphX(bool final = false, bool round = false) { return(round ? new Measure.Point(final ? (int)GraphAreaBase.GetFinalX(this) : (int)GraphAreaBase.GetX(this), final ? (int)GraphAreaBase.GetFinalY(this) : (int)GraphAreaBase.GetY(this)) : new Measure.Point(final ? GraphAreaBase.GetFinalX(this) : GraphAreaBase.GetX(this), final ? GraphAreaBase.GetFinalY(this) : GraphAreaBase.GetY(this))); }
/// <summary> /// Get control position on the GraphArea panel in attached coords X and Y /// </summary> /// <param name="final"></param> /// <param name="round"></param> public Point GetPosition(bool final = false, bool round = false) { return(round ? new Point(final ? (int)GraphAreaBase.GetFinalX(this) : (int)GraphAreaBase.GetX(this), final ? (int)GraphAreaBase.GetFinalY(this) : (int)GraphAreaBase.GetY(this)) : new Point(final ? GraphAreaBase.GetFinalX(this) : GraphAreaBase.GetX(this), final ? GraphAreaBase.GetFinalY(this) : GraphAreaBase.GetY(this))); }
/// <summary> /// Create and apply edge path using calculated ER parameters stored in edge /// </summary> /// <param name="useCurrentCoords">Use current vertices coordinates or final coorfinates (for.ex if move animation is active final coords will be its destination)</param> /// <param name="externalRoutingPoints">Provided custom routing points will be used instead of stored ones.</param> /// <param name="updateLabel">Should edge label be updated in this pass</param> public virtual void PrepareEdgePath(bool useCurrentCoords = false, Measure.Point[] externalRoutingPoints = null, bool updateLabel = true) { //do not calculate invisible edges if ((Visibility != Visibility.Visible && !IsHiddenEdgesUpdated) && Source == null || Target == null || ManualDrawing || !IsTemplateLoaded) { return; } #region Get the inputs //get the size of the source var sourceSize = new Size { Width = Source.ActualWidth, Height = Source.ActualHeight }; if (CustomHelper.IsInDesignMode(this)) { sourceSize = new Size(80, 20); } //get the position center of the source var sourcePos = new Point { X = (useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source)) + sourceSize.Width * .5, Y = (useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source)) + sourceSize.Height * .5 }; //get the size of the target var targetSize = new Size { Width = Target.ActualWidth, Height = Target.ActualHeight }; if (CustomHelper.IsInDesignMode(this)) { targetSize = new Size(80, 20); } //get the position center of the target var targetPos = new Point { X = (useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target)) + targetSize.Width * .5, Y = (useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target)) + targetSize.Height * .5 }; var routedEdge = Edge as IRoutingInfo; if (routedEdge == null) { throw new GX_InvalidDataException("Edge must implement IRoutingInfo interface"); } //get the route informations var routeInformation = externalRoutingPoints ?? routedEdge.RoutingPoints; // Get the TopLeft position of the Source Vertex. var sourcePos1 = new Point { X = (useCurrentCoords ? GraphAreaBase.GetX(Source) : GraphAreaBase.GetFinalX(Source)), Y = (useCurrentCoords ? GraphAreaBase.GetY(Source) : GraphAreaBase.GetFinalY(Source)) }; // Get the TopLeft position of the Target Vertex. var targetPos1 = new Point { X = (useCurrentCoords ? GraphAreaBase.GetX(Target) : GraphAreaBase.GetFinalX(Target)), Y = (useCurrentCoords ? GraphAreaBase.GetY(Target) : GraphAreaBase.GetFinalY(Target)) }; var hasEpSource = _edgePointerForSource != null; var hasEpTarget = _edgePointerForTarget != null; #endregion //if self looped edge if (IsSelfLooped) { PrepareSelfLoopedEdge(sourcePos1); return; } //check if we have some edge route data var hasRouteInfo = routeInformation != null && routeInformation.Length > 1; //calculate source and target edge attach points if (RootArea != null && !hasRouteInfo && RootArea.EnableParallelEdges && ParallelEdgeOffset != 0) { sourcePos = GetParallelOffset(Source, Target, ParallelEdgeOffset); targetPos = GetParallelOffset(Target, Source, -ParallelEdgeOffset); } /* Rectangular shapes implementation by bleibold */ var gEdge = Edge as IGraphXCommonEdge; Point p1; Point p2; //calculate edge source (p1) and target (p2) endpoints based on different settings if (gEdge != null && gEdge.SourceConnectionPointId.HasValue) { var sourceCp = Source.GetConnectionPointById(gEdge.SourceConnectionPointId.Value, true); if (sourceCp == null) { throw new GX_ObjectNotFoundException(string.Format("Can't find source vertex VCP by edge source connection point Id({1}) : {0}", Source, gEdge.SourceConnectionPointId)); } if (sourceCp.Shape == VertexShape.None) { p1 = sourceCp.RectangularSize.Center(); } else { var targetCpPos = gEdge.TargetConnectionPointId.HasValue ? Target.GetConnectionPointById(gEdge.TargetConnectionPointId.Value, true).RectangularSize.Center() : (hasRouteInfo ? routeInformation[1].ToWindows() : (targetPos)); p1 = GeometryHelper.GetEdgeEndpoint(sourceCp.RectangularSize.Center(), sourceCp.RectangularSize, targetCpPos, sourceCp.Shape); } } else { p1 = GeometryHelper.GetEdgeEndpoint(sourcePos, new SysRect(sourcePos1, sourceSize), (hasRouteInfo ? routeInformation[1].ToWindows() : (targetPos)), Source.VertexShape); } if (gEdge != null && gEdge.TargetConnectionPointId.HasValue) { var targetCp = Target.GetConnectionPointById(gEdge.TargetConnectionPointId.Value, true); if (targetCp == null) { throw new GX_ObjectNotFoundException(string.Format("Can't find target vertex VCP by edge target connection point Id({1}) : {0}", Target, gEdge.TargetConnectionPointId)); } if (targetCp.Shape == VertexShape.None) { p2 = targetCp.RectangularSize.Center(); } else { var sourceCpPos = gEdge.SourceConnectionPointId.HasValue ? Source.GetConnectionPointById(gEdge.SourceConnectionPointId.Value, true).RectangularSize.Center() : hasRouteInfo ? routeInformation[routeInformation.Length - 2].ToWindows() : (sourcePos); p2 = GeometryHelper.GetEdgeEndpoint(targetCp.RectangularSize.Center(), targetCp.RectangularSize, sourceCpPos, targetCp.Shape); } } else { p2 = GeometryHelper.GetEdgeEndpoint(targetPos, new SysRect(targetPos1, targetSize), hasRouteInfo ? routeInformation[routeInformation.Length - 2].ToWindows() : (sourcePos), Target.VertexShape); } SourceConnectionPoint = p1; TargetConnectionPoint = p2; _linegeometry = new PathGeometry(); PathFigure lineFigure; //if we have route and route consist of 2 or more points if (RootArea != null && hasRouteInfo) { //replace start and end points with accurate ones var routePoints = routeInformation.ToWindows().ToList(); routePoints.Remove(routePoints.First()); routePoints.Remove(routePoints.Last()); routePoints.Insert(0, p1); routePoints.Add(p2); if (RootArea.EdgeCurvingEnabled) { var oPolyLineSegment = GeometryHelper.GetCurveThroughPoints(routePoints.ToArray(), 0.5, RootArea.EdgeCurvingTolerance); if (hasEpTarget) { UpdateTargetEpData(oPolyLineSegment.Points[oPolyLineSegment.Points.Count - 1], oPolyLineSegment.Points[oPolyLineSegment.Points.Count - 2]); oPolyLineSegment.Points.RemoveAt(oPolyLineSegment.Points.Count - 1); } if (hasEpSource) { UpdateSourceEpData(oPolyLineSegment.Points.First(), oPolyLineSegment.Points[1]); } lineFigure = GeometryHelper.GetPathFigureFromPathSegments(routePoints[0], true, true, oPolyLineSegment); #if WPF //freeze and create resulting geometry GeometryHelper.TryFreeze(oPolyLineSegment); #endif } else { if (hasEpSource) { UpdateSourceEpData(routePoints.First(), routePoints[1]); } if (hasEpTarget) { routePoints[routePoints.Count - 1] = routePoints[routePoints.Count - 1].Subtract(UpdateTargetEpData(p2, routePoints[routePoints.Count - 2])); } var pcol = new PointCollection(); foreach (var item in routePoints) { pcol.Add(item); } lineFigure = new PathFigure { StartPoint = p1, Segments = new PathSegmentCollection { new PolyLineSegment { Points = pcol } }, IsClosed = false }; } } else // no route defined { if (hasEpSource) { UpdateSourceEpData(p1, p2); } if (hasEpTarget) { p2 = p2.Subtract(UpdateTargetEpData(p2, p1)); } lineFigure = new PathFigure { StartPoint = p1, Segments = new PathSegmentCollection { new LineSegment() { Point = p2 } }, IsClosed = false }; } ((PathGeometry)_linegeometry).Figures.Add(lineFigure); #if WPF GeometryHelper.TryFreeze(lineFigure); GeometryHelper.TryFreeze(_linegeometry); #endif if (ShowLabel && _edgeLabelControl != null && _updateLabelPosition && updateLabel) { _edgeLabelControl.UpdatePosition(); } }
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; }