public CrossRange(float start, float end, uint instanceSource, BondAttachment bondAttachment) { this.crossStart = start; this.crossEnd = end; this.instanceHash = instanceSource; this.bondAttachment = bondAttachment; }
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); }
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); }
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); } }
public static bool IsGuide(this BondAttachment bondTarget) { return (bondTarget == BondAttachment.HGuide || bondTarget == BondAttachment.VGuide || bondTarget == BondAttachment.Template || bondTarget == BondAttachment.CornerGuide); }
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; }
public static int GetHandleIndex(this BondAttachment ba) { int result = -1; if (ba >= BondAttachment.ObjectHandleTL && ba <= BondAttachment.ObjectCenter) { result = (int)(ba - BondAttachment.ObjectHandleTL); } return(result); }
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); }
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)); } }
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]); }
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); }
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); }
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); }
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); } }
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); }
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()); }
public Bond(uint sourceInstanceId, BondAttachment sourceAttachment, BondType bondType) { this.sourceInstanceId = sourceInstanceId; this.sourceAttachment = sourceAttachment; this.bondType = bondType; }
public long GetHandleHash(BondAttachment ba) { return ((long)SourceInstanceId * 10000) + (int)ba; }
public void AnchorObjects(uint instanceIdA, BondAttachment snapTargetA, uint instanceIdB, BondAttachment snapTargetB) { }
public long GetHandleHash(BondAttachment ba) { return(((long)SourceInstanceId * 10000) + (int)ba); }
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; }
public static bool IsBottomOrLeft(this BondAttachment bondTarget) { return(bondTarget == BondAttachment.ObjectHandleL || bondTarget == BondAttachment.ObjectHandleB); }
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); }
public CrossPoint(float start, uint instanceSource, BondAttachment bondAttachment) { this.crossStart = start; this.instanceHash = instanceSource; this.bondAttachment = bondAttachment; }
public static bool IsHandle(this BondAttachment bondTarget) { return(bondTarget >= BondAttachment.SymbolHandle && bondTarget <= BondAttachment.ObjectCenter); }