Skip to content

Commit

Permalink
Merge pull request #22144 from ItsShamed/skin/argon-song-progress-cle…
Browse files Browse the repository at this point in the history
…aner

Add "argon" variant of song progress display
  • Loading branch information
bdach authored Jan 18, 2023
2 parents 761298c + b62ff8d commit 593f5f6
Show file tree
Hide file tree
Showing 19 changed files with 600 additions and 115 deletions.
Binary file not shown.
2 changes: 2 additions & 0 deletions osu.Game.Tests/Skins/SkinDeserialisationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public class SkinDeserialisationTest
"Archives/modified-default-20220818.osk",
// Covers longest combo counter
"Archives/modified-default-20221012.osk",
// Covers Argon variant of song progress bar
"Archives/modified-argon-20221024.osk",
// Covers TextElement and BeatmapInfoDrawable
"Archives/modified-default-20221102.osk",
// Covers BPM counter.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ public void SetUp() => Schedule(() =>
{
var implementation = skin is LegacySkin
? CreateLegacyImplementation()
: CreateDefaultImplementation();
: skin is ArgonSkin
? CreateArgonImplementation()
: CreateDefaultImplementation();

implementation.Anchor = Anchor.Centre;
implementation.Origin = Anchor.Centre;
Expand All @@ -29,6 +31,7 @@ public void SetUp() => Schedule(() =>
});

protected abstract Drawable CreateDefaultImplementation();
protected virtual Drawable CreateArgonImplementation() => CreateDefaultImplementation();
protected abstract Drawable CreateLegacyImplementation();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public partial class TestSceneSongProgressGraph : OsuTestScene
public partial class TestSceneDefaultSongProgressGraph : OsuTestScene
{
private TestSongProgressGraph graph;

Expand Down Expand Up @@ -59,7 +59,7 @@ private void displayRandomValues()
graph.Objects = objects;
}

private partial class TestSongProgressGraph : SongProgressGraph
private partial class TestSongProgressGraph : DefaultSongProgressGraph
{
public int CreationCount { get; private set; }

Expand Down
6 changes: 3 additions & 3 deletions osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public void TestHoldForMenuDoesWorkWhenHidden()
[Test]
public void TestInputDoesntWorkWhenHUDHidden()
{
SongProgressBar? getSongProgress() => hudOverlay.ChildrenOfType<SongProgressBar>().SingleOrDefault();
ArgonSongProgress? getSongProgress() => hudOverlay.ChildrenOfType<ArgonSongProgress>().SingleOrDefault();

bool seeked = false;

Expand All @@ -204,8 +204,8 @@ public void TestInputDoesntWorkWhenHUDHidden()

Debug.Assert(progress != null);

progress.ShowHandle = true;
progress.OnSeek += _ => seeked = true;
progress.Interactive.Value = true;
progress.ChildrenOfType<ArgonSongProgressBar>().Single().OnSeek += _ => seeked = true;
});

AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false);
Expand Down
66 changes: 39 additions & 27 deletions osu.Game.Tests/Visual/Gameplay/TestSceneSongProgress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
using osu.Game.Screens.Play.HUD;
using osu.Game.Skinning;
Expand All @@ -28,50 +28,62 @@ private void load()
{
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);

Add(gameplayClockContainer = new MasterGameplayClockContainer(Beatmap.Value, skip_target_time));
FrameStabilityContainer frameStabilityContainer;

Add(gameplayClockContainer = new MasterGameplayClockContainer(Beatmap.Value, skip_target_time)
{
Child = frameStabilityContainer = new FrameStabilityContainer
{
MaxCatchUpFrames = 1
}
});

Dependencies.CacheAs<IGameplayClock>(gameplayClockContainer);
Dependencies.CacheAs<IFrameStableClock>(frameStabilityContainer);
}

[SetUpSteps]
public void SetupSteps()
{
AddStep("reset clock", () => gameplayClockContainer.Reset());
AddStep("set hit objects", setHitObjects);
}

[Test]
public void TestDisplay()
{
AddStep("set hit objects", () => this.ChildrenOfType<SongProgress>().ForEach(progress => progress.Objects = Beatmap.Value.Beatmap.HitObjects));
AddStep("hook seeking", () =>
{
applyToDefaultProgress(d => d.ChildrenOfType<DefaultSongProgressBar>().Single().OnSeek += t => gameplayClockContainer.Seek(t));
applyToArgonProgress(d => d.ChildrenOfType<ArgonSongProgressBar>().Single().OnSeek += t => gameplayClockContainer.Seek(t));
});
AddStep("seek to intro", () => gameplayClockContainer.Seek(skip_target_time));
AddStep("start", gameplayClockContainer.Start);
AddStep("stop", gameplayClockContainer.Stop);
AddStep("start", () => gameplayClockContainer.Start());
}

[Test]
public void TestToggleSeeking()
public void TestBasic()
{
void applyToDefaultProgress(Action<DefaultSongProgress> action) =>
this.ChildrenOfType<DefaultSongProgress>().ForEach(action);

AddStep("allow seeking", () => applyToDefaultProgress(s => s.AllowSeeking.Value = true));
AddStep("hide graph", () => applyToDefaultProgress(s => s.ShowGraph.Value = false));
AddStep("disallow seeking", () => applyToDefaultProgress(s => s.AllowSeeking.Value = false));
AddStep("allow seeking", () => applyToDefaultProgress(s => s.AllowSeeking.Value = true));
AddStep("show graph", () => applyToDefaultProgress(s => s.ShowGraph.Value = true));
}
AddToggleStep("toggle seeking", b =>
{
applyToDefaultProgress(s => s.Interactive.Value = b);
applyToArgonProgress(s => s.Interactive.Value = b);
});

