diff --git a/.editorconfig b/.editorconfig
index 8cdb92d11c..67f98f94eb 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -135,7 +135,7 @@ csharp_preferred_modifier_order = public,private,protected,internal,new,abstract
csharp_style_expression_bodied_accessors = true:warning
csharp_style_expression_bodied_constructors = false:none
csharp_style_expression_bodied_indexers = true:warning
-csharp_style_expression_bodied_methods = true:silent
+csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_operators = true:warning
csharp_style_expression_bodied_properties = true:warning
csharp_style_expression_bodied_local_functions = true:silent
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index da47ad8223..b9294088f4 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -29,7 +29,7 @@
-
+
diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
index 589503c35b..2d71fb93fb 100644
--- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
@@ -20,7 +20,9 @@ namespace osu.Game.Rulesets.Catch.UI
internal readonly CatcherArea CatcherArea;
- public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || CatcherArea.ReceivePositionalInputAt(screenSpacePos);
+ public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
+ // only check the X position; handle all vertical space.
+ base.ReceivePositionalInputAt(new Vector2(screenSpacePos.X, ScreenSpaceDrawQuad.Centre.Y));
public CatchPlayfield(BeatmapDifficulty difficulty, Func> createDrawableRepresentation)
{
diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
index 02c2158383..b7b523a94d 100644
--- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs
+++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
@@ -237,19 +237,19 @@ namespace osu.Game.Rulesets.Mania
{
LeftKeys = new[]
{
- InputKey.Number1,
- InputKey.Number2,
- InputKey.Number3,
- InputKey.Number4,
+ InputKey.Q,
+ InputKey.W,
+ InputKey.E,
+ InputKey.R,
},
RightKeys = new[]
{
- InputKey.Z,
InputKey.X,
InputKey.C,
- InputKey.V
+ InputKey.V,
+ InputKey.B
},
- SpecialKey = InputKey.Tilde,
+ SpecialKey = InputKey.S,
SpecialAction = ManiaAction.Special1,
NormalActionStart = ManiaAction.Key1
}.GenerateKeyBindingsFor(keys, out var nextNormal);
@@ -265,12 +265,12 @@ namespace osu.Game.Rulesets.Mania
},
RightKeys = new[]
{
- InputKey.O,
- InputKey.P,
- InputKey.BracketLeft,
- InputKey.BracketRight
+ InputKey.K,
+ InputKey.L,
+ InputKey.Semicolon,
+ InputKey.Quote
},
- SpecialKey = InputKey.BackSlash,
+ SpecialKey = InputKey.I,
SpecialAction = ManiaAction.Special2,
NormalActionStart = nextNormal
}.GenerateKeyBindingsFor(keys, out _);
diff --git a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs
index e825df5a3f..5a4e76d586 100644
--- a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs
+++ b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs
@@ -118,17 +118,19 @@ namespace osu.Game.Tests.Editor
[Test]
public void TestGetSnappedDurationFromDistance()
{
- assertSnappedDuration(50, 0);
+ assertSnappedDuration(0, 0);
+ assertSnappedDuration(50, 1000);
assertSnappedDuration(100, 1000);
- assertSnappedDuration(150, 1000);
+ assertSnappedDuration(150, 2000);
assertSnappedDuration(200, 2000);
- assertSnappedDuration(250, 2000);
+ assertSnappedDuration(250, 3000);
AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier = 2);
+ assertSnappedDuration(0, 0);
assertSnappedDuration(50, 0);
- assertSnappedDuration(100, 0);
- assertSnappedDuration(150, 0);
+ assertSnappedDuration(100, 1000);
+ assertSnappedDuration(150, 1000);
assertSnappedDuration(200, 1000);
assertSnappedDuration(250, 1000);
@@ -139,8 +141,8 @@ namespace osu.Game.Tests.Editor
});
assertSnappedDuration(50, 0);
- assertSnappedDuration(100, 0);
- assertSnappedDuration(150, 0);
+ assertSnappedDuration(100, 500);
+ assertSnappedDuration(150, 500);
assertSnappedDuration(200, 500);
assertSnappedDuration(250, 500);
assertSnappedDuration(400, 1000);
@@ -149,17 +151,17 @@ namespace osu.Game.Tests.Editor
[Test]
public void GetSnappedDistanceFromDistance()
{
- assertSnappedDistance(50, 0);
+ assertSnappedDistance(50, 100);
assertSnappedDistance(100, 100);
- assertSnappedDistance(150, 100);
+ assertSnappedDistance(150, 200);
assertSnappedDistance(200, 200);
- assertSnappedDistance(250, 200);
+ assertSnappedDistance(250, 300);
AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier = 2);
assertSnappedDistance(50, 0);
- assertSnappedDistance(100, 0);
- assertSnappedDistance(150, 0);
+ assertSnappedDistance(100, 200);
+ assertSnappedDistance(150, 200);
assertSnappedDistance(200, 200);
assertSnappedDistance(250, 200);
@@ -170,8 +172,8 @@ namespace osu.Game.Tests.Editor
});
assertSnappedDistance(50, 0);
- assertSnappedDistance(100, 0);
- assertSnappedDistance(150, 0);
+ assertSnappedDistance(100, 200);
+ assertSnappedDistance(150, 200);
assertSnappedDistance(200, 200);
assertSnappedDistance(250, 200);
assertSnappedDistance(400, 400);
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs
index 847d168e51..f49256a633 100644
--- a/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs
+++ b/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs
@@ -85,64 +85,64 @@ namespace osu.Game.Tests.Visual.Editor
{
}
- protected override void CreateContent(Vector2 startPosition)
+ protected override void CreateContent()
{
AddInternal(new Circle
{
Origin = Anchor.Centre,
Size = new Vector2(5),
- Position = startPosition
+ Position = StartPosition
});
- int beatIndex = 0;
+ int indexFromPlacement = 0;
- for (float s = startPosition.X + DistanceSpacing; s <= DrawWidth && beatIndex < MaxIntervals; s += DistanceSpacing, beatIndex++)
+ for (float s = StartPosition.X + DistanceSpacing; s <= DrawWidth && indexFromPlacement < MaxIntervals; s += DistanceSpacing, indexFromPlacement++)
{
AddInternal(new Circle
{
Origin = Anchor.Centre,
Size = new Vector2(5, 10),
- Position = new Vector2(s, startPosition.Y),
- Colour = GetColourForBeatIndex(beatIndex)
+ Position = new Vector2(s, StartPosition.Y),
+ Colour = GetColourForIndexFromPlacement(indexFromPlacement)
});
}
- beatIndex = 0;
+ indexFromPlacement = 0;
- for (float s = startPosition.X - DistanceSpacing; s >= 0 && beatIndex < MaxIntervals; s -= DistanceSpacing, beatIndex++)
+ for (float s = StartPosition.X - DistanceSpacing; s >= 0 && indexFromPlacement < MaxIntervals; s -= DistanceSpacing, indexFromPlacement++)
{
AddInternal(new Circle
{
Origin = Anchor.Centre,
Size = new Vector2(5, 10),
- Position = new Vector2(s, startPosition.Y),
- Colour = GetColourForBeatIndex(beatIndex)
+ Position = new Vector2(s, StartPosition.Y),
+ Colour = GetColourForIndexFromPlacement(indexFromPlacement)
});
}
- beatIndex = 0;
+ indexFromPlacement = 0;
- for (float s = startPosition.Y + DistanceSpacing; s <= DrawHeight && beatIndex < MaxIntervals; s += DistanceSpacing, beatIndex++)
+ for (float s = StartPosition.Y + DistanceSpacing; s <= DrawHeight && indexFromPlacement < MaxIntervals; s += DistanceSpacing, indexFromPlacement++)
{
AddInternal(new Circle
{
Origin = Anchor.Centre,
Size = new Vector2(10, 5),
- Position = new Vector2(startPosition.X, s),
- Colour = GetColourForBeatIndex(beatIndex)
+ Position = new Vector2(StartPosition.X, s),
+ Colour = GetColourForIndexFromPlacement(indexFromPlacement)
});
}
- beatIndex = 0;
+ indexFromPlacement = 0;
- for (float s = startPosition.Y - DistanceSpacing; s >= 0 && beatIndex < MaxIntervals; s -= DistanceSpacing, beatIndex++)
+ for (float s = StartPosition.Y - DistanceSpacing; s >= 0 && indexFromPlacement < MaxIntervals; s -= DistanceSpacing, indexFromPlacement++)
{
AddInternal(new Circle
{
Origin = Anchor.Centre,
Size = new Vector2(10, 5),
- Position = new Vector2(startPosition.X, s),
- Colour = GetColourForBeatIndex(beatIndex)
+ Position = new Vector2(StartPosition.X, s),
+ Colour = GetColourForIndexFromPlacement(indexFromPlacement)
});
}
}
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs
index e7b2508ac7..3c75fd5310 100644
--- a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs
+++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs
@@ -1,146 +1,15 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System;
-using System.Collections.Generic;
using NUnit.Framework;
-using osu.Framework.Allocation;
-using osu.Framework.Audio;
-using osu.Framework.Bindables;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Shapes;
-using osu.Framework.Timing;
-using osu.Game.Beatmaps;
-using osu.Game.Graphics.UserInterface;
-using osu.Game.Rulesets.Edit;
-using osu.Game.Rulesets.Objects;
-using osu.Game.Screens.Edit;
using osu.Game.Screens.Edit.Compose.Components.Timeline;
-using osuTK;
-using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
- public class TestSceneTimelineBlueprintContainer : EditorClockTestScene
+ public class TestSceneTimelineBlueprintContainer : TimelineTestScene
{
- public override IReadOnlyList RequiredTypes => new[]
- {
- typeof(TimelineArea),
- typeof(Timeline),
- typeof(TimelineButton),
- typeof(CentreMarker)
- };
-
- [BackgroundDependencyLoader]
- private void load(AudioManager audio)
- {
- Beatmap.Value = new WaveformTestBeatmap(audio);
-
- var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap, BeatDivisor);
-
- Dependencies.Cache(editorBeatmap);
- Dependencies.CacheAs(editorBeatmap);
-
- Children = new Drawable[]
- {
- new FillFlowContainer
- {
- AutoSizeAxes = Axes.Both,
- Direction = FillDirection.Vertical,
- Spacing = new Vector2(0, 5),
- Children = new Drawable[]
- {
- new StartStopButton(),
- new AudioVisualiser(),
- }
- },
- new TimelineArea
- {
- Child = new TimelineBlueprintContainer(),
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.X,
- Size = new Vector2(0.8f, 100)
- }
- };
- }
-
- private class AudioVisualiser : CompositeDrawable
- {
- private readonly Drawable marker;
-
- [Resolved]
- private IBindable beatmap { get; set; }
-
- [Resolved]
- private IAdjustableClock adjustableClock { get; set; }
-
- public AudioVisualiser()
- {
- Size = new Vector2(250, 25);
-
- InternalChildren = new[]
- {
- new Box
- {
- RelativeSizeAxes = Axes.Both,
- Alpha = 0.25f,
- },
- marker = new Box
- {
- RelativePositionAxes = Axes.X,
- RelativeSizeAxes = Axes.Y,
- Width = 2,
- }
- };
- }
-
- protected override void Update()
- {
- base.Update();
-
- if (beatmap.Value.Track.IsLoaded)
- marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length);
- }
- }
-
- private class StartStopButton : OsuButton
- {
- private IAdjustableClock adjustableClock;
- private bool started;
-
- public StartStopButton()
- {
- BackgroundColour = Color4.SlateGray;
- Size = new Vector2(100, 50);
- Text = "Start";
-
- Action = onClick;
- }
-
- [BackgroundDependencyLoader]
- private void load(IAdjustableClock adjustableClock)
- {
- this.adjustableClock = adjustableClock;
- }
-
- private void onClick()
- {
- if (started)
- {
- adjustableClock.Stop();
- Text = "Start";
- }
- else
- {
- adjustableClock.Start();
- Text = "Stop";
- }
-
- started = !started;
- }
- }
+ public override Drawable CreateTestComponent() => new TimelineBlueprintContainer();
}
}
diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimelineTickDisplay.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineTickDisplay.cs
new file mode 100644
index 0000000000..43a3cd6122
--- /dev/null
+++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineTickDisplay.cs
@@ -0,0 +1,32 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Game.Screens.Edit.Compose.Components;
+using osu.Game.Screens.Edit.Compose.Components.Timeline;
+using osuTK;
+
+namespace osu.Game.Tests.Visual.Editor
+{
+ [TestFixture]
+ public class TestSceneTimelineTickDisplay : TimelineTestScene
+ {
+ public override Drawable CreateTestComponent() => new TimelineTickDisplay();
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ BeatDivisor.Value = 4;
+
+ Add(new BeatDivisorControl(BeatDivisor)
+ {
+ Anchor = Anchor.TopRight,
+ Origin = Anchor.TopRight,
+ Margin = new MarginPadding(30),
+ Size = new Vector2(90)
+ });
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs
new file mode 100644
index 0000000000..b5e526d3c2
--- /dev/null
+++ b/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs
@@ -0,0 +1,148 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using osu.Framework.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Timing;
+using osu.Game.Beatmaps;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Rulesets.Edit;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Screens.Edit;
+using osu.Game.Screens.Edit.Compose.Components.Timeline;
+using osuTK;
+using osuTK.Graphics;
+
+namespace osu.Game.Tests.Visual.Editor
+{
+ public abstract class TimelineTestScene : EditorClockTestScene
+ {
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(TimelineArea),
+ typeof(Timeline),
+ typeof(TimelineButton),
+ typeof(CentreMarker)
+ };
+
+ protected TimelineArea TimelineArea { get; private set; }
+
+ [BackgroundDependencyLoader]
+ private void load(AudioManager audio)
+ {
+ Beatmap.Value = new WaveformTestBeatmap(audio);
+
+ var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap, BeatDivisor);
+
+ Dependencies.Cache(editorBeatmap);
+ Dependencies.CacheAs(editorBeatmap);
+
+ AddRange(new Drawable[]
+ {
+ new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 5),
+ Children = new Drawable[]
+ {
+ new StartStopButton(),
+ new AudioVisualiser(),
+ }
+ },
+ TimelineArea = new TimelineArea
+ {
+ Child = CreateTestComponent(),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.X,
+ Size = new Vector2(0.8f, 100),
+ }
+ });
+ }
+
+ public abstract Drawable CreateTestComponent();
+
+ private class AudioVisualiser : CompositeDrawable
+ {
+ private readonly Drawable marker;
+
+ [Resolved]
+ private IBindable beatmap { get; set; }
+
+ [Resolved]
+ private IAdjustableClock adjustableClock { get; set; }
+
+ public AudioVisualiser()
+ {
+ Size = new Vector2(250, 25);
+
+ InternalChildren = new[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0.25f,
+ },
+ marker = new Box
+ {
+ RelativePositionAxes = Axes.X,
+ RelativeSizeAxes = Axes.Y,
+ Width = 2,
+ }
+ };
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ if (beatmap.Value.Track.IsLoaded)
+ marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length);
+ }
+ }
+
+ private class StartStopButton : OsuButton
+ {
+ private IAdjustableClock adjustableClock;
+ private bool started;
+
+ public StartStopButton()
+ {
+ BackgroundColour = Color4.SlateGray;
+ Size = new Vector2(100, 50);
+ Text = "Start";
+
+ Action = onClick;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(IAdjustableClock adjustableClock)
+ {
+ this.adjustableClock = adjustableClock;
+ }
+
+ private void onClick()
+ {
+ if (started)
+ {
+ adjustableClock.Stop();
+ Text = "Start";
+ }
+ else
+ {
+ adjustableClock.Start();
+ Text = "Stop";
+ }
+
+ started = !started;
+ }
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs
new file mode 100644
index 0000000000..662d9977ba
--- /dev/null
+++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs
@@ -0,0 +1,122 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Configuration;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Platform;
+using osu.Framework.Screens;
+using osu.Framework.Testing;
+using osu.Game.Beatmaps;
+using osu.Game.Configuration;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Online.API;
+using osu.Game.Overlays;
+using osu.Game.Rulesets;
+using osu.Game.Screens;
+using osu.Game.Screens.Menu;
+using osuTK.Graphics;
+using IntroSequence = osu.Game.Configuration.IntroSequence;
+
+namespace osu.Game.Tests.Visual.Navigation
+{
+ ///
+ /// A scene which tests full game flow.
+ ///
+ public abstract class OsuGameTestScene : ManualInputManagerTestScene
+ {
+ private GameHost host;
+
+ protected TestOsuGame Game;
+
+ [BackgroundDependencyLoader]
+ private void load(GameHost host)
+ {
+ this.host = host;
+
+ Child = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black,
+ };
+ }
+
+ [SetUpSteps]
+ public void SetUpSteps()
+ {
+ AddStep("Create new game instance", () =>
+ {
+ if (Game != null)
+ {
+ Remove(Game);
+ Game.Dispose();
+ }
+
+ RecycleLocalStorage();
+
+ // see MouseSettings
+ var frameworkConfig = host.Dependencies.Get();
+ frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity).Disabled = false;
+
+ Game = new TestOsuGame(LocalStorage, API);
+ Game.SetHost(host);
+
+ // todo: this can be removed once we can run audio tracks without a device present
+ // see https://github.com/ppy/osu/issues/1302
+ Game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles);
+
+ Add(Game);
+ });
+
+ AddUntilStep("Wait for load", () => Game.IsLoaded);
+ AddUntilStep("Wait for intro", () => Game.ScreenStack.CurrentScreen is IntroScreen);
+
+ ConfirmAtMainMenu();
+ }
+
+ protected void ConfirmAtMainMenu() => AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded);
+
+ public class TestOsuGame : OsuGame
+ {
+ public new ScreenStack ScreenStack => base.ScreenStack;
+
+ public new BackButton BackButton => base.BackButton;
+
+ public new BeatmapManager BeatmapManager => base.BeatmapManager;
+
+ public new SettingsPanel Settings => base.Settings;
+
+ public new OsuConfigManager LocalConfig => base.LocalConfig;
+
+ public new Bindable Beatmap => base.Beatmap;
+
+ public new Bindable Ruleset => base.Ruleset;
+
+ protected override Loader CreateLoader() => new TestLoader();
+
+ public TestOsuGame(Storage storage, IAPIProvider api)
+ {
+ Storage = storage;
+ API = api;
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+ API.Login("Rhythm Champion", "osu!");
+ }
+ }
+
+ public class TestLoader : Loader
+ {
+ protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler();
+
+ private class TestShaderPrecompiler : ShaderPrecompiler
+ {
+ protected override bool AllLoaded => true;
+ }
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs
new file mode 100644
index 0000000000..909409835c
--- /dev/null
+++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs
@@ -0,0 +1,110 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// 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.Screens;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets;
+using osu.Game.Rulesets.Mania;
+using osu.Game.Rulesets.Osu;
+using osu.Game.Screens.Menu;
+
+namespace osu.Game.Tests.Visual.Navigation
+{
+ public class TestScenePresentBeatmap : OsuGameTestScene
+ {
+ [Test]
+ public void TestFromMainMenu()
+ {
+ var firstImport = importBeatmap(1);
+ presentAndConfirm(firstImport);
+
+ AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit());
+ AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
+
+ var secondimport = importBeatmap(2);
+ presentAndConfirm(secondimport);
+ }
+
+ [Test]
+ public void TestFromMainMenuDifferentRuleset()
+ {
+ var firstImport = importBeatmap(1);
+ presentAndConfirm(firstImport);
+
+ AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit());
+ AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
+
+ var secondimport = importBeatmap(2, new ManiaRuleset().RulesetInfo);
+ presentAndConfirm(secondimport);
+ }
+
+ [Test]
+ public void TestFromSongSelect()
+ {
+ var firstImport = importBeatmap(1);
+ presentAndConfirm(firstImport);
+
+ var secondimport = importBeatmap(2);
+ presentAndConfirm(secondimport);
+ }
+
+ [Test]
+ public void TestFromSongSelectDifferentRuleset()
+ {
+ var firstImport = importBeatmap(1);
+ presentAndConfirm(firstImport);
+
+ var secondimport = importBeatmap(2, new ManiaRuleset().RulesetInfo);
+ presentAndConfirm(secondimport);
+ }
+
+ private Func importBeatmap(int i, RulesetInfo ruleset = null)
+ {
+ BeatmapSetInfo imported = null;
+ AddStep($"import beatmap {i}", () =>
+ {
+ var difficulty = new BeatmapDifficulty();
+ var metadata = new BeatmapMetadata
+ {
+ Artist = "SomeArtist",
+ AuthorString = "SomeAuthor",
+ Title = $"import {i}"
+ };
+
+ imported = Game.BeatmapManager.Import(new BeatmapSetInfo
+ {
+ Hash = Guid.NewGuid().ToString(),
+ OnlineBeatmapSetID = i,
+ Metadata = metadata,
+ Beatmaps = new List
+ {
+ new BeatmapInfo
+ {
+ OnlineBeatmapID = i * 1024,
+ Metadata = metadata,
+ BaseDifficulty = difficulty,
+ Ruleset = ruleset ?? new OsuRuleset().RulesetInfo
+ },
+ }
+ }).Result;
+ });
+
+ AddAssert($"import {i} succeeded", () => imported != null);
+
+ return () => imported;
+ }
+
+ private void presentAndConfirm(Func getImport)
+ {
+ AddStep("present beatmap", () => Game.PresentBeatmap(getImport()));
+
+ AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect);
+ AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapSetInfo.ID == getImport().ID);
+ AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Beatmaps.First().Ruleset.ID);
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
similarity index 56%
rename from osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs
rename to osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
index 471f67b7b6..d706d47384 100644
--- a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
@@ -6,78 +6,26 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
-using osu.Framework.Bindables;
-using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Shapes;
-using osu.Framework.Platform;
using osu.Framework.Screens;
-using osu.Framework.Testing;
using osu.Game.Beatmaps;
-using osu.Game.Configuration;
-using osu.Game.Graphics.UserInterface;
-using osu.Game.Online.API;
using osu.Game.Overlays;
using osu.Game.Overlays.Mods;
-using osu.Game.Screens;
-using osu.Game.Screens.Menu;
using osu.Game.Screens.Play;
using osu.Game.Screens.Select;
using osu.Game.Tests.Beatmaps.IO;
using osuTK;
-using osuTK.Graphics;
using osuTK.Input;
-using IntroSequence = osu.Game.Configuration.IntroSequence;
-namespace osu.Game.Tests.Visual.Menus
+namespace osu.Game.Tests.Visual.Navigation
{
- public class TestSceneScreenNavigation : ManualInputManagerTestScene
+ public class TestSceneScreenNavigation : OsuGameTestScene
{
private const float click_padding = 25;
- private GameHost host;
- private TestOsuGame game;
+ private Vector2 backButtonPosition => Game.ToScreenSpace(new Vector2(click_padding, Game.LayoutRectangle.Bottom - click_padding));
- private Vector2 backButtonPosition => game.ToScreenSpace(new Vector2(click_padding, game.LayoutRectangle.Bottom - click_padding));
-
- private Vector2 optionsButtonPosition => game.ToScreenSpace(new Vector2(click_padding, click_padding));
-
- [BackgroundDependencyLoader]
- private void load(GameHost host)
- {
- this.host = host;
-
- Child = new Box
- {
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.Black,
- };
- }
-
- [SetUpSteps]
- public void SetUpSteps()
- {
- AddStep("Create new game instance", () =>
- {
- if (game != null)
- {
- Remove(game);
- game.Dispose();
- }
-
- game = new TestOsuGame(LocalStorage, API);
- game.SetHost(host);
-
- // todo: this can be removed once we can run audio trakcs without a device present
- // see https://github.com/ppy/osu/issues/1302
- game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles);
-
- Add(game);
- });
- AddUntilStep("Wait for load", () => game.IsLoaded);
- AddUntilStep("Wait for intro", () => game.ScreenStack.CurrentScreen is IntroScreen);
- confirmAtMainMenu();
- }
+ private Vector2 optionsButtonPosition => Game.ToScreenSpace(new Vector2(click_padding, click_padding));
[Test]
public void TestExitSongSelectWithEscape()
@@ -98,21 +46,21 @@ namespace osu.Game.Tests.Visual.Menus
{
Player player = null;
- WorkingBeatmap beatmap() => game.Beatmap.Value;
+ WorkingBeatmap beatmap() => Game.Beatmap.Value;
Track track() => beatmap().Track;
pushAndConfirm(() => new TestSongSelect());
- AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Wait());
+ AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
- AddUntilStep("wait for selected", () => !game.Beatmap.IsDefault);
+ AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
if (withUserPause)
- AddStep("pause", () => game.Dependencies.Get().Stop());
+ AddStep("pause", () => Game.Dependencies.Get().Stop());
AddStep("press enter", () => pressAndRelease(Key.Enter));
- AddUntilStep("wait for player", () => (player = game.ScreenStack.CurrentScreen as Player) != null);
+ AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null);
AddUntilStep("wait for fail", () => player.HasFailed);
AddUntilStep("wait for track stop", () => !track().IsRunning);
@@ -135,7 +83,7 @@ namespace osu.Game.Tests.Visual.Menus
AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition));
// BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered.
- AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == game.BackButton));
+ AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == Game.BackButton));
AddStep("Click back button", () => InputManager.Click(MouseButton.Left));
AddUntilStep("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden);
@@ -159,20 +107,20 @@ namespace osu.Game.Tests.Visual.Menus
[Test]
public void TestOpenOptionsAndExitWithEscape()
{
- AddUntilStep("Wait for options to load", () => game.Settings.IsLoaded);
+ AddUntilStep("Wait for options to load", () => Game.Settings.IsLoaded);
AddStep("Enter menu", () => pressAndRelease(Key.Enter));
AddStep("Move mouse to options overlay", () => InputManager.MoveMouseTo(optionsButtonPosition));
AddStep("Click options overlay", () => InputManager.Click(MouseButton.Left));
- AddAssert("Options overlay was opened", () => game.Settings.State.Value == Visibility.Visible);
+ AddAssert("Options overlay was opened", () => Game.Settings.State.Value == Visibility.Visible);
AddStep("Hide options overlay using escape", () => pressAndRelease(Key.Escape));
- AddAssert("Options overlay was closed", () => game.Settings.State.Value == Visibility.Hidden);
+ AddAssert("Options overlay was closed", () => Game.Settings.State.Value == Visibility.Hidden);
}
private void pushAndConfirm(Func newScreen)
{
Screen screen = null;
- AddStep("Push new screen", () => game.ScreenStack.Push(screen = newScreen()));
- AddUntilStep("Wait for new screen", () => game.ScreenStack.CurrentScreen == screen && screen.IsLoaded);
+ AddStep("Push new screen", () => Game.ScreenStack.Push(screen = newScreen()));
+ AddUntilStep("Wait for new screen", () => Game.ScreenStack.CurrentScreen == screen && screen.IsLoaded);
}
private void pushEscape() =>
@@ -181,64 +129,25 @@ namespace osu.Game.Tests.Visual.Menus
private void exitViaEscapeAndConfirm()
{
pushEscape();
- confirmAtMainMenu();
+ ConfirmAtMainMenu();
}
private void exitViaBackButtonAndConfirm()
{
AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition));
AddStep("Click back button", () => InputManager.Click(MouseButton.Left));
- confirmAtMainMenu();
+ ConfirmAtMainMenu();
}
- private void confirmAtMainMenu() => AddUntilStep("Wait for main menu", () => game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded);
-
private void pressAndRelease(Key key)
{
InputManager.PressKey(key);
InputManager.ReleaseKey(key);
}
- private class TestOsuGame : OsuGame
- {
- public new ScreenStack ScreenStack => base.ScreenStack;
-
- public new BackButton BackButton => base.BackButton;
-
- public new SettingsPanel Settings => base.Settings;
-
- public new OsuConfigManager LocalConfig => base.LocalConfig;
-
- public new Bindable Beatmap => base.Beatmap;
-
- protected override Loader CreateLoader() => new TestLoader();
-
- public TestOsuGame(Storage storage, IAPIProvider api)
- {
- Storage = storage;
- API = api;
- }
-
- protected override void LoadComplete()
- {
- base.LoadComplete();
- API.Login("Rhythm Champion", "osu!");
- }
- }
-
private class TestSongSelect : PlaySongSelect
{
public ModSelectOverlay ModSelectOverlay => ModSelect;
}
-
- private class TestLoader : Loader
- {
- protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler();
-
- private class TestShaderPrecompiler : ShaderPrecompiler
- {
- protected override bool AllLoaded => true;
- }
- }
}
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs
index 658f678b10..7a8570c09b 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs
@@ -13,7 +13,7 @@ namespace osu.Game.Tests.Visual.Online
[TestFixture]
public class TestSceneChangelogOverlay : OsuTestScene
{
- private ChangelogOverlay changelog;
+ private TestChangelogOverlay changelog;
public override IReadOnlyList RequiredTypes => new[]
{
@@ -29,23 +29,40 @@ namespace osu.Game.Tests.Visual.Online
protected override bool UseOnlineAPI => true;
- protected override void LoadComplete()
+ [SetUp]
+ public void SetUp() => Schedule(() =>
{
- base.LoadComplete();
+ Child = changelog = new TestChangelogOverlay();
+ });
- Add(changelog = new ChangelogOverlay());
- AddStep(@"Show", changelog.Show);
- AddStep(@"Hide", changelog.Hide);
+ [Test]
+ public void ShowWithNoFetch()
+ {
+ AddStep(@"Show", () => changelog.Show());
+ AddUntilStep(@"wait for streams", () => changelog.Streams?.Count > 0);
+ AddAssert(@"listing displayed", () => changelog.Current.Value == null);
+ AddAssert(@"no stream selected", () => changelog.Header.Streams.Current.Value == null);
+ }
- AddWaitStep("wait for hide", 3);
+ [Test]
+ public void ShowWithListing()
+ {
+ AddStep(@"Show with listing", () => changelog.ShowListing());
+ AddUntilStep(@"wait for streams", () => changelog.Streams?.Count > 0);
+ AddAssert(@"listing displayed", () => changelog.Current.Value == null);
+ AddAssert(@"no stream selected", () => changelog.Header.Streams.Current.Value == null);
+ }
+ [Test]
+ public void ShowWithBuild()
+ {
AddStep(@"Show with Lazer 2018.712.0", () =>
{
changelog.ShowBuild(new APIChangelogBuild
{
Version = "2018.712.0",
DisplayVersion = "2018.712.0",
- UpdateStream = new APIUpdateStream { Name = OsuGameBase.CLIENT_STREAM_NAME },
+ UpdateStream = new APIUpdateStream { Id = 7, Name = OsuGameBase.CLIENT_STREAM_NAME },
ChangelogEntries = new List
{
new APIChangelogEntry
@@ -56,19 +73,16 @@ namespace osu.Game.Tests.Visual.Online
}
}
});
- changelog.Show();
});
- AddWaitStep("wait for show", 3);
- AddStep(@"Hide", changelog.Hide);
- AddWaitStep("wait for hide", 3);
-
- AddStep(@"Show with listing", () =>
- {
- changelog.ShowListing();
- changelog.Show();
- });
+ AddUntilStep(@"wait for streams", () => changelog.Streams?.Count > 0);
+ AddAssert(@"correct build displayed", () => changelog.Current.Value.Version == "2018.712.0");
+ AddAssert(@"correct stream selected", () => changelog.Header.Streams.Current.Value.Id == 7);
+ }
+ [Test]
+ public void TestHTMLUnescaping()
+ {
AddStep(@"Ensure HTML string unescaping", () =>
{
changelog.ShowBuild(new APIChangelogBuild
@@ -97,5 +111,12 @@ namespace osu.Game.Tests.Visual.Online
});
});
}
+
+ private class TestChangelogOverlay : ChangelogOverlay
+ {
+ public new List Streams => base.Streams;
+
+ public new ChangelogHeader Header => base.Header;
+ }
}
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs
index 8134c10750..3deb9cb1fa 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs
@@ -8,6 +8,8 @@ using osu.Game.Online.API.Requests;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Game.Overlays.Comments;
+using osu.Game.Overlays;
+using osu.Framework.Allocation;
namespace osu.Game.Tests.Visual.Online
{
@@ -22,12 +24,15 @@ namespace osu.Game.Tests.Visual.Online
typeof(HeaderButton),
typeof(SortTabControl),
typeof(ShowChildrenButton),
- typeof(DeletedChildrenPlaceholder),
+ typeof(DeletedCommentsCounter),
typeof(VotePill)
};
protected override bool UseOnlineAPI => true;
+ [Cached]
+ private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
+
public TestSceneCommentsContainer()
{
BasicScrollContainer scroll;
diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs
index bc3e0eff1a..a60f220e4b 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs
@@ -4,7 +4,9 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
+using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Game.Overlays;
using osu.Game.Overlays.Comments;
namespace osu.Game.Tests.Visual.Online
@@ -19,6 +21,9 @@ namespace osu.Game.Tests.Visual.Online
typeof(SortTabControl),
};
+ [Cached]
+ private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
+
private readonly Bindable sort = new Bindable();
private readonly BindableBool showDeleted = new BindableBool();
diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs
index d3b037f499..1b7a2160d0 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs
@@ -4,10 +4,12 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
+using osu.Game.Overlays;
using osu.Game.Overlays.Profile.Sections;
using osu.Game.Overlays.Profile.Sections.Historical;
using osu.Game.Users;
@@ -27,6 +29,9 @@ namespace osu.Game.Tests.Visual.Online
typeof(DrawableProfileRow)
};
+ [Cached]
+ private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink);
+
public TestSceneHistoricalSection()
{
HistoricalSection section;
diff --git a/osu.Game.Tests/Visual/Online/TestSceneTotalCommentsCounter.cs b/osu.Game.Tests/Visual/Online/TestSceneTotalCommentsCounter.cs
index f14c75084f..8ecbf0891b 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneTotalCommentsCounter.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneTotalCommentsCounter.cs
@@ -7,6 +7,8 @@ using osu.Framework.Graphics;
using osu.Framework.Bindables;
using osu.Game.Overlays.Comments;
using osu.Framework.Utils;
+using osu.Framework.Allocation;
+using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.Online
{
@@ -17,6 +19,9 @@ namespace osu.Game.Tests.Visual.Online
typeof(TotalCommentsCounter),
};
+ [Cached]
+ private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
+
public TestSceneTotalCommentsCounter()
{
var count = new BindableInt();
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
index f825e4f1e9..523de4e38f 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs
@@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online
typeof(ProfileHeader),
typeof(RankGraph),
typeof(LineGraph),
- typeof(TabControlOverlayHeader.OverlayHeaderTabControl),
+ typeof(TabControlOverlayHeader<>.OverlayHeaderTabControl),
typeof(CentreHeaderContainer),
typeof(BottomHeaderContainer),
typeof(DetailHeaderContainer),
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs
new file mode 100644
index 0000000000..19b72e7071
--- /dev/null
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs
@@ -0,0 +1,101 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using osu.Game.Overlays.Profile.Sections;
+using osu.Game.Overlays.Profile.Sections.Ranks;
+using osu.Framework.Graphics;
+using osu.Game.Scoring;
+using osu.Framework.Graphics.Containers;
+using osuTK;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Osu.Mods;
+using osu.Game.Overlays;
+using osu.Framework.Allocation;
+
+namespace osu.Game.Tests.Visual.Online
+{
+ public class TestSceneUserProfileScores : OsuTestScene
+ {
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(DrawableProfileScore),
+ typeof(DrawableProfileWeightedScore),
+ typeof(ProfileItemContainer),
+ };
+
+ public TestSceneUserProfileScores()
+ {
+ var score = new ScoreInfo
+ {
+ PP = 134.32,
+ Rank = ScoreRank.A,
+ Beatmap = new BeatmapInfo
+ {
+ Metadata = new BeatmapMetadata
+ {
+ Title = "Triumph & Regret",
+ Artist = "typeMARS"
+ },
+ Version = "[4K] Regret"
+ },
+ Date = DateTimeOffset.Now,
+ Mods = new Mod[]
+ {
+ new OsuModHardRock(),
+ new OsuModDoubleTime(),
+ },
+ Accuracy = 0.998546
+ };
+
+ var noPPScore = new ScoreInfo
+ {
+ Rank = ScoreRank.B,
+ Beatmap = new BeatmapInfo
+ {
+ Metadata = new BeatmapMetadata
+ {
+ Title = "C18H27NO3(extend)",
+ Artist = "Team Grimoire"
+ },
+ Version = "[4K] Cataclysmic Hypernova"
+ },
+ Date = DateTimeOffset.Now,
+ Accuracy = 0.55879
+ };
+
+ Add(new FillFlowContainer
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 10),
+ Children = new[]
+ {
+ new ColourProvidedContainer(OverlayColourScheme.Green, new DrawableProfileScore(score)),
+ new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileScore(noPPScore)),
+ new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileWeightedScore(score, 0.85))
+ }
+ });
+ }
+
+ private class ColourProvidedContainer : Container
+ {
+ [Cached]
+ private readonly OverlayColourProvider colourProvider;
+
+ public ColourProvidedContainer(OverlayColourScheme colourScheme, DrawableProfileScore score)
+ {
+ colourProvider = new OverlayColourProvider(colourScheme);
+
+ AutoSizeAxes = Axes.Y;
+ RelativeSizeAxes = Axes.X;
+ Add(score);
+ }
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs
index 2951f6b63e..c8e94b2915 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs
@@ -4,11 +4,13 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
+using osu.Game.Overlays;
using osu.Game.Overlays.Profile.Sections;
using osu.Game.Overlays.Profile.Sections.Ranks;
using osu.Game.Users;
@@ -20,7 +22,15 @@ namespace osu.Game.Tests.Visual.Online
{
protected override bool UseOnlineAPI => true;
- public override IReadOnlyList RequiredTypes => new[] { typeof(DrawableProfileScore), typeof(RanksSection) };
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(DrawableProfileScore),
+ typeof(DrawableProfileWeightedScore),
+ typeof(RanksSection)
+ };
+
+ [Cached]
+ private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
public TestSceneUserRanks()
{
diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
index eb812f5d5a..fc06780431 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
@@ -14,6 +14,7 @@ using osu.Framework.Extensions;
using osu.Framework.Utils;
using osu.Framework.Platform;
using osu.Framework.Screens;
+using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Overlays;
@@ -25,6 +26,7 @@ using osu.Game.Rulesets.Taiko;
using osu.Game.Screens.Select;
using osu.Game.Screens.Select.Carousel;
using osu.Game.Screens.Select.Filter;
+using osuTK.Input;
namespace osu.Game.Tests.Visual.SongSelect
{
@@ -95,6 +97,127 @@ namespace osu.Game.Tests.Visual.SongSelect
AddAssert("filter count is 1", () => songSelect.FilterCount == 1);
}
+ [Test]
+ public void TestChangeBeatmapBeforeEnter()
+ {
+ addRulesetImportStep(0);
+
+ createSongSelect();
+
+ AddUntilStep("wait for initial selection", () => !Beatmap.IsDefault);
+
+ WorkingBeatmap selected = null;
+
+ AddStep("store selected beatmap", () => selected = Beatmap.Value);
+
+ AddStep("select next and enter", () =>
+ {
+ InputManager.PressKey(Key.Down);
+ InputManager.ReleaseKey(Key.Down);
+ InputManager.PressKey(Key.Enter);
+ InputManager.ReleaseKey(Key.Enter);
+ });
+
+ AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
+ AddAssert("ensure selection changed", () => selected != Beatmap.Value);
+
+ AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen());
+ AddUntilStep("bindable lease returned", () => !Beatmap.Disabled);
+ }
+
+ [Test]
+ public void TestChangeBeatmapAfterEnter()
+ {
+ addRulesetImportStep(0);
+
+ createSongSelect();
+
+ AddUntilStep("wait for initial selection", () => !Beatmap.IsDefault);
+
+ WorkingBeatmap selected = null;
+
+ AddStep("store selected beatmap", () => selected = Beatmap.Value);
+
+ AddStep("select next and enter", () =>
+ {
+ InputManager.PressKey(Key.Enter);
+ InputManager.ReleaseKey(Key.Enter);
+ InputManager.PressKey(Key.Down);
+ InputManager.ReleaseKey(Key.Down);
+ });
+
+ AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
+ AddAssert("ensure selection didn't change", () => selected == Beatmap.Value);
+
+ AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen());
+ AddUntilStep("bindable lease returned", () => !Beatmap.Disabled);
+ }
+
+ [Test]
+ public void TestChangeBeatmapViaMouseBeforeEnter()
+ {
+ addRulesetImportStep(0);
+
+ createSongSelect();
+
+ AddUntilStep("wait for initial selection", () => !Beatmap.IsDefault);
+
+ WorkingBeatmap selected = null;
+
+ AddStep("store selected beatmap", () => selected = Beatmap.Value);
+
+ AddStep("select next and enter", () =>
+ {
+ InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType()
+ .First(b => ((CarouselBeatmap)b.Item).Beatmap != songSelect.Carousel.SelectedBeatmap));
+
+ InputManager.PressButton(MouseButton.Left);
+ InputManager.ReleaseButton(MouseButton.Left);
+
+ InputManager.PressKey(Key.Enter);
+ InputManager.ReleaseKey(Key.Enter);
+ });
+
+ AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
+ AddAssert("ensure selection changed", () => selected != Beatmap.Value);
+
+ AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen());
+ AddUntilStep("bindable lease returned", () => !Beatmap.Disabled);
+ }
+
+ [Test]
+ public void TestChangeBeatmapViaMouseAfterEnter()
+ {
+ addRulesetImportStep(0);
+
+ createSongSelect();
+
+ AddUntilStep("wait for initial selection", () => !Beatmap.IsDefault);
+
+ WorkingBeatmap selected = null;
+
+ AddStep("store selected beatmap", () => selected = Beatmap.Value);
+
+ AddStep("select next and enter", () =>
+ {
+ InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType()
+ .First(b => ((CarouselBeatmap)b.Item).Beatmap != songSelect.Carousel.SelectedBeatmap));
+
+ InputManager.PressButton(MouseButton.Left);
+
+ InputManager.PressKey(Key.Enter);
+ InputManager.ReleaseKey(Key.Enter);
+
+ InputManager.ReleaseButton(MouseButton.Left);
+ });
+
+ AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen());
+ AddAssert("ensure selection didn't change", () => selected == Beatmap.Value);
+
+ AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen());
+ AddUntilStep("bindable lease returned", () => !Beatmap.Disabled);
+ }
+
[Test]
public void TestNoFilterOnSimpleResume()
{
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs
index 19eebc89b6..3967b62c95 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBreadcrumbControl.cs
@@ -1,9 +1,11 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
@@ -12,11 +14,11 @@ namespace osu.Game.Tests.Visual.UserInterface
[TestFixture]
public class TestSceneBreadcrumbControl : OsuTestScene
{
- private readonly BreadcrumbControl breadcrumbs;
+ private readonly TestBreadcrumbControl breadcrumbs;
public TestSceneBreadcrumbControl()
{
- Add(breadcrumbs = new BreadcrumbControl
+ Add(breadcrumbs = new TestBreadcrumbControl
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -25,8 +27,13 @@ namespace osu.Game.Tests.Visual.UserInterface
});
AddStep(@"first", () => breadcrumbs.Current.Value = BreadcrumbTab.Click);
+ assertVisible(1);
+
AddStep(@"second", () => breadcrumbs.Current.Value = BreadcrumbTab.The);
+ assertVisible(2);
+
AddStep(@"third", () => breadcrumbs.Current.Value = BreadcrumbTab.Circles);
+ assertVisible(3);
}
[BackgroundDependencyLoader]
@@ -35,11 +42,27 @@ namespace osu.Game.Tests.Visual.UserInterface
breadcrumbs.StripColour = colours.Blue;
}
+ private void assertVisible(int count) => AddAssert($"first {count} item(s) visible", () =>
+ {
+ for (int i = 0; i < count; i++)
+ {
+ if (breadcrumbs.GetDrawable((BreadcrumbTab)i).State != Visibility.Visible)
+ return false;
+ }
+
+ return true;
+ });
+
private enum BreadcrumbTab
{
Click,
The,
Circles,
}
+
+ private class TestBreadcrumbControl : BreadcrumbControl
+ {
+ public BreadcrumbTabItem GetDrawable(BreadcrumbTab tab) => (BreadcrumbTabItem)TabContainer.First(t => t.Value == tab);
+ }
}
}
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs
index 6eb621ca3b..63197ed26a 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs
@@ -16,7 +16,8 @@ namespace osu.Game.Tests.Visual.UserInterface
{
public override IReadOnlyList RequiredTypes => new[]
{
- typeof(FooterButtonMods)
+ typeof(FooterButtonMods),
+ typeof(FooterButton)
};
private readonly TestFooterButtonMods footerButtonMods;
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs
new file mode 100644
index 0000000000..c899ccb9eb
--- /dev/null
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs
@@ -0,0 +1,163 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics.Containers;
+using osu.Game.Overlays;
+using System;
+using System.Collections.Generic;
+using osu.Framework.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Framework.Allocation;
+using osu.Game.Graphics.UserInterface;
+using osu.Framework.Graphics.Shapes;
+using osuTK.Graphics;
+
+namespace osu.Game.Tests.Visual.UserInterface
+{
+ public class TestSceneOverlayHeader : OsuTestScene
+ {
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(OverlayHeader),
+ typeof(TabControlOverlayHeader<>),
+ typeof(BreadcrumbControlOverlayHeader),
+ typeof(TestNoControlHeader),
+ typeof(TestStringTabControlHeader),
+ typeof(TestEnumTabControlHeader),
+ typeof(TestBreadcrumbControlHeader),
+ typeof(OverlayHeaderBackground)
+ };
+
+ private readonly FillFlowContainer flow;
+
+ public TestSceneOverlayHeader()
+ {
+ AddRange(new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black,
+ },
+ new BasicScrollContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Child = flow = new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Y,
+ RelativeSizeAxes = Axes.X,
+ Direction = FillDirection.Vertical
+ }
+ }
+ });
+
+ addHeader("Orange OverlayHeader (no background)", new TestNoBackgroundHeader(), OverlayColourScheme.Orange);
+ addHeader("Blue OverlayHeader", new TestNoControlHeader(), OverlayColourScheme.Blue);
+ addHeader("Green TabControlOverlayHeader (string)", new TestStringTabControlHeader(), OverlayColourScheme.Green);
+ addHeader("Pink TabControlOverlayHeader (enum)", new TestEnumTabControlHeader(), OverlayColourScheme.Pink);
+ addHeader("Red BreadcrumbControlOverlayHeader (no background)", new TestBreadcrumbControlHeader(), OverlayColourScheme.Red);
+ }
+
+ private void addHeader(string name, OverlayHeader header, OverlayColourScheme colourScheme)
+ {
+ flow.Add(new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Y,
+ RelativeSizeAxes = Axes.X,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Margin = new MarginPadding(20),
+ Text = name,
+ },
+ new ColourProvidedContainer(colourScheme, header)
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ }
+ }
+ });
+ }
+
+ private class ColourProvidedContainer : Container
+ {
+ [Cached]
+ private readonly OverlayColourProvider colourProvider;
+
+ public ColourProvidedContainer(OverlayColourScheme colourScheme, OverlayHeader header)
+ {
+ colourProvider = new OverlayColourProvider(colourScheme);
+
+ AutoSizeAxes = Axes.Y;
+ RelativeSizeAxes = Axes.X;
+ Add(header);
+ }
+ }
+
+ private class TestNoBackgroundHeader : OverlayHeader
+ {
+ protected override ScreenTitle CreateTitle() => new TestTitle();
+ }
+
+ private class TestNoControlHeader : OverlayHeader
+ {
+ protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/changelog");
+
+ protected override ScreenTitle CreateTitle() => new TestTitle();
+ }
+
+ private class TestStringTabControlHeader : TabControlOverlayHeader
+ {
+ protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/news");
+
+ protected override ScreenTitle CreateTitle() => new TestTitle();
+
+ public TestStringTabControlHeader()
+ {
+ TabControl.AddItem("tab1");
+ TabControl.AddItem("tab2");
+ }
+ }
+
+ private class TestEnumTabControlHeader : TabControlOverlayHeader
+ {
+ protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/rankings");
+
+ protected override ScreenTitle CreateTitle() => new TestTitle();
+ }
+
+ private enum TestEnum
+ {
+ Some,
+ Cool,
+ Tabs
+ }
+
+ private class TestBreadcrumbControlHeader : BreadcrumbControlOverlayHeader
+ {
+ protected override ScreenTitle CreateTitle() => new TestTitle();
+
+ public TestBreadcrumbControlHeader()
+ {
+ TabControl.AddItem("tab1");
+ TabControl.AddItem("tab2");
+ TabControl.Current.Value = "tab2";
+ }
+ }
+
+ private class TestTitle : ScreenTitle
+ {
+ public TestTitle()
+ {
+ Title = "title";
+ Section = "section";
+ }
+
+ protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog");
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaderBackground.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaderBackground.cs
new file mode 100644
index 0000000000..5a0b28e24a
--- /dev/null
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeaderBackground.cs
@@ -0,0 +1,42 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics.Containers;
+using osu.Game.Overlays;
+using System;
+using System.Collections.Generic;
+using osu.Framework.Graphics;
+using osuTK;
+
+namespace osu.Game.Tests.Visual.UserInterface
+{
+ public class TestSceneOverlayHeaderBackground : OsuTestScene
+ {
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(OverlayHeaderBackground)
+ };
+
+ public TestSceneOverlayHeaderBackground()
+ {
+ Add(new BasicScrollContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Child = new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Y,
+ RelativeSizeAxes = Axes.X,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 20),
+ Children = new[]
+ {
+ new OverlayHeaderBackground(@"Headers/changelog"),
+ new OverlayHeaderBackground(@"Headers/news"),
+ new OverlayHeaderBackground(@"Headers/rankings"),
+ new OverlayHeaderBackground(@"Headers/search"),
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs
index 533f02af7b..925c7981e0 100644
--- a/osu.Game/Graphics/DrawableDate.cs
+++ b/osu.Game/Graphics/DrawableDate.cs
@@ -29,9 +29,9 @@ namespace osu.Game.Graphics
}
}
- public DrawableDate(DateTimeOffset date)
+ public DrawableDate(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE)
{
- Font = OsuFont.GetFont(weight: FontWeight.Regular, italics: true);
+ Font = OsuFont.GetFont(weight: FontWeight.Regular, size: textSize, italics: true);
Date = date;
}
diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs
index 7f20c30048..3ad36577b5 100644
--- a/osu.Game/Graphics/ScreenshotManager.cs
+++ b/osu.Game/Graphics/ScreenshotManager.cs
@@ -90,7 +90,7 @@ namespace osu.Game.Graphics
{
ScheduledDelegate waitDelegate = host.DrawThread.Scheduler.AddDelayed(() =>
{
- if (framesWaited++ < frames_to_wait)
+ if (framesWaited++ >= frames_to_wait)
// ReSharper disable once AccessToDisposedClosure
framesWaitedEvent.Set();
}, 10, true);
diff --git a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs
index e2438cc4cd..84429bf5bd 100644
--- a/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs
+++ b/osu.Game/Graphics/UserInterface/BreadcrumbControl.cs
@@ -34,13 +34,13 @@ namespace osu.Game.Graphics.UserInterface
var tIndex = TabContainer.IndexOf(t);
var tabIndex = TabContainer.IndexOf(TabMap[index.NewValue]);
- t.State = tIndex < tabIndex ? Visibility.Hidden : Visibility.Visible;
- t.Chevron.FadeTo(tIndex <= tabIndex ? 0f : 1f, 500, Easing.OutQuint);
+ t.State = tIndex > tabIndex ? Visibility.Hidden : Visibility.Visible;
+ t.Chevron.FadeTo(tIndex >= tabIndex ? 0f : 1f, 500, Easing.OutQuint);
}
};
}
- protected class BreadcrumbTabItem : OsuTabItem, IStateful
+ public class BreadcrumbTabItem : OsuTabItem, IStateful
{
protected virtual float ChevronSize => 10;
diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
index 2112aac6a3..d0356e77c7 100644
--- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
+++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs
@@ -36,6 +36,11 @@ namespace osu.Game.Graphics.UserInterface
public virtual string TooltipText { get; private set; }
+ ///
+ /// Whether to format the tooltip as a percentage or the actual value.
+ ///
+ public bool DisplayAsPercentage { get; set; }
+
private Color4 accentColour;
public Color4 AccentColour
@@ -169,11 +174,11 @@ namespace osu.Game.Graphics.UserInterface
else
{
double floatValue = value.ToDouble(NumberFormatInfo.InvariantInfo);
- double floatMinValue = CurrentNumber.MinValue.ToDouble(NumberFormatInfo.InvariantInfo);
- double floatMaxValue = CurrentNumber.MaxValue.ToDouble(NumberFormatInfo.InvariantInfo);
- if (floatMaxValue == 1 && floatMinValue >= -1)
- TooltipText = floatValue.ToString("P0");
+ if (DisplayAsPercentage)
+ {
+ TooltipText = floatValue.ToString("0%");
+ }
else
{
var decimalPrecision = normalise(CurrentNumber.Precision.ToDecimal(NumberFormatInfo.InvariantInfo), max_decimal_digits);
diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs
index 1bfbee4a60..9fa6085035 100644
--- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs
+++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs
@@ -21,6 +21,22 @@ namespace osu.Game.Graphics.UserInterface
{
public class OsuTabControl : TabControl
{
+ private Color4 accentColour;
+
+ public virtual Color4 AccentColour
+ {
+ get => accentColour;
+ set
+ {
+ accentColour = value;
+
+ if (Dropdown is IHasAccentColour dropdown)
+ dropdown.AccentColour = value;
+ foreach (var i in TabContainer.Children.OfType())
+ i.AccentColour = value;
+ }
+ }
+
private readonly Box strip;
protected override Dropdown CreateDropdown() => new OsuTabDropdown();
@@ -62,21 +78,6 @@ namespace osu.Game.Graphics.UserInterface
AccentColour = colours.Blue;
}
- private Color4 accentColour;
-
- public Color4 AccentColour
- {
- get => accentColour;
- set
- {
- accentColour = value;
- if (Dropdown is IHasAccentColour dropdown)
- dropdown.AccentColour = value;
- foreach (var i in TabContainer.Children.OfType())
- i.AccentColour = value;
- }
- }
-
public Color4 StripColour
{
get => strip.Colour;
diff --git a/osu.Game/IO/Legacy/SerializationWriter.cs b/osu.Game/IO/Legacy/SerializationWriter.cs
index c75de93bc8..bb8014fe54 100644
--- a/osu.Game/IO/Legacy/SerializationWriter.cs
+++ b/osu.Game/IO/Legacy/SerializationWriter.cs
@@ -130,91 +130,91 @@ namespace osu.Game.IO.Legacy
}
else
{
- switch (obj.GetType().Name)
+ switch (obj)
{
- case "Boolean":
+ case bool boolObj:
Write((byte)ObjType.boolType);
- Write((bool)obj);
+ Write(boolObj);
break;
- case "Byte":
+ case byte byteObj:
Write((byte)ObjType.byteType);
- Write((byte)obj);
+ Write(byteObj);
break;
- case "UInt16":
+ case ushort ushortObj:
Write((byte)ObjType.uint16Type);
- Write((ushort)obj);
+ Write(ushortObj);
break;
- case "UInt32":
+ case uint uintObj:
Write((byte)ObjType.uint32Type);
- Write((uint)obj);
+ Write(uintObj);
break;
- case "UInt64":
+ case ulong ulongObj:
Write((byte)ObjType.uint64Type);
- Write((ulong)obj);
+ Write(ulongObj);
break;
- case "SByte":
+ case sbyte sbyteObj:
Write((byte)ObjType.sbyteType);
- Write((sbyte)obj);
+ Write(sbyteObj);
break;
- case "Int16":
+ case short shortObj:
Write((byte)ObjType.int16Type);
- Write((short)obj);
+ Write(shortObj);
break;
- case "Int32":
+ case int intObj:
Write((byte)ObjType.int32Type);
- Write((int)obj);
+ Write(intObj);
break;
- case "Int64":
+ case long longObj:
Write((byte)ObjType.int64Type);
- Write((long)obj);
+ Write(longObj);
break;
- case "Char":
+ case char charObj:
Write((byte)ObjType.charType);
- base.Write((char)obj);
+ base.Write(charObj);
break;
- case "String":
+ case string stringObj:
Write((byte)ObjType.stringType);
- base.Write((string)obj);
+ base.Write(stringObj);
break;
- case "Single":
+ case float floatObj:
Write((byte)ObjType.singleType);
- Write((float)obj);
+ Write(floatObj);
break;
- case "Double":
+ case double doubleObj:
Write((byte)ObjType.doubleType);
- Write((double)obj);
+ Write(doubleObj);
break;
- case "Decimal":
+ case decimal decimalObj:
Write((byte)ObjType.decimalType);
- Write((decimal)obj);
+ Write(decimalObj);
break;
- case "DateTime":
+ case DateTime dateTimeObj:
Write((byte)ObjType.dateTimeType);
- Write((DateTime)obj);
+ Write(dateTimeObj);
break;
- case "Byte[]":
+ case byte[] byteArray:
Write((byte)ObjType.byteArrayType);
- base.Write((byte[])obj);
+ base.Write(byteArray);
break;
- case "Char[]":
+ case char[] charArray:
Write((byte)ObjType.charArrayType);
- base.Write((char[])obj);
+ base.Write(charArray);
break;
default:
diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs
index 9c7324d913..c8b2f2327b 100644
--- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs
+++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs
@@ -277,7 +277,7 @@ namespace osu.Game.Online.Leaderboards
protected virtual IEnumerable GetStatistics(ScoreInfo model) => new[]
{
new LeaderboardScoreStatistic(FontAwesome.Solid.Link, "Max Combo", model.MaxCombo.ToString()),
- new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy))
+ new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:0%}" : @"{0:0.00%}", model.Accuracy))
};
protected override bool OnHover(HoverEvent e)
diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs
index 0258a0301a..cd81013c30 100644
--- a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs
+++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapSet
int playCount = beatmap?.OnlineInfo?.PlayCount ?? 0;
var rate = playCount != 0 ? (float)passCount / playCount : 0;
- successPercent.Text = rate.ToString("P0");
+ successPercent.Text = rate.ToString("0%");
successRate.Length = rate;
percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic);
diff --git a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs
index c3f35b4313..1d8411dfcc 100644
--- a/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs
+++ b/osu.Game/Overlays/BreadcrumbControlOverlayHeader.cs
@@ -1,24 +1,15 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays
{
- public abstract class BreadcrumbControlOverlayHeader : OverlayHeader
+ public abstract class BreadcrumbControlOverlayHeader : TabControlOverlayHeader
{
- protected OverlayHeaderBreadcrumbControl BreadcrumbControl;
-
- protected override TabControl CreateTabControl() => BreadcrumbControl = new OverlayHeaderBreadcrumbControl();
-
- [BackgroundDependencyLoader]
- private void load(OverlayColourProvider colourProvider)
- {
- BreadcrumbControl.AccentColour = colourProvider.Highlight1;
- }
+ protected override OsuTabControl CreateTabControl() => new OverlayHeaderBreadcrumbControl();
public class OverlayHeaderBreadcrumbControl : BreadcrumbControl
{
diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs
index 70a45f2667..4165a180da 100644
--- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs
+++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs
@@ -2,13 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.Collections.Generic;
using System.Linq;
-using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.Textures;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
@@ -26,8 +24,8 @@ namespace osu.Game.Overlays.Changelog
public ChangelogHeader()
{
- BreadcrumbControl.AddItem(listing_string);
- BreadcrumbControl.Current.ValueChanged += e =>
+ TabControl.AddItem(listing_string);
+ TabControl.Current.ValueChanged += e =>
{
if (e.NewValue == listing_string)
ListingSelected?.Invoke();
@@ -37,7 +35,7 @@ namespace osu.Game.Overlays.Changelog
Streams.Current.ValueChanged += e =>
{
- if (e.NewValue?.LatestBuild != null && e.NewValue != Current.Value?.UpdateStream)
+ if (e.NewValue?.LatestBuild != null && !e.NewValue.Equals(Current.Value?.UpdateStream))
Current.Value = e.NewValue.LatestBuild;
};
}
@@ -47,26 +45,26 @@ namespace osu.Game.Overlays.Changelog
private void showBuild(ValueChangedEvent e)
{
if (e.OldValue != null)
- BreadcrumbControl.RemoveItem(e.OldValue.ToString());
+ TabControl.RemoveItem(e.OldValue.ToString());
if (e.NewValue != null)
{
- BreadcrumbControl.AddItem(e.NewValue.ToString());
- BreadcrumbControl.Current.Value = e.NewValue.ToString();
+ TabControl.AddItem(e.NewValue.ToString());
+ TabControl.Current.Value = e.NewValue.ToString();
- Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == e.NewValue.UpdateStream.Name);
+ updateCurrentStream();
title.Version = e.NewValue.UpdateStream.DisplayName;
}
else
{
- BreadcrumbControl.Current.Value = listing_string;
+ TabControl.Current.Value = listing_string;
Streams.Current.Value = null;
title.Version = null;
}
}
- protected override Drawable CreateBackground() => new HeaderBackground();
+ protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/changelog");
protected override Drawable CreateContent() => new Container
{
@@ -80,19 +78,18 @@ namespace osu.Game.Overlays.Changelog
protected override ScreenTitle CreateTitle() => title = new ChangelogHeaderTitle();
- public class HeaderBackground : Sprite
+ public void Populate(List streams)
{
- public HeaderBackground()
- {
- RelativeSizeAxes = Axes.Both;
- FillMode = FillMode.Fill;
- }
+ Streams.Populate(streams);
+ updateCurrentStream();
+ }
- [BackgroundDependencyLoader]
- private void load(TextureStore textures)
- {
- Texture = textures.Get(@"Headers/changelog");
- }
+ private void updateCurrentStream()
+ {
+ if (Current.Value == null)
+ return;
+
+ Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == Current.Value.UpdateStream.Name);
}
private class ChangelogHeaderTitle : ScreenTitle
diff --git a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs b/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs
index 2b48811bd6..ca57ba24e2 100644
--- a/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs
+++ b/osu.Game/Overlays/Changelog/UpdateStreamBadgeArea.cs
@@ -29,8 +29,6 @@ namespace osu.Game.Overlays.Changelog
public void Populate(List streams)
{
- Current.Value = null;
-
foreach (APIUpdateStream updateStream in streams)
AddItem(updateStream);
}
diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs
index 412e29735a..90ba206077 100644
--- a/osu.Game/Overlays/ChangelogOverlay.cs
+++ b/osu.Game/Overlays/ChangelogOverlay.cs
@@ -26,7 +26,7 @@ namespace osu.Game.Overlays
{
public readonly Bindable Current = new Bindable();
- private ChangelogHeader header;
+ protected ChangelogHeader Header;
private Container content;
@@ -34,7 +34,7 @@ namespace osu.Game.Overlays
private List builds;
- private List streams;
+ protected List Streams;
public ChangelogOverlay()
: base(OverlayColourScheme.Purple)
@@ -62,7 +62,7 @@ namespace osu.Game.Overlays
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
- header = new ChangelogHeader
+ Header = new ChangelogHeader
{
ListingSelected = ShowListing,
},
@@ -78,7 +78,7 @@ namespace osu.Game.Overlays
sampleBack = audio.Samples.Get(@"UI/generic-select-soft");
- header.Current.BindTo(Current);
+ Header.Current.BindTo(Current);
Current.BindValueChanged(e =>
{
@@ -117,7 +117,7 @@ namespace osu.Game.Overlays
performAfterFetch(() =>
{
var build = builds.Find(b => b.Version == version && b.UpdateStream.Name == updateStream)
- ?? streams.Find(s => s.Name == updateStream)?.LatestBuild;
+ ?? Streams.Find(s => s.Name == updateStream)?.LatestBuild;
if (build != null)
ShowBuild(build);
@@ -179,9 +179,9 @@ namespace osu.Game.Overlays
res.Streams.ForEach(s => s.LatestBuild.UpdateStream = res.Streams.Find(s2 => s2.Id == s.LatestBuild.UpdateStream.Id));
builds = res.Builds;
- streams = res.Streams;
+ Streams = res.Streams;
- header.Streams.Populate(res.Streams);
+ Header.Populate(res.Streams);
tcs.SetResult(true);
});
diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs
index d252083411..e641cd8ddf 100644
--- a/osu.Game/Overlays/Comments/CommentsContainer.cs
+++ b/osu.Game/Overlays/Comments/CommentsContainer.cs
@@ -8,7 +8,6 @@ using osu.Game.Online.API.Requests;
using osu.Framework.Graphics;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Shapes;
-using osu.Game.Graphics;
using osu.Game.Online.API.Requests.Responses;
using System.Threading;
using System.Linq;
@@ -27,28 +26,26 @@ namespace osu.Game.Overlays.Comments
[Resolved]
private IAPIProvider api { get; set; }
- [Resolved]
- private OsuColour colours { get; set; }
-
private GetCommentsRequest request;
private CancellationTokenSource loadCancellation;
private int currentPage;
- private readonly Box background;
- private readonly FillFlowContainer content;
- private readonly DeletedChildrenPlaceholder deletedChildrenPlaceholder;
- private readonly CommentsShowMoreButton moreButton;
- private readonly TotalCommentsCounter commentCounter;
+ private FillFlowContainer content;
+ private DeletedCommentsCounter deletedCommentsCounter;
+ private CommentsShowMoreButton moreButton;
+ private TotalCommentsCounter commentCounter;
- public CommentsContainer()
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
AddRangeInternal(new Drawable[]
{
- background = new Box
+ new Box
{
RelativeSizeAxes = Axes.Both,
+ Colour = colourProvider.Background5
},
new FillFlowContainer
{
@@ -78,7 +75,7 @@ namespace osu.Game.Overlays.Comments
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.Gray(0.2f)
+ Colour = colourProvider.Background4
},
new FillFlowContainer
{
@@ -87,7 +84,7 @@ namespace osu.Game.Overlays.Comments
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
- deletedChildrenPlaceholder = new DeletedChildrenPlaceholder
+ deletedCommentsCounter = new DeletedCommentsCounter
{
ShowDeleted = { BindTarget = ShowDeleted }
},
@@ -113,12 +110,6 @@ namespace osu.Game.Overlays.Comments
});
}
- [BackgroundDependencyLoader]
- private void load()
- {
- background.Colour = colours.Gray2;
- }
-
protected override void LoadComplete()
{
Sort.BindValueChanged(_ => refetchComments(), true);
@@ -162,7 +153,7 @@ namespace osu.Game.Overlays.Comments
private void clearComments()
{
currentPage = 1;
- deletedChildrenPlaceholder.DeletedCount.Value = 0;
+ deletedCommentsCounter.Count.Value = 0;
moreButton.IsLoading = true;
content.Clear();
}
@@ -193,7 +184,7 @@ namespace osu.Game.Overlays.Comments
{
content.Add(loaded);
- deletedChildrenPlaceholder.DeletedCount.Value += response.Comments.Count(c => c.IsDeleted && c.IsTopLevel);
+ deletedCommentsCounter.Count.Value += response.Comments.Count(c => c.IsDeleted && c.IsTopLevel);
if (response.HasMore)
{
diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs
index 6a7a678cc7..ad80e67330 100644
--- a/osu.Game/Overlays/Comments/CommentsHeader.cs
+++ b/osu.Game/Overlays/Comments/CommentsHeader.cs
@@ -76,9 +76,9 @@ namespace osu.Game.Overlays.Comments
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- background.Colour = colours.Gray3;
+ background.Colour = colourProvider.Background4;
}
private class ShowDeletedButton : HeaderButton
diff --git a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs
index b0174e7b1a..ab65c9c63a 100644
--- a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs
+++ b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs
@@ -1,8 +1,8 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using osu.Framework.Allocation;
using osu.Framework.Bindables;
-using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.Comments
@@ -11,11 +11,12 @@ namespace osu.Game.Overlays.Comments
{
public readonly BindableInt Current = new BindableInt();
- public CommentsShowMoreButton()
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
{
- IdleColour = OsuColour.Gray(0.3f);
- HoverColour = OsuColour.Gray(0.4f);
- ChevronIconColour = OsuColour.Gray(0.5f);
+ IdleColour = colourProvider.Background2;
+ HoverColour = colourProvider.Background1;
+ ChevronIconColour = colourProvider.Foreground1;
}
protected override void LoadComplete()
diff --git a/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedCommentsCounter.cs
similarity index 51%
rename from osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs
rename to osu.Game/Overlays/Comments/DeletedCommentsCounter.cs
index 6b41453b91..f22086bf23 100644
--- a/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs
+++ b/osu.Game/Overlays/Comments/DeletedCommentsCounter.cs
@@ -12,51 +12,56 @@ using osu.Game.Graphics.Sprites;
namespace osu.Game.Overlays.Comments
{
- public class DeletedChildrenPlaceholder : FillFlowContainer
+ public class DeletedCommentsCounter : CompositeDrawable
{
public readonly BindableBool ShowDeleted = new BindableBool();
- public readonly BindableInt DeletedCount = new BindableInt();
+
+ public readonly BindableInt Count = new BindableInt();
private readonly SpriteText countText;
- public DeletedChildrenPlaceholder()
+ public DeletedCommentsCounter()
{
AutoSizeAxes = Axes.Both;
- Direction = FillDirection.Horizontal;
- Spacing = new Vector2(3, 0);
Margin = new MarginPadding { Vertical = 10, Left = 80 };
- Children = new Drawable[]
+
+ InternalChild = new FillFlowContainer
{
- new SpriteIcon
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(3, 0),
+ Children = new Drawable[]
{
- Icon = FontAwesome.Solid.Trash,
- Size = new Vector2(14),
- },
- countText = new OsuSpriteText
- {
- Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
+ new SpriteIcon
+ {
+ Icon = FontAwesome.Solid.Trash,
+ Size = new Vector2(14),
+ },
+ countText = new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
+ }
}
};
}
protected override void LoadComplete()
{
- DeletedCount.BindValueChanged(_ => updateDisplay(), true);
- ShowDeleted.BindValueChanged(_ => updateDisplay(), true);
base.LoadComplete();
+
+ Count.BindValueChanged(_ => updateDisplay(), true);
+ ShowDeleted.BindValueChanged(_ => updateDisplay(), true);
}
private void updateDisplay()
{
- if (DeletedCount.Value != 0)
+ if (!ShowDeleted.Value && Count.Value != 0)
{
- countText.Text = @"deleted comment".ToQuantity(DeletedCount.Value);
- this.FadeTo(ShowDeleted.Value ? 0 : 1);
+ countText.Text = @"deleted comment".ToQuantity(Count.Value);
+ Show();
}
else
- {
Hide();
- }
}
}
}
diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs
index bdae9da226..0f217f057d 100644
--- a/osu.Game/Overlays/Comments/DrawableComment.cs
+++ b/osu.Game/Overlays/Comments/DrawableComment.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Comments
{
LinkFlowContainer username;
FillFlowContainer childCommentsContainer;
- DeletedChildrenPlaceholder deletedChildrenPlaceholder;
+ DeletedCommentsCounter deletedCommentsCounter;
FillFlowContainer info;
LinkFlowContainer message;
GridContainer content;
@@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Comments
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical
},
- deletedChildrenPlaceholder = new DeletedChildrenPlaceholder
+ deletedCommentsCounter = new DeletedCommentsCounter
{
ShowDeleted = { BindTarget = ShowDeleted }
}
@@ -193,7 +193,7 @@ namespace osu.Game.Overlays.Comments
}
};
- deletedChildrenPlaceholder.DeletedCount.Value = comment.DeletedChildrenCount;
+ deletedCommentsCounter.Count.Value = comment.DeletedChildrenCount;
if (comment.UserId.HasValue)
username.AddUserLink(comment.User);
diff --git a/osu.Game/Overlays/Comments/HeaderButton.cs b/osu.Game/Overlays/Comments/HeaderButton.cs
index 8789cf5830..fdc8db35ab 100644
--- a/osu.Game/Overlays/Comments/HeaderButton.cs
+++ b/osu.Game/Overlays/Comments/HeaderButton.cs
@@ -5,7 +5,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
-using osu.Game.Graphics;
using osu.Framework.Input.Events;
using osu.Game.Graphics.UserInterface;
@@ -45,9 +44,9 @@ namespace osu.Game.Overlays.Comments
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- background.Colour = colours.Gray4;
+ background.Colour = colourProvider.Background3;
}
protected override bool OnHover(HoverEvent e)
diff --git a/osu.Game/Overlays/Comments/SortTabControl.cs b/osu.Game/Overlays/Comments/SortTabControl.cs
index a114197b8d..700d63351f 100644
--- a/osu.Game/Overlays/Comments/SortTabControl.cs
+++ b/osu.Game/Overlays/Comments/SortTabControl.cs
@@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Comments
public readonly BindableBool Active = new BindableBool();
[Resolved]
- private OsuColour colours { get; set; }
+ private OverlayColourProvider colourProvider { get; set; }
private readonly SpriteText text;
@@ -78,7 +78,7 @@ namespace osu.Game.Overlays.Comments
updateBackgroundState();
text.Font = text.Font.With(weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium);
- text.Colour = active.NewValue ? colours.BlueLighter : Color4.White;
+ text.Colour = active.NewValue ? colourProvider.Light1 : Color4.White;
}, true);
}
diff --git a/osu.Game/Overlays/Comments/TotalCommentsCounter.cs b/osu.Game/Overlays/Comments/TotalCommentsCounter.cs
index 376853c1de..1bb9b52689 100644
--- a/osu.Game/Overlays/Comments/TotalCommentsCounter.cs
+++ b/osu.Game/Overlays/Comments/TotalCommentsCounter.cs
@@ -5,7 +5,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
-using osu.Framework.Graphics.Sprites;
using osuTK;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -17,9 +16,10 @@ namespace osu.Game.Overlays.Comments
{
public readonly BindableInt Current = new BindableInt();
- private readonly SpriteText counter;
+ private OsuSpriteText counter;
- public TotalCommentsCounter()
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
{
RelativeSizeAxes = Axes.X;
Height = 50;
@@ -38,6 +38,7 @@ namespace osu.Game.Overlays.Comments
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: 20, italics: true),
+ Colour = colourProvider.Light1,
Text = @"Comments"
},
new CircularContainer
@@ -51,14 +52,15 @@ namespace osu.Game.Overlays.Comments
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.Gray(0.05f)
+ Colour = colourProvider.Background6
},
counter = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Margin = new MarginPadding { Horizontal = 10, Vertical = 5 },
- Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold)
+ Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
+ Colour = colourProvider.Foreground1
}
},
}
@@ -66,12 +68,6 @@ namespace osu.Game.Overlays.Comments
});
}
- [BackgroundDependencyLoader]
- private void load(OsuColour colours)
- {
- counter.Colour = colours.BlueLighter;
- }
-
protected override void LoadComplete()
{
Current.BindValueChanged(value => counter.Text = value.NewValue.ToString("N0"), true);
diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs
index 959f6749d2..3464ce6086 100644
--- a/osu.Game/Overlays/FullscreenOverlay.cs
+++ b/osu.Game/Overlays/FullscreenOverlay.cs
@@ -18,11 +18,11 @@ namespace osu.Game.Overlays
protected IAPIProvider API { get; private set; }
[Cached]
- private readonly OverlayColourProvider colourProvider;
+ protected readonly OverlayColourProvider ColourProvider;
protected FullscreenOverlay(OverlayColourScheme colourScheme)
{
- colourProvider = new OverlayColourProvider(colourScheme);
+ ColourProvider = new OverlayColourProvider(colourScheme);
RelativeSizeAxes = Axes.Both;
RelativePositionAxes = Axes.Both;
@@ -43,10 +43,10 @@ namespace osu.Game.Overlays
[BackgroundDependencyLoader]
private void load()
{
- Waves.FirstWaveColour = colourProvider.Light4;
- Waves.SecondWaveColour = colourProvider.Light3;
- Waves.ThirdWaveColour = colourProvider.Dark4;
- Waves.FourthWaveColour = colourProvider.Dark3;
+ Waves.FirstWaveColour = ColourProvider.Light4;
+ Waves.SecondWaveColour = ColourProvider.Light3;
+ Waves.ThirdWaveColour = ColourProvider.Dark4;
+ Waves.FourthWaveColour = ColourProvider.Dark3;
}
public override void Show()
diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs
index 1152d9044b..b525ba7a82 100644
--- a/osu.Game/Overlays/News/NewsHeader.cs
+++ b/osu.Game/Overlays/News/NewsHeader.cs
@@ -1,11 +1,8 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.Textures;
using osu.Game.Graphics.UserInterface;
using System;
@@ -23,9 +20,9 @@ namespace osu.Game.Overlays.News
public NewsHeader()
{
- BreadcrumbControl.AddItem(front_page_string);
+ TabControl.AddItem(front_page_string);
- BreadcrumbControl.Current.ValueChanged += e =>
+ TabControl.Current.ValueChanged += e =>
{
if (e.NewValue == front_page_string)
ShowFrontPage?.Invoke();
@@ -37,41 +34,26 @@ namespace osu.Game.Overlays.News
private void showPost(ValueChangedEvent e)
{
if (e.OldValue != null)
- BreadcrumbControl.RemoveItem(e.OldValue);
+ TabControl.RemoveItem(e.OldValue);
if (e.NewValue != null)
{
- BreadcrumbControl.AddItem(e.NewValue);
- BreadcrumbControl.Current.Value = e.NewValue;
+ TabControl.AddItem(e.NewValue);
+ TabControl.Current.Value = e.NewValue;
title.IsReadingPost = true;
}
else
{
- BreadcrumbControl.Current.Value = front_page_string;
+ TabControl.Current.Value = front_page_string;
title.IsReadingPost = false;
}
}
- protected override Drawable CreateBackground() => new NewsHeaderBackground();
+ protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/news");
protected override ScreenTitle CreateTitle() => title = new NewsHeaderTitle();
- private class NewsHeaderBackground : Sprite
- {
- public NewsHeaderBackground()
- {
- RelativeSizeAxes = Axes.Both;
- FillMode = FillMode.Fill;
- }
-
- [BackgroundDependencyLoader]
- private void load(TextureStore textures)
- {
- Texture = textures.Get(@"Headers/news");
- }
- }
-
private class NewsHeaderTitle : ScreenTitle
{
private const string post_string = "post";
diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs
index bc58a17401..5596f71dd0 100644
--- a/osu.Game/Overlays/OverlayHeader.cs
+++ b/osu.Game/Overlays/OverlayHeader.cs
@@ -6,7 +6,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface;
using osuTK.Graphics;
@@ -15,14 +14,9 @@ namespace osu.Game.Overlays
public abstract class OverlayHeader : Container
{
private readonly Box titleBackground;
- private readonly Box controlBackground;
- private readonly Container background;
private readonly ScreenTitle title;
- protected float BackgroundHeight
- {
- set => background.Height = value;
- }
+ protected readonly FillFlowContainer HeaderInfo;
protected OverlayHeader()
{
@@ -36,46 +30,36 @@ namespace osu.Game.Overlays
Direction = FillDirection.Vertical,
Children = new[]
{
- background = new Container
- {
- RelativeSizeAxes = Axes.X,
- Height = 80,
- Masking = true,
- Child = CreateBackground()
- },
- new Container
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Children = new Drawable[]
- {
- titleBackground = new Box
- {
- RelativeSizeAxes = Axes.Both,
- },
- title = CreateTitle().With(title =>
- {
- title.Margin = new MarginPadding
- {
- Vertical = 10,
- Left = UserProfileOverlay.CONTENT_X_MARGIN
- };
- })
- }
- },
- new Container
+ HeaderInfo = new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Vertical,
Depth = -float.MaxValue,
- Children = new Drawable[]
+ Children = new[]
{
- controlBackground = new Box
+ CreateBackground(),
+ new Container
{
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.Gray,
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Children = new Drawable[]
+ {
+ titleBackground = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Gray,
+ },
+ title = CreateTitle().With(title =>
+ {
+ title.Margin = new MarginPadding
+ {
+ Vertical = 10,
+ Left = UserProfileOverlay.CONTENT_X_MARGIN
+ };
+ })
+ }
},
- CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN })
}
},
CreateContent()
@@ -88,16 +72,14 @@ namespace osu.Game.Overlays
{
titleBackground.Colour = colourProvider.Dark5;
title.AccentColour = colourProvider.Highlight1;
- controlBackground.Colour = colourProvider.Dark4;
}
- protected abstract Drawable CreateBackground();
+ [NotNull]
+ protected virtual Drawable CreateContent() => Drawable.Empty();
[NotNull]
- protected virtual Drawable CreateContent() => new Container();
+ protected virtual Drawable CreateBackground() => Drawable.Empty();
protected abstract ScreenTitle CreateTitle();
-
- protected abstract TabControl CreateTabControl();
}
}
diff --git a/osu.Game/Overlays/OverlayHeaderBackground.cs b/osu.Game/Overlays/OverlayHeaderBackground.cs
new file mode 100644
index 0000000000..2fef593285
--- /dev/null
+++ b/osu.Game/Overlays/OverlayHeaderBackground.cs
@@ -0,0 +1,43 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.Textures;
+
+namespace osu.Game.Overlays
+{
+ public class OverlayHeaderBackground : CompositeDrawable
+ {
+ public OverlayHeaderBackground(string textureName)
+ {
+ Height = 80;
+ RelativeSizeAxes = Axes.X;
+ Masking = true;
+ InternalChild = new Background(textureName);
+ }
+
+ private class Background : Sprite
+ {
+ private readonly string textureName;
+
+ public Background(string textureName)
+ {
+ this.textureName = textureName;
+
+ Anchor = Anchor.Centre;
+ Origin = Anchor.Centre;
+ RelativeSizeAxes = Axes.Both;
+ FillMode = FillMode.Fill;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(TextureStore textures)
+ {
+ Texture = textures.Get(textureName);
+ }
+ }
+ }
+}
diff --git a/osu.Game/Overlays/OverlayTabControl.cs b/osu.Game/Overlays/OverlayTabControl.cs
index 812f8963c9..aa96f0e19b 100644
--- a/osu.Game/Overlays/OverlayTabControl.cs
+++ b/osu.Game/Overlays/OverlayTabControl.cs
@@ -13,41 +13,25 @@ using osuTK.Graphics;
namespace osu.Game.Overlays
{
- public abstract class OverlayTabControl : TabControl
+ public abstract class OverlayTabControl : OsuTabControl
{
private readonly Box bar;
- private Color4 accentColour = Color4.White;
-
- public Color4 AccentColour
- {
- get => accentColour;
- set
- {
- if (accentColour == value)
- return;
-
- accentColour = value;
- bar.Colour = value;
-
- foreach (TabItem tabItem in TabContainer)
- {
- ((OverlayTabItem)tabItem).AccentColour = value;
- }
- }
- }
-
- public new MarginPadding Padding
- {
- get => TabContainer.Padding;
- set => TabContainer.Padding = value;
- }
-
protected float BarHeight
{
set => bar.Height = value;
}
+ public override Color4 AccentColour
+ {
+ get => base.AccentColour;
+ set
+ {
+ base.AccentColour = value;
+ bar.Colour = value;
+ }
+ }
+
protected OverlayTabControl()
{
TabContainer.Masking = false;
@@ -66,7 +50,7 @@ namespace osu.Game.Overlays
protected override TabItem CreateTabItem(T value) => new OverlayTabItem(value);
- protected class OverlayTabItem : TabItem
+ protected class OverlayTabItem : TabItem, IHasAccentColour
{
protected readonly ExpandingBar Bar;
protected readonly OsuSpriteText Text;
diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs
index 158641d816..b6c6f33678 100644
--- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs
@@ -33,16 +33,16 @@ namespace osu.Game.Overlays.Profile.Header
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- iconColour = colours.GreySeafoamLighter;
+ iconColour = colourProvider.Foreground1;
InternalChildren = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = colours.GreySeafoamDark,
+ Colour = colourProvider.Background4
},
new FillFlowContainer
{
diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs
index 68fd77dd84..658cdb8ce3 100644
--- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs
@@ -7,7 +7,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Textures;
-using osu.Game.Graphics;
using osu.Game.Overlays.Profile.Header.Components;
using osu.Game.Users;
using osuTK;
@@ -28,7 +27,7 @@ namespace osu.Game.Overlays.Profile.Header
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours, TextureStore textures)
+ private void load(OverlayColourProvider colourProvider, TextureStore textures)
{
Container hiddenDetailContainer;
Container expandedDetailContainer;
@@ -38,7 +37,7 @@ namespace osu.Game.Overlays.Profile.Header
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = colours.GreySeafoam
+ Colour = colourProvider.Background4
},
new FillFlowContainer
{
@@ -119,12 +118,12 @@ namespace osu.Game.Overlays.Profile.Header
hiddenDetailGlobal = new OverlinedInfoContainer
{
Title = "Global Ranking",
- LineColour = colours.Yellow
+ LineColour = colourProvider.Highlight1
},
hiddenDetailCountry = new OverlinedInfoContainer
{
Title = "Country Ranking",
- LineColour = colours.Yellow
+ LineColour = colourProvider.Highlight1
},
}
}
diff --git a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs
index 46d24608ed..29e13e4f51 100644
--- a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs
@@ -6,7 +6,6 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Graphics;
using osuTK;
namespace osu.Game.Overlays.Profile.Header.Components
@@ -25,10 +24,10 @@ namespace osu.Game.Overlays.Profile.Header.Components
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- IdleColour = colours.GreySeafoamLight;
- HoverColour = colours.GreySeafoamLight.Darken(0.2f);
+ IdleColour = colourProvider.Background2;
+ HoverColour = colourProvider.Background2.Lighten(0.2f);
Child = icon = new SpriteIcon
{
diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs
index c40ddca688..b11e41f90f 100644
--- a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs
@@ -43,7 +43,8 @@ namespace osu.Game.Overlays.Profile.Header.Components
line = new Circle
{
RelativeSizeAxes = Axes.X,
- Height = 4,
+ Height = 2,
+ Margin = new MarginPadding { Bottom = 2 }
},
title = new OsuSpriteText
{
diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs
index 2c88a83680..be96840217 100644
--- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs
@@ -6,7 +6,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
-using osu.Game.Graphics;
using osu.Game.Users;
namespace osu.Game.Overlays.Profile.Header.Components
@@ -27,12 +26,12 @@ namespace osu.Game.Overlays.Profile.Header.Components
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
InternalChild = info = new OverlinedInfoContainer
{
Title = "Total Play Time",
- LineColour = colours.Yellow,
+ LineColour = colourProvider.Highlight1,
};
User.BindValueChanged(updateTime, true);
diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs
index 6ee0d9ee8f..cf6ae1a3fc 100644
--- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs
@@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Profile.Header
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider, OsuColour colours)
{
AutoSizeAxes = Axes.Y;
@@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Profile.Header
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = colours.GreySeafoamDarker,
+ Colour = colourProvider.Background5,
},
fillFlow = new FillFlowContainer
{
@@ -152,12 +152,12 @@ namespace osu.Game.Overlays.Profile.Header
detailGlobalRank = new OverlinedInfoContainer(true, 110)
{
Title = "Global Ranking",
- LineColour = colours.Yellow,
+ LineColour = colourProvider.Highlight1,
},
detailCountryRank = new OverlinedInfoContainer(false, 110)
{
Title = "Country Ranking",
- LineColour = colours.Yellow,
+ LineColour = colourProvider.Highlight1,
},
}
}
diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs
index 45bc60f794..a5938a3fe7 100644
--- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs
@@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Game.Graphics;
using osu.Game.Overlays.Profile.Header.Components;
using osu.Game.Users;
using osuTK;
@@ -23,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Header
public readonly Bindable User = new Bindable();
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
Alpha = 0;
AutoSizeAxes = Axes.Y;
@@ -34,7 +33,7 @@ namespace osu.Game.Overlays.Profile.Header
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = colours.GreySeafoamDarker,
+ Colour = colourProvider.Background5,
},
new Container //artificial shadow
{
diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
index b0d7070994..19a24dd576 100644
--- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
@@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Profile.Header
private FillFlowContainer userStats;
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
Height = 150;
@@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Profile.Header
new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = colours.GreySeafoamDark,
+ Colour = colourProvider.Background5,
},
new FillFlowContainer
{
@@ -117,7 +117,7 @@ namespace osu.Game.Overlays.Profile.Header
RelativeSizeAxes = Axes.X,
Height = 1.5f,
Margin = new MarginPadding { Top = 10 },
- Colour = colours.GreySeafoamLighter,
+ Colour = colourProvider.Light1,
},
new FillFlowContainer
{
@@ -137,7 +137,7 @@ namespace osu.Game.Overlays.Profile.Header
Margin = new MarginPadding { Left = 10 },
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
- Colour = colours.GreySeafoamLighter,
+ Colour = colourProvider.Light1,
}
}
},
diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs
index f8eb03770a..3e78423a5a 100644
--- a/osu.Game/Overlays/Profile/ProfileHeader.cs
+++ b/osu.Game/Overlays/Profile/ProfileHeader.cs
@@ -14,7 +14,7 @@ using osu.Game.Users;
namespace osu.Game.Overlays.Profile
{
- public class ProfileHeader : TabControlOverlayHeader
+ public class ProfileHeader : TabControlOverlayHeader
{
private UserCoverBackground coverContainer;
@@ -25,8 +25,6 @@ namespace osu.Game.Overlays.Profile
public ProfileHeader()
{
- BackgroundHeight = 150;
-
User.ValueChanged += e => updateDisplay(e.NewValue);
TabControl.AddItem("info");
@@ -38,7 +36,9 @@ namespace osu.Game.Overlays.Profile
protected override Drawable CreateBackground() =>
new Container
{
- RelativeSizeAxes = Axes.Both,
+ RelativeSizeAxes = Axes.X,
+ Height = 150,
+ Masking = true,
Children = new Drawable[]
{
coverContainer = new UserCoverBackground
diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs
index f3590d4bb7..2e19ae4b64 100644
--- a/osu.Game/Overlays/Profile/ProfileSection.cs
+++ b/osu.Game/Overlays/Profile/ProfileSection.cs
@@ -95,10 +95,10 @@ namespace osu.Game.Overlays.Profile
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- background.Colour = colours.GreySeafoamDarker;
- underscore.Colour = colours.Seafoam;
+ background.Colour = colourProvider.Background5;
+ underscore.Colour = colourProvider.Highlight1;
}
private class SectionTriangles : Container
@@ -128,11 +128,11 @@ namespace osu.Game.Overlays.Profile
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- triangles.ColourLight = colours.GreySeafoamDark;
- triangles.ColourDark = colours.GreySeafoamDarker.Darken(0.2f);
- foreground.Colour = ColourInfo.GradientVertical(colours.GreySeafoamDarker, colours.GreySeafoamDarker.Opacity(0));
+ triangles.ColourLight = colourProvider.Background4;
+ triangles.ColourDark = colourProvider.Background5.Darken(0.2f);
+ foreground.Colour = ColourInfo.GradientVertical(colourProvider.Background5, colourProvider.Background5.Opacity(0));
}
}
}
diff --git a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs
index 0206c4e13b..e75ad2f161 100644
--- a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs
+++ b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
using osu.Game.Beatmaps;
@@ -13,32 +12,25 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osuTK;
-using System.Collections.Generic;
using osu.Framework.Graphics.Cursor;
namespace osu.Game.Overlays.Profile.Sections.Historical
{
- public class DrawableMostPlayedBeatmap : OsuHoverContainer
+ public class DrawableMostPlayedBeatmap : CompositeDrawable
{
private const int cover_width = 100;
private const int corner_radius = 6;
- private const int height = 50;
private readonly BeatmapInfo beatmap;
private readonly int playCount;
- private Box background;
-
- protected override IEnumerable EffectTargets => new[] { background };
-
public DrawableMostPlayedBeatmap(BeatmapInfo beatmap, int playCount)
{
this.beatmap = beatmap;
this.playCount = playCount;
- Enabled.Value = true; //manually enabled, because we have no action
RelativeSizeAxes = Axes.X;
- Height = height;
+ Height = 50;
Masking = true;
CornerRadius = corner_radius;
@@ -47,10 +39,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
- IdleColour = colours.GreySeafoam;
- HoverColour = colours.GreySeafoamLight;
-
- Children = new Drawable[]
+ AddRangeInternal(new Drawable[]
{
new UpdateableBeatmapSetCover
{
@@ -72,46 +61,48 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
CornerRadius = corner_radius,
Children = new Drawable[]
{
- background = new Box { RelativeSizeAxes = Axes.Both },
- new Container
+ new ProfileItemContainer
{
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding(10),
- Children = new Drawable[]
+ Child = new Container
{
- new FillFlowContainer
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(10),
+ Children = new Drawable[]
{
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.CentreLeft,
- AutoSizeAxes = Axes.Both,
- Direction = FillDirection.Vertical,
- Children = new Drawable[]
+ new FillFlowContainer
{
- new MostPlayedBeatmapMetadataContainer(beatmap),
- new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular))
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
{
- AutoSizeAxes = Axes.Both,
- Direction = FillDirection.Horizontal,
- Colour = colours.GreySeafoamLighter
- }.With(d =>
- {
- d.AddText("mapped by ");
- d.AddUserLink(beatmap.Metadata.Author);
- }),
- }
- },
- new PlayCountText(playCount)
- {
- Anchor = Anchor.CentreRight,
- Origin = Anchor.CentreRight
- },
- }
- },
+ new MostPlayedBeatmapMetadataContainer(beatmap),
+ new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular))
+ {
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Colour = colours.GreySeafoamLighter
+ }.With(d =>
+ {
+ d.AddText("mapped by ");
+ d.AddUserLink(beatmap.Metadata.Author);
+ }),
+ }
+ },
+ new PlayCountText(playCount)
+ {
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight
+ },
+ }
+ },
+ }
}
}
}
}
- };
+ });
}
private class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer
diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs
index aabfa56ee6..d4d0976724 100644
--- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs
+++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs
@@ -101,7 +101,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu
{
Masking = true,
RelativeSizeAxes = Axes.X,
- Height = 5,
+ Height = 2,
Child = lineBackground = new Box
{
RelativeSizeAxes = Axes.Both,
@@ -128,10 +128,10 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- lineBackground.Colour = colours.Yellow;
- DescriptionText.Colour = colours.GreySeafoamLighter;
+ lineBackground.Colour = colourProvider.Highlight1;
+ DescriptionText.Colour = colourProvider.Foreground1;
}
}
}
diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs
new file mode 100644
index 0000000000..717ec4fb1a
--- /dev/null
+++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs
@@ -0,0 +1,63 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Input.Events;
+using osuTK.Graphics;
+
+namespace osu.Game.Overlays.Profile.Sections
+{
+ public class ProfileItemContainer : Container
+ {
+ private const int hover_duration = 200;
+
+ protected override Container Content => content;
+
+ private Color4 idleColour;
+ private Color4 hoverColour;
+
+ private readonly Box background;
+ private readonly Container content;
+
+ public ProfileItemContainer()
+ {
+ RelativeSizeAxes = Axes.Both;
+ Masking = true;
+ CornerRadius = 6;
+
+ AddRangeInternal(new Drawable[]
+ {
+ background = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ content = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ }
+ });
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OverlayColourProvider colourProvider)
+ {
+ background.Colour = idleColour = colourProvider.Background4;
+ hoverColour = colourProvider.Background3;
+ }
+
+ protected override bool OnHover(HoverEvent e)
+ {
+ background.FadeColour(hoverColour, hover_duration, Easing.OutQuint);
+ return base.OnHover(e);
+ }
+
+ protected override void OnHoverLost(HoverLostEvent e)
+ {
+ base.OnHoverLost(e);
+ background.FadeColour(idleColour, hover_duration, Easing.OutQuint);
+ }
+ }
+}
diff --git a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs
index 28486cc743..426ebeebe6 100644
--- a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs
+++ b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.Profile.Sections
@@ -10,11 +9,11 @@ namespace osu.Game.Overlays.Profile.Sections
public class ProfileShowMoreButton : ShowMoreButton
{
[BackgroundDependencyLoader]
- private void load(OsuColour colors)
+ private void load(OverlayColourProvider colourProvider)
{
- IdleColour = colors.GreySeafoamDark;
- HoverColour = colors.GreySeafoam;
- ChevronIconColour = colors.Yellow;
+ IdleColour = colourProvider.Background2;
+ HoverColour = colourProvider.Background1;
+ ChevronIconColour = colourProvider.Foreground1;
}
}
}
diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePerformanceScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePerformanceScore.cs
deleted file mode 100644
index 843f9b7ef2..0000000000
--- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePerformanceScore.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-using osu.Framework.Allocation;
-using osu.Framework.Graphics;
-using osu.Game.Graphics;
-using osu.Game.Graphics.Sprites;
-using osu.Game.Scoring;
-
-namespace osu.Game.Overlays.Profile.Sections.Ranks
-{
- public class DrawablePerformanceScore : DrawableProfileScore
- {
- private readonly double? weight;
-
- public DrawablePerformanceScore(ScoreInfo score, double? weight = null)
- : base(score)
- {
- this.weight = weight;
- }
-
- [BackgroundDependencyLoader]
- private void load(OsuColour colour)
- {
- double pp = Score.PP ?? 0;
- RightFlowContainer.Add(new OsuSpriteText
- {
- Text = $"{pp:0}pp",
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
- Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
- });
-
- if (weight.HasValue)
- {
- RightFlowContainer.Add(new OsuSpriteText
- {
- Text = $"weighted: {pp * weight:0}pp ({weight:P0})",
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
- Colour = colour.GrayA,
- Font = OsuFont.GetFont(size: 11, weight: FontWeight.Regular, italics: true)
- });
- }
- }
- }
-}
diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs
index 6362d3dfb0..5196bef48d 100644
--- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs
+++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs
@@ -1,76 +1,225 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using osuTK;
+using System.Linq;
+using JetBrains.Annotations;
using osu.Framework.Allocation;
+using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Localisation;
+using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.Leaderboards;
-using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Scoring;
-using osu.Game.Beatmaps;
-using osu.Framework.Localisation;
-using osu.Framework.Graphics.Containers;
+using osuTK;
+using osuTK.Graphics;
namespace osu.Game.Overlays.Profile.Sections.Ranks
{
- public abstract class DrawableProfileScore : DrawableProfileRow
+ public class DrawableProfileScore : CompositeDrawable
{
- private readonly FillFlowContainer modsContainer;
+ private const int performance_width = 80;
+ private const int content_padding = 10;
+
protected readonly ScoreInfo Score;
- protected DrawableProfileScore(ScoreInfo score)
+ [Resolved]
+ private OsuColour colours { get; set; }
+
+ [Resolved]
+ private OverlayColourProvider colourProvider { get; set; }
+
+ public DrawableProfileScore(ScoreInfo score)
{
Score = score;
RelativeSizeAxes = Axes.X;
- Height = 60;
- Children = new Drawable[]
+ Height = 40;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ AddInternal(new ProfileItemContainer
{
- modsContainer = new FillFlowContainer
+ Children = new Drawable[]
{
- AutoSizeAxes = Axes.Both,
- Anchor = Anchor.CentreRight,
- Origin = Anchor.CentreRight,
- Spacing = new Vector2(1),
- Margin = new MarginPadding { Right = 160 }
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = content_padding, Right = performance_width + content_padding },
+ Children = new Drawable[]
+ {
+ new FillFlowContainer
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(8, 0),
+ Children = new Drawable[]
+ {
+ new UpdateableRank(Score.Rank)
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ Size = new Vector2(50, 20),
+ },
+ new FillFlowContainer
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Vertical,
+ Spacing = new Vector2(0, 2),
+ Children = new Drawable[]
+ {
+ new ScoreBeatmapMetadataContainer(Score.Beatmap),
+ new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(5, 0),
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Text = $"{Score.Beatmap.Version}",
+ Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular),
+ Colour = colours.Yellow
+ },
+ new DrawableDate(Score.Date, 12)
+ {
+ Colour = colourProvider.Foreground1
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ new FillFlowContainer
+ {
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(15),
+ Children = new[]
+ {
+ CreateRightContent().With(c =>
+ {
+ c.Anchor = Anchor.CentreRight;
+ c.Origin = Anchor.CentreRight;
+ }),
+ new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(2),
+ Children = Score.Mods.Select(mod => new ModIcon(mod)
+ {
+ Scale = new Vector2(0.35f)
+ }).ToList(),
+ }
+ }
+ }
+ }
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Y,
+ Width = performance_width,
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight,
+ Children = new[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(1, 0.5f),
+ Colour = Color4.Black.Opacity(0.5f),
+ Shear = new Vector2(-0.45f, 0),
+ EdgeSmoothness = new Vector2(2, 0),
+ },
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ RelativePositionAxes = Axes.Y,
+ Size = new Vector2(1, -0.5f),
+ Position = new Vector2(0, 1),
+ Colour = Color4.Black.Opacity(0.5f),
+ Shear = new Vector2(0.45f, 0),
+ EdgeSmoothness = new Vector2(2, 0),
+ },
+ createDrawablePerformance().With(d =>
+ {
+ d.Anchor = Anchor.Centre;
+ d.Origin = Anchor.Centre;
+ })
+ }
+ }
}
- };
+ });
}
- [BackgroundDependencyLoader(true)]
- private void load(OsuColour colour)
+ [NotNull]
+ protected virtual Drawable CreateRightContent() => CreateDrawableAccuracy();
+
+ protected OsuSpriteText CreateDrawableAccuracy() => new OsuSpriteText
{
- var text = new OsuSpriteText
- {
- Text = $"accuracy: {Score.Accuracy:P2}",
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
- Colour = colour.GrayA,
- Font = OsuFont.GetFont(size: 11, weight: FontWeight.Regular, italics: true)
- };
-
- RightFlowContainer.Insert(1, text);
-
- LeftFlowContainer.Add(new ProfileScoreBeatmapMetadataContainer(Score.Beatmap));
- LeftFlowContainer.Add(new DrawableDate(Score.Date));
-
- foreach (Mod mod in Score.Mods)
- modsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.5f) });
- }
-
- protected override Drawable CreateLeftVisual() => new UpdateableRank(Score.Rank)
- {
- RelativeSizeAxes = Axes.Y,
- Width = 60,
- FillMode = FillMode.Fit,
+ Text = $"{Score.Accuracy:0.00%}",
+ Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
+ Colour = colours.Yellow,
};
- private class ProfileScoreBeatmapMetadataContainer : BeatmapMetadataContainer
+ private Drawable createDrawablePerformance()
{
- public ProfileScoreBeatmapMetadataContainer(BeatmapInfo beatmap)
+ if (Score.PP.HasValue)
+ {
+ return new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Children = new[]
+ {
+ new OsuSpriteText
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Font = OsuFont.GetFont(weight: FontWeight.Bold),
+ Text = $"{Score.PP:0}",
+ Colour = colourProvider.Highlight1
+ },
+ new OsuSpriteText
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold),
+ Text = "pp",
+ Colour = colourProvider.Light3
+ }
+ }
+ };
+ }
+
+ return new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(weight: FontWeight.Bold),
+ Text = "-",
+ Colour = colourProvider.Highlight1
+ };
+ }
+
+ private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer
+ {
+ public ScoreBeatmapMetadataContainer(BeatmapInfo beatmap)
: base(beatmap)
{
}
@@ -79,16 +228,19 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
{
new OsuSpriteText
{
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
Text = new LocalisedString((
- $"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} [{beatmap.Version}] ",
- $"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} [{beatmap.Version}] ")),
- Font = OsuFont.GetFont(size: 15, weight: FontWeight.SemiBold, italics: true)
+ $"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} ",
+ $"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} ")),
+ Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true)
},
new OsuSpriteText
{
- Text = new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)),
- Padding = new MarginPadding { Top = 3 },
- Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular, italics: true)
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Text = "by " + new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)),
+ Font = OsuFont.GetFont(size: 12, italics: true)
},
};
}
diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs
new file mode 100644
index 0000000000..e741c88aeb
--- /dev/null
+++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs
@@ -0,0 +1,55 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Scoring;
+
+namespace osu.Game.Overlays.Profile.Sections.Ranks
+{
+ public class DrawableProfileWeightedScore : DrawableProfileScore
+ {
+ private readonly double weight;
+
+ public DrawableProfileWeightedScore(ScoreInfo score, double weight)
+ : base(score)
+ {
+ this.weight = weight;
+ }
+
+ protected override Drawable CreateRightContent() => new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
+ {
+ new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ AutoSizeAxes = Axes.Y,
+ Width = 60,
+ Child = CreateDrawableAccuracy()
+ },
+ new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
+ Text = $"{Score.PP * weight:0}pp",
+ },
+ }
+ },
+ new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(size: 12),
+ Text = $@"weighted {weight:0%}"
+ }
+ }
+ };
+ }
+}
diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableTotalScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableTotalScore.cs
deleted file mode 100644
index 8bfca08fe7..0000000000
--- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableTotalScore.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-using osu.Framework.Allocation;
-using osu.Framework.Graphics;
-using osu.Game.Graphics;
-using osu.Game.Graphics.Sprites;
-using osu.Game.Scoring;
-
-namespace osu.Game.Overlays.Profile.Sections.Ranks
-{
- public class DrawableTotalScore : DrawableProfileScore
- {
- public DrawableTotalScore(ScoreInfo score)
- : base(score)
- {
- }
-
- [BackgroundDependencyLoader]
- private void load()
- {
- RightFlowContainer.Add(new OsuSpriteText
- {
- Text = Score.TotalScore.ToString("#,###"),
- Anchor = Anchor.TopRight,
- Origin = Anchor.TopRight,
- Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
- });
- }
- }
-}
diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs
index e0f1c935da..64494f9814 100644
--- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs
+++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs
@@ -15,14 +15,12 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
{
public class PaginatedScoreContainer : PaginatedContainer
{
- private readonly bool includeWeight;
private readonly ScoreType type;
- public PaginatedScoreContainer(ScoreType type, Bindable user, string header, string missing, bool includeWeight = false)
+ public PaginatedScoreContainer(ScoreType type, Bindable user, string header, string missing)
: base(user, header, missing)
{
this.type = type;
- this.includeWeight = includeWeight;
ItemsPerPage = 5;
@@ -43,10 +41,10 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
switch (type)
{
default:
- return new DrawablePerformanceScore(model.CreateScoreInfo(Rulesets), includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null);
+ return new DrawableProfileScore(model.CreateScoreInfo(Rulesets));
- case ScoreType.Recent:
- return new DrawableTotalScore(model.CreateScoreInfo(Rulesets));
+ case ScoreType.Best:
+ return new DrawableProfileWeightedScore(model.CreateScoreInfo(Rulesets), Math.Pow(0.95, ItemsContainer.Count));
}
}
}
diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs
index c4b933593e..dbdff3a273 100644
--- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs
+++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections
{
Children = new[]
{
- new PaginatedScoreContainer(ScoreType.Best, User, "Best Performance", "No performance records. :(", true),
+ new PaginatedScoreContainer(ScoreType.Best, User, "Best Performance", "No performance records. :("),
new PaginatedScoreContainer(ScoreType.Firsts, User, "First Place Ranks", "No awesome performance records yet. :("),
};
}
diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs
index 0124f7090e..bda677ecd6 100644
--- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs
@@ -17,10 +17,34 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
{
Children = new Drawable[]
{
- new SettingsSlider { LabelText = "Master", Bindable = audio.Volume, KeyboardStep = 0.01f },
- new SettingsSlider { LabelText = "Master (window inactive)", Bindable = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.01f },
- new SettingsSlider { LabelText = "Effect", Bindable = audio.VolumeSample, KeyboardStep = 0.01f },
- new SettingsSlider { LabelText = "Music", Bindable = audio.VolumeTrack, KeyboardStep = 0.01f },
+ new SettingsSlider
+ {
+ LabelText = "Master",
+ Bindable = audio.Volume,
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
+ },
+ new SettingsSlider
+ {
+ LabelText = "Master (window inactive)",
+ Bindable = config.GetBindable(OsuSetting.VolumeInactive),
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
+ },
+ new SettingsSlider
+ {
+ LabelText = "Effect",
+ Bindable = audio.VolumeSample,
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
+ },
+ new SettingsSlider
+ {
+ LabelText = "Music",
+ Bindable = audio.VolumeTrack,
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
+ },
};
}
}
diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs
index 08bc67e43e..2d2cd42213 100644
--- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs
@@ -21,13 +21,15 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay
{
LabelText = "Background dim",
Bindable = config.GetBindable(OsuSetting.DimLevel),
- KeyboardStep = 0.01f
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
},
new SettingsSlider
{
LabelText = "Background blur",
Bindable = config.GetBindable(OsuSetting.BlurLevel),
- KeyboardStep = 0.01f
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
},
new SettingsCheckbox
{
diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
index 02b9edd975..efbb08b7df 100644
--- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
@@ -98,25 +98,29 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
{
LabelText = "Horizontal position",
Bindable = scalingPositionX,
- KeyboardStep = 0.01f
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
},
new SettingsSlider
{
LabelText = "Vertical position",
Bindable = scalingPositionY,
- KeyboardStep = 0.01f
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
},
new SettingsSlider
{
LabelText = "Horizontal scale",
Bindable = scalingSizeX,
- KeyboardStep = 0.01f
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
},
new SettingsSlider
{
LabelText = "Vertical scale",
Bindable = scalingSizeY,
- KeyboardStep = 0.01f
+ KeyboardStep = 0.01f,
+ DisplayAsPercentage = true
},
}
},
diff --git a/osu.Game/Overlays/Settings/SettingsSlider.cs b/osu.Game/Overlays/Settings/SettingsSlider.cs
index 96c0279a7b..9fc3379b94 100644
--- a/osu.Game/Overlays/Settings/SettingsSlider.cs
+++ b/osu.Game/Overlays/Settings/SettingsSlider.cs
@@ -3,6 +3,7 @@
using System;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics.UserInterface;
namespace osu.Game.Overlays.Settings
@@ -22,16 +23,32 @@ namespace osu.Game.Overlays.Settings
RelativeSizeAxes = Axes.X
};
+ ///
+ /// When set, value changes based on user input are only transferred to any bound control's Current on commit.
+ /// This is useful if the UI interaction could be adversely affected by the value changing, such as the position of the on the screen.
+ ///
public bool TransferValueOnCommit
{
get => ((TSlider)Control).TransferValueOnCommit;
set => ((TSlider)Control).TransferValueOnCommit = value;
}
+ ///
+ /// A custom step value for each key press which actuates a change on this control.
+ ///
public float KeyboardStep
{
get => ((TSlider)Control).KeyboardStep;
set => ((TSlider)Control).KeyboardStep = value;
}
+
+ ///
+ /// Whether to format the tooltip as a percentage or the actual value.
+ ///
+ public bool DisplayAsPercentage
+ {
+ get => ((TSlider)Control).DisplayAsPercentage;
+ set => ((TSlider)Control).DisplayAsPercentage = value;
+ }
}
}
diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs
index 0c55b8383b..b410739b25 100644
--- a/osu.Game/Overlays/TabControlOverlayHeader.cs
+++ b/osu.Game/Overlays/TabControlOverlayHeader.cs
@@ -1,28 +1,56 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
+using osu.Game.Graphics.UserInterface;
using osuTK;
namespace osu.Game.Overlays
{
- public abstract class TabControlOverlayHeader : OverlayHeader
+ ///
+ /// An overlay header which contains a .
+ ///
+ /// The type of item to be represented by tabs.
+ public abstract class TabControlOverlayHeader : OverlayHeader
{
- protected OverlayHeaderTabControl TabControl;
+ protected OsuTabControl TabControl;
- protected override TabControl CreateTabControl() => TabControl = new OverlayHeaderTabControl();
+ private readonly Box controlBackground;
+
+ protected TabControlOverlayHeader()
+ {
+ HeaderInfo.Add(new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Children = new Drawable[]
+ {
+ controlBackground = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ },
+ TabControl = CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN })
+ }
+ });
+ }
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
TabControl.AccentColour = colourProvider.Highlight1;
+ controlBackground.Colour = colourProvider.Dark4;
}
- public class OverlayHeaderTabControl : OverlayTabControl
+ [NotNull]
+ protected virtual OsuTabControl CreateTabControl() => new OverlayHeaderTabControl();
+
+ public class OverlayHeaderTabControl : OverlayTabControl
{
public OverlayHeaderTabControl()
{
@@ -34,10 +62,7 @@ namespace osu.Game.Overlays
Height = 35;
}
- protected override TabItem CreateTabItem(string value) => new OverlayHeaderTabItem(value)
- {
- AccentColour = AccentColour,
- };
+ protected override TabItem CreateTabItem(T value) => new OverlayHeaderTabItem(value);
protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer
{
@@ -49,10 +74,10 @@ namespace osu.Game.Overlays
private class OverlayHeaderTabItem : OverlayTabItem
{
- public OverlayHeaderTabItem(string value)
+ public OverlayHeaderTabItem(T value)
: base(value)
{
- Text.Text = value;
+ Text.Text = value.ToString().ToLower();
Text.Font = OsuFont.GetFont(size: 14);
Bar.ExpandedSize = 5;
}
diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs
index 07c0dbed43..6f0d96c226 100644
--- a/osu.Game/Overlays/UserProfileOverlay.cs
+++ b/osu.Game/Overlays/UserProfileOverlay.cs
@@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
-using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays.Profile;
@@ -30,7 +29,7 @@ namespace osu.Game.Overlays
public const float CONTENT_X_MARGIN = 70;
public UserProfileOverlay()
- : base(OverlayColourScheme.Green)
+ : base(OverlayColourScheme.Pink)
{
}
@@ -74,7 +73,7 @@ namespace osu.Game.Overlays
Add(new Box
{
RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.Gray(0.1f)
+ Colour = ColourProvider.Background6
});
Add(sectionsContainer = new ProfileSectionsContainer
@@ -83,7 +82,8 @@ namespace osu.Game.Overlays
FixedHeader = tabs,
HeaderBackground = new Box
{
- Colour = OsuColour.Gray(34),
+ // this is only visible as the ProfileTabControl background
+ Colour = ColourProvider.Background5,
RelativeSizeAxes = Axes.Both
},
});
@@ -165,9 +165,9 @@ namespace osu.Game.Overlays
};
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
- AccentColour = colours.Seafoam;
+ AccentColour = colourProvider.Highlight1;
}
private class ProfileTabItem : OverlayTabItem
diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
index 9ee3bacf9b..ab8dccb9dd 100644
--- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs
+++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs
@@ -9,6 +9,7 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input;
+using osu.Framework.Input.Events;
using osu.Framework.Logging;
using osu.Framework.Threading;
using osu.Framework.Timing;
@@ -25,6 +26,7 @@ using osu.Game.Screens.Edit.Components.RadioButtons;
using osu.Game.Screens.Edit.Compose;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
+using Key = osuTK.Input.Key;
namespace osu.Game.Rulesets.Edit
{
@@ -58,6 +60,8 @@ namespace osu.Game.Rulesets.Edit
private InputManager inputManager;
+ private RadioButtonCollection toolboxCollection;
+
protected HitObjectComposer(Ruleset ruleset)
{
Ruleset = ruleset;
@@ -100,7 +104,6 @@ namespace osu.Game.Rulesets.Edit
layerContainers.Add(layerBelowRuleset);
layerContainers.Add(layerAboveRuleset);
- RadioButtonCollection toolboxCollection;
InternalChild = new GridContainer
{
RelativeSizeAxes = Axes.Both,
@@ -137,16 +140,32 @@ namespace osu.Game.Rulesets.Edit
}
};
- toolboxCollection.Items =
- CompositionTools.Select(t => new RadioButton(t.Name, () => selectTool(t)))
- .Prepend(new RadioButton("Select", () => selectTool(null)))
- .ToList();
+ toolboxCollection.Items = CompositionTools
+ .Prepend(new SelectTool())
+ .Select(t => new RadioButton(t.Name, () => toolSelected(t)))
+ .ToList();
- toolboxCollection.Items[0].Select();
+ setSelectTool();
blueprintContainer.SelectionChanged += selectionChanged;
}
+ protected override bool OnKeyDown(KeyDownEvent e)
+ {
+ if (e.Key >= Key.Number1 && e.Key <= Key.Number9)
+ {
+ var item = toolboxCollection.Items.Skip(e.Key - Key.Number1).FirstOrDefault();
+
+ if (item != null)
+ {
+ item.Select();
+ return true;
+ }
+ }
+
+ return base.OnKeyDown(e);
+ }
+
protected override void LoadComplete()
{
base.LoadComplete();
@@ -181,20 +200,30 @@ namespace osu.Game.Rulesets.Edit
{
var hitObjects = selectedHitObjects.ToArray();
- if (!hitObjects.Any())
- distanceSnapGridContainer.Hide();
- else
+ if (hitObjects.Any())
+ {
+ // ensure in selection mode if a selection is made.
+ setSelectTool();
+
showGridFor(hitObjects);
+ }
+ else
+ distanceSnapGridContainer.Hide();
}
- private void selectTool(HitObjectCompositionTool tool)
+ private void setSelectTool() => toolboxCollection.Items.First().Select();
+
+ private void toolSelected(HitObjectCompositionTool tool)
{
blueprintContainer.CurrentTool = tool;
- if (tool == null)
+ if (tool is SelectTool)
distanceSnapGridContainer.Hide();
else
+ {
+ EditorBeatmap.SelectedHitObjects.Clear();
showGridFor(Enumerable.Empty());
+ }
}
private void showGridFor(IEnumerable selectedHitObjects)
@@ -275,10 +304,10 @@ namespace osu.Game.Rulesets.Edit
}
public override double GetSnappedDurationFromDistance(double referenceTime, float distance)
- => beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance));
+ => beatSnapProvider.SnapTime(referenceTime + DistanceToDuration(referenceTime, distance), referenceTime) - referenceTime;
public override float GetSnappedDistanceFromDistance(double referenceTime, float distance)
- => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance)));
+ => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(DistanceToDuration(referenceTime, distance), referenceTime));
protected override void Dispose(bool isDisposing)
{
diff --git a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs
index e1daafaebe..616f854cd7 100644
--- a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs
+++ b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs
@@ -8,10 +8,10 @@ namespace osu.Game.Rulesets.Edit
///
/// Snaps a duration to the closest beat of a timing point applicable at the reference time.
///
- /// The time of the timing point which resides in.
- /// The duration to snap.
- /// A value that represents snapped to the closest beat of the timing point.
- double SnapTime(double referenceTime, double duration);
+ /// The time to snap.
+ /// An optional reference point to use for timing point lookup.
+ /// A value that represents snapped to the closest beat of the timing point.
+ double SnapTime(double time, double? referenceTime = null);
///
/// Get the most appropriate beat length at a given time.
diff --git a/osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs b/osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs
index 825c63e6ee..0631031302 100644
--- a/osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs
+++ b/osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs
@@ -13,5 +13,7 @@ namespace osu.Game.Rulesets.Edit.Tools
}
public abstract PlacementBlueprint CreatePlacementBlueprint();
+
+ public override string ToString() => Name;
}
}
diff --git a/osu.Game/Rulesets/Edit/Tools/SelectTool.cs b/osu.Game/Rulesets/Edit/Tools/SelectTool.cs
new file mode 100644
index 0000000000..b96eeb0790
--- /dev/null
+++ b/osu.Game/Rulesets/Edit/Tools/SelectTool.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+namespace osu.Game.Rulesets.Edit.Tools
+{
+ public class SelectTool : HitObjectCompositionTool
+ {
+ public SelectTool()
+ : base("Select")
+ {
+ }
+
+ public override PlacementBlueprint CreatePlacementBlueprint() => null;
+ }
+}
diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs
index 133f9ceb39..9e63142b42 100644
--- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs
+++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs
@@ -20,6 +20,9 @@ namespace osu.Game.Rulesets.Mods
///
private const double final_rate_progress = 0.75f;
+ [SettingSource("Initial rate", "The starting speed of the track")]
+ public abstract BindableNumber InitialRate { get; }
+
[SettingSource("Final rate", "The final speed to ramp to")]
public abstract BindableNumber FinalRate { get; }
@@ -69,6 +72,6 @@ namespace osu.Game.Rulesets.Mods
///
/// The amount of adjustment to apply (from 0..1).
private void applyAdjustment(double amount) =>
- SpeedChange.Value = 1 + (FinalRate.Value - 1) * Math.Clamp(amount, 0, 1);
+ SpeedChange.Value = InitialRate.Value + (FinalRate.Value - InitialRate.Value) * Math.Clamp(amount, 0, 1);
}
}
diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs
index da3bd75b44..5e634ac434 100644
--- a/osu.Game/Rulesets/Mods/ModWindDown.cs
+++ b/osu.Game/Rulesets/Mods/ModWindDown.cs
@@ -17,6 +17,16 @@ namespace osu.Game.Rulesets.Mods
public override IconUsage? Icon => FontAwesome.Solid.ChevronCircleDown;
public override double ScoreMultiplier => 1.0;
+ [SettingSource("Initial rate", "The starting speed of the track")]
+ public override BindableNumber InitialRate { get; } = new BindableDouble
+ {
+ MinValue = 1,
+ MaxValue = 2,
+ Default = 1,
+ Value = 1,
+ Precision = 0.01,
+ };
+
[SettingSource("Final rate", "The speed increase to ramp towards")]
public override BindableNumber FinalRate { get; } = new BindableDouble
{
diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs
index 3f456a42a5..74c6fc22d3 100644
--- a/osu.Game/Rulesets/Mods/ModWindUp.cs
+++ b/osu.Game/Rulesets/Mods/ModWindUp.cs
@@ -17,6 +17,16 @@ namespace osu.Game.Rulesets.Mods
public override IconUsage? Icon => FontAwesome.Solid.ChevronCircleUp;
public override double ScoreMultiplier => 1.0;
+ [SettingSource("Initial rate", "The starting speed of the track")]
+ public override BindableNumber InitialRate { get; } = new BindableDouble
+ {
+ MinValue = 0.5,
+ MaxValue = 1,
+ Default = 1,
+ Value = 1,
+ Precision = 0.01,
+ };
+
[SettingSource("Final rate", "The speed increase to ramp towards")]
public override BindableNumber FinalRate { get; } = new BindableDouble
{
diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
index 8ccc2af93b..8eafaa88ec 100644
--- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
@@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Scoring
public readonly Bindable Rank = new Bindable(ScoreRank.X);
///
- /// THe highest combo achieved by this score.
+ /// The highest combo achieved by this score.
///
public readonly BindableInt HighestCombo = new BindableInt();
diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs
index ce95d81f54..d9477dd4bc 100644
--- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs
+++ b/osu.Game/Screens/Edit/BindableBeatDivisor.cs
@@ -52,30 +52,52 @@ namespace osu.Game.Screens.Edit
{
switch (beatDivisor)
{
+ case 1:
+ return Color4.White;
+
case 2:
- return colours.BlueLight;
+ return colours.Red;
case 4:
return colours.Blue;
case 8:
- return colours.BlueDarker;
+ return colours.Yellow;
case 16:
return colours.PurpleDark;
case 3:
- return colours.YellowLight;
+ return colours.Purple;
case 6:
- return colours.Yellow;
+ return colours.YellowDark;
case 12:
return colours.YellowDarker;
default:
- return Color4.White;
+ return Color4.Red;
}
}
+
+ ///
+ /// Retrieves the applicable divisor for a specific beat index.
+ ///
+ /// The 0-based beat index.
+ /// The beat divisor.
+ /// The applicable divisor.
+ public static int GetDivisorForBeatIndex(int index, int beatDivisor)
+ {
+ int beat = index % beatDivisor;
+
+ foreach (var divisor in BindableBeatDivisor.VALID_DIVISORS)
+ {
+ if ((beat * divisor) % beatDivisor == 0)
+ return divisor;
+ }
+
+ return 0;
+ }
}
}
diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs
index 5854d66aa8..7be91f4e8e 100644
--- a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs
+++ b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs
@@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
-using osu.Framework.Input.Events;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
@@ -37,8 +36,8 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
{
this.button = button;
- Text = button.Text;
- Action = button.Action;
+ Text = button.Item.ToString();
+ Action = button.Select;
RelativeSizeAxes = Axes.X;
@@ -100,19 +99,6 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
bubble.Colour = button.Selected.Value ? selectedBubbleColour : defaultBubbleColour;
}
- protected override bool OnClick(ClickEvent e)
- {
- if (button.Selected.Value)
- return true;
-
- if (!Enabled.Value)
- return true;
-
- button.Selected.Value = true;
-
- return base.OnClick(e);
- }
-
protected override SpriteText CreateText() => new OsuSpriteText
{
Depth = -1,
diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs
index 3692c0437b..b515d7c8bd 100644
--- a/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs
+++ b/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs
@@ -15,33 +15,37 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons
public readonly BindableBool Selected;
///
- /// The text that should be displayed in this button.
+ /// The item related to this button.
///
- public string Text;
+ public object Item;
- ///
- /// The that should be invoked when this button is selected.
- ///
- public Action Action;
+ private readonly Action action;
- public RadioButton(string text, Action action)
+ public RadioButton(object item, Action action)
{
- Text = text;
- Action = action;
+ Item = item;
+ this.action = action;
Selected = new BindableBool();
}
- public RadioButton(string text)
- : this(text, null)
+ public RadioButton(string item)
+ : this(item, null)
{
- Text = text;
- Action = null;
+ Item = item;
+ action = null;
}
///
/// Selects this .
///
- public void Select() => Selected.Value = true;
+ public void Select()
+ {
+ if (!Selected.Value)
+ {
+ Selected.Value = true;
+ action?.Invoke();
+ }
+ }
///
/// Deselects this .
diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs
index 9c00cce57a..1ac960039e 100644
--- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs
+++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs
@@ -12,7 +12,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations
///
public class PointVisualisation : Box
{
- protected PointVisualisation(double startTime)
+ public PointVisualisation(double startTime)
{
Origin = Anchor.TopCentre;
diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
index 6b21f56567..675b2b648d 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs
@@ -74,12 +74,16 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
foreach (var o in objects)
selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select();
+
+ SelectionChanged?.Invoke(selectedHitObjects);
};
selectedHitObjects.ItemsRemoved += objects =>
{
foreach (var o in objects)
selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect();
+
+ SelectionChanged?.Invoke(selectedHitObjects);
};
}
@@ -332,8 +336,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
selectionHandler.HandleSelected(blueprint);
selectionBlueprints.ChangeChildDepth(blueprint, 1);
beatmap.SelectedHitObjects.Add(blueprint.HitObject);
-
- SelectionChanged?.Invoke(selectionHandler.SelectedHitObjects);
}
private void onBlueprintDeselected(SelectionBlueprint blueprint)
@@ -341,8 +343,6 @@ namespace osu.Game.Screens.Edit.Compose.Components
selectionHandler.HandleDeselected(blueprint);
selectionBlueprints.ChangeChildDepth(blueprint, 0);
beatmap.SelectedHitObjects.Remove(blueprint.HitObject);
-
- SelectionChanged?.Invoke(selectionHandler.SelectedHitObjects);
}
#endregion
diff --git a/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs
index 23ed10b92d..730f482f83 100644
--- a/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
}
- protected override void CreateContent(Vector2 startPosition)
+ protected override void CreateContent()
{
const float crosshair_thickness = 1;
const float crosshair_max_size = 10;
@@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
new Box
{
Origin = Anchor.Centre,
- Position = startPosition,
+ Position = StartPosition,
Width = crosshair_thickness,
EdgeSmoothness = new Vector2(1),
Height = Math.Min(crosshair_max_size, DistanceSpacing * 2),
@@ -34,15 +34,15 @@ namespace osu.Game.Screens.Edit.Compose.Components
new Box
{
Origin = Anchor.Centre,
- Position = startPosition,
+ Position = StartPosition,
EdgeSmoothness = new Vector2(1),
Width = Math.Min(crosshair_max_size, DistanceSpacing * 2),
Height = crosshair_thickness,
}
});
- float dx = Math.Max(startPosition.X, DrawWidth - startPosition.X);
- float dy = Math.Max(startPosition.Y, DrawHeight - startPosition.Y);
+ float dx = Math.Max(StartPosition.X, DrawWidth - StartPosition.X);
+ float dy = Math.Max(StartPosition.Y, DrawHeight - StartPosition.Y);
float maxDistance = new Vector2(dx, dy).Length;
int requiredCircles = Math.Min(MaxIntervals, (int)(maxDistance / DistanceSpacing));
@@ -53,11 +53,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
AddInternal(new CircularProgress
{
Origin = Anchor.Centre,
- Position = startPosition,
+ Position = StartPosition,
Current = { Value = 1 },
Size = new Vector2(radius),
InnerRadius = 4 * 1f / radius,
- Colour = GetColourForBeatIndex(i)
+ Colour = GetColourForIndexFromPlacement(i)
});
}
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
index 53c5cf97fa..479de64eab 100644
--- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs
@@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+using System;
using osu.Framework.Allocation;
using osu.Framework.Caching;
using osu.Framework.Graphics;
@@ -106,7 +107,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
if (!gridCache.IsValid)
{
ClearInternal();
- CreateContent(StartPosition);
+ CreateContent();
gridCache.Validate();
}
}
@@ -114,7 +115,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
///
/// Creates the content which visualises the grid ticks.
///
- protected abstract void CreateContent(Vector2 startPosition);
+ protected abstract void CreateContent();
///
/// Snaps a position to this grid.
@@ -126,25 +127,17 @@ namespace osu.Game.Screens.Edit.Compose.Components
///
/// Retrieves the applicable colour for a beat index.
///
- /// The 0-based beat index.
+ /// The 0-based beat index from the point of placement.
/// The applicable colour.
- protected ColourInfo GetColourForBeatIndex(int index)
+ protected ColourInfo GetColourForIndexFromPlacement(int placementIndex)
{
- int beat = (index + 1) % beatDivisor.Value;
- ColourInfo colour = Colours.Gray5;
+ var timingPoint = beatmap.ControlPointInfo.TimingPointAt(StartTime);
+ var beatLength = timingPoint.BeatLength / beatDivisor.Value;
+ var beatIndex = (int)Math.Round((StartTime - timingPoint.Time) / beatLength);
- for (int i = 0; i < BindableBeatDivisor.VALID_DIVISORS.Length; i++)
- {
- int divisor = BindableBeatDivisor.VALID_DIVISORS[i];
+ var colour = BindableBeatDivisor.GetColourFor(BindableBeatDivisor.GetDivisorForBeatIndex(beatIndex + placementIndex + 1, beatDivisor.Value), Colours);
- if ((beat * divisor) % beatDivisor.Value == 0)
- {
- colour = BindableBeatDivisor.GetColourFor(divisor, Colours);
- break;
- }
- }
-
- int repeatIndex = index / beatDivisor.Value;
+ int repeatIndex = placementIndex / beatDivisor.Value;
return colour.MultiplyAlpha(0.5f / (repeatIndex + 1));
}
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
index 96395696c3..a33040f400 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs
@@ -30,7 +30,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
ZoomDuration = 200;
ZoomEasing = Easing.OutQuint;
- Zoom = 10;
ScrollbarVisible = false;
}
@@ -61,9 +60,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
waveform.Waveform = b.NewValue.Waveform;
track = b.NewValue.Track;
+
+ MinZoom = getZoomLevelForVisibleMilliseconds(10000);
+ MaxZoom = getZoomLevelForVisibleMilliseconds(500);
+ Zoom = getZoomLevelForVisibleMilliseconds(2000);
}, true);
}
+ private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds);
+
///
/// The timeline's scroll position in the last frame.
///
@@ -177,7 +182,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time)
{
var targetTime = (position.X / Content.DrawWidth) * track.Length;
- return (position, beatSnapProvider.SnapTime(targetTime, targetTime));
+ return (position, beatSnapProvider.SnapTime(targetTime));
}
public float GetBeatSnapDistanceAt(double referenceTime) => throw new NotImplementedException();
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs
new file mode 100644
index 0000000000..f9b92c0504
--- /dev/null
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs
@@ -0,0 +1,90 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Linq;
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics;
+using osu.Game.Beatmaps;
+using osu.Game.Graphics;
+using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts;
+using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations;
+
+namespace osu.Game.Screens.Edit.Compose.Components.Timeline
+{
+ public class TimelineTickDisplay : TimelinePart
+ {
+ [Resolved]
+ private EditorBeatmap beatmap { get; set; }
+
+ [Resolved]
+ private Bindable working { get; set; }
+
+ [Resolved]
+ private BindableBeatDivisor beatDivisor { get; set; }
+
+ [Resolved]
+ private OsuColour colours { get; set; }
+
+ public TimelineTickDisplay()
+ {
+ RelativeSizeAxes = Axes.Both;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ beatDivisor.BindValueChanged(_ => createLines(), true);
+ }
+
+ private void createLines()
+ {
+ Clear();
+
+ for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++)
+ {
+ var point = beatmap.ControlPointInfo.TimingPoints[i];
+ var until = beatmap.ControlPointInfo.TimingPoints.Count < i + 1 ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length;
+
+ int beat = 0;
+
+ for (double t = point.Time; t < until; t += point.BeatLength / beatDivisor.Value)
+ {
+ var indexInBeat = beat % beatDivisor.Value;
+
+ if (indexInBeat == 0)
+ {
+ Add(new PointVisualisation(t)
+ {
+ Colour = BindableBeatDivisor.GetColourFor(1, colours),
+ Origin = Anchor.TopCentre,
+ });
+ }
+ else
+ {
+ var divisor = BindableBeatDivisor.GetDivisorForBeatIndex(beat, beatDivisor.Value);
+ var colour = BindableBeatDivisor.GetColourFor(divisor, colours);
+ var height = 0.1f - (float)divisor / BindableBeatDivisor.VALID_DIVISORS.Last() * 0.08f;
+
+ Add(new PointVisualisation(t)
+ {
+ Colour = colour,
+ Height = height,
+ Origin = Anchor.TopCentre,
+ });
+
+ Add(new PointVisualisation(t)
+ {
+ Colour = colour,
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomCentre,
+ Height = height,
+ });
+ }
+
+ beat++;
+ }
+ }
+ }
+ }
+}
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs
index 9aa527667b..7ce8a751e0 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs
@@ -36,12 +36,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y });
}
- private int minZoom = 1;
+ private float minZoom = 1;
///
/// The minimum zoom level allowed.
///
- public int MinZoom
+ public float MinZoom
{
get => minZoom;
set
@@ -56,12 +56,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}
}
- private int maxZoom = 60;
+ private float maxZoom = 60;
///
/// The maximum zoom level allowed.
///
- public int MaxZoom
+ public float MaxZoom
{
get => maxZoom;
set
diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs
index eae94a3c8e..8c7270d3a2 100644
--- a/osu.Game/Screens/Edit/Editor.cs
+++ b/osu.Game/Screens/Edit/Editor.cs
@@ -348,7 +348,7 @@ namespace osu.Game.Screens.Edit
beatmapManager.Export(Beatmap.Value.BeatmapSetInfo);
}
- public double SnapTime(double referenceTime, double duration) => editorBeatmap.SnapTime(referenceTime, duration);
+ public double SnapTime(double time, double? referenceTime) => editorBeatmap.SnapTime(time, referenceTime);
public double GetBeatLengthAtTime(double referenceTime) => editorBeatmap.GetBeatLengthAtTime(referenceTime);
diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs
index 9c75d40bec..6edd62fa67 100644
--- a/osu.Game/Screens/Edit/EditorBeatmap.cs
+++ b/osu.Game/Screens/Edit/EditorBeatmap.cs
@@ -128,12 +128,12 @@ namespace osu.Game.Screens.Edit
return list.Count - 1;
}
- public double SnapTime(double referenceTime, double duration)
+ public double SnapTime(double time, double? referenceTime)
{
- double beatLength = GetBeatLengthAtTime(referenceTime);
+ var timingPoint = ControlPointInfo.TimingPointAt(referenceTime ?? time);
+ var beatLength = timingPoint.BeatLength / BeatDivisor;
- // A 1ms offset prevents rounding errors due to minute variations in duration
- return (int)((duration + 1) / beatLength) * beatLength;
+ return timingPoint.Time + (int)Math.Round((time - timingPoint.Time) / beatLength, MidpointRounding.AwayFromZero) * beatLength;
}
public double GetBeatLengthAtTime(double referenceTime) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor;
diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
index 8967f24185..7ee1005add 100644
--- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
+++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
@@ -102,7 +102,11 @@ namespace osu.Game.Screens.Edit
LoadComponentAsync(new TimelineArea
{
RelativeSizeAxes = Axes.Both,
- Child = CreateTimelineContent()
+ Children = new[]
+ {
+ new TimelineTickDisplay(),
+ CreateTimelineContent(),
+ }
}, timelineContainer.Add);
});
}
diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs
index aa92451c77..bab9672d65 100644
--- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs
+++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs
@@ -28,7 +28,7 @@ namespace osu.Game.Screens.Multi.Match.Components
protected override IEnumerable GetStatistics(ScoreInfo model) => new[]
{
- new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", model.Accuracy)),
+ new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:0%}" : @"{0:0.00%}", model.Accuracy)),
new LeaderboardScoreStatistic(FontAwesome.Solid.Sync, "Total Attempts", score.TotalAttempts.ToString()),
new LeaderboardScoreStatistic(FontAwesome.Solid.Check, "Completed Beatmaps", score.CompletedBeatmaps.ToString()),
};
diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs
index 0f3c92a962..00edd4db99 100644
--- a/osu.Game/Screens/Play/HUD/ModDisplay.cs
+++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs
@@ -41,7 +41,7 @@ namespace osu.Game.Screens.Play.HUD
}
}
- private readonly FillFlowContainer iconsContainer;
+ protected readonly FillFlowContainer IconsContainer;
private readonly OsuSpriteText unrankedText;
public ModDisplay()
@@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play.HUD
Children = new Drawable[]
{
- iconsContainer = new ReverseChildIDFillFlowContainer
+ IconsContainer = new ReverseChildIDFillFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
@@ -69,11 +69,11 @@ namespace osu.Game.Screens.Play.HUD
Current.ValueChanged += mods =>
{
- iconsContainer.Clear();
+ IconsContainer.Clear();
foreach (Mod mod in mods.NewValue)
{
- iconsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.6f) });
+ IconsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.6f) });
}
if (IsLoaded)
@@ -92,7 +92,7 @@ namespace osu.Game.Screens.Play.HUD
base.LoadComplete();
appearTransform();
- iconsContainer.FadeInFromZero(fade_duration, Easing.OutQuint);
+ IconsContainer.FadeInFromZero(fade_duration, Easing.OutQuint);
}
private void appearTransform()
@@ -104,17 +104,17 @@ namespace osu.Game.Screens.Play.HUD
expand();
- using (iconsContainer.BeginDelayedSequence(1200))
+ using (IconsContainer.BeginDelayedSequence(1200))
contract();
}
private void expand()
{
if (AllowExpand)
- iconsContainer.TransformSpacingTo(new Vector2(5, 0), 500, Easing.OutQuint);
+ IconsContainer.TransformSpacingTo(new Vector2(5, 0), 500, Easing.OutQuint);
}
- private void contract() => iconsContainer.TransformSpacingTo(new Vector2(-25, 0), 500, Easing.OutQuint);
+ private void contract() => IconsContainer.TransformSpacingTo(new Vector2(-25, 0), 500, Easing.OutQuint);
protected override bool OnHover(HoverEvent e)
{
diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs
index ff64f35a18..9db3a587fa 100644
--- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs
+++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs
@@ -27,12 +27,18 @@ namespace osu.Game.Screens.Play.PlayerSettings
{
Text = "Background dim:"
},
- dimSliderBar = new PlayerSliderBar(),
+ dimSliderBar = new PlayerSliderBar
+ {
+ DisplayAsPercentage = true
+ },
new OsuSpriteText
{
Text = "Background blur:"
},
- blurSliderBar = new PlayerSliderBar(),
+ blurSliderBar = new PlayerSliderBar
+ {
+ DisplayAsPercentage = true
+ },
new OsuSpriteText
{
Text = "Toggles:"
diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs
index 4433543ca1..592e26adc2 100644
--- a/osu.Game/Screens/Select/BeatmapCarousel.cs
+++ b/osu.Game/Screens/Select/BeatmapCarousel.cs
@@ -56,6 +56,9 @@ namespace osu.Game.Screens.Select
public override bool HandleNonPositionalInput => AllowSelection;
public override bool HandlePositionalInput => AllowSelection;
+ public override bool PropagatePositionalInputSubTree => AllowSelection;
+ public override bool PropagateNonPositionalInputSubTree => AllowSelection;
+
///
/// Whether carousel items have completed asynchronously loaded.
///
@@ -65,6 +68,7 @@ namespace osu.Game.Screens.Select
private IEnumerable beatmapSets => root.Children.OfType();
+ // todo: only used for testing, maybe remove.
public IEnumerable BeatmapSets
{
get => beatmapSets.Select(g => g.BeatmapSet);
@@ -130,8 +134,11 @@ namespace osu.Game.Screens.Select
};
}
+ [Resolved]
+ private BeatmapManager beatmaps { get; set; }
+
[BackgroundDependencyLoader(permitNulls: true)]
- private void load(OsuConfigManager config, BeatmapManager beatmaps)
+ private void load(OsuConfigManager config)
{
config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm);
config.BindWith(OsuSetting.SongSelectRightMouseScroll, RightClickScrollingEnabled);
@@ -139,6 +146,11 @@ namespace osu.Game.Screens.Select
RightClickScrollingEnabled.ValueChanged += enabled => scroll.RightMouseScrollbar = enabled.NewValue;
RightClickScrollingEnabled.TriggerChange();
+ beatmaps.ItemAdded += beatmapAdded;
+ beatmaps.ItemRemoved += beatmapRemoved;
+ beatmaps.BeatmapHidden += beatmapHidden;
+ beatmaps.BeatmapRestored += beatmapRestored;
+
loadBeatmapSets(beatmaps.GetAllUsableBeatmapSetsEnumerable());
}
@@ -449,8 +461,6 @@ namespace osu.Game.Screens.Select
return true;
}
- protected override bool ReceivePositionalInputAtSubTree(Vector2 screenSpacePos) => ReceivePositionalInputAt(screenSpacePos);
-
protected override void Update()
{
base.Update();
@@ -534,11 +544,27 @@ namespace osu.Game.Screens.Select
{
base.Dispose(isDisposing);
+ if (beatmaps != null)
+ {
+ beatmaps.ItemAdded -= beatmapAdded;
+ beatmaps.ItemRemoved -= beatmapRemoved;
+ beatmaps.BeatmapHidden -= beatmapHidden;
+ beatmaps.BeatmapRestored -= beatmapRestored;
+ }
+
// aggressively dispose "off-screen" items to reduce GC pressure.
foreach (var i in Items)
i.Dispose();
}
+ private void beatmapRemoved(BeatmapSetInfo item) => RemoveBeatmapSet(item);
+
+ private void beatmapAdded(BeatmapSetInfo item) => UpdateBeatmapSet(item);
+
+ private void beatmapRestored(BeatmapInfo b) => UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID));
+
+ private void beatmapHidden(BeatmapInfo b) => UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID));
+
private CarouselBeatmapSet createCarouselSet(BeatmapSetInfo beatmapSet)
{
if (beatmapSet.Beatmaps.All(b => b.Hidden))
diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs
index b7f60a8370..56c400e869 100644
--- a/osu.Game/Screens/Select/Details/AdvancedStats.cs
+++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs
@@ -117,9 +117,20 @@ namespace osu.Game.Screens.Select.Details
mod.ApplyToDifficulty(adjustedDifficulty);
}
- // Account for mania differences
- firstValue.Title = (Beatmap?.Ruleset?.ID ?? 0) == 3 ? "Key Amount" : "Circle Size";
- firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize);
+ switch (Beatmap?.Ruleset?.ID ?? 0)
+ {
+ case 3:
+ // Account for mania differences locally for now
+ // Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes
+ firstValue.Title = "Key Count";
+ firstValue.Value = (baseDifficulty?.CircleSize ?? 0, null);
+ break;
+
+ default:
+ firstValue.Title = "Circle Size";
+ firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize);
+ break;
+ }
starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null);
diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs
index 4dcab60548..35970cd960 100644
--- a/osu.Game/Screens/Select/FooterButton.cs
+++ b/osu.Game/Screens/Select/FooterButton.cs
@@ -56,6 +56,7 @@ namespace osu.Game.Screens.Select
}
}
+ protected FillFlowContainer ButtonContentContainer;
protected readonly Container TextContainer;
protected readonly SpriteText SpriteText;
private readonly Box box;
@@ -80,15 +81,36 @@ namespace osu.Game.Screens.Select
EdgeSmoothness = new Vector2(2, 0),
RelativeSizeAxes = Axes.X,
},
- TextContainer = new Container
+ new Container
{
- Size = new Vector2(100 - SHEAR_WIDTH, 50),
- Shear = -SHEAR,
- Child = SpriteText = new OsuSpriteText
+ AutoSizeAxes = Axes.Both,
+ Children = new Drawable[]
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- }
+ ButtonContentContainer = new FillFlowContainer
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ Direction = FillDirection.Horizontal,
+ Shear = -SHEAR,
+ AutoSizeAxes = Axes.X,
+ Height = 50,
+ Spacing = new Vector2(15, 0),
+ Children = new Drawable[]
+ {
+ TextContainer = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Both,
+ Child = SpriteText = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ }
+ },
+ },
+ },
+ },
},
};
}
@@ -97,6 +119,19 @@ namespace osu.Game.Screens.Select
public Action HoverLost;
public Key? Hotkey;
+ protected override void UpdateAfterChildren()
+ {
+ base.UpdateAfterChildren();
+
+ float horizontalMargin = (100 - TextContainer.Width) / 2;
+ ButtonContentContainer.Padding = new MarginPadding
+ {
+ Left = horizontalMargin,
+ // right side margin offset to compensate for shear
+ Right = horizontalMargin - SHEAR_WIDTH / 2
+ };
+ }
+
protected override bool OnHover(HoverEvent e)
{
Hovered?.Invoke();
diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs
index 8419ee0c2a..4f2369847f 100644
--- a/osu.Game/Screens/Select/FooterButtonMods.cs
+++ b/osu.Game/Screens/Select/FooterButtonMods.cs
@@ -3,7 +3,6 @@
using osu.Framework.Bindables;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
using osu.Game.Screens.Play.HUD;
using osu.Game.Rulesets.Mods;
using System.Collections.Generic;
@@ -34,31 +33,18 @@ namespace osu.Game.Screens.Select
public FooterButtonMods()
{
- Add(new FillFlowContainer
+ ButtonContentContainer.Add(modDisplay = new FooterModDisplay
{
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.CentreLeft,
- Direction = FillDirection.Horizontal,
- Shear = -SHEAR,
- Children = new Drawable[]
- {
- modDisplay = new FooterModDisplay
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- DisplayUnrankedText = false,
- Scale = new Vector2(0.8f)
- },
- MultiplierText = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(weight: FontWeight.Bold),
- Margin = new MarginPadding { Right = 10 }
- }
- },
- AutoSizeAxes = Axes.Both,
- Margin = new MarginPadding { Left = 70 }
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ DisplayUnrankedText = false,
+ Scale = new Vector2(0.8f)
+ });
+ ButtonContentContainer.Add(MultiplierText = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(weight: FontWeight.Bold),
});
}
@@ -92,6 +78,11 @@ namespace osu.Game.Screens.Select
MultiplierText.FadeColour(lowMultiplierColour, 200);
else
MultiplierText.FadeColour(Color4.White, 200);
+
+ if (Current.Value?.Count > 0)
+ modDisplay.FadeIn();
+ else
+ modDisplay.FadeOut();
}
private class FooterModDisplay : ModDisplay
@@ -101,6 +92,7 @@ namespace osu.Game.Screens.Select
public FooterModDisplay()
{
AllowExpand = false;
+ IconsContainer.Margin = new MarginPadding();
}
}
}
diff --git a/osu.Game/Screens/Select/FooterButtonRandom.cs b/osu.Game/Screens/Select/FooterButtonRandom.cs
index 9bc5181f6f..a42e6721db 100644
--- a/osu.Game/Screens/Select/FooterButtonRandom.cs
+++ b/osu.Game/Screens/Select/FooterButtonRandom.cs
@@ -24,8 +24,11 @@ namespace osu.Game.Screens.Select
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Text = @"rewind",
- Alpha = 0
+ Alpha = 0,
});
+
+ // force both text sprites to always be present to avoid width flickering while they're being swapped out
+ SpriteText.AlwaysPresent = secondaryText.AlwaysPresent = true;
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs
index 97df40fa6d..99e76124e8 100644
--- a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs
+++ b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs
@@ -32,7 +32,7 @@ namespace osu.Game.Screens.Select
BeatmapInfo beatmap = beatmapManager.QueryBeatmap(b => b.ID == score.BeatmapInfoID);
Debug.Assert(beatmap != null);
- string accuracy = string.Format(score.Accuracy == 1 ? "{0:P0}" : "{0:P2}", score.Accuracy);
+ string accuracy = string.Format(score.Accuracy == 1 ? "{0:0%}" : "{0:0.00%}", score.Accuracy);
BodyText = $"{score.User} ({accuracy}, {score.Rank})";
Icon = FontAwesome.Regular.TrashAlt;
diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs
index c5fa9e2396..a78477c771 100644
--- a/osu.Game/Screens/Select/MatchSongSelect.cs
+++ b/osu.Game/Screens/Select/MatchSongSelect.cs
@@ -24,6 +24,8 @@ namespace osu.Game.Screens.Select
[Resolved(typeof(Room))]
protected Bindable CurrentItem { get; private set; }
+ public override bool AllowEditing => false;
+
[Resolved]
private BeatmapManager beatmaps { get; set; }
diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs
index 1a29f336ea..a16401a527 100644
--- a/osu.Game/Screens/Select/SongSelect.cs
+++ b/osu.Game/Screens/Select/SongSelect.cs
@@ -35,6 +35,7 @@ using System.Linq;
using System.Threading.Tasks;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
+using osu.Game.Overlays.Notifications;
using osu.Game.Scoring;
namespace osu.Game.Screens.Select
@@ -66,13 +67,23 @@ namespace osu.Game.Screens.Select
///
protected Container FooterPanels { get; private set; }
+ ///
+ /// Whether entering editor mode should be allowed.
+ ///
+ public virtual bool AllowEditing => true;
+
+ [Resolved(canBeNull: true)]
+ private NotificationOverlay notificationOverlay { get; set; }
+
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value);
protected BeatmapCarousel Carousel { get; private set; }
private BeatmapInfoWedge beatmapInfoWedge;
private DialogOverlay dialogOverlay;
- private BeatmapManager beatmaps;
+
+ [Resolved]
+ private BeatmapManager beatmaps { get; set; }
protected ModSelectOverlay ModSelect { get; private set; }
@@ -89,7 +100,7 @@ namespace osu.Game.Screens.Select
private MusicController music { get; set; }
[BackgroundDependencyLoader(true)]
- private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, ScoreManager scores)
+ private void load(AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, ScoreManager scores)
{
// initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter).
transferRulesetValue();
@@ -247,14 +258,6 @@ namespace osu.Game.Screens.Select
BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo), Key.Number3);
}
- if (this.beatmaps == null)
- this.beatmaps = beatmaps;
-
- this.beatmaps.ItemAdded += onBeatmapSetAdded;
- this.beatmaps.ItemRemoved += onBeatmapSetRemoved;
- this.beatmaps.BeatmapHidden += onBeatmapHidden;
- this.beatmaps.BeatmapRestored += onBeatmapRestored;
-
dialogOverlay = dialog;
sampleChangeDifficulty = audio.Samples.Get(@"SongSelect/select-difficulty");
@@ -283,7 +286,7 @@ namespace osu.Game.Screens.Select
// if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter).
bool shouldDebounce = this.IsCurrentScreen();
- Schedule(() => Carousel.Filter(criteria, shouldDebounce));
+ Carousel.Filter(criteria, shouldDebounce);
}
private DependencyContainer dependencies;
@@ -301,6 +304,12 @@ namespace osu.Game.Screens.Select
public void Edit(BeatmapInfo beatmap = null)
{
+ if (!AllowEditing)
+ {
+ notificationOverlay?.Post(new SimpleNotification { Text = "Editing is not available from the current mode." });
+ return;
+ }
+
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap ?? beatmapNoDebounce);
this.Push(new Editor());
}
@@ -316,8 +325,10 @@ namespace osu.Game.Screens.Select
if (!Carousel.BeatmapSetsLoaded)
return;
- // if we have a pending filter operation, we want to run it now.
- // it could change selection (ie. if the ruleset has been changed).
+ transferRulesetValue();
+
+ // while transferRulesetValue will flush, it only does so if the ruleset changes.
+ // the user could have changed a filter, and we want to ensure we are 100% up-to-date and consistent here.
Carousel.FlushPendingFilterOperations();
// avoid attempting to continue before a selection has been obtained.
@@ -403,20 +414,10 @@ namespace osu.Game.Screens.Select
{
Logger.Log($"updating selection with beatmap:{beatmap?.ID.ToString() ?? "null"} ruleset:{ruleset?.ID.ToString() ?? "null"}");
- if (ruleset?.Equals(decoupledRuleset.Value) == false)
+ if (transferRulesetValue())
{
- Logger.Log($"ruleset changed from \"{decoupledRuleset.Value}\" to \"{ruleset}\"");
-
+ // if the ruleset changed, the rest of the selection update will happen via updateSelectedRuleset.
Mods.Value = Array.Empty();
- decoupledRuleset.Value = ruleset;
-
- // force a filter before attempting to change the beatmap.
- // we may still be in the wrong ruleset as there is a debounce delay on ruleset changes.
- Carousel.Filter(null, false);
-
- // Filtering only completes after the carousel runs Update.
- // If we also have a pending beatmap change we should delay it one frame.
- selectionChangedDebounce = Schedule(run);
return;
}
@@ -563,14 +564,6 @@ namespace osu.Game.Screens.Select
base.Dispose(isDisposing);
decoupledRuleset.UnbindAll();
-
- if (beatmaps != null)
- {
- beatmaps.ItemAdded -= onBeatmapSetAdded;
- beatmaps.ItemRemoved -= onBeatmapSetRemoved;
- beatmaps.BeatmapHidden -= onBeatmapHidden;
- beatmaps.BeatmapRestored -= onBeatmapRestored;
- }
}
///
@@ -617,11 +610,6 @@ namespace osu.Game.Screens.Select
lastTrack.SetTarget(track);
}
- private void onBeatmapSetAdded(BeatmapSetInfo s) => Carousel.UpdateBeatmapSet(s);
- private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s);
- private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID));
- private void onBeatmapHidden(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID));
-
private void carouselBeatmapsLoaded()
{
bindBindables();
@@ -653,6 +641,7 @@ namespace osu.Game.Screens.Select
// manual binding to parent ruleset to allow for delayed load in the incoming direction.
transferRulesetValue();
+
Ruleset.ValueChanged += r => updateSelectedRuleset(r.NewValue);
decoupledRuleset.ValueChanged += r => Ruleset.Value = r.NewValue;
@@ -664,9 +653,23 @@ namespace osu.Game.Screens.Select
boundLocalBindables = true;
}
- private void transferRulesetValue()
+ ///
+ /// Transfer the game-wide ruleset to the local decoupled ruleset.
+ /// Will immediately run filter operations if required.
+ ///
+ /// Whether a transfer occurred.
+ private bool transferRulesetValue()
{
+ if (decoupledRuleset.Value?.Equals(Ruleset.Value) == true)
+ return false;
+
+ Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\"");
rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value;
+
+ // if we have a pending filter operation, we want to run it now.
+ // it could change selection (ie. if the ruleset has been changed).
+ Carousel?.FlushPendingFilterOperations();
+ return true;
}
private void delete(BeatmapSetInfo beatmap)
diff --git a/osu.Game/Tests/Visual/ManualInputManagerTestScene.cs b/osu.Game/Tests/Visual/ManualInputManagerTestScene.cs
index 86191609a4..a0af07013c 100644
--- a/osu.Game/Tests/Visual/ManualInputManagerTestScene.cs
+++ b/osu.Game/Tests/Visual/ManualInputManagerTestScene.cs
@@ -8,6 +8,7 @@ using osu.Framework.Testing.Input;
using osu.Game.Graphics.Cursor;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Input.Bindings;
using osuTK;
using osuTK.Graphics;
@@ -30,7 +31,11 @@ namespace osu.Game.Tests.Visual
InputManager = new ManualInputManager
{
UseParentInput = true,
- Child = content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both },
+ Child = new GlobalActionContainer(null)
+ {
+ RelativeSizeAxes = Axes.Both,
+ Child = content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both }
+ },
},
new Container
{
diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs
index 8926c76018..41ab7fce99 100644
--- a/osu.Game/Tests/Visual/OsuTestScene.cs
+++ b/osu.Game/Tests/Visual/OsuTestScene.cs
@@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual
protected new OsuScreenDependencies Dependencies { get; private set; }
- private readonly Lazy localStorage;
+ private Lazy localStorage;
protected Storage LocalStorage => localStorage.Value;
private readonly Lazy contextFactory;
@@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual
protected OsuTestScene()
{
- localStorage = new Lazy(() => new NativeStorage($"{GetType().Name}-{Guid.NewGuid()}"));
+ RecycleLocalStorage();
contextFactory = new Lazy(() =>
{
var factory = new DatabaseContextFactory(LocalStorage);
@@ -104,6 +104,23 @@ namespace osu.Game.Tests.Visual
base.Content.Add(content = new DrawSizePreservingFillContainer());
}
+ public void RecycleLocalStorage()
+ {
+ if (localStorage?.IsValueCreated == true)
+ {
+ try
+ {
+ localStorage.Value.DeleteDirectory(".");
+ }
+ catch
+ {
+ // we don't really care if this fails; it will just leave folders lying around from test runs.
+ }
+ }
+
+ localStorage = new Lazy(() => new NativeStorage($"{GetType().Name}-{Guid.NewGuid()}"));
+ }
+
[Resolved]
protected AudioManager Audio { get; private set; }
@@ -131,17 +148,7 @@ namespace osu.Game.Tests.Visual
if (contextFactory.IsValueCreated)
contextFactory.Value.ResetDatabase();
- if (localStorage.IsValueCreated)
- {
- try
- {
- localStorage.Value.DeleteDirectory(".");
- }
- catch
- {
- // we don't really care if this fails; it will just leave folders lying around from test runs.
- }
- }
+ RecycleLocalStorage();
}
protected override ITestSceneTestRunner CreateRunner() => new OsuTestSceneTestRunner();
diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings
index 15ea20084d..e3b64c03b9 100644
--- a/osu.sln.DotSettings
+++ b/osu.sln.DotSettings
@@ -1,4 +1,4 @@
-
+
True
True
True
@@ -245,7 +245,7 @@
RequiredForMultiline
Explicit
ExpressionBody
- ExpressionBody
+ BlockBody
True
NEXT_LINE
True
@@ -298,6 +298,7 @@
GL
GLSL
HID
+ HTML
HUD
ID
IL