Пример #1
0
        public void UnExecute()
        {
            StageView     stage = MainForm.CurrentStage;
            InstanceGroup sel   = MainForm.CurrentStage.Selection;

            uint[] ids = sel.SelectedIds;

            foreach (Bond b in addedBonds)
            {
                stage.CurrentEditItem.BondStore.RemoveBond(b);
            }

            for (int i = 0; i < ids.Length; i++)
            {
                DesignInstance di = MainForm.CurrentInstanceManager[ids[i]];

                Vex.Matrix m      = di.GetMatrix();
                Vex.Point  offset = new Vex.Point(-offsets[i].X, -offsets[i].Y);
                m.Translate(offset);
                stage.SetDesignInstanceMatrix(di, m);
            }

            if (useSmartBonds)
            {
                foreach (Bond b in previousBonds)
                {
                    stage.CurrentEditItem.BondStore.AddBond(b);
                }
            }

            sel.Update();
            MainForm.CurrentStage.ResetTransformHandles();
            MainForm.CurrentStage.InvalidateTransformedSelection();
        }
Пример #2
0
 public static Vex.Point GetTransformedPoint(Vex.Point pt, Vex.Matrix m, bool invert)
 {
     PointF[] pts = new PointF[] { pt.SysPointF() };
     using (Matrix ms = m.SysMatrix())
     {
         TransformPoints(pts, ms, invert);
     }
     return(pts[0].VexPoint());
 }
Пример #3
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;
        }
Пример #4
0
        public void ConstrainOffset(IEnumerable <uint> sourceIds, ref Vex.Point offset)
        {
            HashSet <uint> tested            = new HashSet <uint>();
            HashSet <uint> alreadyDiscovered = new HashSet <uint>();
            List <Bond>    guideBonds        = new List <Bond>();

            AppendJoinedRelations(sourceIds, tested, alreadyDiscovered, guideBonds);
            foreach (Bond b in guideBonds)
            {
                offset.X = b.Next.SourceAttachment.IsVGuide() ? 0 : offset.X;
                offset.Y = b.Next.SourceAttachment.IsHGuide() ? 0 : offset.Y;
            }
        }
Пример #5
0
        private void GetRelatedObjectTransformsRec(IEnumerable <uint> ids, Dictionary <uint, Vex.Rectangle> alreadyDiscovered, Vex.Point offset, HashSet <Bond> starts)
        {
            List <Bond>    externalBonds = new List <Bond>();
            DesignTimeline designStage   = MainForm.CurrentStage.CurrentEditItem;

            //alreadyDiscovered.UnionWith(ids);
            //foreach (uint id in ids)
            //{
            //    alreadyDiscovered.Add(id, designStage[id].StrokeBounds.TranslatedRectangle(tx, ty));
            //}

            List <Bond>    guideBonds = new List <Bond>();
            HashSet <uint> joinedIds  = new HashSet <uint>();

            designStage.BondStore.AppendJoinedRelations(ids, joinedIds, alreadyDiscovered.Keys, guideBonds);
            foreach (Bond b in guideBonds)
            {
                if (b.Next.SourceAttachment.IsGuide())
                {
                    bool      guideMoved  = b.Next.GuideMoved;
                    Vex.Point guideOffset = b.Next.GuideMoved ? offset : Vex.Point.Zero;
                    offset.X = b.Next.SourceAttachment.IsVGuide() ? guideOffset.X : offset.X;
                    offset.Y = b.Next.SourceAttachment.IsHGuide() ? guideOffset.Y : offset.Y;
                }
            }

            foreach (uint id in joinedIds)
            {
                if (!alreadyDiscovered.ContainsKey(id))
                {
                    alreadyDiscovered.Add(id, designStage[id].StrokeBounds.TranslatedRectangle(offset.X, offset.Y));
                }
                externalBonds.AddRange(designStage.BondStore.GetExternalBondIds(alreadyDiscovered.Keys, id, starts));
            }

            foreach (Bond b in externalBonds)
            {
                // todo: this algorithm ignores multiple chains on an object.
                // probably need to keep track of 'join islands' and their outward chains
                if (!alreadyDiscovered.ContainsKey(b.SourceInstanceId))
                {
                    float newTx = offset.X;
                    float newTy = offset.Y;
                    if (offset.X != 0 || offset.Y != 0)
                    {
                        designStage.BondStore.GetFinalOffset(b, ref newTx, ref newTy);
                    }
                    GetRelatedObjectTransformsRec(new uint[] { b.SourceInstanceId }, alreadyDiscovered, new Vex.Point(newTx, newTy), starts);
                }
            }
        }