private void setHitObjects()
{
var objects = new List<HitObject>();
for (double i = 0; i < 5000; i++)
objects.Add(new HitObject { StartTime = i });
AddToggleStep("toggle graph", b =>
{
applyToDefaultProgress(s => s.ShowGraph.Value = b);
applyToArgonProgress(s => s.ShowGraph.Value = b);
});

this.ChildrenOfType<SongProgress>().ForEach(progress => progress.Objects = objects);
AddStep("stop", gameplayClockContainer.Stop);
}

private void applyToArgonProgress(Action<ArgonSongProgress> action) =>
this.ChildrenOfType<ArgonSongProgress>().ForEach(action);

private void applyToDefaultProgress(Action<DefaultSongProgress> action) =>
this.ChildrenOfType<DefaultSongProgress>().ForEach(action);

protected override Drawable CreateDefaultImplementation() => new DefaultSongProgress();

protected override Drawable CreateArgonImplementation() => new ArgonSongProgress();

protected override Drawable CreateLegacyImplementation() => new LegacySongProgress();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public void TestSpectatorPlayerInteractiveElementsHidden()
AddUntilStep("all interactive elements removed", () => this.ChildrenOfType<Player>().All(p =>
!p.ChildrenOfType<PlayerSettingsOverlay>().Any() &&
!p.ChildrenOfType<HoldForMenuButton>().Any() &&
p.ChildrenOfType<SongProgressBar>().SingleOrDefault()?.ShowHandle == false));
p.ChildrenOfType<ArgonSongProgressBar>().SingleOrDefault()?.Interactive == false));

AddStep("restore config hud visibility", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue));
}
Expand Down
9 changes: 3 additions & 6 deletions osu.Game/Graphics/UserInterface/SegmentedGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,14 @@ public T[] Values
}
}

private Colour4[] tierColours;
private IReadOnlyList<Colour4> tierColours;

public Colour4[] TierColours
public IReadOnlyList<Colour4> TierColours
{
get => tierColours;
set
{
if (value.Length == 0 || value == tierColours)
return;

tierCount = value.Length;
tierCount = value.Count;
tierColours = value;

graphNeedsUpdate = true;
Expand Down
117 changes: 117 additions & 0 deletions osu.Game/Screens/Play/HUD/ArgonSongProgress.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// 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.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects;

namespace osu.Game.Screens.Play.HUD
{
public partial class ArgonSongProgress : SongProgress
{
private readonly SongProgressInfo info;
private readonly ArgonSongProgressGraph graph;
private readonly ArgonSongProgressBar bar;
private readonly Container graphContainer;

private const float bar_height = 10;

[SettingSource("Show difficulty graph", "Whether a graph displaying difficulty throughout the beatmap should be shown")]
public Bindable<bool> ShowGraph { get; } = new BindableBool(true);

[Resolved]
private Player? player { get; set; }

public ArgonSongProgress()
{
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
Masking = true;
CornerRadius = 5;
Children = new Drawable[]
{
info = new SongProgressInfo
{
Origin = Anchor.TopLeft,
Name = "Info",
Anchor = Anchor.TopLeft,
RelativeSizeAxes = Axes.X,
ShowProgress = false
},
bar = new ArgonSongProgressBar(bar_height)
{
Name = "Seek bar",
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
OnSeek = time => player?.Seek(time),
},
graphContainer = new Container
{
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Masking = true,
CornerRadius = 5,
Child = graph = new ArgonSongProgressGraph
{
Name = "Difficulty graph",
RelativeSizeAxes = Axes.Both,
Blending = BlendingParameters.Additive
},
RelativeSizeAxes = Axes.X,
},
};
RelativeSizeAxes = Axes.X;
}

[BackgroundDependencyLoader]
private void load()
{
info.TextColour = Colour4.White;
info.Font = OsuFont.Torus.With(size: 18, weight: FontWeight.Bold);
}

protected override void LoadComplete()
{
base.LoadComplete();

Interactive.BindValueChanged(_ => bar.Interactive = Interactive.Value, true);
ShowGraph.BindValueChanged(_ => updateGraphVisibility(), true);
}

protected override void UpdateObjects(IEnumerable<HitObject> objects)
{
graph.Objects = objects;

info.StartTime = bar.StartTime = FirstHitTime;
info.EndTime = bar.EndTime = LastHitTime;
}

private void updateGraphVisibility()
{
graph.FadeTo(ShowGraph.Value ? 1 : 0, 200, Easing.In);
bar.ShowBackground = !ShowGraph.Value;
}

protected override void Update()
{
base.Update();
Height = bar.Height + bar_height + info.Height;
graphContainer.Height = bar.Height;
}

protected override void UpdateProgress(double progress, bool isIntro)
{
bar.TrackTime = GameplayClock.CurrentTime;

if (isIntro)
bar.CurrentTime = 0;
else
bar.CurrentTime = FrameStableClock.CurrentTime;
}
}
}
Loading

0 comments on commit 593f5f6

Please sign in to comment.