public SnapEngine(IAttractable attractable, IAttractionHandler attractionHandler, ManipulateEdges manipulateEdges, WindowState state, Vector2 mousePosition, IEnumerable <ISnappable> snappables = null) { m_Attractable = attractable; m_ManipulateEdges = manipulateEdges; m_AttractionHandler = attractionHandler; m_State = state; m_CurrentTimes = m_GrabbedTimes = new TimeBoundaries(m_Attractable.start, m_Attractable.end); m_GrabbedTime = m_State.PixelToTime(mousePosition.x); // Add Time zero as Magnet AddMagnet(0.0, true, state); // Add current Time as Magnet // case1157280 only add current time as magnet if visible if (TimelineWindow.instance.currentMode.ShouldShowTimeCursor(m_State)) { AddMagnet(state.editSequence.time, true, state); } if (state.IsEditingASubTimeline()) { // Add start and end of evaluable range as Magnets // This includes the case where the master timeline has a fixed length var range = state.editSequence.GetEvaluableRange(); AddMagnet(range.start, true, state); AddMagnet(range.end, true, state); } else if (state.masterSequence.asset.durationMode == TimelineAsset.DurationMode.FixedLength) { // Add end sequence Time as Magnet AddMagnet(state.masterSequence.asset.duration, true, state); } if (snappables == null) { snappables = GetVisibleSnappables(m_State); } foreach (var snappable in snappables) { if (!attractable.ShouldSnapTo(snappable)) { continue; } var edges = snappable.SnappableEdgesFor(attractable, manipulateEdges); foreach (var edge in edges) { AddMagnet(edge.time, edge.showSnapHint, state); } } }
public void Snap(Vector2 currentMousePosition, EventModifiers modifiers) { var d = m_State.PixelToTime(currentMousePosition.x) - m_GrabbedTime; m_CurrentTimes = m_GrabbedTimes.Translate(d); bool isLeft = m_ManipulateEdges == ManipulateEdges.Left || m_ManipulateEdges == ManipulateEdges.Both; bool isRight = m_ManipulateEdges == ManipulateEdges.Right || m_ManipulateEdges == ManipulateEdges.Both; bool attracted = false; m_SnapEnabled = modifiers == ManipulatorsUtils.actionModifier ? !m_State.edgeSnaps : m_State.edgeSnaps; if (m_SnapEnabled) { SnapInfo leftActiveMagnet = null; SnapInfo rightActiveMagnet = null; if (isLeft) { leftActiveMagnet = ClosestMagnet(m_CurrentTimes.left); } if (isRight) { rightActiveMagnet = ClosestMagnet(m_CurrentTimes.right); } if (leftActiveMagnet != null || rightActiveMagnet != null) { attracted = true; bool leftAttraction = false; if (rightActiveMagnet == null) { // Attracted by a left magnet only. leftAttraction = true; } else { if (leftActiveMagnet != null) { // Attracted by both magnets, choose the closest one. var leftDistance = Math.Abs(leftActiveMagnet.time - m_CurrentTimes.left); var rightDistance = Math.Abs(rightActiveMagnet.time - m_CurrentTimes.right); leftAttraction = leftDistance <= rightDistance; } // else, Attracted by right magnet only } if (leftAttraction) { m_AttractionHandler.OnAttractedEdge(m_Attractable, m_ManipulateEdges, AttractedEdge.Left, leftActiveMagnet.time); } else { m_AttractionHandler.OnAttractedEdge(m_Attractable, m_ManipulateEdges, AttractedEdge.Right, rightActiveMagnet.time); } } } if (!attracted) { var time = isLeft ? m_CurrentTimes.left : m_CurrentTimes.right; time = m_State.SnapToFrameIfRequired(time); m_AttractionHandler.OnAttractedEdge(m_Attractable, m_ManipulateEdges, AttractedEdge.None, time); } }