diff --git a/osu.Desktop.VisualTests/Tests/TestCaseSongProgress.cs b/osu.Desktop.VisualTests/Tests/TestCaseSongProgress.cs index 6d8aac1d09..e3c343f5f8 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseSongProgress.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseSongProgress.cs @@ -18,10 +18,14 @@ namespace osu.Desktop.VisualTests.Tests private SongProgress progress; private SongProgressGraph graph; + private StopwatchClock clock; + public override void Reset() { base.Reset(); + clock = new StopwatchClock(true); + Add(progress = new SongProgress { RelativeSizeAxes = Axes.X, @@ -55,6 +59,9 @@ namespace osu.Desktop.VisualTests.Tests progress.Objects = objects; graph.Objects = objects; + + progress.AudioClock = clock; + progress.OnSeek = pos => clock.Seek(pos); } } } diff --git a/osu.Game/Screens/Play/SongProgress.cs b/osu.Game/Screens/Play/SongProgress.cs index ed57dad644..8cead0684e 100644 --- a/osu.Game/Screens/Play/SongProgress.cs +++ b/osu.Game/Screens/Play/SongProgress.cs @@ -28,10 +28,12 @@ namespace osu.Game.Screens.Play private readonly SongProgressBar bar; private readonly SongProgressGraph graph; + private readonly SongProgressInfo info; public Action OnSeek; - public IClock AudioClock; + private IClock audioClock; + public IClock AudioClock { set { audioClock = info.AudioClock = value; } } private double lastHitTime => ((objects.Last() as IHasEndTime)?.EndTime ?? objects.Last().StartTime) + 1; @@ -44,6 +46,9 @@ namespace osu.Game.Screens.Play set { graph.Objects = objects = value; + + info.StartTime = firstHitTime; + info.EndTime = lastHitTime; } } @@ -62,6 +67,14 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { + info = new SongProgressInfo + { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Bottom = bottom_bar_height + graph_height }, + }, graph = new SongProgressGraph { RelativeSizeAxes = Axes.X, @@ -130,10 +143,13 @@ namespace osu.Game.Screens.Play if (objects == null) return; - double progress = ((AudioClock?.CurrentTime ?? Time.Current) - firstHitTime) / lastHitTime; + double progress = ((audioClock?.CurrentTime ?? Time.Current) - firstHitTime) / (lastHitTime - firstHitTime); - bar.UpdatePosition((float)progress); - graph.Progress = (int)(graph.ColumnCount * progress); + if(progress < 1) + { + bar.UpdatePosition((float)progress); + graph.Progress = (int)(graph.ColumnCount * progress); + } } } } diff --git a/osu.Game/Screens/Play/SongProgressGraph.cs b/osu.Game/Screens/Play/SongProgressGraph.cs index 20548970e5..4e56f60c31 100644 --- a/osu.Game/Screens/Play/SongProgressGraph.cs +++ b/osu.Game/Screens/Play/SongProgressGraph.cs @@ -20,12 +20,13 @@ namespace osu.Game.Screens.Play const int granularity = 200; + var firstHit = objects.First().StartTime; var lastHit = (objects.Last() as IHasEndTime)?.EndTime ?? 0; if (lastHit == 0) lastHit = objects.Last().StartTime; - var interval = (lastHit + 1) / granularity; + var interval = (lastHit - firstHit + 1) / granularity; var values = new int[granularity]; @@ -33,8 +34,8 @@ namespace osu.Game.Screens.Play { IHasEndTime end = h as IHasEndTime; - int startRange = (int)(h.StartTime / interval); - int endRange = (int)((end?.EndTime > 0 ? end.EndTime : h.StartTime) / interval); + int startRange = (int)((h.StartTime - firstHit)/ interval); + int endRange = (int)(((end?.EndTime > 0 ? end.EndTime : h.StartTime) - firstHit) / interval); for (int i = startRange; i <= endRange; i++) values[i]++; } diff --git a/osu.Game/Screens/Play/SongProgressInfo.cs b/osu.Game/Screens/Play/SongProgressInfo.cs new file mode 100644 index 0000000000..4c53b61313 --- /dev/null +++ b/osu.Game/Screens/Play/SongProgressInfo.cs @@ -0,0 +1,96 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Timing; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using System; + +namespace osu.Game.Screens.Play +{ + public class SongProgressInfo : Container + { + private OsuSpriteText timeCurrent; + private OsuSpriteText timeLeft; + private OsuSpriteText progress; + + private double startTime; + private double endTime; + + private int? previousPercent; + private int? previousSecond; + + private double songLength => endTime - startTime; + + private const int margin = 10; + + public IClock AudioClock; + + public double StartTime { set { startTime = value; } } + public double EndTime { set { endTime = value; } } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Children = new Drawable[] + { + timeCurrent = new OsuSpriteText + { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + Colour = colours.BlueLighter, + Font = @"Venera", + Margin = new MarginPadding + { + Left = margin, + }, + }, + progress = new OsuSpriteText + { + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + Colour = colours.BlueLighter, + Font = @"Venera", + }, + timeLeft = new OsuSpriteText + { + Origin = Anchor.BottomRight, + Anchor = Anchor.BottomRight, + Colour = colours.BlueLighter, + Font = @"Venera", + Margin = new MarginPadding + { + Right = margin, + }, + } + }; + } + + protected override void Update() + { + base.Update(); + + double songCurrentTime = AudioClock.CurrentTime - startTime; + int currentPercent = Math.Max(0, Math.Min(100, (int)(songCurrentTime / songLength * 100))); + int currentSecond = (int)Math.Floor(songCurrentTime / 1000.0); + + if (currentPercent != previousPercent) + { + progress.Text = currentPercent.ToString() + @"%"; + previousPercent = currentPercent; + } + + if (currentSecond != previousSecond && songCurrentTime < songLength) + { + timeCurrent.Text = TimeSpan.FromSeconds(currentSecond).ToString(songCurrentTime < 0 ? @"\-m\:ss" : @"m\:ss"); + timeLeft.Text = TimeSpan.FromMilliseconds(endTime - AudioClock.CurrentTime).ToString(@"\-m\:ss"); + + previousSecond = currentSecond; + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fd15115fe2..be031ee95b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -227,6 +227,7 @@ +