protected override Size ArrangeOverride(Size finalSize)
        {
            double height = 0;
            double width  = 0;

            for (int i = 0; i < Children.Count; i++)
            {
                Point pt   = new Point(0, 0);
                Size  size = Children[i].DesiredSize;
                if (Children[i].GetType() == typeof(Connector))
                {
                    ((UIElement)Children[i]).Arrange(new Rect(pt, size));
                }
                else
                {
                    pt = FreeFormPanel.GetLocation(Children[i]);
                    ((UIElement)Children[i]).Arrange(new Rect(pt, size));
                }
                if (width < (size.Width + pt.X))
                {
                    width = size.Width + pt.X;
                }
                if (height < (size.Height + pt.Y))
                {
                    height = size.Height + pt.Y;
                }
            }
            width = (width < this.MinWidth) ? this.MinWidth : width;
            width = (width < this.Width) ? (this.Width < Double.MaxValue ? this.Width : width) : width;

            height = (height < this.MinHeight) ? this.MinHeight : height;
            height = (height < this.Height) ? (this.Height < Double.MaxValue ? this.Height : height) : height;

            return(new Size(width, height));
        }
예제 #2
0
 //The Connector editor is to be destroyed. Remove the adorners on the editor. activeEditPoint=null sets BeingEdited property to false.
 public void Remove()
 {
     this.activeEditPoint = null;
     RemoveAdorners();
     this.EditPoints.Clear();
     this.Connector.IsSelected = false;
     // Restore the IsHitTestVisible property
     this.SetIsHitTestVisibleForOverlappingStartDots(true);
     this.Connector   = null;
     this.parentPanel = null;
 }
예제 #3
0
        public static Point CalculateDropLocation(Point mousePosition, Point originalDropLocation, Connector connector, Size droppedSize, HashSet <Point> shapeLocations)
        {
            UIElement srcShape     = FreeFormPanel.GetSourceConnectionPoint(connector).ParentDesigner;
            UIElement destShape    = FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner;
            Point     srcLocation  = FreeFormPanel.GetLocation(srcShape);
            Point     destLocation = FreeFormPanel.GetLocation(destShape);
            Size      srcSize      = FreeFormPanel.GetChildSize(srcShape);
            Size      destSize     = FreeFormPanel.GetChildSize(destShape);

            return(CalculateDropLocation(mousePosition, originalDropLocation, droppedSize, srcLocation, destLocation, srcSize, destSize, shapeLocations));
        }
예제 #4
0
        void SetIsHitTestVisibleForOverlappingStartDots(bool hitTestVisible)
        {
            ConnectionPoint srcConnectionPoint = FreeFormPanel.GetSourceConnectionPoint(this.Connector);

            foreach (Connector overlappingConnector in srcConnectionPoint.AttachedConnectors)
            {
                if (overlappingConnector.StartDot != null)
                {
                    overlappingConnector.StartDot.IsHitTestVisible = hitTestVisible;
                }
            }
        }
        internal static ConnectionPoint ConnectionPointHitTest(Point hitPoint, List <ConnectionPoint> connectionPoints, FreeFormPanel panel)
        {
            ConnectionPoint hitConnectionPoint = null;
            FreeFormPanel   outmost            = panel.GetOutmostPanel();

            foreach (ConnectionPoint connPoint in connectionPoints)
            {
                if (connPoint != null && connPoint.IsEnabled)
                {
                    if (new Rect(panel.TranslatePoint(connPoint.Location, outmost) + connPoint.HitTestOffset, connPoint.HitTestSize).Contains(hitPoint))
                    {
                        hitConnectionPoint = connPoint;
                        break;
                    }
                }
            }
            return(hitConnectionPoint);
        }
 public ConnectorEditor(FreeFormPanel panel, Connector connector)
 {
     if (panel == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("panel"));
     }
     if (connector == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("connector"));
     }
     this.editPoints = new List<EditPoint>();
     this.parentPanel = panel;
     this.editedConnector = connector;
     this.activeEditPoint = null;
     connector.IsSelected = true;
     // When the ConnectorEditor is active, we allow reconnecting the start point of the Connector instead
     // of creating a new transition that shares the same trigger. So we need to disable tooltips and 
     // highlighting effects for all overlapping start dots.
     this.SetIsHitTestVisibleForOverlappingStartDots(false);
     DisplayEditPoints();
 }
