1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-16 10:23:04 +08:00

Merge pull request #29020 from bdach/drag-selection-tolerance

Add tolerance when drag-scrolling editor timeline
This commit is contained in:
Dean Herbert 2024-07-23 22:28:29 +09:00 committed by GitHub
commit a9ccb50b98
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -3,6 +3,7 @@
#nullable disable
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
@ -100,10 +101,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
return base.OnDragStart(e);
}
private float dragTimeAccumulated;
protected override void Update()
{
if (IsDragged || hitObjectDragged)
handleScrollViaDrag();
else
dragTimeAccumulated = 0;
if (Composer != null && timeline != null)
{
@ -193,16 +198,42 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
private void handleScrollViaDrag()
{
// The amount of time dragging before we reach maximum drag speed.
const float time_ramp_multiplier = 5000;
// A maximum drag speed to ensure things don't get out of hand.
const float max_velocity = 10;
if (timeline == null) return;
var timelineQuad = timeline.ScreenSpaceDrawQuad;
float mouseX = InputManager.CurrentState.Mouse.Position.X;
var mousePos = timeline.ToLocalSpace(InputManager.CurrentState.Mouse.Position);
// scroll if in a drag and dragging outside visible extents
if (mouseX > timelineQuad.TopRight.X)
timeline.ScrollBy((float)((mouseX - timelineQuad.TopRight.X) / 10 * Clock.ElapsedFrameTime));
else if (mouseX < timelineQuad.TopLeft.X)
timeline.ScrollBy((float)((mouseX - timelineQuad.TopLeft.X) / 10 * Clock.ElapsedFrameTime));
// for better UX do not require the user to drag all the way to the edge and beyond to initiate a drag-scroll.
// this is especially important in scenarios like fullscreen, where mouse confine will usually be on
// and the user physically *won't be able to* drag beyond the edge of the timeline
// (since its left edge is co-incident with the window edge).
const float scroll_tolerance = 40;
float leftBound = timeline.BoundingBox.TopLeft.X + scroll_tolerance;
float rightBound = timeline.BoundingBox.TopRight.X - scroll_tolerance;
float amount = 0;
if (mousePos.X > rightBound)
amount = mousePos.X - rightBound;
else if (mousePos.X < leftBound)
amount = mousePos.X - leftBound;
if (amount == 0)
{
dragTimeAccumulated = 0;
return;
}
amount = Math.Sign(amount) * Math.Min(max_velocity, MathF.Pow(Math.Clamp(Math.Abs(amount), 0, scroll_tolerance), 2));
dragTimeAccumulated += (float)Clock.ElapsedFrameTime;
timeline.ScrollBy(amount * (float)Clock.ElapsedFrameTime * Math.Min(1, dragTimeAccumulated / time_ramp_multiplier));
}
private partial class SelectableAreaBackground : CompositeDrawable