/// <summary> /// Handles input. Should be called by the owning window whenever a pointer is moved. /// </summary> /// <param name="ev">Object containing pointer move event information.</param> internal void OnPointerMoved(PointerEvent ev) { if (ev.Button != PointerButton.Left) { return; } if (isPointerHeld) { Vector2I windowPos = window.ScreenToWindowPos(ev.ScreenPos); Rect2I elementBounds = GUIUtility.CalculateBounds(gui, window.GUI); Vector2I pointerPos = windowPos - new Vector2I(elementBounds.x, elementBounds.y); if (isMousePressedOverKey || isMousePressedOverTangent) { Rect2I drawingBounds = drawingPanel.Bounds; Vector2I drawingPos = pointerPos - new Vector2I(drawingBounds.x, drawingBounds.y); if (!isDragInProgress) { int distance = Vector2I.Distance(drawingPos, dragStart); if (distance >= DRAG_START_DISTANCE) { if (isMousePressedOverKey && !disableCurveEdit) { draggedKeyframes.Clear(); foreach (var selectedEntry in selectedKeyframes) { EdAnimationCurve curve = curveInfos[selectedEntry.curveIdx].curve; KeyFrame[] keyFrames = curve.KeyFrames; DraggedKeyframes newEntry = new DraggedKeyframes(); newEntry.curveIdx = selectedEntry.curveIdx; draggedKeyframes.Add(newEntry); foreach (var keyframeIdx in selectedEntry.keyIndices) { newEntry.keys.Add(new DraggedKeyframe(keyframeIdx, keyFrames[keyframeIdx])); } } } // TODO - UNDOREDO record keyframe or tangent isDragInProgress = true; } } if (isDragInProgress) { if (isMousePressedOverKey && !disableCurveEdit) { Vector2 diff = Vector2.Zero; Vector2 dragStartCurve; if (guiCurveDrawing.PixelToCurveSpace(dragStart, out dragStartCurve)) { Vector2 currentPosCurve; if (guiCurveDrawing.PixelToCurveSpace(drawingPos, out currentPosCurve)) { diff = currentPosCurve - dragStartCurve; } } foreach (var draggedEntry in draggedKeyframes) { EdAnimationCurve curve = curveInfos[draggedEntry.curveIdx].curve; for (int i = 0; i < draggedEntry.keys.Count; i++) { DraggedKeyframe draggedKey = draggedEntry.keys[i]; float newTime = draggedKey.original.time + diff.x; float newValue = draggedKey.original.value + diff.y; int newIndex = curve.UpdateKeyframe(draggedKey.index, newTime, newValue); // It's possible key changed position due to time change, but since we're moving all // keys at once they cannot change position relative to one another, otherwise we would // need to update indices for other keys as well. draggedKey.index = newIndex; draggedEntry.keys[i] = draggedKey; } curve.Apply(); } // Rebuild selected keys from dragged keys (after potential sorting) ClearSelection(); foreach (var draggedEntry in draggedKeyframes) { foreach (var keyframe in draggedEntry.keys) { SelectKeyframe(new KeyframeRef(draggedEntry.curveIdx, keyframe.index)); } } OnCurveModified?.Invoke(); guiCurveDrawing.Rebuild(); UpdateEventsGUI(); } else if (isMousePressedOverTangent && !disableCurveEdit) { EdAnimationCurve curve = curveInfos[draggedTangent.keyframeRef.curveIdx].curve; KeyFrame keyframe = curve.KeyFrames[draggedTangent.keyframeRef.keyIdx]; Vector2 keyframeCurveCoords = new Vector2(keyframe.time, keyframe.value); Vector2 currentPosCurve; if (guiCurveDrawing.PixelToCurveSpace(drawingPos, out currentPosCurve)) { Vector2 normal = currentPosCurve - keyframeCurveCoords; normal = normal.Normalized; float tangent = EdAnimationCurve.NormalToTangent(normal); if (draggedTangent.type == TangentType.In) { if (normal.x > 0.0f) { tangent = float.PositiveInfinity; } keyframe.inTangent = -tangent; if (curve.TangentModes[draggedTangent.keyframeRef.keyIdx] == TangentMode.Free) { keyframe.outTangent = -tangent; } } else { if (normal.x < 0.0f) { tangent = float.PositiveInfinity; } keyframe.outTangent = tangent; if (curve.TangentModes[draggedTangent.keyframeRef.keyIdx] == TangentMode.Free) { keyframe.inTangent = tangent; } } curve.KeyFrames[draggedTangent.keyframeRef.keyIdx] = keyframe; curve.Apply(); OnCurveModified?.Invoke(); guiCurveDrawing.Rebuild(); } } } } else // Move frame marker { int frameIdx = guiTimeline.GetFrame(pointerPos); if (frameIdx != -1) { SetMarkedFrame(frameIdx); } OnFrameSelected?.Invoke(frameIdx); } } }
/// <summary> /// Handles input. Should be called by the owning window whenever a pointer is moved. /// </summary> /// <param name="ev">Object containing pointer move event information.</param> internal void OnPointerMoved(PointerEvent ev) { if (ev.Button != PointerButton.Left) return; if (isPointerHeld) { Vector2I windowPos = window.ScreenToWindowPos(ev.ScreenPos); Rect2I elementBounds = GUIUtility.CalculateBounds(gui, window.GUI); Vector2I pointerPos = windowPos - new Vector2I(elementBounds.x, elementBounds.y); if (isMousePressedOverKey || isMousePressedOverTangent) { Rect2I drawingBounds = drawingPanel.Bounds; Vector2I drawingPos = pointerPos - new Vector2I(drawingBounds.x, drawingBounds.y); if (!isDragInProgress) { int distance = Vector2I.Distance(drawingPos, dragStart); if (distance >= DRAG_START_DISTANCE) { if (isMousePressedOverKey && !disableCurveEdit) { draggedKeyframes.Clear(); foreach (var selectedEntry in selectedKeyframes) { EdAnimationCurve curve = curveInfos[selectedEntry.curveIdx].curve; KeyFrame[] keyFrames = curve.KeyFrames; DraggedKeyframes newEntry = new DraggedKeyframes(); newEntry.curveIdx = selectedEntry.curveIdx; draggedKeyframes.Add(newEntry); foreach (var keyframeIdx in selectedEntry.keyIndices) newEntry.keys.Add(new DraggedKeyframe(keyframeIdx, keyFrames[keyframeIdx])); } } isDragInProgress = true; } } if (isDragInProgress) { if (isMousePressedOverKey && !disableCurveEdit) { Vector2 diff = Vector2.Zero; Vector2 dragStartCurve; if (guiCurveDrawing.PixelToCurveSpace(dragStart, out dragStartCurve, true)) { Vector2 currentPosCurve; if (guiCurveDrawing.PixelToCurveSpace(drawingPos, out currentPosCurve, true)) diff = currentPosCurve - dragStartCurve; } foreach (var draggedEntry in draggedKeyframes) { EdAnimationCurve curve = curveInfos[draggedEntry.curveIdx].curve; for (int i = 0; i < draggedEntry.keys.Count; i++) { DraggedKeyframe draggedKey = draggedEntry.keys[i]; float newTime = Math.Max(0.0f, draggedKey.original.time + diff.x); float newValue = draggedKey.original.value + diff.y; int newIndex = curve.UpdateKeyframe(draggedKey.index, newTime, newValue); // It's possible key changed position due to time change, but since we're moving all // keys at once they cannot change position relative to one another, otherwise we would // need to update indices for other keys as well. draggedKey.index = newIndex; draggedEntry.keys[i] = draggedKey; } curve.Apply(); } // Rebuild selected keys from dragged keys (after potential sorting) ClearSelection(); foreach (var draggedEntry in draggedKeyframes) { foreach (var keyframe in draggedEntry.keys) SelectKeyframe(new KeyframeRef(draggedEntry.curveIdx, keyframe.index)); } isModifiedDuringDrag = true; window.RecordClipState(); guiCurveDrawing.Rebuild(); UpdateEventsGUI(); } else if (isMousePressedOverTangent && !disableCurveEdit) { EdAnimationCurve curve = curveInfos[draggedTangent.keyframeRef.curveIdx].curve; KeyFrame keyframe = curve.KeyFrames[draggedTangent.keyframeRef.keyIdx]; Vector2 keyframeCurveCoords = new Vector2(keyframe.time, keyframe.value); Vector2 currentPosCurve; if (guiCurveDrawing.PixelToCurveSpace(drawingPos, out currentPosCurve, true)) { Vector2 normal = currentPosCurve - keyframeCurveCoords; normal = normal.Normalized; float tangent = EdAnimationCurve.NormalToTangent(normal); if (draggedTangent.type == TangentType.In) { if (normal.x > 0.0f) tangent = float.PositiveInfinity; keyframe.inTangent = -tangent; if(curve.TangentModes[draggedTangent.keyframeRef.keyIdx] == TangentMode.Free) keyframe.outTangent = -tangent; } else { if (normal.x < 0.0f) tangent = float.PositiveInfinity; keyframe.outTangent = tangent; if (curve.TangentModes[draggedTangent.keyframeRef.keyIdx] == TangentMode.Free) keyframe.inTangent = tangent; } curve.KeyFrames[draggedTangent.keyframeRef.keyIdx] = keyframe; curve.Apply(); isModifiedDuringDrag = true; window.RecordClipState(); guiCurveDrawing.Rebuild(); } } } } else // Move frame marker { int frameIdx = guiTimeline.GetFrame(pointerPos); if (frameIdx != -1) SetMarkedFrame(frameIdx); OnFrameSelected?.Invoke(frameIdx); } } }