static void SetConnectorSrcDestConnectionPoints(Connector connector, ConnectionPoint srcConnectionPoint, ConnectionPoint destConnectionPoint)
 {
     FreeFormPanel.SetSourceConnectionPoint(connector, srcConnectionPoint);
     FreeFormPanel.SetDestinationConnectionPoint(connector, destConnectionPoint);
     srcConnectionPoint.AttachedConnectors.Add(connector);
     destConnectionPoint.AttachedConnectors.Add(connector);
 }
 protected void DrawConnectionPoint(ConnectionPoint connPoint, Point actualLocation, DrawingContext drawingContext)
 {
     if (connPoint.IsEnabled)
     {
         // actualLocation is the point on the Edge with respect to the coordinate system defined by the top left corner of the adorned element
         // We will need this transparent rectangle to make sure OnMouseOver event can be triggered, for hit test.
         drawingContext.DrawRectangle(Brushes.Transparent, new Pen(Brushes.Transparent, 0),
             new Rect(actualLocation + connPoint.HitTestOffset, connPoint.HitTestSize));
         drawingContext.DrawRectangle(this.renderBrush, this.renderPen,
             new Rect(actualLocation + connPoint.DrawingOffset, connPoint.DrawingSize));
     }
 }
        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);
        }
Exemplo n.º 4
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);
        }
 void ConnectionPoint_MouseDown(object sender, MouseButtonEventArgs e)
 {
     UIElement srcElement = ((Adorner)sender).AdornedElement as UIElement;
     this.srcConnectionPoint = ConnectionPointHitTest(srcElement, e.GetPosition(this.panel));
     e.Handled = true;
 }
 private void OnFlowchartGridMouseUp(object sender, MouseButtonEventArgs e)
 {
     if (this.srcConnectionPoint != null)
     {
         RemoveAdorner(this.panel, typeof(ConnectorCreationAdorner));
         this.srcConnectionPoint = null;
     }
 }
        private ConnectionPoint GetSourceConnectionPointForAutoSplit(ConnectionPoint destConnPoint, UIElement srcDesigner)
        {
            this.MeasureView(srcDesigner);
            ConnectionPoint point = this.GetEmptyEdgeMidConnectionPointNotOfType(srcDesigner, this.exitEdgeForAutoSplit, ConnectionPointKind.Incoming);
            if (point == null)
            {
                point = this.FindClosestConnectionPointNotOfType(destConnPoint, new List<ConnectionPoint>(FlowchartDesigner.GetConnectionPoints(srcDesigner).Where<ConnectionPoint>(p =>
                {
                    return p.AttachedConnectors.Count == 0;
                })), ConnectionPointKind.Incoming);
            }

            return point;
        }
        public void DoAutoConnect(DragEventArgs e, UIElement targetElement, AutoConnectDirections direction)
        {
            UIElement sourceElement = targetElement;
            bool immediatelyCommit = ModelItemHelper.CanCreateImmediateEditingScope(this.ModelItem);

            using (EditingScope scope = (EditingScope)this.ModelItem.BeginEdit(SR.AutoConnect, immediatelyCommit))
            {
                ModelItem droppedModelItem = this.DoFlowchartGridDrop(e, direction, null);
                bool autoConnected = false;
                if (droppedModelItem != null)
                {
                    ModelItem sourceModelItem = this.GetSourceModelItemForAutoConnect(sourceElement);
                    if (sourceModelItem != null)
                    {
                        if (sourceModelItem.ItemType == typeof(FlowStep))
                        {
                            sourceModelItem.Properties["Next"].SetValue(droppedModelItem);
                            autoConnected = true;
                        }
                        else if (sourceModelItem.ItemType == typeof(FlowDecision))
                        {
                            if (direction == AutoConnectDirections.Left)
                            {
                                sourceModelItem.Properties["True"].SetValue(droppedModelItem);
                                autoConnected = true;
                            }
                            else if (direction == AutoConnectDirections.Right)
                            {
                                sourceModelItem.Properties["False"].SetValue(droppedModelItem);
                                autoConnected = true;
                            }
                        }
                        else if (GenericFlowSwitchHelper.IsGenericFlowSwitch(sourceModelItem.ItemType))
                        {
                            string message = string.Empty;
                            autoConnected = this.CreateFlowSwitchLink(this.srcConnectionPointForAutoConnect, sourceModelItem, droppedModelItem, null, null, ref message);
                        }
                        else if (sourceModelItem.ItemType == typeof(StartNode))
                        {
                            this.ModelItem.Properties["StartNode"].SetValue(droppedModelItem);
                            autoConnected = true;
                        }
                    }
                }
                if (autoConnected)
                {
                    this.srcConnectionPointForAutoConnect = this.GetSourceConnectionPointForAutoConnect(sourceElement, AutoConnectHelper.AutoConnectDirection2EdgeLocation(direction));
                    scope.Complete();
                }
                else
                {
                    scope.Revert();
                }
            }
        }
        private void OnFlowchartGridPreviewMouseUp(object sender, MouseButtonEventArgs e)
        {
            if (this.srcConnectionPoint != null)
            {
                UIElement destElement = VisualTreeUtils.FindVisualAncestor<VirtualizedContainerService.VirtualizingContainer>(e.OriginalSource as DependencyObject);
                if (destElement != null && this.panel.Children.Contains(destElement))
                {
                    string errorMessage = string.Empty;
                    Point mouseUpLocation = e.GetPosition(sender as IInputElement);

                    if (!CreateLinkGesture(this.srcConnectionPoint, destElement, mouseUpLocation, out errorMessage, false, null) && !errorMessage.Equals(string.Empty))
                    {
                        ErrorReporting.ShowErrorMessage(errorMessage);
                    }
                    this.srcConnectionPoint = null;
                    RemoveAdorner(this.panel, typeof(ConnectorCreationAdorner));
                    RemoveAdorner(destElement, typeof(FlowchartConnectionPointsAdorner));
                    // Simulate a MouseEnter to show connection points
                    ChildElement_MouseEnter(destElement, null);
                }
            }
        }
 void StoreConnectorViewState(ModelItem linkModelItem, PointCollection viewState, ConnectionPoint srcConnPoint)
 {
     StoreConnectorViewState(linkModelItem, viewState, srcConnPoint, true);
 }
        static internal ConnectionPoint GetClosestConnectionPoint(ConnectionPoint srcConnPoint, List<ConnectionPoint> destConnPoints, out double minDist)
        {
            minDist = double.PositiveInfinity;
            double dist = 0;
            ConnectionPoint closestPoint = null;
            Point srcPoint = FreeFormPanel.GetLocationRelativeToOutmostPanel(srcConnPoint);
            foreach (ConnectionPoint destConnPoint in destConnPoints)
            {
                if (srcConnPoint != destConnPoint)
                {
                    dist = DesignerGeometryHelper.ManhattanDistanceBetweenPoints(srcPoint, FreeFormPanel.GetLocationRelativeToOutmostPanel(destConnPoint));
                    if (dist < minDist)
                    {
                        minDist = dist;
                        closestPoint = destConnPoint;
                    }
                }
            }

            return closestPoint;
        }
        // Create a connector by view state of the connector model item, and if failed, just create a connector using the connection points
        // of the source and destination designers. Then add the connector created to the free form panel.
        void AddConnector(
            UIElement sourceDesigner,
            UIElement destinationDesigner,
            ModelItem connectorModelItem,
            ConnectionPoint sourceConnectionPoint = null,
            ConnectionPoint destinationConnectionPoint = null)
        {
            // Check whether connector already exists.
            // If users programmatically add state with transition to the stateMachine, AddConnector will be called twice for one connectorModelItem.
            if (GetConnectorInStateMachine(connectorModelItem) != null)
            {
                return;
            }

            Connector connector = CreateConnectorByConnectorModelItemViewState(sourceDesigner, destinationDesigner, connectorModelItem);
            if (connector == null)
            {
                PointCollection connectorPoints = this.CreatePointCollectionForAutoConnectOrAutoSplit(sourceDesigner, destinationDesigner, connectorModelItem, ref sourceConnectionPoint, ref destinationConnectionPoint);
                if (connectorPoints != null)
                {
                    connector = CreateConnector(sourceConnectionPoint, destinationConnectionPoint, connectorPoints, connectorModelItem);
                    this.ViewStateService.StoreViewState(connectorModelItem, ConnectorLocationViewStateKey, connectorPoints);
                }
            }
            if (connector != null)
            {
                this.panel.Children.Add(connector);
            }
        }
 static public Point GetLocationRelativeToOutmostPanel(ConnectionPoint connectionPoint)
 {
     return(connectionPoint.Location);
 }
 static public List <Point> GetEdgeRelativeToOutmostPanel(ConnectionPoint connectionPoint)
 {
     return(connectionPoint.Edge);
 }
 public static void SetSourceConnectionPoint(DependencyObject obj, ConnectionPoint connectionPoint)
 {
     obj.SetValue(FreeFormPanel.SourceConnectionPointProperty, connectionPoint);
 }
        void UpdateFlowchartOnLinkVisualMoved(ConnectionPoint knownConnectionPoint, Point newPoint, Connector movedConnector, bool isSourceKnown)
        {
            Fx.Assert(this.panel != null, "This code should not be hit if panel is null");
            HitTestResult hitTestResult = VisualTreeHelper.HitTest(this.panel, newPoint);
            if (hitTestResult == null)
            {
                return;
            }
            //Test if the last connectionPoint hit, is the new location for the connector.
            UIElement newViewElement = null;
            ConnectionPoint newConnectionPoint = null;

            //The case where the link is dropped on a connectionpoint.
            if (this.lastConnectionPointMouseUpElement != null)
            {
                newConnectionPoint = this.ConnectionPointHitTest(this.lastConnectionPointMouseUpElement, newPoint);
                if (newConnectionPoint != null)
                {
                    newViewElement = this.lastConnectionPointMouseUpElement;
                }
            }
            //The case where the link is dropped on a shape.
            if (newViewElement == null)
            {
                newViewElement = VisualTreeUtils.FindVisualAncestor<StartSymbol>(hitTestResult.VisualHit);
                if (newViewElement == null)
                {
                    newViewElement = VisualTreeUtils.FindVisualAncestor<VirtualizedContainerService.VirtualizingContainer>(hitTestResult.VisualHit);
                }
            }
            if (newViewElement != null)
            {
                if (this.panel.Children.Contains(newViewElement))
                {
                    using (EditingScope es = (EditingScope)this.ModelItem.BeginEdit(SR.FCLinkMove))
                    {
                        //Delete the existing link and keep the caseKey
                        IFlowSwitchLink oldCaseKey = this.DeleteLink(movedConnector, true);

                        //Create new link
                        bool linkCreated = false;
                        string errorMessage = string.Empty;
                        if (isSourceKnown)
                        {
                            if (newConnectionPoint == null)
                            {
                                linkCreated = CreateLinkGesture(knownConnectionPoint, newViewElement, newPoint, out errorMessage, true, oldCaseKey);
                            }
                            else
                            {
                                linkCreated = CreateLinkGesture(knownConnectionPoint, newConnectionPoint, out errorMessage, true, oldCaseKey);
                            }
                        }
                        else
                        {
                            //If the Link source is dropped onto itself, we need to set the isLinkValidDueToLinkMove flag.
                            bool isLinkValidDueToLinkMove = FreeFormPanel.GetSourceConnectionPoint(movedConnector).ParentDesigner.Equals(newViewElement);
                            if (newConnectionPoint == null)
                            {
                                linkCreated = CreateLinkGesture(newViewElement, knownConnectionPoint, newPoint, out errorMessage, isLinkValidDueToLinkMove, oldCaseKey);
                            }
                            else
                            {
                                linkCreated = CreateLinkGesture(newConnectionPoint, knownConnectionPoint, out errorMessage, isLinkValidDueToLinkMove, oldCaseKey);
                            }
                        }
                        if (!linkCreated)
                        {
                            if (!errorMessage.Equals(string.Empty))
                            {
                                ErrorReporting.ShowErrorMessage(errorMessage);
                            }
                            es.Revert();
                        }
                        else
                        {
                            es.Complete();
                        }
                    }
                }
            }
        }
        void SetConnectorLabel(Connector connector, ConnectionPoint srcConnPoint, ModelItem linkModelItem)
        {
            BindingBase labelBinding = null;

            if (typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType))
            {
                if (FlowchartDesigner.GetTrueConnectionPoint(srcConnPoint.ParentDesigner).Equals(srcConnPoint))
                {
                    labelBinding = new Binding { Source = linkModelItem, Path = new PropertyPath("TrueLabel") };
                }
                else
                {
                    labelBinding = new Binding { Source = linkModelItem, Path = new PropertyPath("FalseLabel") };
                }

                SetConnectorLabelToolTip(connector, labelBinding);
            }
            else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
            {
                IFlowSwitchLink flowSwitchLink = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
                labelBinding = flowSwitchLink.CreateConnectorLabelTextBinding();
                SetConnectorLabelToolTip(connector, labelBinding);
            }
        }
 static ConnectionPoint GetClosestConnectionPointNotOfType(ConnectionPoint srcConnectionPoint, List<ConnectionPoint> targetConnectionPoints, ConnectionPointKind illegalConnectionPointKind)
 {
     double minDist;
     List<ConnectionPoint> filteredConnectionPoints = new List<ConnectionPoint>();
     foreach (ConnectionPoint connPoint in targetConnectionPoints)
     {
         if (connPoint.PointType != illegalConnectionPointKind && !connPoint.Equals(srcConnectionPoint) && connPoint.AttachedConnectors.Count == 0)
         {
             filteredConnectionPoints.Add(connPoint);
         }
     }
     return GetClosestConnectionPoint(srcConnectionPoint, filteredConnectionPoints, out minDist);
 }
 //Save the connector.Points property on the CFx object for serialization and viewstate maintenance.
 void StoreConnectorViewState(ModelItem linkModelItem, PointCollection viewState, ConnectionPoint srcConnPoint, bool isUndoableViewState)
 {
     ModelItem storageModelItem = GetConnectorViewStateStorageModelItem(linkModelItem);
     string viewStateKey = GetConnectorViewStateKey(linkModelItem, srcConnPoint);
     StoreConnectorViewState(storageModelItem, viewStateKey, viewState, isUndoableViewState);
 }
 static void GetClosestConnectionPointPair(List<ConnectionPoint> srcConnPoints, List<ConnectionPoint> destConnPoints, out ConnectionPoint srcConnPoint, out ConnectionPoint destConnPoint)
 {
     double minDist = double.PositiveInfinity;
     double dist;
     ConnectionPoint tempConnPoint;
     srcConnPoint = null;
     destConnPoint = null;
     foreach (ConnectionPoint connPoint in srcConnPoints)
     {
         tempConnPoint = GetClosestConnectionPoint(connPoint, destConnPoints, out dist);
         if (dist < minDist)
         {
             minDist = dist;
             srcConnPoint = connPoint;
             destConnPoint = tempConnPoint;
         }
     }
     Fx.Assert(srcConnPoint != null, "No ConnectionPoint found");
     Fx.Assert(destConnPoint != null, "No ConnectionPoint found");
 }
 string GetConnectorViewStateKey(ModelItem linkModelItem, ConnectionPoint srcConnPoint)
 {
     string viewStateKey = ConnectorViewStateKey;
     if ((typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType)))
     {
         if (srcConnPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkModelItem])))
         {
             viewStateKey = TrueConnectorViewStateKey;
         }
         else
         {
             viewStateKey = FalseConnectorViewStateKey;
         }
     }
     else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
     {
         IFlowSwitchLink link = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
         if (link.IsDefaultCase)
         {
             viewStateKey = FlowSwitchDefaultViewStateKey;
         }
         else
         {
             viewStateKey = link.CaseName + CaseViewStateKeyAppendString;
         }
     }
     return viewStateKey;
 }
 static void GetEmptySrcDestConnectionPoints(UIElement source, UIElement dest, out ConnectionPoint srcConnPoint, out ConnectionPoint destConnPoint)
 {
     srcConnPoint = null;
     destConnPoint = null;
     List<ConnectionPoint> srcConnectionPoints = GetEmptyConnectionPoints(source);
     List<ConnectionPoint> destConnectionPoints = GetEmptyConnectionPoints(dest);
     if (srcConnectionPoints.Count > 0 && destConnectionPoints.Count > 0)
     {
         GetClosestConnectionPointPair(srcConnectionPoints, destConnectionPoints, out srcConnPoint, out destConnPoint);
     }
 }
 internal static ConnectionPoint GetDestinationConnectionPointForAutoConnect(UIElement dest, ConnectionPoint srcConnPoint)
 {
     EdgeLocation destEdgeLocation = EdgeLocation.Top;
     if (!((dest is VirtualizedContainerService.VirtualizingContainer) && ((VirtualizedContainerService.VirtualizingContainer)dest).ModelItem.ItemType == typeof(FlowDecision)))
     {
         switch (srcConnPoint.EdgeLocation)
         {
             case EdgeLocation.Top:
                 destEdgeLocation = EdgeLocation.Bottom;
                 break;
             case EdgeLocation.Bottom:
                 destEdgeLocation = EdgeLocation.Top;
                 break;
             case EdgeLocation.Left:
                 destEdgeLocation = EdgeLocation.Right;
                 break;
             case EdgeLocation.Right:
                 destEdgeLocation = EdgeLocation.Left;
                 break;
         }
     }
     List<ConnectionPoint> destConnectionPoints = new List<ConnectionPoint>(FlowchartDesigner.GetConnectionPoints(dest).Where<ConnectionPoint>((p) =>
     {
         return p.PointType != ConnectionPointKind.Outgoing && p.EdgeLocation == destEdgeLocation;
     }));
     Fx.Assert(destConnectionPoints.Count > 0, "There should be at least one dest connection point available");
     return FlowchartDesigner.GetConnectionPointForAutoConnect(destConnectionPoints);
 }
 //This returns the closest non-incoming connectionPoint on source. Return value will be different than destConnectionPoint.
 static ConnectionPoint GetClosestSrcConnectionPoint(UIElement src, ConnectionPoint destConnectionPoint)
 {
     ConnectionPoint srcConnectionPoint = null;
     if (destConnectionPoint.PointType != ConnectionPointKind.Outgoing)
     {
         srcConnectionPoint = GetClosestConnectionPointNotOfType(destConnectionPoint, StateContainerEditor.GetConnectionPoints(src), ConnectionPointKind.Incoming);
     }
     return srcConnectionPoint;
 }
 internal static int GetConnectionPointIndex(UIElement element, ConnectionPoint pnt)
 {
     List<ConnectionPoint> list = FlowchartDesigner.GetAllConnectionPoints(element);
     return list.IndexOf(pnt);
 }
 //This returns the closest non-outgoing connectionPoint on dest. Return value will be different than sourceConnectionPoint.
 static ConnectionPoint GetClosestDestConnectionPoint(ConnectionPoint sourceConnectionPoint, UIElement dest)
 {
     ConnectionPoint destConnectionPoint = null;
     if (sourceConnectionPoint.PointType != ConnectionPointKind.Incoming)
     {
         destConnectionPoint = GetClosestConnectionPointNotOfType(sourceConnectionPoint, StateContainerEditor.GetConnectionPoints(dest), ConnectionPointKind.Outgoing);
     }
     return destConnectionPoint;
 }
 private void OnFlowchartGridMouseLeave(object sender, MouseEventArgs e)
 {
     bool endLinkCreation = !IsVisualHit(sender as UIElement, sender as UIElement, e.GetPosition(sender as IInputElement));
     if (endLinkCreation)
     {
         RemoveAdorner(this.panel, typeof(ConnectorCreationAdorner));
         this.srcConnectionPoint = null;
     }
 }
 //widthFraction, heightFraction determine location of connectionpoint on the shape.
 ConnectionPoint CreateConnectionPoint(UIElement element, double widthFraction, double heightFraction, EdgeLocation location)
 {
     ConnectionPoint connectionPoint = new ConnectionPoint();
     connectionPoint.EdgeLocation = location;
     connectionPoint.PointType = ConnectionPointKind.Default;
     connectionPoint.ParentDesigner = element;
     BindingOperations.SetBinding(connectionPoint, ConnectionPoint.LocationProperty, GetConnectionPointBinding(element as FrameworkElement, widthFraction, heightFraction));
     return connectionPoint;
 }
 static void SetTrueConnectionPoint(DependencyObject obj, ConnectionPoint connectionPoint)
 {
     obj.SetValue(FlowchartDesigner.TrueConnectionPointProperty, connectionPoint);
 }
        void GetSrcDestConnectionPoints(UIElement source, UIElement dest, out ConnectionPoint srcConnPoint, out ConnectionPoint destConnPoint, out string errorMessage)
        {
            srcConnPoint = null;
            destConnPoint = null;
            errorMessage = string.Empty;
            VirtualizedContainerService.VirtualizingContainer sourceContainer = source as VirtualizedContainerService.VirtualizingContainer;
            if (sourceContainer != null && typeof(FlowDecision).IsAssignableFrom(sourceContainer.ModelItem.ItemType))
            {
                srcConnPoint = FindFlowDecisionSrcConnectionPoint(source, out errorMessage);
                if (srcConnPoint != null)
                {
                    destConnPoint = FindBestMatchDestConnectionPoint(srcConnPoint, dest, out errorMessage);
                }
            }
            else
            {

                List<ConnectionPoint> srcConnectionPoints = FlowchartDesigner.GetConnectionPoints(source);
                List<ConnectionPoint> destConnectionPoints = FlowchartDesigner.GetConnectionPoints(dest);
                if (sourceContainer != null && GenericFlowSwitchHelper.IsGenericFlowSwitch(sourceContainer.ModelItem.ItemType))
                {
                    FindBestMatchConnectionPointPair(srcConnectionPoints, destConnectionPoints, out srcConnPoint, out destConnPoint);
                }
                else
                {
                    // Flowstep
                    FindBestMatchConnectionPointPair(srcConnectionPoints, destConnectionPoints, out srcConnPoint, out destConnPoint);
                }
            }
        }
 void ConnectionPoint_MouseUp(object sender, MouseButtonEventArgs e)
 {
     Fx.Assert(this.panel != null, "This code should not be hit if panel is null");
     UIElement dest = ((Adorner)sender).AdornedElement as UIElement;
     Fx.Assert(dest != null, "Adorned element is not a UIElement");
     if (this.srcConnectionPoint != null)
     {
         ConnectionPoint destConnectionPoint = ConnectionPointHitTest(dest, e.GetPosition(this.panel));
         if (destConnectionPoint != null && !this.srcConnectionPoint.Equals(destConnectionPoint))
         {
             string errorMessage = string.Empty;
             if (!CreateLinkGesture(this.srcConnectionPoint, destConnectionPoint, out errorMessage, null) && !errorMessage.Equals(string.Empty))
             {
                 ErrorReporting.ShowErrorMessage(errorMessage);
             }
         }
         this.srcConnectionPoint = null;
         RemoveAdorner(this.panel, typeof(ConnectorCreationAdorner));
         RemoveAdorner(dest, typeof(FlowchartConnectionPointsAdorner));
     }
     else
     {
         //This will cause the FreeFormPanel to handle the event and is useful while moving connection end points of a connector.
         lastConnectionPointMouseUpElement = dest;
         dest.RaiseEvent(e);
     }
 }
        //This returns the closest non-outgoing connectionPoint on dest. Return value will be different than sourceConnectionPoint.
        ConnectionPoint ClosestDestConnectionPoint(ConnectionPoint sourceConnectionPoint, UIElement dest, out string errorMessage)
        {
            ConnectionPoint destConnectionPoint = null;
            errorMessage = string.Empty;
            if (sourceConnectionPoint.PointType != ConnectionPointKind.Incoming)
            {
                destConnectionPoint = FindClosestConnectionPointNotOfType(sourceConnectionPoint, FlowchartDesigner.GetConnectionPoints(dest), ConnectionPointKind.Outgoing);
            }
            else
            {
                errorMessage = SR.FCInvalidLink;
            }
            return destConnectionPoint;

        }
        Connector GetConnector(ModelItem linkModelItem, ConnectionPoint srcConnPoint, ConnectionPoint destConnPoint)
        {
            Fx.Assert(this.panel != null, "This code should not be hit if panel is null");
            ConnectorWithoutStartDot connector = new ConnectorWithoutStartDot();
            connector.FocusVisualStyle = null;
            connector.Focusable = true;
            DesignerView.SetCommandMenuMode(connector, CommandMenuMode.NoCommandMenu);
            SetConnectorLabel(connector, srcConnPoint, linkModelItem);

            connector.GotKeyboardFocus += new KeyboardFocusChangedEventHandler(OnConnectorGotKeyboardFocus);
            connector.RequestBringIntoView += new RequestBringIntoViewEventHandler(OnConnectorRequestBringIntoView);
            connector.MouseDown += new MouseButtonEventHandler(OnConnectorMouseDown);
            connector.GotFocus += new RoutedEventHandler(OnConnectorGotFocus);
            SetConnectorSrcDestConnectionPoints(connector, srcConnPoint, destConnPoint);
            FlowchartDesigner.SetLinkModelItem(connector, linkModelItem);
            connector.Unloaded += new RoutedEventHandler(OnConnectorUnloaded);
            connector.AutoSplitContainer = this;
            return connector;
        }
 //This returns the closest non-Incoming connectionPoint on source. Return value will be different than destConnectionPoint.
 ConnectionPoint ClosestSrcConnectionPoint(UIElement src, ConnectionPoint destConnectionPoint, out string errorMessage)
 {
     ConnectionPoint sourceConnectionPoint = null;
     errorMessage = string.Empty;
     if (destConnectionPoint.PointType != ConnectionPointKind.Outgoing)
     {
         VirtualizedContainerService.VirtualizingContainer srcContainer = src as VirtualizedContainerService.VirtualizingContainer;
         if (srcContainer != null && typeof(FlowDecision).IsAssignableFrom(srcContainer.ModelItem.ItemType))
         {
             sourceConnectionPoint = FindFlowDecisionSrcConnectionPoint(src, out errorMessage);
         }
         else
         {
             sourceConnectionPoint = FindClosestConnectionPointNotOfType(destConnectionPoint, FlowchartDesigner.GetConnectionPoints(src), ConnectionPointKind.Incoming);
         }
     }
     else
     {
         errorMessage = SR.FCInvalidLink;
     }
     return sourceConnectionPoint;
 }
 //Returns a new connector if viewstate exists, null otherwise.
 Connector GetConnectorViewState(UIElement source, UIElement dest, ModelItem linkModelItem, ConnectionPoint sourceConnectionPoint)
 {
     Fx.Assert(this.panel != null, "This code should not be hit if panel is null");
     Connector connector = null;
     object connectorLocation = null;
     if (typeof(FlowDecision).IsAssignableFrom(linkModelItem.ItemType))
     {
         Fx.Assert(sourceConnectionPoint != null, "Source connection point is null.");
         if (sourceConnectionPoint.Equals(FlowchartDesigner.GetTrueConnectionPoint(this.modelElement[linkModelItem])))
         {
             connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, TrueConnectorViewStateKey);
         }
         else
         {
             connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, FalseConnectorViewStateKey);
         }
     }
     else if (typeof(IFlowSwitchLink).IsAssignableFrom(linkModelItem.ItemType))
     {
         string key = null;
         IFlowSwitchLink link = (IFlowSwitchLink)linkModelItem.GetCurrentValue();
         if (link.IsDefaultCase)
         {
             key = FlowSwitchDefaultViewStateKey;
         }
         else
         {
             key = link.CaseName + CaseViewStateKeyAppendString;
         }
         //Transitioning from fake ModelItem world to real ModelItem world.
         ModelItem realFSModelItem = (this.ModelItem as IModelTreeItem).ModelTreeManager.WrapAsModelItem(link.ParentFlowSwitch);
         connectorLocation = this.ViewStateService.RetrieveViewState(realFSModelItem, key);
     }
     else
     {
         connectorLocation = this.ViewStateService.RetrieveViewState(linkModelItem, ConnectorViewStateKey);
     }
     PointCollection locationPts = connectorLocation as PointCollection;
     if (locationPts != null)
     {
         ConnectionPoint srcConnPoint, destConnPoint;
         System.Diagnostics.Debug.WriteLine(this.isLoaded ? "About to call ConnectionPointHitTest - Loaded" : "About to call ConnectionPointHitTest - Not Loaded");
         srcConnPoint = ConnectionPointHitTest(source, locationPts[0]);
         destConnPoint = ConnectionPointHitTest(dest, locationPts[locationPts.Count - 1]);
         //In Debug mode, the size of the designer changes due to the debug adorner(border). Because of this connection points will move and
         //won't coincide with the viewstate.
         //The following code path is added for the scenario where we reload the flowchart designer by navigating back and forth on breadcrumb
         //when one of the flowchart activities has the debug border.
         //In this scenario we try to find the closest connection point from the end point stored in viewstate. If the distance between the two
         //is within the acceptable range, we will reuse the viewstate and avoid re-drawing the connector.
         if (this.IsReadOnly)
         {
             ConnectionPoint pt;
             double dist;
             if (srcConnPoint == null)
             {
                 pt = FindClosestConnectionPoint(locationPts[0], FlowchartDesigner.GetConnectionPoints(source), out dist);
                 if (pt != null && pt.PointType != ConnectionPointKind.Incoming && dist <= DebugTimeMaxConnectorShapeDist)
                 {
                     srcConnPoint = pt;
                 }
             }
             if (destConnPoint == null)
             {
                 pt = FindClosestConnectionPoint(locationPts[locationPts.Count - 1], FlowchartDesigner.GetConnectionPoints(dest), out dist);
                 if (pt != null && pt.PointType != ConnectionPointKind.Outgoing && dist <= DebugTimeMaxConnectorShapeDist)
                 {
                     destConnPoint = pt;
                 }
             }
         }
         if (srcConnPoint != null && destConnPoint != null)
         {
             connector = GetConnector(linkModelItem, srcConnPoint, destConnPoint);
             connector.Points = locationPts;
         }
     }
     return connector;
 }
Exemplo n.º 36
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.");
        }