Пример #6
0
        public DesignInstance Add(uint definitionId, Vex.Point location)
        {
            DesignInstance si = stage.CreateInstance(definitionId, location);

            if (si != null)
            {
                timeline.AddInstance(si.Instance);
                si.ParentInstanceId = InstanceHash;
                selectedItems.Clear();
                selectedItems.Add(si.InstanceHash);
                SnapStore.AddInstance(si);
            }
            return(si);
        }
Пример #7
0
        public void UnExecute()
        {
            StageView   stage                = MainForm.CurrentStage;
            List <Bond> discardAddedBonds    = new List <Bond>();
            List <Bond> discardPreviousBonds = new List <Bond>();

            foreach (Bond b in addedBonds)
            {
                stage.CurrentEditItem.BondStore.RemoveBond(b);
            }

            Vex.Point unOffset = new Vex.Point(-offset.X, -offset.Y);
            stage.TranslateSelection(unOffset, false, discardAddedBonds, discardPreviousBonds);

            foreach (Bond b in previousBonds)
            {
                stage.CurrentEditItem.BondStore.AddBond(b);
            }

            addedBonds.Clear();
            previousBonds.Clear();
        }
Пример #8
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);
            }
        }
Пример #9
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);
        }
Пример #10
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());
        }
Пример #11
0
 public MoveSelectionCommand(Vex.Point offset)
 {
     this.offset   = offset;
     useSmartBonds = MainForm.CurrentStage.UseSmartBonds;
 }
Пример #12
0
        public void GetRelatedObjectTransforms(IEnumerable <uint> ids, Dictionary <uint, Vex.Rectangle> alreadyDiscovered, Vex.Point offset)
        {
            HashSet <Bond> starts = new HashSet <Bond>();

            GetRelatedObjectTransformsRec(ids, alreadyDiscovered, offset, starts);

            foreach (Bond start in starts)
            {
                SortBondChain(ids, start, alreadyDiscovered);
            }
        }
Пример #13
0
 public Vex.Point LocalToContainer(Vex.Point pt)
 {
     Vex.Point result = Gdi.GdiRenderer.GetTransformedPoint(pt.SysPointF(), GetSysMatrix(), false).VexPoint();
     return(result);
 }
