Example #1
0
        void RemoveEditPointSegmentsWithinTolerance(List <EditPoint> pointsToRetain)
        {
            for (int i = 1; i < this.editPoints.Count - 1; i++)
            {
                EditPoint previous = this.editPoints[i - 1];
                EditPoint current  = this.editPoints[i];
                EditPoint next     = this.editPoints[i + 1];

                if (pointsToRetain == null || !pointsToRetain.Contains(current))
                {
                    double distance = DesignerGeometryHelper.DistanceOfLineSegments(new Point[] { previous.Location, current.Location });
                    if (distance < ConnectorEditor.EditPointRadius && next.Type == EditPoint.EditPointTypes.MultiSegmentEditPoint)
                    {
                        double slope = DesignerGeometryHelper.SlopeOfLineSegment(current.Location, next.Location);
                        next.Location = (slope < 1) ? new Point(next.Location.X, previous.Location.Y) : new Point(previous.Location.X, next.Location.Y);
                        this.editPoints.Remove(current);
                        i -= 1;
                    }
                    else
                    {
                        distance = DesignerGeometryHelper.DistanceOfLineSegments(new Point[] { current.Location, next.Location });
                        if (distance < ConnectorEditor.EditPointRadius && previous.Type == EditPoint.EditPointTypes.MultiSegmentEditPoint)
                        {
                            double slope = DesignerGeometryHelper.SlopeOfLineSegment(previous.Location, current.Location);
                            previous.Location = (slope < 1) ? new Point(previous.Location.X, next.Location.Y) : new Point(next.Location.X, previous.Location.Y);
                            this.editPoints.Remove(current);
                            i--;
                        }
                    }
                }
            }
        }
Example #2
0
 //If the result is true this method also sets the currently active edit point.
 public bool EditPointsHitTest(Point pt)
 {
     if (this.EditPoints.Count > 0)
     {
         foreach (EditPoint editPoint in this.EditPoints)
         {
             if (DesignerGeometryHelper.DistanceBetweenPoints(pt, editPoint.Location) <= EditPointHitTestRadius)
             {
                 this.activeEditPoint = editPoint;
                 return(true);
             }
         }
     }
     return(false);
 }
Example #3
0
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            Visibility      connectorLabelVisibility = Visibility.Collapsed;
            string          labelText       = values[0] as string;
            PointCollection connectorPoints = values[1] as PointCollection;

            if (!String.IsNullOrEmpty(labelText) && connectorPoints != null)
            {
                int maxSegmentStartPoint;
                if (DesignerGeometryHelper.LongestSegmentLength(connectorPoints, out maxSegmentStartPoint) > Connector.MinConnectorSegmentLengthForLabel)
                {
                    connectorLabelVisibility = Visibility.Visible;
                }
            }
            return(connectorLabelVisibility);
        }
Example #4
0
 void RemoveCoincidingEditPoints(List <EditPoint> pointsToRetain)
 {
     for (int i = 1; i < this.EditPoints.Count - 1; i++)
     {
         EditPoint current = this.EditPoints[i];
         if (pointsToRetain == null || !pointsToRetain.Contains(current))
         {
             EditPoint previous = this.EditPoints[i - 1];
             EditPoint next     = this.EditPoints[i + 1];
             double    slope1   = DesignerGeometryHelper.SlopeOfLineSegment(previous.Location, current.Location);
             double    slope2   = DesignerGeometryHelper.SlopeOfLineSegment(current.Location, next.Location);
             if (Math.Abs(slope1) == Math.Abs(slope2))
             {
                 this.EditPoints.Remove(current);
                 i -= 1;
             }
         }
     }
 }
