예제 #1
0
        /// Gets location offset from oldContainer to newContainer, compensate renderer displacements for element title
        /// and margin sub-nodes location are defined relative to the parent container
        private Point GetRelativeOffset(ICircuitContainer oldContainer, ICircuitContainer newContainer)
        {
            AdaptableControl control = m_viewingContext.Cast <AdaptableControl>();

            var offset          = new Point();
            var oldDomContainer = oldContainer.Cast <DomNode>();
            var newDomContainer = newContainer.Cast <DomNode>();

            var commonAncestor = DomNode.GetLowestCommonAncestor(oldDomContainer, newDomContainer);

            var upPath   = oldDomContainer.Lineage.TakeWhile(x => x != commonAncestor);
            var upOffset = GetWorldOffset(control, upPath.AsIEnumerable <Element>());

            offset.Offset(upOffset.X, upOffset.Y);

            var downPath   = newDomContainer.Lineage.TakeWhile(x => x != commonAncestor).Reverse();
            var downOffset = GetWorldOffset(control, downPath.AsIEnumerable <Element>());

            offset.Offset(-downOffset.X, -downOffset.Y);
            return(offset);
        }
예제 #2
0
        /// <summary>
        /// Populates a newly created group with circuit elements that are currently in the given graph</summary>
        /// <param name="newGroup">A new group, empty of circuit elements</param>
        /// <param name="elementsToGroup">The circuit elements to move into 'newGroup'.</param>
        /// <param name="graphContainer">The container for the circuit elements and their wires. These will
        /// be removed from 'graphContainer' and placed into 'newGroup'.</param>
        /// <remarks>This method is intended to help with persistence of circuit groups.</remarks>
        public static void CreateGroup(Group newGroup, IEnumerable <object> elementsToGroup, ICircuitContainer graphContainer)
        {
            // get the selected modules and the connections between them
            HashSet <Element> modules             = new HashSet <Element>();
            List <Wire>       internalConnections = new List <Wire>();
            List <Wire>       externalConnections = new List <Wire>();

            CircuitUtil.GetSubGraph(graphContainer, elementsToGroup, modules, internalConnections, externalConnections, externalConnections);

            // the group must be added before transferring modules and connections to it,
            //  so that the history mechanism will capture all the changes.
            graphContainer.Elements.Add(newGroup);

            // transfer modules
            foreach (Element module in modules)
            {
                graphContainer.Elements.Remove(module);
                newGroup.Elements.Add(module);
            }

            // auto-generate sub-graph group pins to support the external connections to group
            // group pins may have multiple external connections
            newGroup.UpdateGroupPins(modules, internalConnections, externalConnections);

            // transfer internal connections (those between grouped modules)
            foreach (Wire connection in internalConnections)
            {
                graphContainer.Wires.Remove(connection);
                newGroup.Wires.Add(connection);
            }

            // initalize group pin's index and pinY
            newGroup.InitializeGroupPinIndexes(internalConnections);

            if (graphContainer.Is <Group>()) // making a group inside a group
            {
                // remap group pins in the parent group
                var parentGroup = graphContainer.Cast <Group>();

                // remap parent group pins that reference the new group's subnodes to the new group
                foreach (var grpPin in parentGroup.InputGroupPins)
                {
                    if (modules.Contains(grpPin.InternalElement))
                    {
                        // adjust the internal pin index first
                        for (int j = 0; j < newGroup.Inputs.Count; ++j)
                        {
                            var newGrpPin = newGroup.Inputs[j] as GroupPin;
                            if (newGrpPin.InternalElement.DomNode == grpPin.InternalElement.DomNode &&
                                newGrpPin.InternalPinIndex == grpPin.InternalPinIndex)
                            {
                                grpPin.InternalPinIndex = j;
                                newGrpPin.Name          = grpPin.Name;
                                //grpPin.Name = newGroup.Name + ":" + newGrpPin.Name;

                                break;
                            }
                        }
                        // now update node references for the parent group pin
                        grpPin.InternalElement = newGroup;
                    }
                }

                foreach (var grpPin in parentGroup.OutputGroupPins)
                {
                    if (modules.Contains(grpPin.InternalElement))
                    {
                        // adjust the internal pin index first
                        for (int j = 0; j < newGroup.Outputs.Count; ++j)
                        {
                            var newGrpPin = newGroup.Outputs[j] as GroupPin;
                            if (newGrpPin.InternalElement.DomNode == grpPin.InternalElement.DomNode &&
                                newGrpPin.InternalPinIndex == grpPin.InternalPinIndex)
                            {
                                grpPin.InternalPinIndex = j;
                                newGrpPin.Name          = grpPin.Name;
                                //grpPin.Name = newGroup.Name + ":" + newGrpPin.Name;

                                break;
                            }
                        }
                        // now update node references for the parent group pin
                        grpPin.InternalElement = newGroup;
                    }
                }
            }

            newGroup.OnChanged(EventArgs.Empty); // notify the change( derived class of Group may need custom actions)

            // Remap external connections from grouped modules to group.
            foreach (Wire connection in externalConnections)
            {
                var groupInputPin = newGroup.MatchedGroupPin(connection.InputElement, connection.InputPin.Index, true);
                if (groupInputPin != null)
                {
                    groupInputPin.SetPinTarget(true);

                    // reroute original edge
                    connection.SetInput(newGroup, groupInputPin);
                    connection.InputPinTarget = groupInputPin.PinTarget;
                }

                var groupOutputPin = newGroup.MatchedGroupPin(connection.OutputElement, connection.OutputPin.Index, false);
                if (groupOutputPin != null)
                {
                    groupOutputPin.SetPinTarget(false);

                    // reroute original edge
                    connection.SetOutput(newGroup, groupOutputPin);
                    connection.OutputPinTarget = groupOutputPin.PinTarget;
                }
            }


            // find upper-left corner of the subnodes
            Point minLocation = new Point(int.MaxValue, int.MaxValue);

            foreach (var module in newGroup.Elements)
            {
                if (minLocation.X > module.Bounds.Location.X)
                {
                    minLocation.X = module.Bounds.Location.X;
                }
                if (minLocation.Y > module.Bounds.Location.Y)
                {
                    minLocation.Y = module.Bounds.Location.Y;
                }
            }
            // offset sub-nodes location so they are relative to the parent
            foreach (var module in newGroup.Elements)
            {
                var relLoc = module.Bounds.Location;
                relLoc.Offset(-minLocation.X, -minLocation.Y);
                module.Bounds   = new Rectangle(relLoc, module.Bounds.Size);
                module.Position = module.Bounds.Location;
            }
        }