Пример #14
0
        public void Execute()
        {
            StageView     stage = MainForm.CurrentStage;
            InstanceGroup sel   = MainForm.CurrentStage.Selection;

            Vex.Rectangle bounds = sel.StrokeBounds;
            uint[]        ids    = sel.SelectedIds;
            offsets = new Vex.Point[ids.Length];

            InstanceManager im      = MainForm.CurrentInstanceManager;
            List <uint>     sortIds = new List <uint>(ids);

            im.SortIndexesByLocation(sortIds, chainType);

            Vex.Point target = Vex.Point.Empty;

            if (chainType == ChainType.DistributedHorizontal)
            {
                float firstWidth      = MainForm.CurrentInstanceManager[sortIds[0]].StrokeBounds.Width;
                float lastWidth       = MainForm.CurrentInstanceManager[sortIds[sortIds.Count - 1]].StrokeBounds.Width;
                float fillWidth       = bounds.Width - firstWidth - lastWidth;
                float remainingWidths = 0;
                for (int i = 1; i < sortIds.Count - 1; i++)
                {
                    DesignInstance di = MainForm.CurrentInstanceManager[sortIds[i]];
                    remainingWidths += di.StrokeBounds.Width;
                }

                float spacing = (fillWidth - remainingWidths) / (sortIds.Count - 1);
                float curLoc  = bounds.Left;

                for (int i = 0; i < sortIds.Count; i++)
                {
                    DesignInstance di     = MainForm.CurrentInstanceManager[sortIds[i]];
                    Vex.Point      offset = new Vex.Point(curLoc - di.StrokeBounds.Left, 0);

                    Vex.Matrix m = di.GetMatrix();
                    m.Translate(offset);
                    stage.SetDesignInstanceMatrix(di, m);

                    curLoc += spacing + di.StrokeBounds.Width;

                    int realIndex = Array.IndexOf(ids, sortIds[i]);
                    offsets[realIndex] = offset;
                }

                target = new Vex.Point(spacing, float.NaN);
            }
            else if (chainType == ChainType.DistributedVertical)
            {
                float firstHeight      = MainForm.CurrentInstanceManager[sortIds[0]].StrokeBounds.Height;
                float lastHeight       = MainForm.CurrentInstanceManager[sortIds[sortIds.Count - 1]].StrokeBounds.Height;
                float fillHeight       = bounds.Height - firstHeight - lastHeight;
                float remainingHeights = 0;
                for (int i = 1; i < sortIds.Count - 1; i++)
                {
                    DesignInstance di = MainForm.CurrentInstanceManager[sortIds[i]];
                    remainingHeights += di.StrokeBounds.Height;
                }

                float spacing = (fillHeight - remainingHeights) / (sortIds.Count - 1);
                float curLoc  = bounds.Top;

                for (int i = 0; i < sortIds.Count; i++)
                {
                    DesignInstance di     = MainForm.CurrentInstanceManager[sortIds[i]];
                    Vex.Point      offset = new Vex.Point(0, curLoc - di.StrokeBounds.Top);

                    Vex.Matrix m = di.GetMatrix();
                    m.Translate(offset);
                    stage.SetDesignInstanceMatrix(di, m);

                    curLoc += spacing + di.StrokeBounds.Height;

                    int realIndex = Array.IndexOf(ids, sortIds[i]);
                    offsets[realIndex] = offset;
                }
                target = new Vex.Point(float.NaN, spacing);
            }
            else
            {
                Vex.Rectangle contrainedBounds = bounds.Clone();
                stage.CurrentEditItem.BondStore.ConstrainBounds(sortIds, ref contrainedBounds, chainType);

                switch (chainType)
                {
                case ChainType.AlignedLeft:
                    target = new Vex.Point(contrainedBounds.Left, float.NaN);
                    break;

                case ChainType.AlignedCenterVertical:
                    target = new Vex.Point(contrainedBounds.Center.X, float.NaN);
                    break;

                case ChainType.AlignedRight:
                    target = new Vex.Point(contrainedBounds.Right, float.NaN);
                    break;

                case ChainType.AlignedTop:
                    target = new Vex.Point(float.NaN, contrainedBounds.Top);
                    break;

                case ChainType.AlignedCenterHorizontal:
                    target = new Vex.Point(float.NaN, contrainedBounds.Center.Y);
                    break;

                case ChainType.AlignedBottom:
                    target = new Vex.Point(float.NaN, contrainedBounds.Bottom);
                    break;
                }

                for (int i = 0; i < sortIds.Count; i++)
                {
                    DesignInstance di     = MainForm.CurrentInstanceManager[sortIds[i]];
                    Vex.Point      offset = Vex.Point.Zero;

                    switch (chainType)
                    {
                    case ChainType.AlignedLeft:
                        offset.X = target.X - di.StrokeBounds.Left;
                        break;

                    case ChainType.AlignedCenterVertical:
                        offset.X = target.X - (di.StrokeBounds.Left + di.StrokeBounds.Width / 2);
                        break;

                    case ChainType.AlignedRight:
                        offset.X = target.X - (di.StrokeBounds.Left + di.StrokeBounds.Width);
                        break;

                    case ChainType.AlignedTop:
                        offset.Y = target.Y - di.StrokeBounds.Top;
                        break;

                    case ChainType.AlignedCenterHorizontal:
                        offset.Y = target.Y - (di.StrokeBounds.Top + di.StrokeBounds.Height / 2);
                        break;

                    case ChainType.AlignedBottom:
                        offset.Y = target.Y - (di.StrokeBounds.Top + di.StrokeBounds.Height);
                        break;
                    }

                    Vex.Matrix m = di.GetMatrix();
                    m.Translate(offset);
                    stage.SetDesignInstanceMatrix(di, m);

                    offsets[i] = offset;
                }
            }

            if (useSmartBonds)
            {
                stage.CurrentEditItem.BondStore.Align(sortIds.ToArray(), chainType, target, addedBonds, previousBonds);
            }

            sel.Update();
            MainForm.CurrentStage.ResetTransformHandles();
            MainForm.CurrentStage.InvalidateTransformedSelection();
        }
Пример #15
0
 public static Point SysPoint(this Vex.Point p)
 {
     return(new Point(
                (int)Math.Ceiling(p.X),
                (int)Math.Ceiling(p.Y)));
 }
Пример #16
0
 public static PointF SysPointF(this Vex.Point p)
 {
     return(new PointF(p.X, p.Y));
 }
Пример #17
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);
        }