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 #nullable disable
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -100,10 +101,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
return base.OnDragStart(e); return base.OnDragStart(e);
} }
private float dragTimeAccumulated;
protected override void Update() protected override void Update()
{ {
if (IsDragged || hitObjectDragged) if (IsDragged || hitObjectDragged)
handleScrollViaDrag(); handleScrollViaDrag();
else
dragTimeAccumulated = 0;
if (Composer != null && timeline != null) if (Composer != null && timeline != null)
{ {
@ -193,16 +198,42 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
private void handleScrollViaDrag() 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; if (timeline == null) return;
var timelineQuad = timeline.ScreenSpaceDrawQuad; var mousePos = timeline.ToLocalSpace(InputManager.CurrentState.Mouse.Position);
float mouseX = InputManager.CurrentState.Mouse.Position.X;
// scroll if in a drag and dragging outside visible extents // for better UX do not require the user to drag all the way to the edge and beyond to initiate a drag-scroll.
if (mouseX > timelineQuad.TopRight.X) // this is especially important in scenarios like fullscreen, where mouse confine will usually be on
timeline.ScrollBy((float)((mouseX - timelineQuad.TopRight.X) / 10 * Clock.ElapsedFrameTime)); // and the user physically *won't be able to* drag beyond the edge of the timeline
else if (mouseX < timelineQuad.TopLeft.X) // (since its left edge is co-incident with the window edge).
timeline.ScrollBy((float)((mouseX - timelineQuad.TopLeft.X) / 10 * Clock.ElapsedFrameTime)); 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 private partial class SelectableAreaBackground : CompositeDrawable