protected override VisualGroup UpdateVisual(IRenderContext context, VisualGroup group, INode node)
        {
            if (group == null)
            {
                return(CreateVisual(context, node));
            }
            // update the node visualization
            group.Children[0] = NodeStyle.Renderer.GetVisualCreator(node, NodeStyle).UpdateVisual(context, group.Children[0]);

            // update the "visual" ports
            int count = 1;

            foreach (var portDescriptor in PortDescriptor.CreatePortDescriptors(FlowChartType))
            {
                if (portDescriptor.X != int.MaxValue)
                {
                    var parameter = FreeNodePortLocationModel.Instance.CreateParameter(PointD.Origin, new PointD(portDescriptor.X, portDescriptor.Y));
                    var port      = new SimplePort(node, parameter)
                    {
                        LookupImplementation = Lookups.Empty
                    };
                    // see if we have a visual to update...
                    if (count < group.Children.Count)
                    {
                        var oldPortVisual = group.Children[count];
                        group.Children[count] = PortStyle.Renderer.GetVisualCreator(port, PortStyle).UpdateVisual(context, oldPortVisual);
                    }
                    else
                    {
                        // no - add a new one
                        var portVisual = PortStyle.Renderer.GetVisualCreator(port, PortStyle).CreateVisual(context);
                        group.Children.Add(portVisual);
                    }
                }
                count++;
            }
            // see if the number of ports decreased
            while (count < group.Children.Count)
            {
                // yes, remove the old visual
                var index = group.Children.Count - 1;
                group.Children.RemoveAt(index);
            }
            return(group);
        }
        /// <summary>
        /// Actually creates the visual appearance of a node.
        /// </summary>
        /// <remarks>
        /// This renders the node and the edges to the labels and adds the visuals to the <paramref name="container"/>.
        /// All items are arranged as if the node was located at (0,0). <see cref="CreateVisual"/> and <see cref="UpdateVisual"/>
        /// finally arrange the container so that the drawing is translated into the final position.
        /// </remarks>
        private void Render(IRenderContext context, INode node, VisualGroup container)
        {
            var innerVisual = NodeStyle.Renderer.GetVisualCreator(node, NodeStyle).CreateVisual(context);

            container.Add(innerVisual);

            // draw "visual" ports
            foreach (var portDescriptor in PortDescriptor.CreatePortDescriptors(FlowChartType))
            {
                if (portDescriptor.X != int.MaxValue)
                {
                    var parameter = FreeNodePortLocationModel.Instance.CreateParameter(PointD.Origin, new PointD(portDescriptor.X, portDescriptor.Y));
                    var port      = new SimplePort(node, parameter)
                    {
                        LookupImplementation = Lookups.Empty
                    };
                    var portVisual = PortStyle.Renderer.GetVisualCreator(port, PortStyle).CreateVisual(context);
                    container.Children.Add(portVisual);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Perform the layout operation
        /// </summary>
        private async Task ApplyLayout()
        {
            // layout starting, disable button
            layoutButton.IsEnabled = false;

            // create the layout algorithm
            var layout = new HierarchicLayout
            {
                OrthogonalRouting = true,
                LayoutOrientation = LayoutOrientation.TopToBottom
            };

            // do the layout
            await graphControl.MorphLayout(layout,
                                           TimeSpan.FromSeconds(1),
                                           new HierarchicLayoutData {
                //Automatically determine port constraints for source and target
                NodePortCandidateSets =
                {
                    Delegate              = node => {
                        var candidateSet  = new PortCandidateSet();
                        // iterate the port descriptors
                        var descriptors   = PortDescriptor.CreatePortDescriptors(((FlowChartNodeStyle)node.Style).FlowChartType);
                        foreach (var portDescriptor in descriptors)
                        {
                            PortCandidate candidate;
                            // isn't a fixed port candidate (location is variable)
                            if (portDescriptor.X == int.MaxValue)
                            {
                                // create a port candidate at the specified side (east, west, north, south) and apply a cost to it
                                candidate = PortCandidate.CreateCandidate(portDescriptor.Side, portDescriptor.Cost);
                            }
                            else
                            {
                                // create a candidate at a fixed location and side
                                var x     = portDescriptor.X - node.Layout.Width / 2;
                                var y     = portDescriptor.Y - node.Layout.Height / 2;
                                candidate = PortCandidate.CreateCandidate(x, y, portDescriptor.Side, portDescriptor.Cost);
                            }
                            candidateSet.Add(candidate, portDescriptor.Capacity);
                        }
                        return(candidateSet);
                    }
                },
                SourceGroupIds = { Delegate           = edge => {
                                       // create bus-like edge groups for outgoing edges at Start nodes
                                       var sourceNode = edge.SourcePort.Owner as INode;
                                       if (sourceNode != null && ((((FlowChartNodeStyle)sourceNode.Style).FlowChartType)) == FlowChartType.Start)
                                       {
                                           return(sourceNode);
                                       }
                                       return(null);
                                   } },

                TargetGroupIds = { Delegate           = edge => {
                                       // create bus-like edge groups for incoming edges at Branch nodes
                                       var targetNode = edge.TargetPort.Owner as INode;
                                       if (targetNode != null && (((FlowChartNodeStyle)targetNode.Style).FlowChartType) == FlowChartType.Branch)
                                       {
                                           return(targetNode);
                                       }
                                       return(null);
                                   } }
            });

            // enable button again
            layoutButton.IsEnabled = true;
        }