예제 #7
0
 public ConnectorEditor(FreeFormPanel panel, Connector connector)
 {
     if (panel == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("panel"));
     }
     if (connector == null)
     {
         throw FxTrace.Exception.AsError(new ArgumentNullException("connector"));
     }
     this.editPoints      = new List <EditPoint>();
     this.parentPanel     = panel;
     this.editedConnector = connector;
     this.activeEditPoint = null;
     connector.IsSelected = true;
     // When the ConnectorEditor is active, we allow reconnecting the start point of the Connector instead
     // of creating a new transition that shares the same trigger. So we need to disable tooltips and
     // highlighting effects for all overlapping start dots.
     this.SetIsHitTestVisibleForOverlappingStartDots(false);
     DisplayEditPoints();
 }
예제 #8
0
        public static void CalculateEntryExitEdges(Point mousePosition, Connector connector, out EdgeLocation entryEdge, out EdgeLocation exitEdge)
        {
            UIElement srcShape     = FreeFormPanel.GetSourceConnectionPoint(connector).ParentDesigner;
            UIElement destShape    = FreeFormPanel.GetDestinationConnectionPoint(connector).ParentDesigner;
            Point     srcLocation  = FreeFormPanel.GetLocation(srcShape);
            Point     destLocation = FreeFormPanel.GetLocation(destShape);
            Size      srcSize      = FreeFormPanel.GetChildSize(srcShape);
            Size      destSize     = FreeFormPanel.GetChildSize(destShape);

            Point srcCenter  = new Point(srcLocation.X + (srcSize.Width / 2), srcLocation.Y + (srcSize.Height / 2));
            Point destCenter = new Point(destLocation.X + (destSize.Width / 2), destLocation.Y + (destSize.Height / 2));

            entryEdge = CalculateEdgeLocation(mousePosition, srcCenter);
            exitEdge  = CalculateEdgeLocation(mousePosition, destCenter);

            if (exitEdge == entryEdge)
            {
                switch (entryEdge)
                {
                case EdgeLocation.Top:
                    exitEdge = EdgeLocation.Bottom;
                    break;

                case EdgeLocation.Bottom:
                    exitEdge = EdgeLocation.Top;
                    break;

                case EdgeLocation.Left:
                    exitEdge = EdgeLocation.Right;
                    break;

                case EdgeLocation.Right:
                    exitEdge = EdgeLocation.Left;
                    break;
                }
            }
        }
 void OnFreeFormPanelLoaded(object sender, RoutedEventArgs eventArgs)
 {
     //Adding the following check because of 137896: Inside tab control multiple Loaded events happen without an Unloaded event.
     if (this.panel != null)
     {
         CleanupFlowchart();
     }
     this.panel = (FreeFormPanel)sender;
     if (this.ShowExpanded)
     {
         PopulateFlowchartChildren();
     }
 }
 //Unregister all events. Reset startNodeAdded to enable reuse of the designer.
 void CleanupFlowchart()
 {
     this.startNodeAdded = false;
     this.panel.Children.Clear();
     this.flowNodeToUIElement.Clear();
     // Cleaning up the designers as they might be re-used.
     foreach (UIElement element in this.modelElement.Values)
     {
         element.MouseEnter -= new MouseEventHandler(ChildElement_MouseEnter);
         element.MouseLeave -= new MouseEventHandler(ChildElement_MouseLeave);
     }
     this.panel.LocationChanged -= new LocationChangedEventHandler(OnFreeFormPanelLocationChanged);
     this.panel.ConnectorMoved -= new ConnectorMovedEventHandler(OnFreeFormPanelConnectorMoved);
     this.panel.LayoutUpdated -= new EventHandler(OnFreeFormPanelLayoutUpdated);
     this.panel.RequiredSizeChanged -= new RequiredSizeChangedEventHandler(OnFreeFormPanelRequiredSizeChanged);
     this.panel = null;
     ModelTreeManager modelTreeManager = (this.ModelItem as IModelTreeItem).ModelTreeManager;
     modelTreeManager.EditingScopeCompleted -= new EventHandler<EditingScopeEventArgs>(ModelTreeManager_EditingScopeCompleted);
     this.ViewStateService.ViewStateChanged -= new ViewStateChangedEventHandler(OnViewStateChanged);
 }
 public AutoConnectHelper(FreeFormPanel panel)
 {
     this.panel = panel;
 }
예제 #12
0
 //The Connector editor is to be destroyed. Remove the adorners on the editor. activeEditPoint=null sets BeingEdited property to false.
 public void Remove()
 {
     this.activeEditPoint = null;
     RemoveAdorners();
     this.EditPoints.Clear();
     this.Connector.IsSelected = false;
     // Restore the IsHitTestVisible property
     this.SetIsHitTestVisibleForOverlappingStartDots(true);
     this.Connector = null;
     this.parentPanel = null;
 }
