Esempio n. 1
0
        public void TestGetLowestCommonAncestor()
        {
            DomNodeType type      = new DomNodeType("type");
            ChildInfo   childInfo = new ChildInfo("child", type, true);

            type.Define(childInfo);

            DomNode parent = new DomNode(type);
            DomNode child1 = new DomNode(type);
            DomNode child2 = new DomNode(type);

            parent.GetChildList(childInfo).Add(child1);
            parent.GetChildList(childInfo).Add(child2);
            DomNode grandchild1 = new DomNode(type);

            child1.GetChildList(childInfo).Add(grandchild1);
            DomNode grandchild2 = new DomNode(type);

            child2.GetChildList(childInfo).Add(grandchild2);

            Assert.AreSame(DomNode.GetLowestCommonAncestor(child1, child2), parent);
            Assert.AreSame(DomNode.GetLowestCommonAncestor(grandchild1, grandchild2), parent);
            Assert.AreSame(DomNode.GetLowestCommonAncestor(child1, grandchild1), child1);

            Assert.AreSame(DomNode.GetLowestCommonAncestor(new DomNode[] { child1, child2, grandchild1 }), parent);
        }
Esempio n. 2
0
        // an element is eligible to move into another container only it first moves out its current container
        private bool IsSelfContainedOrIntersected(DomNode element, DomNode container)
        {
            // the moving element should first move out of the  parent container next to the common ancestor
            var commonAncestor   = DomNode.GetLowestCommonAncestor(element, container);
            var currentContainer = element.Lineage.First(x => x.Parent == commonAncestor);

            if (element == currentContainer)
            {
                return(false); // no self containing
            }
            var control             = m_viewingContext.Cast <AdaptableControl>();
            var elemLocalBound      = GetLocalBound(control, element.Cast <Element>());
            var containerLocalBound = GetLocalBound(control, currentContainer.Cast <Element>());

            containerLocalBound.Location = new PointF(0, GetTitleHeight(control));
            containerLocalBound.Height  -= GetLabelHeight(control);// exclude bottom label area

            elemLocalBound.Offset(GetSubContentOffset(control));
            bool contained = containerLocalBound.Contains(elemLocalBound);

            containerLocalBound.Height -= GetTitleHeight(control);// no subcontent offset if element is moved out of the current container
            bool intersected = containerLocalBound.IntersectsWith(elemLocalBound);

            return(contained || intersected);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        // update edge routes
        private void UpdateWires(IEnumerable <ICircuitContainer> containers)
        {
            foreach (var container in containers)
            {
                foreach (var wire  in container.Wires.ToArray())
                {
                    //string edgeName = CircuitUtil.GetDomNodeName(wire.DomNode);
                    bool input  = container.Elements.Contains(wire.InputElement);
                    bool output = container.Elements.Contains(wire.OutputElement);

                    if (input && output) // still an internal edge of the container (not a container-crossing link)
                    {
                        if (wire.InputElement.Type is MissingElementType || wire.OutputElement.Type is MissingElementType)
                        {
                            continue; // skip wires connected to missing types
                        }
                        var matchedInput = new Pair <Element, ICircuitPin>();
                        foreach (var module in container.Elements)
                        {
                            matchedInput = module.FullyMatchPinTarget(wire.InputPinTarget, true);
                            if (matchedInput.First != null)
                            {
                                break;
                            }
                        }

                        var matchedOutput = new Pair <Element, ICircuitPin>();
                        foreach (var module in container.Elements)
                        {
                            matchedOutput = module.FullyMatchPinTarget(wire.OutputPinTarget, false);
                            if (matchedOutput.First != null)
                            {
                                break;
                            }
                        }

                        if (matchedInput.First != null && matchedOutput.First != null)
                        {
                            wire.InputElement = matchedInput.First;
                            wire.InputPin     = matchedInput.Second;

                            Debug.Assert(matchedOutput.First != null);
                            wire.OutputElement = matchedOutput.First;
                            wire.OutputPin     = matchedOutput.Second;
                            continue;
                        }
                    }

                    if (MovingCrossContainer)
                    {
                        var leafNodeIn  = wire.InputPinTarget.InstancingNode ?? wire.InputPinTarget.LeafDomNode;
                        var leafNodeOut = wire.OutputPinTarget.InstancingNode ?? wire.OutputPinTarget.LeafDomNode;
                        var newParent   = DomNode.GetLowestCommonAncestor(leafNodeIn, leafNodeOut);
                        if (newParent == null)
                        {
                            continue;
                        }
                        var newParentContainer = newParent.Cast <ICircuitContainer>();

                        var matchedInput = newParentContainer.FullyMatchPinTarget(wire.InputPinTarget, true);
                        Debug.Assert(matchedInput.First != null);
                        var matchedOutput = newParentContainer.FullyMatchPinTarget(wire.OutputPinTarget, false);
                        Debug.Assert(matchedOutput.First != null);

                        if (newParentContainer.Is <Group>()) // the edge should connect to child nodes of the parent container
                        {
                            var grpPin = matchedInput.Second.Cast <GroupPin>();
                            wire.InputElement = grpPin.InternalElement;
                            wire.InputPin     = grpPin.InternalElement.AllInputPins.ElementAt(grpPin.InternalPinIndex);
                        }
                        else
                        {
                            wire.InputElement = matchedInput.First;
                            wire.InputPin     = matchedInput.Second;
                        }

                        if (newParentContainer.Is <Group>())
                        {
                            var grpPin = matchedOutput.Second.Cast <GroupPin>();
                            wire.OutputElement = grpPin.InternalElement;
                            wire.OutputPin     = grpPin.InternalElement.AllOutputPins.ElementAt(grpPin.InternalPinIndex);
                        }
                        else
                        {
                            wire.OutputElement = matchedOutput.First;
                            wire.OutputPin     = matchedOutput.Second;
                        }

                        if (container != newParentContainer)
                        {
                            container.Wires.Remove(wire);
                            newParentContainer.Wires.Add(wire);
                        }
                    }
                    else
                    {
                        // the edge has invalid route, must be caused by nodes deletion down the container hierarchy
                        container.Wires.Remove(wire);
                    }
                }
            }
        }