1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-17 19:55:37 +08:00
osu-lazer/osu.Game/Screens/Play/HUD/SongProgressBar.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

98 lines
2.9 KiB
C#
Raw Normal View History

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
2024-01-28 23:06:09 +08:00
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
using osu.Framework.Threading;
2024-01-28 23:06:09 +08:00
using osuTK;
namespace osu.Game.Screens.Play.HUD
{
2024-01-29 00:49:34 +08:00
public abstract partial class SongProgressBar : CompositeDrawable
{
/// <summary>
/// The current seek position of the audio, on a (0..1) range.
/// This is generally the seek target, which will eventually match the gameplay clock when it catches up.
/// </summary>
protected double AudioProgress => length == 0 ? 1 : AudioTime / length;
/// <summary>
/// The current (non-frame-stable) audio time.
/// </summary>
protected double AudioTime => Math.Clamp(GameplayClock.CurrentTime - StartTime, 0.0, length);
[Resolved]
protected IGameplayClock GameplayClock { get; private set; } = null!;
/// <summary>
/// Action which is invoked when a seek is requested, with the proposed millisecond value for the seek operation.
/// </summary>
public Action<double>? OnSeek { get; set; }
/// <summary>
/// Whether the progress bar should allow interaction, ie. to perform seek operations.
/// </summary>
2024-01-29 01:13:39 +08:00
public virtual bool Interactive { get; set; }
2024-01-28 23:06:09 +08:00
public double StartTime { get; set; }
public double EndTime { get; set; } = 1.0;
private double length => EndTime - StartTime;
private bool handleClick;
protected override bool OnMouseDown(MouseDownEvent e)
{
2024-01-28 23:06:09 +08:00
handleClick = true;
return base.OnMouseDown(e);
}
2024-01-28 23:06:09 +08:00
protected override bool OnClick(ClickEvent e)
{
2024-01-28 23:06:09 +08:00
if (handleClick)
handleMouseInput(e);
return true;
}
2024-01-28 23:06:09 +08:00
protected override void OnDrag(DragEvent e)
{
2024-01-28 23:06:09 +08:00
handleMouseInput(e);
}
2024-01-28 23:06:09 +08:00
protected override bool OnDragStart(DragStartEvent e)
{
2024-01-28 23:06:09 +08:00
Vector2 posDiff = e.MouseDownPosition - e.MousePosition;
if (Math.Abs(posDiff.X) < Math.Abs(posDiff.Y))
{
handleClick = false;
return false;
}
handleMouseInput(e);
return true;
}
2024-01-28 23:06:09 +08:00
private void handleMouseInput(UIEvent e)
{
2024-01-28 23:06:09 +08:00
if (!Interactive)
return;
double relativeX = Math.Clamp(ToLocalSpace(e.ScreenSpaceMousePosition).X / DrawWidth, 0, 1);
onUserChange(StartTime + (EndTime - StartTime) * relativeX);
}
private ScheduledDelegate? scheduledSeek;
2024-01-28 23:06:09 +08:00
private void onUserChange(double value)
{
scheduledSeek?.Cancel();
2024-01-28 23:06:09 +08:00
scheduledSeek = Schedule(() => OnSeek?.Invoke(value));
}
}
}