Esempio n. 1
0
        // whether freePin's desired location overlaps static pin's actual location
        private static bool PinOverlap(GroupPin freePin, GroupPin againstPin)
        {
            // consider a pin's y interval is  (pinY - PinNodeMargin,  pinY +  PinNodeHeight +PinNodeMargin) top down
            // freePin overlaps againstPin if the two intervals overlap
            var freePinInterval = new Pair<int, int>(freePin.DesiredLocation.Y - CircuitGroupPinInfo.FloatingPinNodeMargin, freePin.DesiredLocation.Y + CircuitGroupPinInfo.FloatingPinNodeHeight + CircuitGroupPinInfo.FloatingPinNodeMargin);
            var pinInterval = new Pair<int, int>(againstPin.Bounds.Location.Y - CircuitGroupPinInfo.FloatingPinNodeMargin, againstPin.Bounds.Location.Y + CircuitGroupPinInfo.FloatingPinNodeHeight + CircuitGroupPinInfo.FloatingPinNodeMargin);
            // two intervals i1 = (s1, e1) and i2 = (s2, e2) overlap if and only if s2 < e1 and s1 < e2
            return ((pinInterval.First < freePinInterval.Second) && // s2 < e1
                    (freePinInterval.First < pinInterval.Second)); //s1 < e2


        }
Esempio n. 2
0
        /// <summary>
        /// Propagate up group pin name changes to the parent pin (only need to take care of non-default name,
        /// the default names are auto-updated in Group.UpdateGroupPins())</summary>
        private void UpdateParentGroupPinName(bool inputSide, GroupPin childPin)
        {
            var parentGrpPin = childPin.GetAncestry(inputSide).FirstOrDefault();
            if (parentGrpPin != null)
            {
                if (!childPin.IsDefaultName && parentGrpPin.IsDefaultName)
                {

                    parentGrpPin.Name = childPin.Name;
                    parentGrpPin.IsDefaultName = false;
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Resolve pin node position to avoid colliding with any node in againstPinNodes</summary>
        /// <param name="againstPinNodes">List of GroupPins to avoid collision with</param>
        /// <param name="floatingPin">Floating pin to adjust: use its DesiredLocation to check collisions and its ActualLocation will be set upon return</param>
        /// <param name="minY">Minimum Y value the floating pin is allowed to take</param>
        private void PositioningFloatigPin(IList<GroupPin> againstPinNodes,  GroupPin floatingPin, int minY)
        {
            // resolve pin node position to avoid colliding with any against-pins 
            bool overlapped = false;
            for (int p = 0; p < againstPinNodes.Count; ++p) // try to locate sufficient empty space between the static nodes
            {
                var againstpin = againstPinNodes[p];
                if (againstpin.Bounds.Location.Y + CircuitGroupPinInfo.FloatingPinNodeHeight + CircuitGroupPinInfo.FloatingPinNodeMargin < minY)
                    continue; 
                if (PinOverlap(floatingPin, againstpin))
                {
                    overlapped = true;
                    // find next suitable place from p down (note againstPinNodes y-ascending order, i.e. higher notes appear first)
                    for (int j = p; j < againstPinNodes.Count - 1; ++j)
                    {
                        if (againstPinNodes[j+1].Bounds.Location.Y - againstPinNodes[j ].Bounds.Location.Y >= 2 * (CircuitGroupPinInfo.FloatingPinNodeHeight + CircuitGroupPinInfo.FloatingPinNodeMargin))
                        {
                            // find empty space >=  pin node height + margin
                            // place the floating pin just above static pin j
                            int pinNewY = Constrain(againstPinNodes[j].Bounds.Location.Y + CircuitGroupPinInfo.FloatingPinNodeHeight + CircuitGroupPinInfo.FloatingPinNodeMargin);
                            floatingPin.Bounds = new Rectangle(floatingPin.Bounds.Location.X, pinNewY, floatingPin.Bounds.Width, floatingPin.Bounds.Height);
                            return;
                        }
                    }
                }
            }

            if (overlapped) // no in-between empty space to insert, try at the top region first, then the bottom region
            {
                // top region 
                var topStaticPin = againstPinNodes[0];
                int pinNewY = Constrain(topStaticPin.Bounds.Location.Y - (CircuitGroupPinInfo.FloatingPinNodeHeight + CircuitGroupPinInfo.FloatingPinNodeMargin));
                pinNewY = Math.Max(pinNewY, minY);
                floatingPin.DesiredLocation = new Point(floatingPin.DesiredLocation.X, pinNewY);
                if (pinNewY > minY &&  !PinOverlap(floatingPin, topStaticPin))
                {
                    floatingPin.Bounds = new Rectangle(floatingPin.Bounds.Location.X, pinNewY, floatingPin.Bounds.Width,
                                                       floatingPin.Bounds.Height);
                }
                else // bottom region
                {
                    var bottomStaticPin = againstPinNodes[againstPinNodes.Count - 1];
                    pinNewY =
                        Constrain(bottomStaticPin.Bounds.Location.Y +
                                  (CircuitGroupPinInfo.FloatingPinNodeHeight + CircuitGroupPinInfo.FloatingPinNodeMargin));
                    pinNewY = Math.Max(pinNewY, minY);
                    floatingPin.DesiredLocation = new Point(floatingPin.DesiredLocation.X, pinNewY);
                    const int increment = 1; 
                    while (PinOverlap(floatingPin, bottomStaticPin))
                    {
                        pinNewY += increment; 
                        floatingPin.DesiredLocation = new Point(floatingPin.DesiredLocation.X, pinNewY);
                    }

                    floatingPin.Bounds = new Rectangle(floatingPin.Bounds.Location.X, pinNewY, floatingPin.Bounds.Width,
                                                       floatingPin.Bounds.Height);
                }
            }
            else // the disired location turns out just fine
            {
                floatingPin.Bounds = new Rectangle(floatingPin.Bounds.Location.X, Constrain(floatingPin.DesiredLocation.Y), floatingPin.Bounds.Width, floatingPin.Bounds.Height);
            }

        }