Example #5
0
        //Remove points with the same slope
        void RemoveCoincidingEditPoints()
        {
            if (this.editPoints.Count < 2 ||
                this.editPoints[0].Type != EditPoint.EditPointTypes.ConnectionEditPoint ||
                this.editPoints[this.editPoints.Count - 1].Type != EditPoint.EditPointTypes.ConnectionEditPoint ||
                (this.activeEditPoint != null && this.activeEditPoint.Type == EditPoint.EditPointTypes.ConnectionEditPoint))
            {
                return;
            }

            //Create list of points to retain
            List <EditPoint> editPointsToRetain = new List <EditPoint>(this.editPoints.Count);

            for (int i = 0; i < this.editPoints.Count; i++)
            {
                if (this.editPoints[i].Type != EditPoint.EditPointTypes.MultiSegmentEditPoint ||
                    this.editPoints[i] == this.activeEditPoint)
                {
                    editPointsToRetain.Add(this.editPoints[i]);
                }
            }

            //Step1: Get rid of all the line segments which are within tolerance range
            RemoveEditPointSegmentsWithinTolerance(editPointsToRetain);

            //Step2: We should make sure that the active edit point is always retained but those points which are coincidental are always removed
            RemoveCoincidingEditPoints(editPointsToRetain);

            //Step3: Go through each segment and ensure that all the segments are either vertical or horizontal
            for (int i = 0; i < this.editPoints.Count - 1; i++)
            {
                EditPoint current = this.editPoints[i];
                EditPoint next    = this.editPoints[i + 1];

                double slope = DesignerGeometryHelper.SlopeOfLineSegment(current.Location, next.Location);
                if (slope != 0 && slope != double.MaxValue)
                {
                    Point location = (slope < 1) ? new Point(next.Location.X, current.Location.Y) : new Point(current.Location.X, next.Location.Y);
                    this.editPoints.Insert(i + 1, new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, location));
                }
            }
        }
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            PathSegmentCollection retVal          = new PathSegmentCollection();
            PointCollection       pointCollection = value as PointCollection;

            if (RoundRadius > 0)
            {
                if (pointCollection != null && pointCollection.Count > 0)
                {
                    retVal.Add(new LineSegment(pointCollection[0], true));
                    double curSegmentArcUsed = 0;
                    for (int i = 1; i < pointCollection.Count - 1; i++)
                    {
                        double dist1 = DesignerGeometryHelper.DistanceBetweenPoints(pointCollection[i - 1], pointCollection[i]);
                        double dist2 = DesignerGeometryHelper.DistanceBetweenPoints(pointCollection[i], pointCollection[i + 1]);
                        if (dist1 - curSegmentArcUsed > RoundRadius &&
                            dist2 > RoundRadius)
                        {
                            //build rounded arc at line join.
                            curSegmentArcUsed = RoundRadius;
                            Vector firstSegmentPointingVector  = new Vector(pointCollection[i].X - pointCollection[i - 1].X, pointCollection[i].Y - pointCollection[i - 1].Y);
                            Vector secondSegmentPointingVector = new Vector(pointCollection[i + 1].X - pointCollection[i].X, pointCollection[i + 1].Y - pointCollection[i].Y);
                            firstSegmentPointingVector.Normalize();
                            secondSegmentPointingVector.Normalize();
                            Point  turningPoint1 = Point.Add(pointCollection[i - 1], Vector.Multiply(dist1 - RoundRadius, firstSegmentPointingVector));
                            Point  turningPoint2 = Point.Add(pointCollection[i], Vector.Multiply(RoundRadius, secondSegmentPointingVector));
                            double crossProductZ = firstSegmentPointingVector.X * secondSegmentPointingVector.Y - firstSegmentPointingVector.Y * secondSegmentPointingVector.X;
                            retVal.Add(new LineSegment(turningPoint1, true));
                            retVal.Add(new ArcSegment(turningPoint2, new Size(RoundRadius, RoundRadius), 0, false, crossProductZ > 0 ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, true));
                        }
                        else
                        {
                            curSegmentArcUsed = 0;
                            retVal.Add(new LineSegment(pointCollection[i], true));
                        }
                    }
                    retVal.Add(new LineSegment(pointCollection[pointCollection.Count - 1], true));
                }
            }
            return(retVal);
        }
