Example #1
0
 public CrossRange(float start, float end, uint instanceSource, BondAttachment bondAttachment)
 {
     this.crossStart     = start;
     this.crossEnd       = end;
     this.instanceHash   = instanceSource;
     this.bondAttachment = bondAttachment;
 }
Example #2
0
        private bool RemoveCollidingBond(uint instanceId, BondAttachment attachment, List <Bond> previousBonds, BondType newBondType)
        {
            bool result = true;

            if (!attachment.IsGuide() && bonds.ContainsKey(instanceId))
            {
                Bond cb = null;
                foreach (Bond b in bonds[instanceId])
                {
                    cb = b.GetCollidingBond(attachment);
                    if (cb != null)
                    {
                        break;
                    }
                }

                if (cb != null)
                {
                    bool oldIsFlow = cb.ChainType != ChainType.None;
                    bool newIsLock = newBondType == BondType.Lock;
                    // locks can't break flow bonds
                    if (oldIsFlow && newIsLock)
                    {
                        result = false;
                    }
                    else
                    {
                        RemoveBond(cb);
                        previousBonds.Add(cb);
                    }
                }
            }
            return(result);
        }
Example #3
0
        public static AspectConstraint GetAspectConstraint(this BondAttachment ba)
        {
            AspectConstraint result = AspectConstraint.None;

            switch (ba)
            {
            case BondAttachment.ObjectHandleTL:
            case BondAttachment.ObjectHandleTR:
            case BondAttachment.ObjectHandleBR:
            case BondAttachment.ObjectHandleBL:
                result = AspectConstraint.Locked;
                break;

            case BondAttachment.ObjectHandleT:
            case BondAttachment.ObjectHandleB:
                result = AspectConstraint.Vertical;
                break;

            case BondAttachment.ObjectHandleR:
            case BondAttachment.ObjectHandleL:
                result = AspectConstraint.Horizontal;
                break;
            }
            return(result);
        }
Example #4
0
        private void DrawBond(Bond bond, PointF pt, int handleIndex)
        {
            BondAttachment ba         = BondAttachmentExtensions.GetTargetFromHandleIndex(handleIndex);
            HandleIcon     handleIcon = GetHandleIcon(bond.BondType, TransformKind.Scale);

            if (handleIcon != HandleIcon.Anchor && handleIcon != HandleIcon.Spring)
            {
                float hr             = handleSize / 2f;
                int   variationIndex = handleIndex % icons[(int)handleIcon].Length;
                Point p = new Point((int)(pt.X - hr), (int)(pt.Y - hr));
                graphicHolder.DrawImage(icons[(int)handleIcon][variationIndex], p);
            }

            long handleHash = bond.GetHandleHash(ba);

            if (bondPoints.ContainsKey(handleHash))
            {
                // todo: need to allow vertical align inside horz dist chain (which will conflict on a handle).
                Console.WriteLine("conflict handle: " + handleHash);
            }
            else
            {
                bondPoints.Add(handleHash, pt);
            }
        }
Example #5
0
 public static bool IsGuide(this BondAttachment bondTarget)
 {
     return
         (bondTarget == BondAttachment.HGuide ||
          bondTarget == BondAttachment.VGuide ||
          bondTarget == BondAttachment.Template ||
          bondTarget == BondAttachment.CornerGuide);
 }
Example #6
0
        public void Align(uint[] instanceIds, ChainType chainType, Vex.Point target, List <Bond> addedBonds, List <Bond> previousBonds)
        {
            BondAttachment bt       = chainType.GetAttachment();
            BondType       bondType = chainType.IsAligned() ? BondType.Anchor : BondType.Spring;

            Bond b;
            Bond prev = null;

            for (int i = 0; i < instanceIds.Length - 1; i++)
            {
                uint id = instanceIds[i];

                if (chainType.IsDistributed())
                {
                    if (i > 0)
                    {
                        RemoveCollidingBond(id, bt, previousBonds, BondType.Anchor);
                    }
                    if (i < instanceIds.Length - 1)
                    {
                        BondAttachment btOpp = chainType.GetOppositeAttachment();
                        RemoveCollidingBond(id, btOpp, previousBonds, BondType.Anchor);
                    }
                }
                else
                {
                    RemoveCollidingBond(id, bt, previousBonds, BondType.Anchor);
                }

                b                = new Bond(id, bt, bondType);
                b.ChainType      = chainType;
                b.TargetLocation = target;
                AddBond(b);
                addedBonds.Add(b);

                b.Previous = prev;
                if (prev != null)
                {
                    prev.Next = b;
                }
                prev = b;
            }

            int  lastIndex = instanceIds.Length - 1;
            uint lastId    = instanceIds[lastIndex];

            RemoveCollidingBond(lastId, bt, previousBonds, BondType.Anchor);

            b                = new Bond(lastId, bt, bondType);
            b.ChainType      = chainType;
            b.TargetLocation = target;
            AddBond(b);
            addedBonds.Add(b);

            b.Previous = prev;
            prev.Next  = b;
        }
