private IEnumerator <object> HandleDragTask(VelocityMeter velocityMeter, float mouseProjectedPosition, DragGesture dragGesture) { if (!CanScroll || !ScrollWhenContentFits && MaxScrollPosition == 0 || ScrollBySlider) { yield break; } // Do not block scrollview on refresh gesture IsBeingRefreshed = false; IsDragging = true; float realScrollPosition = ScrollPosition; wheelScrollState = WheelScrollState.Stop; while (dragGesture.IsChanging()) { var newMouseProjectedPosition = ProjectToScrollAxisWithFrameRotation(Input.MousePosition); realScrollPosition += mouseProjectedPosition - newMouseProjectedPosition; // Round scrolling position to prevent blurring ScrollPosition = ClampScrollPositionWithinBounceZone(realScrollPosition).Round(); mouseProjectedPosition = newMouseProjectedPosition; velocityMeter.AddSample(realScrollPosition); yield return(null); } StartScrolling(InertialScrollingTask(velocityMeter.CalcVelocity())); IsDragging = false; }
private IEnumerator <object> WheelScrollingTask() { const int wheelScrollingSpeedFactor = 8; wheelScrollState = WheelScrollState.Stop; float totalScrollAmount = 0f; while (true) { yield return(null); var IsScrollingByMouseWheel = !Frame.Input.IsMousePressed() && (Frame.Input.WasKeyPressed(Key.MouseWheelDown) || Frame.Input.WasKeyPressed(Key.MouseWheelUp)) && CanScroll; if (IsScrollingByMouseWheel) { var newWheelScrollState = (WheelScrollState)Math.Sign(Frame.Input.WheelScrollAmount); if (newWheelScrollState != wheelScrollState) { totalScrollAmount = 0f; wheelScrollState = newWheelScrollState; } totalScrollAmount -= Frame.Input.WheelScrollAmount; } if (totalScrollAmount.Abs() >= 1f && wheelScrollState != WheelScrollState.Stop) { StopScrolling(); var stepPerFrame = totalScrollAmount * Task.Current.Delta * wheelScrollingSpeedFactor; var prevScrollPosition = ScrollPosition; ScrollPosition = Mathf.Clamp(ScrollPosition + stepPerFrame, MinScrollPosition, MaxScrollPosition); if (ScrollPosition == MinScrollPosition || ScrollPosition == MaxScrollPosition) { totalScrollAmount = 0f; } else { // If scroll stopped in the middle, we need to round to upper int if we move down // or to lower int if we move up. ScrollPosition = stepPerFrame > 0 ? ScrollPosition.Ceiling() : ScrollPosition.Floor(); totalScrollAmount += (prevScrollPosition - ScrollPosition); } } else { wheelScrollState = WheelScrollState.Stop; } } }