예제 #13
0
 internal static ConnectionPoint ConnectionPointHitTest(Point hitPoint, List<ConnectionPoint> connectionPoints, FreeFormPanel panel)
 {
     ConnectionPoint hitConnectionPoint = null;
     FreeFormPanel outmost = panel.GetOutmostPanel();
     foreach (ConnectionPoint connPoint in connectionPoints)
     {
         if (connPoint != null && connPoint.IsEnabled)
         {
             if (new Rect(panel.TranslatePoint(connPoint.Location, outmost) + connPoint.HitTestOffset, connPoint.HitTestSize).Contains(hitPoint))
             {
                 hitConnectionPoint = connPoint;
                 break;
             }
         }
     }
     return hitConnectionPoint;
 }
        public AutoConnectAdorner(UIElement adornedElement, FreeFormPanel panel, AutoConnectDirections directions) 
            : base(adornedElement)
        {
            this.panel = panel;
            this.directions = directions;

            Size size = FreeFormPanel.GetChildSize(this.AdornedElement);
            this.adornedElementRect = new Rect(new Point(0, 0), size);
            this.hitTestRects = new Rect[] 
            { 
                new Rect(-HitTestHeight, (size.Height / 2) - (HitTestWidth / 2), HitTestHeight, HitTestWidth),
                new Rect(size.Width, (size.Height / 2) - (HitTestWidth / 2), HitTestHeight, HitTestWidth),
                new Rect((size.Width / 2) - (HitTestWidth / 2), -HitTestHeight, HitTestWidth, HitTestHeight),
                new Rect((size.Width / 2) - (HitTestWidth / 2), size.Height, HitTestWidth, HitTestHeight)
            };

            this.renderGeometries = new PathGeometry[]
            {
                new PathGeometry() 
                { 
                    Figures =
                    {
                        new PathFigure()
                        {
                            StartPoint = new Point(-DropTargetOffset - TriangleHeight, size.Height / 2), Segments = 
                            { 
                                new LineSegment() { Point = new Point(-DropTargetOffset, (size.Height / 2) - (TriangleBaseLength / 2)) },
                                new LineSegment() { Point = new Point(-DropTargetOffset, (size.Height / 2) + (TriangleBaseLength / 2)) },
                                new LineSegment() { Point = new Point(-DropTargetOffset - TriangleHeight, size.Height / 2) }
                            }
                        }
                    } 
                },
                new PathGeometry() 
                { 
                    Figures =
                    {
                        new PathFigure()
                        {
                            StartPoint = new Point(size.Width + DropTargetOffset, (size.Height / 2) - (TriangleBaseLength / 2)), Segments = 
                            { 
                                new LineSegment() { Point = new Point(size.Width + DropTargetOffset + TriangleHeight, size.Height / 2) },
                                new LineSegment() { Point = new Point(size.Width + DropTargetOffset, (size.Height / 2) + (TriangleBaseLength / 2)) },
                                new LineSegment() { Point = new Point(size.Width + DropTargetOffset, (size.Height / 2) - (TriangleBaseLength / 2)) }
                            }
                        }
                    }
                },
                new PathGeometry() 
                { 
                    Figures =
                    {
                        new PathFigure()
                        {
                            StartPoint = new Point((size.Width / 2) - (TriangleBaseLength / 2), -DropTargetOffset), Segments = 
                            { 
                                new LineSegment() { Point = new Point((size.Width / 2), -DropTargetOffset - TriangleHeight) },
                                new LineSegment() { Point = new Point((size.Width / 2) + (TriangleBaseLength / 2), -DropTargetOffset) },
                                new LineSegment() { Point = new Point((size.Width / 2) - (TriangleBaseLength / 2), -DropTargetOffset) }
                            }
                        }
                    }
                },
                new PathGeometry() 
                { 
                    Figures = 
                    {
                        new PathFigure()
                        {
                            StartPoint = new Point((size.Width / 2) - (TriangleBaseLength / 2), size.Height + DropTargetOffset), Segments = 
                            { 
                                new LineSegment() { Point = new Point((size.Width / 2) + (TriangleBaseLength / 2), size.Height + DropTargetOffset) },
                                new LineSegment() { Point = new Point((size.Width / 2), size.Height + TriangleHeight + DropTargetOffset) },
                                new LineSegment() { Point = new Point((size.Width / 2) - (TriangleBaseLength / 2), size.Height + DropTargetOffset) }
                            }
                        }
                    }
                }
            };
        }
        internal static ConnectionPoint ConnectionPointHitTest(Point hitPoint, ConnectionPointsAdorner adorner)
        {
            FreeFormPanel panel = VisualTreeUtils.FindVisualAncestor <FreeFormPanel>(adorner.AdornedElement);

            return(ConnectionPointHitTest(hitPoint, adorner.ConnectionPoints, panel));
        }
예제 #16
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.");
        }