Example #7
0
        public static int GetHandleIndex(this BondAttachment ba)
        {
            int result = -1;

            if (ba >= BondAttachment.ObjectHandleTL && ba <= BondAttachment.ObjectCenter)
            {
                result = (int)(ba - BondAttachment.ObjectHandleTL);
            }
            return(result);
        }
Example #8
0
            public BondLine(PointF p0, PointF p1, BondType bondType, BondAttachment attachment)
            {
                this.bondType   = bondType;
                this.attachment = attachment;
                this.p0         = p0;
                this.p1         = p1;

                offset = Point.Empty;
                GetOffset(p0, p1);
            }
Example #9
0
        public void AddInstance(DesignInstance inst)
        {
            PointF[] pts = (inst.IsRotated) ? inst.GetTransformedCenter() : inst.GetTransformedPoints().GetMidpointsAndCenter();

            for (int i = 0; i < pts.Length; i++)
            {
                BondAttachment ba = BondAttachmentExtensions.GetTargetFromHandleIndex(i);
                AddPoint(xStops, pts[i].X, new CrossPoint(pts[i].Y, inst.InstanceHash, ba));
                AddPoint(yStops, pts[i].Y, new CrossPoint(pts[i].X, inst.InstanceHash, ba));
            }
        }
Example #10
0
        private Bond GetOrCreateGuideBond(uint instanceId, BondAttachment attachment)
        {
            if (!bonds.ContainsKey(instanceId))
            {
                Bond b = new Bond(instanceId, attachment, BondType.Lock);
                bonds.Add(instanceId, new List <Bond>()
                {
                    b
                });
            }

            if (!guideAttachments.ContainsKey(instanceId))
            {
                guideAttachments.Add(instanceId, new List <Bond>());
            }

            return(bonds[instanceId][0]);
        }
Example #11
0
        public static Bitmap GetSnapIcon(BondAttachment bondAttachment)
        {
            Bitmap result = guideIcons[0];

            switch (bondAttachment)
            {
            case BondAttachment.HGuide:
                result = guideIcons[1];
                break;

            case BondAttachment.VGuide:
                result = guideIcons[2];
                break;

            case BondAttachment.CornerGuide:
                result = guideIcons[3];
                break;
            }
            return(result);
        }
Example #12
0
        public static BondAttachment GetBondAttachment(ChainType chainType)
        {
            BondAttachment bt = BondAttachment.None;

            switch (chainType)
            {
            case ChainType.AlignedLeft:
                bt = BondAttachment.ObjectHandleL;
                break;

            case ChainType.AlignedCenterVertical:
                bt = BondAttachment.ObjectCenter;
                break;

            case ChainType.AlignedRight:
                bt = BondAttachment.ObjectHandleR;
                break;

            case ChainType.AlignedTop:
                bt = BondAttachment.ObjectHandleT;
                break;

            case ChainType.AlignedCenterHorizontal:
                bt = BondAttachment.ObjectCenter;
                break;

            case ChainType.AlignedBottom:
                bt = BondAttachment.ObjectHandleB;
                break;

            case ChainType.DistributedHorizontal:
                bt = BondAttachment.ObjectHandleL;
                break;

            case ChainType.DistributedVertical:
                bt = BondAttachment.ObjectHandleT;
                break;
            }

            return(bt);
        }