Example #7
0
        internal static Point CalculateDropLocation(Point mousePosition, Point originalDropLocation, Size droppedSize, Point srcLocation, Point destLocation, Size srcSize, Size destSize, HashSet <Point> shapeLocations)
        {
            Point dropLocation = originalDropLocation;

            double distToSrc  = DesignerGeometryHelper.ManhattanDistanceBetweenPoints(mousePosition, new Point(srcLocation.X + (srcSize.Width / 2), srcLocation.Y + (srcSize.Height / 2)));
            double distToDest = DesignerGeometryHelper.ManhattanDistanceBetweenPoints(mousePosition, new Point(destLocation.X + (destSize.Width / 2), destLocation.Y + (destSize.Height / 2)));

            AutoSplitAlignment srcAlignment  = GetAlignment(mousePosition, srcLocation, srcSize);
            AutoSplitAlignment destAlignment = GetAlignment(mousePosition, destLocation, destSize);

            if ((distToSrc <= distToDest || destAlignment == AutoSplitAlignment.None) && srcAlignment == AutoSplitAlignment.Vertical)
            {
                dropLocation = CalculateDropLocationToAlignVertically(dropLocation, droppedSize, srcLocation, srcSize);
            }
            else if ((distToSrc <= distToDest || destAlignment == AutoSplitAlignment.None) && srcAlignment == AutoSplitAlignment.Horizontal)
            {
                dropLocation = CalculateDropLocationToAlignHorizontally(dropLocation, droppedSize, srcLocation, srcSize);
            }
            else if ((distToSrc >= distToDest || srcAlignment == AutoSplitAlignment.None) && destAlignment == AutoSplitAlignment.Vertical)
            {
                dropLocation = CalculateDropLocationToAlignVertically(dropLocation, droppedSize, destLocation, destSize);
            }
            else if ((distToSrc >= distToDest || srcAlignment == AutoSplitAlignment.None) && destAlignment == AutoSplitAlignment.Horizontal)
            {
                dropLocation = CalculateDropLocationToAlignHorizontally(dropLocation, droppedSize, destLocation, destSize);
            }

            dropLocation.X = dropLocation.X < 0 ? 0 : dropLocation.X;
            dropLocation.Y = dropLocation.Y < 0 ? 0 : dropLocation.Y;

            // To avoid overlaps with existing shapes
            if (shapeLocations != null)
            {
                while (shapeLocations.Contains(dropLocation))
                {
                    dropLocation.Offset(FreeFormPanel.GridSize, FreeFormPanel.GridSize);
                }
            }

            return(dropLocation);
        }
Example #8
0
        public static ConnectionPoint GetClosestConnectionPoint(List <ConnectionPoint> connectionPoints, Point refPoint, out double minDist)
        {
            minDist = double.PositiveInfinity;
            if (connectionPoints == null || connectionPoints.Count == 0)
            {
                return(null);
            }
            double          dist         = 0;
            ConnectionPoint closestPoint = null;

            foreach (ConnectionPoint point in connectionPoints)
            {
                dist = DesignerGeometryHelper.DistanceBetweenPoints(refPoint, point.Location);
                if (dist < minDist)
                {
                    minDist      = dist;
                    closestPoint = point;
                }
            }

            return(closestPoint);
        }
Example #9
0
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            Thickness       margin          = new Thickness(0);
            PointCollection connectorPoints = values[0] as PointCollection;
            // 8 and 4 is calcuated from the margin / padding settings related to the label in xaml
            double labelBorderWidth  = (double)values[1] + 8;
            double labelBorderHeight = (double)values[2] + 4;

            if (connectorPoints != null)
            {
                int longestSegmentIndex;
                DesignerGeometryHelper.LongestSegmentLength(connectorPoints, out longestSegmentIndex);
                if (longestSegmentIndex >= 0)
                {
                    Point labelLocation = DesignerGeometryHelper.MidPointOfLineSegment(connectorPoints[longestSegmentIndex], connectorPoints[longestSegmentIndex + 1]);
                    labelLocation.X = (int)(labelLocation.X - labelBorderWidth / 2 + EPS);
                    labelLocation.Y = (int)(labelLocation.Y - labelBorderHeight / 2 + EPS);
                    margin.Top      = labelLocation.Y;
                    margin.Left     = labelLocation.X;
                }
            }
            return(margin);
        }
        private void MeasureChildren(out double height, out double width)
        {
            height = 0;
            width  = 0;
            Point pt             = new Point(0, 0);
            bool  isOutmostPanel = this.IsOutmostPanel();

            foreach (UIElement child in Children)
            {
                Connector connectorChild = child as Connector;
                if (connectorChild != null && isOutmostPanel)
                {
                    pt = new Point(0, 0);

                    if (measureConnectors)
                    {
                        Point srcPoint  = FreeFormPanel.GetLocationRelativeToOutmostPanel(FreeFormPanel.GetSourceConnectionPoint(connectorChild));
                        Point destPoint = FreeFormPanel.GetLocationRelativeToOutmostPanel(FreeFormPanel.GetDestinationConnectionPoint(connectorChild));
                        if (connectorChild.Points.Count == 0 || !this.Disabled &&
                            ((DesignerGeometryHelper.ManhattanDistanceBetweenPoints(connectorChild.Points[0], srcPoint) > ConnectorRouter.EndPointTolerance) ||
                             (DesignerGeometryHelper.ManhattanDistanceBetweenPoints(connectorChild.Points[connectorChild.Points.Count - 1], destPoint) > ConnectorRouter.EndPointTolerance)))
                        {
                            connectorChild.Points = new PointCollection();
                            RoutePolyLine(connectorChild);
                        }
                        connectorChild.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
                    }
                    else
                    {
                        continue;
                    }
                }
                else //Measure non-connector elements.
                {
                    child.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity));
                    if (!child.DesiredSize.Equals(((Size)FreeFormPanel.GetChildSize(child))))
                    {
                        FreeFormPanel.SetChildSize(child, child.DesiredSize);
                    }
                    pt = FreeFormPanel.GetLocation(child);
                    if (!IsLocationValid(pt))
                    {
                        pt = new Point(LeftStackingMargin, lastYPosition);
                        OnLocationChanged(child, new LocationChangedEventArgs(pt));
                        FreeFormPanel.SetLocation(child, pt);
                        lastYPosition += child.DesiredSize.Height + VerticalStackingDistance;
                    }
                }
                if (height < child.DesiredSize.Height + pt.Y)
                {
                    height = child.DesiredSize.Height + pt.Y;
                }
                if (width < child.DesiredSize.Width + pt.X)
                {
                    width = child.DesiredSize.Width + pt.X;
                }
            }

            width  = (width < this.MinWidth) ? this.MinWidth : width;
            height = (height < this.MinHeight) ? this.MinHeight : height;
        }
