Esempio n. 1
0
            public static void RemoveInvalid(List <SnapOffsetInfo> infos)
            {
                float smallestDist = float.MaxValue;

                for (int i = 0; i < infos.Count; i++)
                {
                    SnapOffsetInfo info = infos[i];
                    if (info.m_dist < smallestDist)
                    {
                        smallestDist = info.m_dist;
                    }
                }

                int nextValid = 0;

                for (int i = 0; i < infos.Count; i++)
                {
                    SnapOffsetInfo info = infos[i];

                    // if smallestDist is still MaxValue, then adding the tolerance has no effect
                    if (info.m_dist < smallestDist + 0.0001f)
                    {
                        infos[nextValid++] = info;
                    }
                }

                infos.RemoveRange(nextValid, infos.Count - nextValid);
            }
Esempio n. 2
0
        /// <summary>
        /// Gets the offset from one of the world snap points to the closest non-selected object's edge</summary>
        /// <param name="movingPoints">The x-coordinates to snap "from", in world coordinates</param>
        /// <param name="options">The options to control the behavior. If null, the defaults are used.</param>
        /// <returns>The value to be added, to GetDragOffset().X, for example. Is in world coordinates.</returns>
        private float GetSnapOffset(IEnumerable <float> movingPoints, TimelineControl.SnapOptions options)
        {
            //we want to recalculate m_snapInfo and reflect changes to the snap-to lines
            m_snapInfo.Clear();
            m_owner.Invalidate();

            if (options == null)
            {
                options = new TimelineControl.SnapOptions();
            }

            // Check for user-forced snapping and no-snapping.
            if (options.CheckModifierKeys)
            {
                Keys modKeys = Control.ModifierKeys;
                if (s_deactivatorKeys != Keys.None &&
                    (modKeys & s_deactivatorKeys) == s_deactivatorKeys)
                {
                    return(0.0f);
                }
                if (s_activatorKeys != Keys.None &&
                    (modKeys & s_activatorKeys) != s_activatorKeys)
                {
                    return(0.0f);
                }
            }

            // Prepare helper object on each moving point.
            foreach (float snapping in movingPoints)
            {
                m_snapInfo.Add(new SnapOffsetInfo(snapping));
            }
            if (m_snapInfo.Count == 0)
            {
                return(0.0f);
            }

            // Find the closest IEvent.
            float worldSnapTolerance = GdiUtil.InverseTransformVector(m_owner.Transform, s_snapTolerance);

            List <TimelinePath> events = new List <TimelinePath>(
                TimelineControl.GetObjects <IEvent>(m_owner.Timeline));

            // Allow for snapping to a scrubber manipulator.
            if (m_scrubber != null && options.IncludeScrubber)
            {
                events.Add(new TimelinePath(m_scrubber));
            }

            foreach (TimelinePath path in events)
            {
                if (options.IncludeSelected ||
                    !m_owner.Selection.SelectionContains(path))
                {
                    IEvent snapToEvent = (IEvent)path.Last;

                    if (options.Filter == null ||
                        options.Filter(snapToEvent, options))
                    {
                        Matrix localToWorld = TimelineControl.CalculateLocalToWorld(path);
                        float  start, length;
                        GetEventDimensions(snapToEvent, localToWorld, out start, out length);

                        foreach (SnapOffsetInfo info in m_snapInfo)
                        {
                            info.Update(start, snapToEvent, worldSnapTolerance);
                            if (length > 0)
                            {
                                info.Update(start + length, snapToEvent, worldSnapTolerance);
                            }
                        }
                    }
                }
            }

            // Keep only the shortest distance snap-to points. Could be multiple in case of tie.
            SnapOffsetInfo.RemoveInvalid(m_snapInfo);
            if (m_snapInfo.Count == 0)
            {
                return(0.0f);
            }

            SnapOffsetInfo topInfo = m_snapInfo[0];

            return(topInfo.Offset);
        }