Example #13
0
        public Bond GetCollidingBond(BondAttachment ba)
        {
            Bond result = null;

            if (ChainType.IsDistributed())
            {
                if (Previous != null && ChainType.GetAttachment() == ba)
                {
                    result = this;
                }
                else if (Next != null && ChainType.GetOppositeAttachment() == ba)
                {
                    result = Next;
                }
            }
            else if (sourceAttachment == ba)
            {
                result = this;
            }
            return(result);
        }
Example #14
0
        public void LockToGuide(
            uint srcId, BondAttachment srcHandle,
            uint targId, BondAttachment targHandle,
            Vex.Point targetLocation, List <Bond> addedBonds, List <Bond> previousBonds)
        {
            bool canAdd = RemoveCollidingBond(srcId, srcHandle, previousBonds, BondType.Lock);

            if (canAdd)
            {
                Bond src  = new Bond(srcId, srcHandle, BondType.Lock);
                Bond targ = GetOrCreateGuideBond(targId, targHandle);

                src.TargetLocation  = targetLocation;
                targ.TargetLocation = targetLocation;

                AddBond(src);
                src.Next = targ;

                addedBonds.Add(src);
                guideAttachments[targId].Add(src);
            }
        }
Example #15
0
        public void JoinHandles(
            uint srcId, BondAttachment srcHandle,
            uint targId, BondAttachment targHandle,
            Vex.Point targetLocation, List <Bond> addedBonds, List <Bond> previousBonds)
        {
            RemoveCollidingBond(srcId, srcHandle, previousBonds, BondType.Join);
            RemoveCollidingBond(targId, targHandle, previousBonds, BondType.Join);

            Bond src  = new Bond(srcId, srcHandle, BondType.Join);
            Bond targ = new Bond(targId, targHandle, BondType.Join);

            AddBond(src);
            AddBond(targ);

            src.Next      = targ;
            targ.Previous = src;

            src.TargetLocation  = targetLocation;
            targ.TargetLocation = targetLocation;

            addedBonds.Add(src);
            addedBonds.Add(targ);
        }
Example #16
0
        public ICrossPoint[] GetCrossPoint(Vex.Point snapPoint, BondAttachment ba)
        {
            List <ICrossPoint> result = new List <ICrossPoint>();

            if (ba.IsHandle())
            {
                if (xStops.ContainsKey(snapPoint.X)) // will not contain point if snaping to original position
                {
                    List <ICrossPoint> cps = xStops[snapPoint.X];
                    ICrossPoint        cp  = cps.Find(item => item.CrossStart == snapPoint.Y);
                    if (cp != null)
                    {
                        result.Add(cp);
                    }
                }
            }
            else
            {
                if (ba.IsVGuide())
                {
                    List <ICrossPoint> cps = xStops[snapPoint.X];
                    if (cps.Count > 0)
                    {
                        result.Add(cps[0]);
                    }
                }
                if (ba.IsHGuide())
                {
                    List <ICrossPoint> cps = yStops[snapPoint.Y];
                    if (cps.Count > 0)
                    {
                        result.Add(cps[0]);
                    }
                }
            }
            return(result.ToArray());
        }
Example #17
0
 public Bond(uint sourceInstanceId, BondAttachment sourceAttachment, BondType bondType)
 {
     this.sourceInstanceId = sourceInstanceId;
     this.sourceAttachment = sourceAttachment;
     this.bondType = bondType;
 }
Example #18
0
 public long GetHandleHash(BondAttachment ba)
 {
     return ((long)SourceInstanceId * 10000) + (int)ba;
 }
Example #19
0
 public Bond(uint sourceInstanceId, BondAttachment sourceAttachment, BondType bondType)
 {
     this.sourceInstanceId = sourceInstanceId;
     this.sourceAttachment = sourceAttachment;
     this.bondType         = bondType;
 }
Example #20
0
 public void AnchorObjects(uint instanceIdA, BondAttachment snapTargetA, uint instanceIdB, BondAttachment snapTargetB)
 {
 }
Example #21
0
 public long GetHandleHash(BondAttachment ba)
 {
     return(((long)SourceInstanceId * 10000) + (int)ba);
 }
