Skip to content

Commit

Permalink
Merge pull request #29020 from bdach/drag-selection-tolerance
Browse files Browse the repository at this point in the history
Add tolerance when drag-scrolling editor timeline
  • Loading branch information
peppy authored Jul 23, 2024
2 parents 40b171f + aed7ba9 commit a9ccb50
Showing 1 changed file with 38 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#nullable disable

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
Expand Down Expand Up @@ -100,10 +101,14 @@ protected override bool OnDragStart(DragStartEvent e)
return base.OnDragStart(e);
}

private float dragTimeAccumulated;

protected override void Update()
{
if (IsDragged || hitObjectDragged)
handleScrollViaDrag();
else
dragTimeAccumulated = 0;

if (Composer != null && timeline != null)
{
Expand Down Expand Up @@ -193,16 +198,42 @@ bool shouldBeSelected(HitObject hitObject)

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);

// 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;

// 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));
timeline.ScrollBy(amount * (float)Clock.ElapsedFrameTime * Math.Min(1, dragTimeAccumulated / time_ramp_multiplier));
}

private partial class SelectableAreaBackground : CompositeDrawable
Expand Down

0 comments on commit a9ccb50

Please sign in to comment.