Example #11
0
 public static bool IsEqualTo(this Point point1, Point point2)
 {
     return(DesignerGeometryHelper.DistanceBetweenPoints(point1, point2) < DesignerGeometryHelper.EPS);
 }
Example #12
0
        void UpdateEditPoints(Point newPoint)
        {
            if (this.editPoints.Count < 2 ||
                this.editPoints[0].Type != EditPoint.EditPointTypes.ConnectionEditPoint ||
                this.editPoints[this.editPoints.Count - 1].Type != EditPoint.EditPointTypes.ConnectionEditPoint)
            {
                Fx.Assert(false, "EditPoints are invalid");
                return;
            }

            if (this.activeEditPoint != null)
            {
                int       activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint);
                EditPoint previous             = (activeEditPointIndex > 0) ? this.editPoints[activeEditPointIndex - 1] : null;
                EditPoint next = (activeEditPointIndex < this.editPoints.Count - 1) ? this.editPoints[activeEditPointIndex + 1] : null;

                //Note that extra edit points are only added if we are connected to connection point
                if (previous != null && previous.Type == EditPoint.EditPointTypes.ConnectionEditPoint)
                {
                    double      slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(previous.Location, this.activeEditPoint.Location);
                    Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical;

                    int editPointOffset = Convert.ToInt32(DesignerGeometryHelper.DistanceBetweenPoints(previous.Location, (next != null) ? next.Location : this.activeEditPoint.Location)) / 4;
                    if (orientation == Orientation.Horizontal)
                    {
                        editPointOffset *= (previous.Location.X < this.activeEditPoint.Location.X) ? 1 : -1;
                    }
                    else
                    {
                        editPointOffset *= (previous.Location.Y < this.activeEditPoint.Location.Y) ? 1 : -1;
                    }

                    activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint);
                    Point editPointLocation = (orientation == Orientation.Horizontal) ? new Point(previous.Location.X + editPointOffset, previous.Location.Y) : new Point(previous.Location.X, previous.Location.Y + editPointOffset);
                    previous = new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation);
                    this.editPoints.InsertRange(activeEditPointIndex, new EditPoint[] { new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation), previous });
                }

                if (next != null && next.Type == EditPoint.EditPointTypes.ConnectionEditPoint)
                {
                    double      slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(this.activeEditPoint.Location, next.Location);
                    Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical;

                    int editPointOffset = Convert.ToInt32(DesignerGeometryHelper.DistanceBetweenPoints((previous != null) ? previous.Location : this.activeEditPoint.Location, next.Location)) / 4;
                    if (orientation == Orientation.Horizontal)
                    {
                        editPointOffset *= (this.activeEditPoint.Location.X < next.Location.X) ? -1 : 1;
                    }
                    else
                    {
                        editPointOffset *= (this.activeEditPoint.Location.Y < next.Location.Y) ? -1 : 1;
                    }

                    activeEditPointIndex = this.editPoints.IndexOf(this.activeEditPoint);
                    Point editPointLocation = (orientation == Orientation.Horizontal) ? new Point(next.Location.X + editPointOffset, next.Location.Y) : new Point(next.Location.X, next.Location.Y + editPointOffset);
                    next = new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation);
                    this.editPoints.InsertRange(activeEditPointIndex + 1, new EditPoint[] { next, new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, editPointLocation) });
                }

                if (this.activeEditPoint.Type == EditPoint.EditPointTypes.ConnectionEditPoint)
                {
                    Fx.Assert(this.editPoints[0].Type == EditPoint.EditPointTypes.ConnectionEditPoint, "EditPoint type is wrong.");
                    Fx.Assert(this.editPoints[editPoints.Count - 1].Type == EditPoint.EditPointTypes.ConnectionEditPoint, "EditPoint type is wrong.");
                    this.activeEditPoint.Location = newPoint;

                    Fx.Assert(this.editPoints.Count > 0, "Some edit point should exist");
                    ConnectionPoint targetConnPt = null;
                    Point[]         points       = null;
                    Point           begin        = this.editPoints[0].Location;
                    Point           end          = this.editPoints[this.editPoints.Count - 1].Location;

                    if (typeof(ConnectionPointsAdorner).IsAssignableFrom(Mouse.DirectlyOver.GetType()))
                    {
                        ConnectionPointsAdorner connPtsAdorner = Mouse.DirectlyOver as ConnectionPointsAdorner;
                        targetConnPt = FreeFormPanel.ConnectionPointHitTest(newPoint, connPtsAdorner);
                    }

                    if (activeEditPointIndex == 0)
                    {
                        // We are dragging the source point of a connector.
                        ConnectionPoint destConnPt = FreeFormPanel.GetDestinationConnectionPoint(this.editedConnector);
                        if (targetConnPt != null)
                        {
                            points = ConnectorRouter.Route(parentPanel, targetConnPt, destConnPt);
                            this.activeEditPoint.Location = targetConnPt.Location;
                        }
                        else
                        {
                            points = ConnectorRouter.Route(parentPanel, begin, destConnPt);
                        }
                    }
                    else
                    {
                        // We are dragging the destination point of a connector.
                        ConnectionPoint srcConnPt = FreeFormPanel.GetSourceConnectionPoint(this.editedConnector);
                        if (targetConnPt != null)
                        {
                            points = ConnectorRouter.Route(parentPanel, srcConnPt, targetConnPt);
                            this.activeEditPoint.Location = targetConnPt.Location;
                        }
                        else
                        {
                            points = ConnectorRouter.Route(parentPanel, srcConnPt, end);
                        }
                    }

                    //When we start editing the end point we need to clear the slate and start over
                    List <EditPoint> newEditPoints = new List <EditPoint>();
                    if (points != null && points.Length > 1)
                    {
                        RemoveEditPoints(EditPoint.EditPointTypes.MultiSegmentEditPoint);
                        for (int i = 1; i < points.Length - 1; ++i)
                        {
                            newEditPoints.Add(new EditPoint(EditPoint.EditPointTypes.MultiSegmentEditPoint, points[i]));
                        }
                        this.editPoints.InsertRange(1, newEditPoints.ToArray());
                    }
                }
                else if (this.activeEditPoint.Type == EditPoint.EditPointTypes.MultiSegmentEditPoint)
                {
                    if (previous != null && previous.Type != EditPoint.EditPointTypes.ConnectionEditPoint && next != null && next.Type != EditPoint.EditPointTypes.ConnectionEditPoint)
                    {
                        //Update the previous point
                        double      slopeOfLine = DesignerGeometryHelper.SlopeOfLineSegment(previous.Location, this.activeEditPoint.Location);
                        Orientation orientation = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical;
                        previous.Location = (orientation == Orientation.Horizontal) ? new Point(previous.Location.X, newPoint.Y) : new Point(newPoint.X, previous.Location.Y);

                        //Update the next point
                        slopeOfLine   = DesignerGeometryHelper.SlopeOfLineSegment(this.activeEditPoint.Location, next.Location);
                        orientation   = (Math.Abs(slopeOfLine) < 1) ? Orientation.Horizontal : Orientation.Vertical;
                        next.Location = (orientation == Orientation.Horizontal) ? new Point(next.Location.X, newPoint.Y) : new Point(newPoint.X, next.Location.Y);

                        //Update the current point
                        this.activeEditPoint.Location = newPoint;
                    }
                    else
                    {
                        Fx.Assert(false, "Should not be here. UpdateEditPoints failed.");
                    }
                }
            }

            // Remove all the redundant edit points
            RemoveCoincidingEditPoints();

            bool validEditPoints = ValidateEditPoints();

            Fx.Assert(validEditPoints, "Validating EditPoints failed.");
        }