Example #22
0
        public Bond GetCollidingBond(BondAttachment ba)
        {
            Bond result = null;

            if (ChainType.IsDistributed())
            {
                if (Previous != null && ChainType.GetAttachment() == ba)
                {
                    result = this;
                }
                else if (Next != null && ChainType.GetOppositeAttachment() == ba)
                {
                    result = Next;
                }
            }
            else if(sourceAttachment == ba)
            {
                result = this;
            }
            return result;
        }
Example #23
0
 public static bool IsBottomOrLeft(this BondAttachment bondTarget)
 {
     return(bondTarget == BondAttachment.ObjectHandleL || bondTarget == BondAttachment.ObjectHandleB);
 }
Example #24
0
        public Vex.Point GetSnapPoints(PointF[] pts, ref Vex.Point[] snapPoints, ref BondAttachment[] snapTypes)
        {
            Vex.Point resultOffset = Vex.Point.Zero;

            // get first snap point for each handle point (based on top left)
            Vex.Point[] snapsXP = new Vex.Point[pts.Length];
            Vex.Point[] snapsY  = new Vex.Point[pts.Length];
            for (int i = 0; i < pts.Length; i++)
            {
                snapsXP[i] = Vex.Point.Empty;
                snapsY[i]  = Vex.Point.Empty;
                GetSnapPoint(xStops, pts[i].X, pts[i].Y, ref snapsXP[i].X, ref snapsXP[i].Y);
                GetSnapPoint(yStops, pts[i].Y, pts[i].X, ref snapsY[i].Y, ref snapsY[i].X, false);
            }

            // get closest X and Y
            float bestDist  = float.MaxValue;
            float bestDistX = float.MaxValue;
            float bestDistY = float.MaxValue;

            Vex.Point bestPoint = Vex.Point.Empty;

            Dictionary <int, BondAttachment> bestIndexes = new Dictionary <int, BondAttachment>();

            for (int i = 0; i < snapsXP.Length; i++)
            {
                // find the distance to the snap(s) for the given handle
                Vex.Point      rp   = snapsXP[i];
                float          difX = 0;
                float          difY = 0;
                BondAttachment targ = BondAttachment.None;
                if (!float.IsNaN(rp.X) && !float.IsNaN(rp.Y)) // point
                {
                    targ = BondAttachment.SymbolHandle;
                    difX = rp.X - pts[i].X;
                    difY = rp.Y - pts[i].Y;
                }
                else if (!float.IsNaN(rp.X)) // vertical guide
                {
                    targ = BondAttachment.VGuide;
                    difX = rp.X - pts[i].X;
                }
                rp = snapsY[i];
                if (float.IsNaN(rp.X) && !float.IsNaN(rp.Y)) // horizontal guide
                {
                    targ = (targ == BondAttachment.VGuide) ? BondAttachment.CornerGuide : BondAttachment.HGuide;
                    difY = rp.Y - pts[i].Y;
                }


                // check if close enough to win or tie
                float distX = difX * difX;
                float distY = difY * difY;
                if (targ.IsHandle())
                {
                    float dist = distX + distY;
                    if (dist <= bestDist + 0.001f)
                    {
                        if (dist + 0.001f < bestDist &&
                            (bestPoint.IsEmpty || Math.Abs(difX - bestPoint.X) < 0.001 || Math.Abs(difY - bestPoint.Y) < 0.001))
                        {
                            bestIndexes.Clear();
                            bestDist  = dist;
                            bestPoint = new Vex.Point(difX, difY);
                            bestDistX = distX;
                            bestDistY = distY;
                            bestIndexes.Add(i, targ);
                        }
                        else if (Math.Abs(distX - bestDistX) < 0.001 && Math.Abs(distY - bestDistY) < 0.001)
                        {
                            bestIndexes.Add(i, targ);
                        }
                    }
                }
                else if (targ != BondAttachment.None)  // guides
                {
                    float minXY = Math.Min(distX, distY);

                    if (minXY < bestDist - 0.0001f)
                    {
                        foreach (var item in bestIndexes.Where(kpv => kpv.Value == BondAttachment.SymbolHandle).ToList())
                        {
                            bestIndexes.Remove(item.Key);
                        }
                        bestDist = minXY;
                    }

                    if (targ == BondAttachment.CornerGuide)
                    {
                        if (distX - 0.0001f <= bestDistX || difY - 0.0001f <= bestDistY)
                        {
                            foreach (var item in bestIndexes.Where(kpv =>
                                                                   ((kpv.Value == BondAttachment.VGuide && bestDistX > distX) || (kpv.Value == BondAttachment.HGuide && bestDistY > distY))
                                                                   ).ToList())
                            {
                                bestIndexes.Remove(item.Key);
                            }

                            bestDistX = Math.Min(bestDistX, distX);
                            bestDistY = Math.Min(bestDistY, distY);
                            bestIndexes.Add(i, targ);
                        }
                    }
                    else if (targ == BondAttachment.VGuide) // clear non HGuides
                    {
                        if (distX - 0.0001f <= bestDistX)
                        {
                            foreach (var item in bestIndexes.Where(kpv => (kpv.Value.IsVGuide() && bestDistX > distX)).ToList())
                            {
                                bestIndexes.Remove(item.Key);
                            }

                            bestDistX = distX;
                            bestIndexes.Add(i, targ);
                        }
                    }
                    else if (targ == BondAttachment.HGuide) // clear non VGuides
                    {
                        if (distY - 0.0001f <= bestDistY)
                        {
                            foreach (var item in bestIndexes.Where(kpv => (kpv.Value.IsHGuide() && bestDistY > distY)).ToList())
                            {
                                bestIndexes.Remove(item.Key);
                            }

                            bestDistY = distY;
                            bestIndexes.Add(i, targ);
                        }
                    }
                }
            }

            // find offset
            bool hasSnap = false;

            Vex.Point target = Vex.Point.Empty;
            foreach (int key in bestIndexes.Keys)
            {
                hasSnap = true;
                BondAttachment bt  = bestIndexes[key];
                PointF         src = pts[key];
                target = (bt == BondAttachment.HGuide) ? snapsY[key] : snapsXP[key];
                if (bt.IsHandle())
                {
                    resultOffset = new Vex.Point(target.X - src.X, target.Y - src.Y);
                    break;
                }
                else if (bt == BondAttachment.CornerGuide)
                {
                    resultOffset = new Vex.Point(target.X - src.X, snapsY[key].Y - src.Y);
                    break;
                }
                else if (bt == BondAttachment.HGuide)
                {
                    if (resultOffset.X != 0)
                    {
                        resultOffset = new Vex.Point(resultOffset.X, target.Y - src.Y);
                        break;
                    }
                    resultOffset = new Vex.Point(0, target.Y - src.Y);
                }
                else if (bt == BondAttachment.VGuide)
                {
                    if (resultOffset.Y != 0)
                    {
                        resultOffset = new Vex.Point(target.X - src.X, resultOffset.Y);
                        break;
                    }
                    resultOffset = new Vex.Point(target.X - src.X, 0);
                }
            }

            // set snap points
            if (hasSnap)
            {
                foreach (int key in bestIndexes.Keys)
                {
                    BondAttachment bt = bestIndexes[key];
                    snapTypes[key] = bt;

                    target = (bt == BondAttachment.HGuide) ? snapsY[key] : snapsXP[key];
                    if (bt.IsHandle())
                    {
                        snapPoints[key] = new Vex.Point(target.X, target.Y);
                    }
                    else if (bt == BondAttachment.HGuide)
                    {
                        snapPoints[key] = new Vex.Point(pts[key].X + resultOffset.X, target.Y);
                    }
                    else if (bt == BondAttachment.VGuide)
                    {
                        snapPoints[key] = new Vex.Point(target.X, pts[key].Y + resultOffset.Y);
                    }
                    else if (bt == BondAttachment.CornerGuide)
                    {
                        snapPoints[key] = new Vex.Point(pts[key].X + resultOffset.X, pts[key].Y + resultOffset.Y);
                    }
                }
            }

            return(resultOffset);
        }
Example #25
0
 public CrossPoint(float start, uint instanceSource, BondAttachment bondAttachment)
 {
     this.crossStart     = start;
     this.instanceHash   = instanceSource;
     this.bondAttachment = bondAttachment;
 }
Example #26
0
 public static bool IsHandle(this BondAttachment bondTarget)
 {
     return(bondTarget >= BondAttachment.SymbolHandle && bondTarget <= BondAttachment.ObjectCenter);
 }