예제 #3
0
        /// <summary>
        /// Populates a newly created group with circuit elements that are currently in the given graph</summary>
        /// <param name="newGroup">A new group, empty of circuit elements</param>
        /// <param name="elementsToGroup">The circuit elements to move into 'newGroup'.</param>
        /// <param name="graphContainer">The container for the circuit elements and their wires. These will
        /// be removed from 'graphContainer' and placed into 'newGroup'.</param>
        /// <remarks>This method is intended to help with persistence of circuit groups.</remarks>
        public static void CreateGroup(Group newGroup, IEnumerable<object> elementsToGroup, ICircuitContainer graphContainer)
        {
            // get the selected modules and the connections between them
            HashSet<Element> modules = new HashSet<Element>();
            List<Wire> internalConnections = new List<Wire>();
            List<Wire> externalConnections = new List<Wire>();

            CircuitUtil.GetSubGraph(graphContainer, elementsToGroup, modules, internalConnections, externalConnections, externalConnections);

            // the group must be added before transferring modules and connections to it,
            //  so that the history mechanism will capture all the changes.
            graphContainer.Elements.Add(newGroup);

            // transfer modules
            foreach (Element module in modules)
            {
                graphContainer.Elements.Remove(module);
                newGroup.Elements.Add(module);
            }

            // auto-generate sub-graph group pins to support the external connections to group
            // group pins may have multiple external connections
            newGroup.UpdateGroupPins(modules, internalConnections, externalConnections);

            // transfer internal connections (those between grouped modules)
            foreach (Wire connection in internalConnections)
            {
                graphContainer.Wires.Remove(connection);
                newGroup.Wires.Add(connection);
            }

            // initialize group pin's index and pinY
            newGroup.InitializeGroupPinIndexes(internalConnections);

            if (graphContainer.Is<Group>()) // making a group inside a group
            {
                // remap group pins in the parent group
                var parentGroup = graphContainer.Cast<Group>();

                // remap parent group pins that reference the new group's subnodes to the new group
                foreach (var grpPin in parentGroup.InputGroupPins)
                {
                    if (modules.Contains(grpPin.InternalElement))
                    {
                        // adjust the internal pin index first 
                        foreach (var newGrpPin in newGroup.InputGroupPins)
                        {
                            if (newGrpPin.InternalElement.DomNode == grpPin.InternalElement.DomNode &&
                                newGrpPin.InternalPinIndex == grpPin.InternalPinIndex)
                            {
                                grpPin.InternalPinIndex = newGrpPin.Index;
                                newGrpPin.Name = grpPin.Name;
                                //grpPin.Name = newGroup.Name + ":" + newGrpPin.Name;

                                break;
                            }
                        }
                        // now update node references for the parent group pin
                        grpPin.InternalElement = newGroup;
                    }
                }

                foreach (var grpPin in parentGroup.OutputGroupPins)
                {
                    if (modules.Contains(grpPin.InternalElement))
                    {
                        // adjust the internal pin index first 
                        foreach (var newGrpPin in newGroup.OutputGroupPins)
                        {
                            if (newGrpPin.InternalElement.DomNode == grpPin.InternalElement.DomNode &&
                                newGrpPin.InternalPinIndex == grpPin.InternalPinIndex)
                            {
                                grpPin.InternalPinIndex = newGrpPin.Index;
                                newGrpPin.Name = grpPin.Name;
                                //grpPin.Name = newGroup.Name + ":" + newGrpPin.Name;

                                break;
                            }
                        }
                        // now update node references for the parent group pin
                        grpPin.InternalElement = newGroup;
                    }
                }

            }

            newGroup.OnChanged(EventArgs.Empty); // notify the change( derived class of Group may need custom actions)

            // Remap external connections from grouped modules to group.
            foreach (Wire connection in externalConnections)
            {
                var groupInputPin = newGroup.MatchedGroupPin(connection.InputElement, connection.InputPin.Index, true);
                if (groupInputPin != null)
                {
                    groupInputPin.SetPinTarget(true);

                    // reroute original edge 
                    connection.SetInput(newGroup, groupInputPin);
                    connection.InputPinTarget = groupInputPin.PinTarget;
                }

                var groupOutputPin = newGroup.MatchedGroupPin(connection.OutputElement, connection.OutputPin.Index, false);
                if (groupOutputPin != null)
                {
                    groupOutputPin.SetPinTarget(false);

                    // reroute original edge 
                    connection.SetOutput(newGroup, groupOutputPin);
                    connection.OutputPinTarget = groupOutputPin.PinTarget;
                }
            }


            // find upper-left corner of the subnodes
            Point minLocation = new Point(int.MaxValue, int.MaxValue);
            foreach (var module in newGroup.Elements)
            {
                if (minLocation.X > module.Bounds.Location.X)
                    minLocation.X = module.Bounds.Location.X;
                if (minLocation.Y > module.Bounds.Location.Y)
                    minLocation.Y = module.Bounds.Location.Y;
            }
            // offset sub-nodes location so they are relative to the parent
            foreach (var module in newGroup.Elements)
            {
                var relLoc = module.Bounds.Location;
                relLoc.Offset(-minLocation.X, -minLocation.Y);
                module.Bounds = new Rectangle(relLoc, module.Bounds.Size);
                module.Position = module.Bounds.Location;
            }
        }