From a01402664f341be9bc04ffbb9811ee6d40cbbdae Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 13 Jul 2021 05:22:11 +0300 Subject: [PATCH 001/103] Add redesigned star rating display Matching the same design as the one in the latest figma designs. --- .../Beatmaps/Drawables/StarRatingDisplayV2.cs | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs new file mode 100644 index 0000000000..aa411e74bd --- /dev/null +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs @@ -0,0 +1,99 @@ +// 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Beatmaps.Drawables +{ + public class StarRatingDisplayV2 : CompositeDrawable, IHasCurrentValue + { + private readonly Box background; + private readonly SpriteIcon starIcon; + private readonly OsuSpriteText starsText; + + private readonly BindableWithCurrent current = new BindableWithCurrent(); + + public Bindable Current + { + get => current.Current; + set => current.Current = value; + } + + [Resolved] + private OsuColour colours { get; set; } + + [Resolved(canBeNull: true)] + private OverlayColourProvider colourProvider { get; set; } + + /// + /// Creates a new using an already computed . + /// + /// The already computed to display the star difficulty of. + public StarRatingDisplayV2(StarDifficulty starDifficulty) + { + Size = new Vector2(52f, 20f); + + Current.Value = starDifficulty; + + InternalChild = new CircularContainer + { + Masking = true, + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + starIcon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Right = 30f }, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(8f), + }, + starsText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Left = 10f, Bottom = 1f }, + Font = OsuFont.Torus.With(size: 12f, weight: FontWeight.Bold), + } + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Current.BindValueChanged(c => + { + starsText.Text = c.NewValue.Stars.ToString("0.00"); + + background.Colour = colours.ForStarDifficulty(c.NewValue.Stars); + + starIcon.Colour = c.NewValue.Stars >= 7.5 + ? colourProvider?.Content1 ?? Color4.White + : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); + + starsText.Colour = c.NewValue.Stars >= 7.5 + ? colourProvider?.Content1 ?? Color4.White.Opacity(0.75f) + : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); + }, true); + } + } +} From 6c9ed16b0caa5e29f436d58c388ada3ab34e31b1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 13 Jul 2021 05:29:16 +0300 Subject: [PATCH 002/103] Add visual test scene --- .../TestSceneStarRatingDisplayV2.cs | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs new file mode 100644 index 0000000000..1b85e25e92 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs @@ -0,0 +1,69 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Utils; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; +using osuTK; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneStarRatingDisplayV2 : OsuTestScene + { + [Test] + public void TestDisplay() + { + AddStep("load displays", () => + { + Child = new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(2f), + Direction = FillDirection.Horizontal, + ChildrenEnumerable = Enumerable.Range(0, 10).Select(i => new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(2f), + Direction = FillDirection.Vertical, + ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplayV2(new StarDifficulty(i + j * 0.1f, 0)) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }) + }) + }; + }); + } + + [Test] + public void TestChangingStarRatingDisplay() + { + StarRatingDisplayV2 starRating = null; + + AddStep("load display", () => Child = starRating = new StarRatingDisplayV2(new StarDifficulty(5.55, 1)) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + AddRepeatStep("set random value", () => + { + starRating.Current.Value = new StarDifficulty(RNG.NextDouble(0.0, 11.0), 1); + }, 10); + + AddSliderStep("set exact stars", 0.0, 11.0, 5.55, d => + { + if (starRating != null) + starRating.Current.Value = new StarDifficulty(d, 1); + }); + } + } +} From 19d54ee7510d0a4d594b0897e22fd39e45c3b9e5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 16 Jul 2021 01:59:32 +0300 Subject: [PATCH 003/103] Update light background handling to `Color4.Yellow` instead Confirmed to be the way forward in https://github.com/ppy/osu-web/pull/7855#issuecomment-880959644. --- osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs index aa411e74bd..6154c8e811 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs @@ -86,13 +86,8 @@ namespace osu.Game.Beatmaps.Drawables background.Colour = colours.ForStarDifficulty(c.NewValue.Stars); - starIcon.Colour = c.NewValue.Stars >= 7.5 - ? colourProvider?.Content1 ?? Color4.White - : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); - - starsText.Colour = c.NewValue.Stars >= 7.5 - ? colourProvider?.Content1 ?? Color4.White.Opacity(0.75f) - : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); + starIcon.Colour = c.NewValue.Stars >= 6.5 ? Color4.Yellow : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); + starsText.Colour = c.NewValue.Stars >= 6.5 ? Color4.Yellow : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); }, true); } } From 95b134f3d82ff42868c6726dcd0ad22220efe327 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 17 Jul 2021 05:41:34 +0300 Subject: [PATCH 004/103] Use `OsuColour.Orange1` instead of pure yellow --- osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs index 6154c8e811..5a942cdeee 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs @@ -86,8 +86,8 @@ namespace osu.Game.Beatmaps.Drawables background.Colour = colours.ForStarDifficulty(c.NewValue.Stars); - starIcon.Colour = c.NewValue.Stars >= 6.5 ? Color4.Yellow : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); - starsText.Colour = c.NewValue.Stars >= 6.5 ? Color4.Yellow : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); + starIcon.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); + starsText.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); }, true); } } From 14da5ab813d1d7fe523827a59de535c2846d9298 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 17 Jul 2021 05:43:04 +0300 Subject: [PATCH 005/103] Remove defined size from the star rating display --- osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs index 5a942cdeee..e8961ae414 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs @@ -43,8 +43,6 @@ namespace osu.Game.Beatmaps.Drawables /// The already computed to display the star difficulty of. public StarRatingDisplayV2(StarDifficulty starDifficulty) { - Size = new Vector2(52f, 20f); - Current.Value = starDifficulty; InternalChild = new CircularContainer From 0a8d37defa3a167ae725f62c9ab39799f03449bd Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 17 Jul 2021 05:48:38 +0300 Subject: [PATCH 006/103] Test star rating display with multiple sizes --- .../Visual/UserInterface/TestSceneStarRatingDisplayV2.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs index 1b85e25e92..43178bb280 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs @@ -14,8 +14,10 @@ namespace osu.Game.Tests.Visual.UserInterface { public class TestSceneStarRatingDisplayV2 : OsuTestScene { - [Test] - public void TestDisplay() + [TestCase(52f, 20f)] + [TestCase(52f, 16f)] + [TestCase(50f, 14f)] + public void TestDisplay(float width, float height) { AddStep("load displays", () => { @@ -37,6 +39,7 @@ namespace osu.Game.Tests.Visual.UserInterface { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Size = new Vector2(width, height), }) }) }; @@ -52,6 +55,7 @@ namespace osu.Game.Tests.Visual.UserInterface { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Size = new Vector2(52f, 20f), }); AddRepeatStep("set random value", () => From d4399f10f9b65bb737da9785ceb44a1bf10ef6e7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 17 Jul 2021 06:54:11 +0300 Subject: [PATCH 007/103] Merge both variants of the star rating display --- .../Ranking/TestSceneStarRatingDisplay.cs | 65 --------- ...layV2.cs => TestSceneStarRatingDisplay.cs} | 36 ++++- ...atingDisplayV2.cs => StarRatingDisplay.cs} | 21 ++- .../Components/StarRatingRangeDisplay.cs | 12 +- .../Screens/Play/BeatmapMetadataDisplay.cs | 2 +- .../Expanded/ExpandedPanelMiddleContent.cs | 1 + .../Ranking/Expanded/StarRatingDisplay.cs | 129 ------------------ osu.Game/Screens/Select/BeatmapInfoWedge.cs | 1 - 8 files changed, 56 insertions(+), 211 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Ranking/TestSceneStarRatingDisplay.cs rename osu.Game.Tests/Visual/UserInterface/{TestSceneStarRatingDisplayV2.cs => TestSceneStarRatingDisplay.cs} (66%) rename osu.Game/Beatmaps/Drawables/{StarRatingDisplayV2.cs => StarRatingDisplay.cs} (75%) delete mode 100644 osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneStarRatingDisplay.cs b/osu.Game.Tests/Visual/Ranking/TestSceneStarRatingDisplay.cs deleted file mode 100644 index 566452249f..0000000000 --- a/osu.Game.Tests/Visual/Ranking/TestSceneStarRatingDisplay.cs +++ /dev/null @@ -1,65 +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 System.Linq; -using NUnit.Framework; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Utils; -using osu.Game.Beatmaps; -using osu.Game.Screens.Ranking.Expanded; -using osuTK; - -namespace osu.Game.Tests.Visual.Ranking -{ - public class TestSceneStarRatingDisplay : OsuTestScene - { - [Test] - public void TestDisplay() - { - AddStep("load displays", () => Child = new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - ChildrenEnumerable = new[] - { - 1.23, - 2.34, - 3.45, - 4.56, - 5.67, - 6.78, - 10.11, - }.Select(starRating => new StarRatingDisplay(new StarDifficulty(starRating, 0)) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre - }) - }); - } - - [Test] - public void TestChangingStarRatingDisplay() - { - StarRatingDisplay starRating = null; - - AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1)) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(3f), - }); - - AddRepeatStep("set random value", () => - { - starRating.Current.Value = new StarDifficulty(RNG.NextDouble(0.0, 11.0), 1); - }, 10); - - AddSliderStep("set exact stars", 0.0, 11.0, 5.55, d => - { - if (starRating != null) - starRating.Current.Value = new StarDifficulty(d, 1); - }); - } - } -} diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs similarity index 66% rename from osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs rename to osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs index 43178bb280..4c65500fbe 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplayV2.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs @@ -12,12 +12,36 @@ using osuTK; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneStarRatingDisplayV2 : OsuTestScene + public class TestSceneStarRatingDisplay : OsuTestScene { + [Test] + public void TestOldColoursDisplay() + { + AddStep("load displays", () => Child = new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + ChildrenEnumerable = new[] + { + 1.23, + 2.34, + 3.45, + 4.56, + 5.67, + 6.78, + 10.11, + }.Select(starRating => new StarRatingDisplay(new StarDifficulty(starRating, 0)) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre + }) + }); + } + [TestCase(52f, 20f)] [TestCase(52f, 16f)] [TestCase(50f, 14f)] - public void TestDisplay(float width, float height) + public void TestNewColoursDisplay(float width, float height) { AddStep("load displays", () => { @@ -35,7 +59,7 @@ namespace osu.Game.Tests.Visual.UserInterface AutoSizeAxes = Axes.Both, Spacing = new Vector2(2f), Direction = FillDirection.Vertical, - ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplayV2(new StarDifficulty(i + j * 0.1f, 0)) + ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplay(new StarDifficulty(i + j * 0.1f, 0), true) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -47,11 +71,11 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void TestChangingStarRatingDisplay() + public void TestChangingStarRatingDisplay([Values(false, true)] bool useNewColours) { - StarRatingDisplayV2 starRating = null; + StarRatingDisplay starRating = null; - AddStep("load display", () => Child = starRating = new StarRatingDisplayV2(new StarDifficulty(5.55, 1)) + AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1), useNewColours) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs similarity index 75% rename from osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs rename to osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index e8961ae414..ed751c66de 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplayV2.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -17,8 +17,12 @@ using osuTK.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class StarRatingDisplayV2 : CompositeDrawable, IHasCurrentValue + /// + /// A pill that displays the star rating of a beatmap. + /// + public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue { + private readonly bool useNewDifficultyColours; private readonly Box background; private readonly SpriteIcon starIcon; private readonly OsuSpriteText starsText; @@ -38,13 +42,18 @@ namespace osu.Game.Beatmaps.Drawables private OverlayColourProvider colourProvider { get; set; } /// - /// Creates a new using an already computed . + /// Creates a new using an already computed . /// - /// The already computed to display the star difficulty of. - public StarRatingDisplayV2(StarDifficulty starDifficulty) + /// The already computed to display. + /// Use the new spectrum-based difficulty colours for the display, rather than the old. + public StarRatingDisplay(StarDifficulty starDifficulty, bool useNewDifficultyColours = false) { + this.useNewDifficultyColours = useNewDifficultyColours; + Current.Value = starDifficulty; + Size = new Vector2(52f, 20f); + InternalChild = new CircularContainer { Masking = true, @@ -82,7 +91,9 @@ namespace osu.Game.Beatmaps.Drawables { starsText.Text = c.NewValue.Stars.ToString("0.00"); - background.Colour = colours.ForStarDifficulty(c.NewValue.Stars); + background.Colour = useNewDifficultyColours + ? colours.ForStarDifficulty(c.NewValue.Stars) + : colours.ForDifficultyRating(c.NewValue.DifficultyRating); starIcon.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); starsText.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); diff --git a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs index 8c1b10e3bd..6f5e48f09c 100644 --- a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs @@ -8,14 +8,16 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Screens.Ranking.Expanded; using osuTK; namespace osu.Game.Screens.OnlinePlay.Components { public class StarRatingRangeDisplay : OnlinePlayComposite { + private readonly bool useNewDifficultyColours; + [Resolved] private OsuColour colours { get; set; } @@ -24,8 +26,10 @@ namespace osu.Game.Screens.OnlinePlay.Components private StarRatingDisplay maxDisplay; private Drawable maxBackground; - public StarRatingRangeDisplay() + public StarRatingRangeDisplay(bool useNewDifficultyColours = false) { + this.useNewDifficultyColours = useNewDifficultyColours; + AutoSizeAxes = Axes.Both; } @@ -62,8 +66,8 @@ namespace osu.Game.Screens.OnlinePlay.Components AutoSizeAxes = Axes.Both, Children = new Drawable[] { - minDisplay = new StarRatingDisplay(default), - maxDisplay = new StarRatingDisplay(default) + minDisplay = new StarRatingDisplay(default) { Size = new Vector2(52f, 16f) }, + maxDisplay = new StarRatingDisplay(default) { Size = new Vector2(52f, 16f) } } } }; diff --git a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs index 4265a83ce1..d77673580a 100644 --- a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs +++ b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs @@ -10,12 +10,12 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play.HUD; -using osu.Game.Screens.Ranking.Expanded; using osuTK; namespace osu.Game.Screens.Play diff --git a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs index e10fe5726d..bcb5e7999f 100644 --- a/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs +++ b/osu.Game/Screens/Ranking/Expanded/ExpandedPanelMiddleContent.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; diff --git a/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs b/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs deleted file mode 100644 index 2b86100be8..0000000000 --- a/osu.Game/Screens/Ranking/Expanded/StarRatingDisplay.cs +++ /dev/null @@ -1,129 +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 System.Globalization; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Screens.Ranking.Expanded -{ - /// - /// A pill that displays the star rating of a . - /// - public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue - { - private Box background; - private FillFlowContainer content; - private OsuTextFlowContainer textFlow; - - [Resolved] - private OsuColour colours { get; set; } - - private readonly BindableWithCurrent current = new BindableWithCurrent(); - - public Bindable Current - { - get => current.Current; - set => current.Current = value; - } - - /// - /// Creates a new using an already computed . - /// - /// The already computed to display the star difficulty of. - public StarRatingDisplay(StarDifficulty starDifficulty) - { - Current.Value = starDifficulty; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours, BeatmapDifficultyCache difficultyCache) - { - AutoSizeAxes = Axes.Both; - - InternalChildren = new Drawable[] - { - new CircularContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - }, - } - }, - content = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 8, Vertical = 4 }, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(2, 0), - Children = new Drawable[] - { - new SpriteIcon - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Size = new Vector2(7), - Icon = FontAwesome.Solid.Star, - }, - textFlow = new OsuTextFlowContainer(s => s.Font = OsuFont.Numeric.With(weight: FontWeight.Black)) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - TextAnchor = Anchor.BottomLeft, - } - } - } - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - Current.BindValueChanged(_ => updateDisplay(), true); - } - - private void updateDisplay() - { - var starRatingParts = Current.Value.Stars.ToString("0.00", CultureInfo.InvariantCulture).Split('.'); - string wholePart = starRatingParts[0]; - string fractionPart = starRatingParts[1]; - string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator; - - var stars = Current.Value.Stars; - - background.Colour = colours.ForStarDifficulty(stars); - content.Colour = stars >= 6.5 ? colours.Orange1 : Color4.Black; - - textFlow.Clear(); - textFlow.AddText($"{wholePart}", s => - { - s.Font = s.Font.With(size: 14); - s.UseFullGlyphHeight = false; - }); - - textFlow.AddText($"{separator}{fractionPart}", s => - { - s.Font = s.Font.With(size: 7); - s.UseFullGlyphHeight = false; - }); - } - } -} diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3779523094..67eb8220f7 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -28,7 +28,6 @@ using osu.Game.Extensions; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Ranking.Expanded; using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Select From 42370e48ec3b06e4861cb56175f521faece1f033 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 18 Jul 2021 08:20:06 +0300 Subject: [PATCH 008/103] Disable shadow on star display text --- osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index ed751c66de..96e830ccc3 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -78,6 +78,7 @@ namespace osu.Game.Beatmaps.Drawables Origin = Anchor.Centre, Margin = new MarginPadding { Left = 10f, Bottom = 1f }, Font = OsuFont.Torus.With(size: 12f, weight: FontWeight.Bold), + Shadow = false, } } }; From 284fa496463bc3c5d718b141bf1dd81293705845 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 18 Jul 2021 08:20:22 +0300 Subject: [PATCH 009/103] Bring margins of components closer to existing designs --- osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index 96e830ccc3..2b555cc096 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -68,7 +68,7 @@ namespace osu.Game.Beatmaps.Drawables { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Margin = new MarginPadding { Right = 30f }, + Margin = new MarginPadding { Right = 26.5f }, Icon = FontAwesome.Solid.Star, Size = new Vector2(8f), }, @@ -76,7 +76,7 @@ namespace osu.Game.Beatmaps.Drawables { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Margin = new MarginPadding { Left = 10f, Bottom = 1f }, + Margin = new MarginPadding { Left = 10f, Bottom = 1.5f }, Font = OsuFont.Torus.With(size: 12f, weight: FontWeight.Bold), Shadow = false, } From 7f9af0ae658331cc424b4572791ea5312bc63013 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 18 Jul 2021 08:21:27 +0300 Subject: [PATCH 010/103] Scale up "changing display" test cases --- .../Visual/UserInterface/TestSceneStarRatingDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs index 4c65500fbe..88f43cd701 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs @@ -79,7 +79,7 @@ namespace osu.Game.Tests.Visual.UserInterface { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(52f, 20f), + Scale = new Vector2(3f), }); AddRepeatStep("set random value", () => From b2332eb5b38091c6ea175cb27ead4b3d8d04c06f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 4 Aug 2021 17:06:07 +0300 Subject: [PATCH 011/103] Use new difficulty colours permanently --- .../TestSceneStarRatingDisplay.cs | 32 +++---------------- .../Beatmaps/Drawables/StarRatingDisplay.cs | 10 ++---- .../Components/StarRatingRangeDisplay.cs | 6 +--- 3 files changed, 7 insertions(+), 41 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs index 88f43cd701..2f3593c062 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs @@ -14,34 +14,10 @@ namespace osu.Game.Tests.Visual.UserInterface { public class TestSceneStarRatingDisplay : OsuTestScene { - [Test] - public void TestOldColoursDisplay() - { - AddStep("load displays", () => Child = new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - ChildrenEnumerable = new[] - { - 1.23, - 2.34, - 3.45, - 4.56, - 5.67, - 6.78, - 10.11, - }.Select(starRating => new StarRatingDisplay(new StarDifficulty(starRating, 0)) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre - }) - }); - } - [TestCase(52f, 20f)] [TestCase(52f, 16f)] [TestCase(50f, 14f)] - public void TestNewColoursDisplay(float width, float height) + public void TestDisplay(float width, float height) { AddStep("load displays", () => { @@ -59,7 +35,7 @@ namespace osu.Game.Tests.Visual.UserInterface AutoSizeAxes = Axes.Both, Spacing = new Vector2(2f), Direction = FillDirection.Vertical, - ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplay(new StarDifficulty(i + j * 0.1f, 0), true) + ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplay(new StarDifficulty(i + j * 0.1f, 0)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -71,11 +47,11 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void TestChangingStarRatingDisplay([Values(false, true)] bool useNewColours) + public void TestChangingStarRatingDisplay() { StarRatingDisplay starRating = null; - AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1), useNewColours) + AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index 2b555cc096..0520cea17a 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -22,7 +22,6 @@ namespace osu.Game.Beatmaps.Drawables /// public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue { - private readonly bool useNewDifficultyColours; private readonly Box background; private readonly SpriteIcon starIcon; private readonly OsuSpriteText starsText; @@ -45,11 +44,8 @@ namespace osu.Game.Beatmaps.Drawables /// Creates a new using an already computed . /// /// The already computed to display. - /// Use the new spectrum-based difficulty colours for the display, rather than the old. - public StarRatingDisplay(StarDifficulty starDifficulty, bool useNewDifficultyColours = false) + public StarRatingDisplay(StarDifficulty starDifficulty) { - this.useNewDifficultyColours = useNewDifficultyColours; - Current.Value = starDifficulty; Size = new Vector2(52f, 20f); @@ -92,9 +88,7 @@ namespace osu.Game.Beatmaps.Drawables { starsText.Text = c.NewValue.Stars.ToString("0.00"); - background.Colour = useNewDifficultyColours - ? colours.ForStarDifficulty(c.NewValue.Stars) - : colours.ForDifficultyRating(c.NewValue.DifficultyRating); + background.Colour = colours.ForStarDifficulty(c.NewValue.Stars); starIcon.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); starsText.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); diff --git a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs index 6f5e48f09c..867fa88352 100644 --- a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs @@ -16,8 +16,6 @@ namespace osu.Game.Screens.OnlinePlay.Components { public class StarRatingRangeDisplay : OnlinePlayComposite { - private readonly bool useNewDifficultyColours; - [Resolved] private OsuColour colours { get; set; } @@ -26,10 +24,8 @@ namespace osu.Game.Screens.OnlinePlay.Components private StarRatingDisplay maxDisplay; private Drawable maxBackground; - public StarRatingRangeDisplay(bool useNewDifficultyColours = false) + public StarRatingRangeDisplay() { - this.useNewDifficultyColours = useNewDifficultyColours; - AutoSizeAxes = Axes.Both; } From b63d47259480ddc46579b76cb8505102f249000c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 4 Aug 2021 18:17:02 +0300 Subject: [PATCH 012/103] Adjust font size to match designs Looks silly when using `12f`, I've added a todo comment so that this specific case does not get forgotten when CSS-compatible font sizing gets supported. The todo comment may not be 100% required but very unsure about silently changing it and forgetting about it. --- osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index 0520cea17a..2c40aebbe1 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -64,7 +64,7 @@ namespace osu.Game.Beatmaps.Drawables { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Margin = new MarginPadding { Right = 26.5f }, + Margin = new MarginPadding { Right = 30f }, Icon = FontAwesome.Solid.Star, Size = new Vector2(8f), }, @@ -72,8 +72,10 @@ namespace osu.Game.Beatmaps.Drawables { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Margin = new MarginPadding { Left = 10f, Bottom = 1.5f }, - Font = OsuFont.Torus.With(size: 12f, weight: FontWeight.Bold), + Margin = new MarginPadding { Left = 10f, Bottom = 2f }, + // todo: this should be size: 12f, but to match up with the design, it needs to be 14.4f + // see https://github.com/ppy/osu-framework/issues/3271. + Font = OsuFont.Torus.With(size: 14.4f, weight: FontWeight.Bold), Shadow = false, } } From 3a0dd5b019e2401f917d2656ae73ef9ddd09847b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 8 Aug 2021 01:37:45 +0300 Subject: [PATCH 013/103] Add more insane star difficulties for visual testing --- .../Visual/UserInterface/TestSceneStarRatingDisplay.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs index 2f3593c062..a8bc5664f3 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics.Containers; using osuTK; namespace osu.Game.Tests.Visual.UserInterface @@ -28,19 +29,19 @@ namespace osu.Game.Tests.Visual.UserInterface AutoSizeAxes = Axes.Both, Spacing = new Vector2(2f), Direction = FillDirection.Horizontal, - ChildrenEnumerable = Enumerable.Range(0, 10).Select(i => new FillFlowContainer + ChildrenEnumerable = Enumerable.Range(0, 15).Select(i => new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Both, Spacing = new Vector2(2f), Direction = FillDirection.Vertical, - ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplay(new StarDifficulty(i + j * 0.1f, 0)) + ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplay(new StarDifficulty(i * (i >= 11 ? 25f : 1f) + j * 0.1f, 0)) { Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(width, height), - }) + }), }) }; }); From c191b3812529e9fdd0f47488fd22e21e6398ff9b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 18:40:34 +0900 Subject: [PATCH 014/103] Reduce transform overhead of `RestoreDefaultValueButton` --- osu.Game/Overlays/RestoreDefaultValueButton.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index fd3ee16fe6..62f5222012 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.UserInterface; @@ -38,7 +39,9 @@ namespace osu.Game.Overlays current.ValueChanged += _ => UpdateState(); current.DefaultChanged += _ => UpdateState(); current.DisabledChanged += _ => UpdateState(); - UpdateState(); + + if (IsLoaded) + UpdateState(); } } @@ -81,7 +84,10 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); - UpdateState(); + + // avoid unnecessary transforms on first display. + Alpha = currentAlpha; + Colour = currentColour; } public LocalisableString TooltipText => "revert to default"; @@ -101,14 +107,16 @@ namespace osu.Game.Overlays public void UpdateState() => Scheduler.AddOnce(updateState); + private float currentAlpha => current.IsDefault ? 0f : hovering && !current.Disabled ? 1f : 0.65f; + private ColourInfo currentColour => current.Disabled ? Color4.Gray : buttonColour; + private void updateState() { if (current == null) return; - this.FadeTo(current.IsDefault ? 0f : - hovering && !current.Disabled ? 1f : 0.65f, 200, Easing.OutQuint); - this.FadeColour(current.Disabled ? Color4.Gray : buttonColour, 200, Easing.OutQuint); + this.FadeTo(currentAlpha, 200, Easing.OutQuint); + this.FadeColour(currentColour, 200, Easing.OutQuint); } } } From 4b975ca10d34211f6555ff0e98b49c99f23981cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 18:43:02 +0900 Subject: [PATCH 015/103] Add better test coverage of `SettingsPanel` --- .../Visual/Settings/TestSceneSettingsPanel.cs | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs index 115d2fec7d..0af77b3b5a 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs @@ -4,6 +4,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Settings @@ -11,27 +12,39 @@ namespace osu.Game.Tests.Visual.Settings [TestFixture] public class TestSceneSettingsPanel : OsuTestScene { - private readonly SettingsPanel settings; - private readonly DialogOverlay dialogOverlay; + private SettingsPanel settings; + private DialogOverlay dialogOverlay; - public TestSceneSettingsPanel() + [SetUpSteps] + public void SetUpSteps() { - settings = new SettingsOverlay + AddStep("create settings", () => { - State = { Value = Visibility.Visible } - }; - Add(dialogOverlay = new DialogOverlay - { - Depth = -1 + settings?.Expire(); + + Add(settings = new SettingsOverlay + { + State = { Value = Visibility.Visible } + }); }); } + [Test] + public void ToggleVisibility() + { + AddWaitStep("wait some", 5); + AddToggleStep("toggle editor visibility", visible => settings.ToggleVisibility()); + } + [BackgroundDependencyLoader] private void load() { - Dependencies.Cache(dialogOverlay); + Add(dialogOverlay = new DialogOverlay + { + Depth = -1 + }); - Add(settings); + Dependencies.Cache(dialogOverlay); } } } From cecb312e7703e1ebacf023a13db78159607b9407 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 18:44:00 +0900 Subject: [PATCH 016/103] Ensure `TakeFocus` does not crash when not yet loaded --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index f77a3109c9..4a42027964 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -22,7 +22,10 @@ namespace osu.Game.Graphics.UserInterface public void TakeFocus() { - if (allowImmediateFocus) GetContainingInputManager().ChangeFocus(this); + if (!allowImmediateFocus) + return; + + Schedule(() => GetContainingInputManager().ChangeFocus(this)); } public bool HoldFocus From c0130da2359ad8947eebdf1a2743cbc2e31e5765 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 18:44:12 +0900 Subject: [PATCH 017/103] Avoid running initial layout transform in `LayoutSettings` --- .../Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 91208cb78a..277e344d84 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -97,8 +97,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics Direction = FillDirection.Vertical, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - AutoSizeDuration = transition_duration, - AutoSizeEasing = Easing.OutQuint, Masking = true, Children = new[] { @@ -177,6 +175,9 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics scalingMode.BindValueChanged(mode => { scalingSettings.ClearTransforms(); + + scalingSettings.AutoSizeDuration = transition_duration; + scalingSettings.AutoSizeEasing = Easing.OutQuint; scalingSettings.AutoSizeAxes = mode.NewValue != ScalingMode.Off ? Axes.Y : Axes.None; if (mode.NewValue == ScalingMode.Off) From 92ad66c86c857b7854064c6d6e87b6b107d472ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 18:56:02 +0900 Subject: [PATCH 018/103] Remove transform overhead from `OsuDropdown` on initial display --- osu.Game/Graphics/UserInterface/OsuDropdown.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuDropdown.cs b/osu.Game/Graphics/UserInterface/OsuDropdown.cs index 61dd5fb2d9..42f628a75a 100644 --- a/osu.Game/Graphics/UserInterface/OsuDropdown.cs +++ b/osu.Game/Graphics/UserInterface/OsuDropdown.cs @@ -69,6 +69,7 @@ namespace osu.Game.Graphics.UserInterface BackgroundColour = Color4.Black.Opacity(0.5f); MaskingContainer.CornerRadius = corner_radius; + Alpha = 0; // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring ItemsContainer.Padding = new MarginPadding(5); @@ -94,9 +95,11 @@ namespace osu.Game.Graphics.UserInterface protected override void AnimateClose() { - this.FadeOut(300, Easing.OutQuint); if (wasOpened) + { + this.FadeOut(300, Easing.OutQuint); sampleClose?.Play(); + } } // todo: this uses the same styling as OsuMenu. hopefully we can just use OsuMenu in the future with some refactoring From 237d3e656b72b2827e04a5228dae4064926a86e5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 18:58:26 +0900 Subject: [PATCH 019/103] Remove initial transform overhead of `Nub` --- osu.Game/Graphics/UserInterface/Nub.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/Nub.cs b/osu.Game/Graphics/UserInterface/Nub.cs index 8d686e8c2f..cbf3e6b3aa 100644 --- a/osu.Game/Graphics/UserInterface/Nub.cs +++ b/osu.Game/Graphics/UserInterface/Nub.cs @@ -6,6 +6,7 @@ using osuTK; using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; @@ -57,18 +58,13 @@ namespace osu.Game.Graphics.UserInterface EdgeEffect = new EdgeEffectParameters { - Colour = GlowColour, + Colour = GlowColour.Opacity(0), Type = EdgeEffectType.Glow, Radius = 10, Roundness = 8, }; } - protected override void LoadComplete() - { - FadeEdgeEffectTo(0); - } - private bool glowing; public bool Glowing From 8d051d9fa0d6c692bc740ec155d0a1bf1914cc7c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 19:16:48 +0900 Subject: [PATCH 020/103] Avoid multiple synchronous overheads in `SettingsItem` --- osu.Game/Overlays/Settings/SettingsItem.cs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index ef2027fdab..c35690151c 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -93,15 +93,13 @@ namespace osu.Game.Overlays.Settings public bool MatchingFilter { - set => this.FadeTo(value ? 1 : 0); + set => Alpha = value ? 1 : 0; } public bool FilteringActive { get; set; } public event Action SettingChanged; - private readonly RestoreDefaultValueButton restoreDefaultButton; - protected SettingsItem() { RelativeSizeAxes = Axes.X; @@ -110,7 +108,6 @@ namespace osu.Game.Overlays.Settings InternalChildren = new Drawable[] { - restoreDefaultButton = new RestoreDefaultValueButton(), FlowContent = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -122,7 +119,11 @@ namespace osu.Game.Overlays.Settings }, }, }; + } + [BackgroundDependencyLoader] + private void load() + { // all bindable logic is in constructor intentionally to support "CreateSettingsControls" being used in a context it is // never loaded, but requires bindable storage. if (controlWithCurrent == null) @@ -130,14 +131,15 @@ namespace osu.Game.Overlays.Settings controlWithCurrent.Current.ValueChanged += _ => SettingChanged?.Invoke(); controlWithCurrent.Current.DisabledChanged += _ => updateDisabled(); - } - - protected override void LoadComplete() - { - base.LoadComplete(); + // intentionally done before LoadComplete to avoid overhead. if (ShowsDefaultIndicator) - restoreDefaultButton.Current = controlWithCurrent.Current; + { + AddInternal(new RestoreDefaultValueButton + { + Current = controlWithCurrent.Current, + }); + } } private void updateDisabled() From b541550ea97516b877363c2d0509848450b02a40 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 19:17:36 +0900 Subject: [PATCH 021/103] Avoid initial synchronous dropdown population overhead in `AudioDevicesSettings` --- .../Sections/Audio/AudioDevicesSettings.cs | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index d64f176468..2354475498 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -20,17 +20,26 @@ namespace osu.Game.Overlays.Settings.Sections.Audio private SettingsDropdown dropdown; - protected override void Dispose(bool isDisposing) + [BackgroundDependencyLoader] + private void load() { - base.Dispose(isDisposing); - - if (audio != null) + Children = new Drawable[] { - audio.OnNewDevice -= onDeviceChanged; - audio.OnLostDevice -= onDeviceChanged; - } + dropdown = new AudioDeviceSettingsDropdown + { + Keywords = new[] { "speaker", "headphone", "output" } + } + }; + + updateItems(); + + audio.OnNewDevice += onDeviceChanged; + audio.OnLostDevice += onDeviceChanged; + dropdown.Current = audio.AudioDevice; } + private void onDeviceChanged(string name) => updateItems(); + private void updateItems() { var deviceItems = new List { string.Empty }; @@ -49,26 +58,15 @@ namespace osu.Game.Overlays.Settings.Sections.Audio dropdown.Items = deviceItems.Distinct().ToList(); } - private void onDeviceChanged(string name) => updateItems(); - - protected override void LoadComplete() + protected override void Dispose(bool isDisposing) { - base.LoadComplete(); + base.Dispose(isDisposing); - Children = new Drawable[] + if (audio != null) { - dropdown = new AudioDeviceSettingsDropdown - { - Keywords = new[] { "speaker", "headphone", "output" } - } - }; - - updateItems(); - - dropdown.Current = audio.AudioDevice; - - audio.OnNewDevice += onDeviceChanged; - audio.OnLostDevice += onDeviceChanged; + audio.OnNewDevice -= onDeviceChanged; + audio.OnLostDevice -= onDeviceChanged; + } } private class AudioDeviceSettingsDropdown : SettingsDropdown From c6bd8520a7464f43e4ef558fd61d0015c1e1f171 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 19:18:39 +0900 Subject: [PATCH 022/103] Add basic asynchronous loading pattern to `SettingsPanel` --- osu.Game/Overlays/SettingsPanel.cs | 93 ++++++++++++++++++++---------- 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index f1c41c4b50..c191f61e60 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using osuTK; using osuTK.Graphics; @@ -13,6 +14,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; @@ -58,6 +60,8 @@ namespace osu.Game.Overlays private readonly bool showSidebar; + private LoadingLayer loading; + protected SettingsPanel(bool showSidebar) { this.showSidebar = showSidebar; @@ -86,45 +90,69 @@ namespace osu.Game.Overlays Colour = OsuColour.Gray(0.05f), Alpha = 1, }, - SectionsContainer = new SettingsSectionsContainer + loading = new LoadingLayer { - Masking = true, - RelativeSizeAxes = Axes.Both, - ExpandableHeader = CreateHeader(), - FixedHeader = searchTextBox = new SeekLimitedSearchTextBox - { - RelativeSizeAxes = Axes.X, - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Width = 0.95f, - Margin = new MarginPadding - { - Top = 20, - Bottom = 20 - }, - }, - Footer = CreateFooter() - }, + State = { Value = Visibility.Visible } + } } }; + SectionsContainer = new SettingsSectionsContainer + { + Masking = true, + RelativeSizeAxes = Axes.Both, + ExpandableHeader = CreateHeader(), + FixedHeader = searchTextBox = new SeekLimitedSearchTextBox + { + RelativeSizeAxes = Axes.X, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Width = 0.95f, + Margin = new MarginPadding + { + Top = 20, + Bottom = 20 + }, + }, + Footer = CreateFooter() + }; + if (showSidebar) { AddInternal(Sidebar = new Sidebar { Width = sidebar_width }); - - SectionsContainer.SelectedSection.ValueChanged += section => - { - selectedSidebarButton.Selected = false; - selectedSidebarButton = Sidebar.Children.Single(b => b.Section == section.NewValue); - selectedSidebarButton.Selected = true; - }; } - searchTextBox.Current.ValueChanged += term => SectionsContainer.SearchContainer.SearchTerm = term.NewValue; - CreateSections()?.ForEach(AddSection); } + private void ensureContentLoaded() + { + if (SectionsContainer.LoadState > LoadState.NotLoaded) + return; + + Debug.Assert(SectionsContainer != null); + + LoadComponentAsync(SectionsContainer, d => + { + ContentContainer.Add(d); + d.FadeInFromZero(500); + loading.Hide(); + + if (Sidebar != null) + { + SectionsContainer.SelectedSection.ValueChanged += section => + { + selectedSidebarButton.Selected = false; + selectedSidebarButton = Sidebar.Children.Single(b => b.Section == section.NewValue); + selectedSidebarButton.Selected = true; + }; + } + + searchTextBox.Current.BindValueChanged(term => SectionsContainer.SearchContainer.SearchTerm = term.NewValue, true); + searchTextBox.TakeFocus(); + }); + } + protected void AddSection(SettingsSection section) { SectionsContainer.Add(section); @@ -136,6 +164,10 @@ namespace osu.Game.Overlays Section = section, Action = () => { + // may not be loaded yet. + if (SectionsContainer == null) + return; + SectionsContainer.ScrollTo(section); Sidebar.State = ExpandedState.Contracted; }, @@ -159,7 +191,8 @@ namespace osu.Game.Overlays { base.PopIn(); - ContentContainer.MoveToX(ExpandedPosition, TRANSITION_LENGTH, Easing.OutQuint); + ContentContainer.MoveToX(ExpandedPosition, TRANSITION_LENGTH, Easing.OutQuint) + .OnComplete(_ => ensureContentLoaded()); Sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(1, TRANSITION_LENGTH, Easing.OutQuint); @@ -187,7 +220,7 @@ namespace osu.Game.Overlays protected override void OnFocus(FocusEvent e) { - searchTextBox.TakeFocus(); + searchTextBox?.TakeFocus(); base.OnFocus(e); } @@ -209,6 +242,8 @@ namespace osu.Game.Overlays { public SearchContainer SearchContainer; + public new ScheduledDelegate Schedule(Action action) => Scheduler.AddDelayed(action, TransformDelay); + protected override FlowContainer CreateScrollContentContainer() => SearchContainer = new SearchContainer { From 230c4eb2475a16c136d001598570d8b4d0c25450 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 19:47:27 +0900 Subject: [PATCH 023/103] Fade in sidebar buttons after the load has completed --- osu.Game/Overlays/Settings/SidebarButton.cs | 3 + osu.Game/Overlays/SettingsPanel.cs | 68 +++++++++++++-------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/osu.Game/Overlays/Settings/SidebarButton.cs b/osu.Game/Overlays/Settings/SidebarButton.cs index 30a53b351d..cf6a313a1f 100644 --- a/osu.Game/Overlays/Settings/SidebarButton.cs +++ b/osu.Game/Overlays/Settings/SidebarButton.cs @@ -22,6 +22,9 @@ namespace osu.Game.Overlays.Settings private readonly Box selectionIndicator; private readonly Container text; + // always consider as part of flow, even when not visible (for the sake of the initial animation). + public override bool IsPresent => true; + private SettingsSection section; public SettingsSection Section diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index c191f61e60..388c809be8 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -135,54 +135,70 @@ namespace osu.Game.Overlays LoadComponentAsync(SectionsContainer, d => { ContentContainer.Add(d); - d.FadeInFromZero(500); + d.FadeInFromZero(750, Easing.OutQuint); loading.Hide(); - if (Sidebar != null) - { - SectionsContainer.SelectedSection.ValueChanged += section => - { - selectedSidebarButton.Selected = false; - selectedSidebarButton = Sidebar.Children.Single(b => b.Section == section.NewValue); - selectedSidebarButton.Selected = true; - }; - } - searchTextBox.Current.BindValueChanged(term => SectionsContainer.SearchContainer.SearchTerm = term.NewValue, true); searchTextBox.TakeFocus(); + + if (Sidebar == null) + return; + + LoadComponentsAsync(createSidebarButtons(), buttons => + { + float delay = 0; + + foreach (var button in buttons) + { + Sidebar.Add(button); + + button.FadeOut() + .Delay(delay) + .FadeInFromZero(1000, Easing.OutQuint); + + delay += 30; + } + + SectionsContainer.SelectedSection.BindValueChanged(section => + { + if (selectedSidebarButton != null) + selectedSidebarButton.Selected = false; + + selectedSidebarButton = Sidebar.Children.Single(b => b.Section == section.NewValue); + selectedSidebarButton.Selected = true; + }, true); + }); }); } - protected void AddSection(SettingsSection section) + private IEnumerable createSidebarButtons() { - SectionsContainer.Add(section); - - if (Sidebar != null) + foreach (var section in SectionsContainer) { - var button = new SidebarButton + yield return new SidebarButton { Section = section, Action = () => { - // may not be loaded yet. - if (SectionsContainer == null) + if (!SectionsContainer.IsLoaded) return; SectionsContainer.ScrollTo(section); Sidebar.State = ExpandedState.Contracted; }, }; - - Sidebar.Add(button); - - if (selectedSidebarButton == null) - { - selectedSidebarButton = Sidebar.Children.First(); - selectedSidebarButton.Selected = true; - } } } + protected void AddSection(SettingsSection section) + { + if (IsLoaded) + // just to keep things simple. can be accommodated for if we ever need it. + throw new InvalidOperationException("All sections must be added before the panel is loaded."); + + SectionsContainer.Add(section); + } + protected virtual Drawable CreateHeader() => new Container(); protected virtual Drawable CreateFooter() => new Container(); From de61cb8e6a9a2fb22263098f6ec779360437adce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 19:51:13 +0900 Subject: [PATCH 024/103] Adjust delay slightly --- osu.Game/Overlays/SettingsPanel.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 388c809be8..6593b6cb1e 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using osuTK; using osuTK.Graphics; @@ -130,8 +129,6 @@ namespace osu.Game.Overlays if (SectionsContainer.LoadState > LoadState.NotLoaded) return; - Debug.Assert(SectionsContainer != null); - LoadComponentAsync(SectionsContainer, d => { ContentContainer.Add(d); @@ -207,8 +204,13 @@ namespace osu.Game.Overlays { base.PopIn(); - ContentContainer.MoveToX(ExpandedPosition, TRANSITION_LENGTH, Easing.OutQuint) - .OnComplete(_ => ensureContentLoaded()); + ContentContainer.MoveToX(ExpandedPosition, TRANSITION_LENGTH, Easing.OutQuint); + + // delay load enough to ensure it doesn't overlap with the initial animation. + // this is done as there is still a brief stutter during load completion which is more visible if the transition is in progress. + // the eventual goal would be to remove the need for this by splitting up load into smaller work pieces, or fixing the remaining + // load complete overheads. + Scheduler.AddDelayed(ensureContentLoaded, TRANSITION_LENGTH / 3); Sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(1, TRANSITION_LENGTH, Easing.OutQuint); From 677f5aff9e39a0a2de16a0c25071f787db4a70e5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Aug 2021 23:30:50 +0900 Subject: [PATCH 025/103] Fix test failures --- osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index fa2c9ecdea..8632bfe681 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -32,6 +32,7 @@ namespace osu.Game.Tests.Visual.Settings [SetUpSteps] public void SetUpSteps() { + AddUntilStep("wait for load", () => panel.ChildrenOfType().Any()); AddStep("Scroll to top", () => panel.ChildrenOfType().First().ScrollToTop()); AddWaitStep("wait for scroll", 5); } From 4bf22db4ff9ff21123d9a0cc35a6aa2ed099b65d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 00:23:30 +0900 Subject: [PATCH 026/103] Attempt to reduce skin lookup overhead where file access is not required --- osu.Game/Database/MutableDatabaseBackedStore.cs | 5 +++++ osu.Game/Skinning/SkinManager.cs | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/MutableDatabaseBackedStore.cs b/osu.Game/Database/MutableDatabaseBackedStore.cs index c9d0c4bc41..b0feb7bb78 100644 --- a/osu.Game/Database/MutableDatabaseBackedStore.cs +++ b/osu.Game/Database/MutableDatabaseBackedStore.cs @@ -36,6 +36,11 @@ namespace osu.Game.Database /// public IQueryable ConsumableItems => AddIncludesForConsumption(ContextFactory.Get().Set()); + /// + /// Access barebones items with no includes. + /// + public IQueryable Items => ContextFactory.Get().Set(); + /// /// Add a to the database. /// diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index ea55fd28c2..fca1670419 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -105,12 +105,12 @@ namespace osu.Game.Skinning /// Returns a list of all usable s that have been loaded by the user. /// /// A newly allocated list of available . - public List GetAllUserSkins() => ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList(); + public List GetAllUserSkins() => ModelStore.Items.Where(s => !s.DeletePending).ToList(); public void SelectRandomSkin() { // choose from only user skins, removing the current selection to ensure a new one is chosen. - var randomChoices = GetAllUsableSkins().Where(s => s.ID != CurrentSkinInfo.Value.ID).ToArray(); + var randomChoices = ModelStore.Items.Where(s => !s.DeletePending && s.ID != CurrentSkinInfo.Value.ID).ToArray(); if (randomChoices.Length == 0) { @@ -118,7 +118,8 @@ namespace osu.Game.Skinning return; } - CurrentSkinInfo.Value = randomChoices.ElementAt(RNG.Next(0, randomChoices.Length)); + var chosen = randomChoices.ElementAt(RNG.Next(0, randomChoices.Length)); + CurrentSkinInfo.Value = ModelStore.ConsumableItems.Single(i => i.ID == chosen.ID); } protected override SkinInfo CreateModel(ArchiveReader archive) => new SkinInfo { Name = archive.Name }; From 060ba0692d27a42507bfcc1fedae13e89f0c8408 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Aug 2021 04:27:04 +0300 Subject: [PATCH 027/103] Add hash code support for `Mod` --- osu.Game/Rulesets/Mods/Mod.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index f2fd02c652..a99ddc6924 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -197,6 +197,18 @@ namespace osu.Game.Rulesets.Mods ModUtils.GetSettingUnderlyingValue(pair.Item2.GetValue(other)))); } + public override int GetHashCode() + { + var hashCode = new HashCode(); + + hashCode.Add(GetType()); + + foreach (var (_, prop) in this.GetSettingsSourceProperties()) + hashCode.Add(ModUtils.GetSettingUnderlyingValue(prop.GetValue(this))); + + return hashCode.ToHashCode(); + } + /// /// Reset all custom settings for this mod back to their defaults. /// From 0291cd5ae2eb269cf10512ce588ac5c762379ebd Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Aug 2021 04:27:43 +0300 Subject: [PATCH 028/103] Consider mod equality in difficulty cache lookup rather than acronym --- osu.Game/Beatmaps/BeatmapDifficultyCache.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs index 6ed623d0c0..8bc043a2e9 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs @@ -297,7 +297,7 @@ namespace osu.Game.Beatmaps public bool Equals(DifficultyCacheLookup other) => Beatmap.ID == other.Beatmap.ID && Ruleset.ID == other.Ruleset.ID - && OrderedMods.Select(m => m.Acronym).SequenceEqual(other.OrderedMods.Select(m => m.Acronym)); + && OrderedMods.SequenceEqual(other.OrderedMods); public override int GetHashCode() { @@ -307,7 +307,7 @@ namespace osu.Game.Beatmaps hashCode.Add(Ruleset.ID); foreach (var mod in OrderedMods) - hashCode.Add(mod.Acronym); + hashCode.Add(mod); return hashCode.ToHashCode(); } From 32ba5255558f6057831f87123135aa64955baab8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Aug 2021 04:28:34 +0300 Subject: [PATCH 029/103] Track changes to mod settings in beatmap difficulty cache with 100ms debouncing --- osu.Game/Beatmaps/BeatmapDifficultyCache.cs | 23 +++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs index 8bc043a2e9..5025e4ad4b 100644 --- a/osu.Game/Beatmaps/BeatmapDifficultyCache.cs +++ b/osu.Game/Beatmaps/BeatmapDifficultyCache.cs @@ -14,6 +14,7 @@ using osu.Framework.Lists; using osu.Framework.Logging; using osu.Framework.Threading; using osu.Framework.Utils; +using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -56,12 +57,28 @@ namespace osu.Game.Beatmaps [Resolved] private Bindable> currentMods { get; set; } + private ModSettingChangeTracker modSettingChangeTracker; + private ScheduledDelegate debouncedModSettingsChange; + protected override void LoadComplete() { base.LoadComplete(); currentRuleset.BindValueChanged(_ => updateTrackedBindables()); - currentMods.BindValueChanged(_ => updateTrackedBindables(), true); + + currentMods.BindValueChanged(mods => + { + modSettingChangeTracker?.Dispose(); + + updateTrackedBindables(); + + modSettingChangeTracker = new ModSettingChangeTracker(mods.NewValue); + modSettingChangeTracker.SettingChanged += _ => + { + debouncedModSettingsChange?.Cancel(); + debouncedModSettingsChange = Scheduler.AddDelayed(updateTrackedBindables, 100); + }; + }, true); } /// @@ -84,7 +101,7 @@ namespace osu.Game.Beatmaps /// Retrieves a bindable containing the star difficulty of a with a given and combination. /// /// - /// The bindable will not update to follow the currently-selected ruleset and mods. + /// The bindable will not update to follow the currently-selected ruleset and mods or its settings. /// /// The to get the difficulty of. /// The to get the difficulty with. If null, the 's ruleset is used. @@ -275,6 +292,8 @@ namespace osu.Game.Beatmaps { base.Dispose(isDisposing); + modSettingChangeTracker?.Dispose(); + cancelTrackedBindableUpdate(); updateScheduler?.Dispose(); } From b419ea716b307eb54fca5892024e5066b81920f0 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Aug 2021 04:29:15 +0300 Subject: [PATCH 030/103] Refactor beatmap info wedge to not fully refresh on star difficulty change Makes it look awkward when changing difficulty via mod settings for example. Now the changes should instead only affect the displayed components which consume it directly. --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 104 ++++++++++---------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 5b4e077100..678e7d5d73 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -21,6 +21,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Game.Configuration; @@ -38,6 +39,8 @@ namespace osu.Game.Screens.Select public const float BORDER_THICKNESS = 2.5f; private const float shear_width = 36.75f; + private const float transition_duration = 250; + private static readonly Vector2 wedged_container_shear = new Vector2(shear_width / SongSelect.WEDGE_HEIGHT, 0); [Resolved] @@ -46,11 +49,6 @@ namespace osu.Game.Screens.Select [Resolved] private IBindable> mods { get; set; } - [Resolved] - private BeatmapDifficultyCache difficultyCache { get; set; } - - private IBindable beatmapDifficulty; - protected Container DisplayedContent { get; private set; } protected WedgeInfoText Info { get; private set; } @@ -81,20 +79,18 @@ namespace osu.Game.Screens.Select { this.MoveToX(0, 800, Easing.OutQuint); this.RotateTo(0, 800, Easing.OutQuint); - this.FadeIn(250); + this.FadeIn(transition_duration); } protected override void PopOut() { this.MoveToX(-100, 800, Easing.In); this.RotateTo(10, 800, Easing.In); - this.FadeOut(500, Easing.In); + this.FadeOut(transition_duration * 2, Easing.In); } private WorkingBeatmap beatmap; - private CancellationTokenSource cancellationSource; - public WorkingBeatmap Beatmap { get => beatmap; @@ -103,12 +99,6 @@ namespace osu.Game.Screens.Select if (beatmap == value) return; beatmap = value; - cancellationSource?.Cancel(); - cancellationSource = new CancellationTokenSource(); - - beatmapDifficulty?.UnbindAll(); - beatmapDifficulty = difficultyCache.GetBindableDifficulty(beatmap.BeatmapInfo, cancellationSource.Token); - beatmapDifficulty.BindValueChanged(_ => updateDisplay()); updateDisplay(); } @@ -128,7 +118,7 @@ namespace osu.Game.Screens.Select { State.Value = beatmap == null ? Visibility.Hidden : Visibility.Visible; - DisplayedContent?.FadeOut(250); + DisplayedContent?.FadeOut(transition_duration); DisplayedContent?.Expire(); DisplayedContent = null; } @@ -147,7 +137,7 @@ namespace osu.Game.Screens.Select Children = new Drawable[] { new BeatmapInfoWedgeBackground(beatmap), - Info = new WedgeInfoText(beatmap, ruleset.Value, mods.Value, beatmapDifficulty.Value ?? new StarDifficulty()), + Info = new WedgeInfoText(beatmap, ruleset.Value, mods.Value), } }, loaded => { @@ -160,12 +150,6 @@ namespace osu.Game.Screens.Select } } - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - cancellationSource?.Cancel(); - } - public class WedgeInfoText : Container { public OsuSpriteText VersionLabel { get; private set; } @@ -174,6 +158,9 @@ namespace osu.Game.Screens.Select public BeatmapSetOnlineStatusPill StatusPill { get; private set; } public FillFlowContainer MapperContainer { get; private set; } + private DifficultyColourBar difficultyColourBar; + private StarRatingDisplay starRatingDisplay; + private ILocalisedBindableString titleBinding; private ILocalisedBindableString artistBinding; private FillFlowContainer infoLabelContainer; @@ -182,20 +169,21 @@ namespace osu.Game.Screens.Select private readonly WorkingBeatmap beatmap; private readonly RulesetInfo ruleset; private readonly IReadOnlyList mods; - private readonly StarDifficulty starDifficulty; private ModSettingChangeTracker settingChangeTracker; - public WedgeInfoText(WorkingBeatmap beatmap, RulesetInfo userRuleset, IReadOnlyList mods, StarDifficulty difficulty) + public WedgeInfoText(WorkingBeatmap beatmap, RulesetInfo userRuleset, IReadOnlyList mods) { this.beatmap = beatmap; ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset; this.mods = mods; - starDifficulty = difficulty; } + private CancellationTokenSource cancellationSource; + private IBindable starDifficulty; + [BackgroundDependencyLoader] - private void load(LocalisationManager localisation) + private void load(LocalisationManager localisation, BeatmapDifficultyCache difficultyCache) { var beatmapInfo = beatmap.BeatmapInfo; var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); @@ -207,7 +195,7 @@ namespace osu.Game.Screens.Select Children = new Drawable[] { - new DifficultyColourBar(starDifficulty) + difficultyColourBar = new DifficultyColourBar { RelativeSizeAxes = Axes.Y, Width = 20, @@ -241,14 +229,15 @@ namespace osu.Game.Screens.Select Padding = new MarginPadding { Top = 14, Right = shear_width / 2 }, AutoSizeAxes = Axes.Both, Shear = wedged_container_shear, - Children = new[] + Children = new Drawable[] { - createStarRatingDisplay(starDifficulty).With(display => + starRatingDisplay = new StarRatingDisplay(default) { - display.Anchor = Anchor.TopRight; - display.Origin = Anchor.TopRight; - display.Shear = -wedged_container_shear; - }), + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Shear = -wedged_container_shear, + Alpha = 0f, + }, StatusPill = new BeatmapSetOnlineStatusPill { Anchor = Anchor.TopRight, @@ -304,6 +293,15 @@ namespace osu.Game.Screens.Select titleBinding.BindValueChanged(_ => setMetadata(metadata.Source)); artistBinding.BindValueChanged(_ => setMetadata(metadata.Source), true); + starDifficulty = difficultyCache.GetBindableDifficulty(beatmapInfo, (cancellationSource = new CancellationTokenSource()).Token); + starDifficulty.BindValueChanged(s => + { + difficultyColourBar.Current.Value = s.NewValue ?? default; + + starRatingDisplay.FadeIn(transition_duration); + starRatingDisplay.Current.Value = s.NewValue ?? default; + }); + // no difficulty means it can't have a status to show if (beatmapInfo.Version == null) StatusPill.Hide(); @@ -311,13 +309,6 @@ namespace osu.Game.Screens.Select addInfoLabels(); } - private static Drawable createStarRatingDisplay(StarDifficulty difficulty) => difficulty.Stars > 0 - ? new StarRatingDisplay(difficulty) - { - Margin = new MarginPadding { Bottom = 5 } - } - : Empty(); - private void setMetadata(string source) { ArtistLabel.Text = artistBinding.Value; @@ -429,6 +420,7 @@ namespace osu.Game.Screens.Select { base.Dispose(isDisposing); settingChangeTracker?.Dispose(); + cancellationSource?.Cancel(); } public class InfoLabel : Container, IHasTooltip @@ -490,41 +482,53 @@ namespace osu.Game.Screens.Select } } - private class DifficultyColourBar : Container + public class DifficultyColourBar : Container, IHasCurrentValue { - private readonly StarDifficulty difficulty; + private readonly BindableWithCurrent current = new BindableWithCurrent(); - public DifficultyColourBar(StarDifficulty difficulty) + public Bindable Current { - this.difficulty = difficulty; + get => current.Current; + set => current.Current = value; } + [Resolved] + private OsuColour colours { get; set; } + [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { const float full_opacity_ratio = 0.7f; - var difficultyColour = colours.ForStarDifficulty(difficulty.Stars); - Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, - Colour = difficultyColour, Width = full_opacity_ratio, }, new Box { RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.Both, - Colour = difficultyColour, Alpha = 0.5f, X = full_opacity_ratio, Width = 1 - full_opacity_ratio, } }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Current.BindValueChanged(c => + { + this.FadeColour(colours.ForStarDifficulty(c.NewValue.Stars), transition_duration, Easing.OutQuint); + }, true); + + FinishTransforms(true); + } } } } From a329216ff350d2f84e66d48e8a4fdbf03e4d9dd0 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Aug 2021 04:28:07 +0300 Subject: [PATCH 031/103] Convert beatmap difficulty test into test scene and extend coverage --- .../Beatmaps/BeatmapDifficultyCacheTest.cs | 56 ------- .../TestSceneBeatmapDifficultyCache.cs | 158 ++++++++++++++++++ 2 files changed, 158 insertions(+), 56 deletions(-) delete mode 100644 osu.Game.Tests/Beatmaps/BeatmapDifficultyCacheTest.cs create mode 100644 osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs diff --git a/osu.Game.Tests/Beatmaps/BeatmapDifficultyCacheTest.cs b/osu.Game.Tests/Beatmaps/BeatmapDifficultyCacheTest.cs deleted file mode 100644 index d407c0663f..0000000000 --- a/osu.Game.Tests/Beatmaps/BeatmapDifficultyCacheTest.cs +++ /dev/null @@ -1,56 +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 NUnit.Framework; -using osu.Game.Beatmaps; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; - -namespace osu.Game.Tests.Beatmaps -{ - [TestFixture] - public class BeatmapDifficultyCacheTest - { - [Test] - public void TestKeyEqualsWithDifferentModInstances() - { - var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); - var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); - - Assert.That(key1, Is.EqualTo(key2)); - } - - [Test] - public void TestKeyEqualsWithDifferentModOrder() - { - var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); - var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() }); - - Assert.That(key1, Is.EqualTo(key2)); - } - - [TestCase(1.3, DifficultyRating.Easy)] - [TestCase(1.993, DifficultyRating.Easy)] - [TestCase(1.998, DifficultyRating.Normal)] - [TestCase(2.4, DifficultyRating.Normal)] - [TestCase(2.693, DifficultyRating.Normal)] - [TestCase(2.698, DifficultyRating.Hard)] - [TestCase(3.5, DifficultyRating.Hard)] - [TestCase(3.993, DifficultyRating.Hard)] - [TestCase(3.997, DifficultyRating.Insane)] - [TestCase(5.0, DifficultyRating.Insane)] - [TestCase(5.292, DifficultyRating.Insane)] - [TestCase(5.297, DifficultyRating.Expert)] - [TestCase(6.2, DifficultyRating.Expert)] - [TestCase(6.493, DifficultyRating.Expert)] - [TestCase(6.498, DifficultyRating.ExpertPlus)] - [TestCase(8.3, DifficultyRating.ExpertPlus)] - public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket) - { - var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating); - - Assert.AreEqual(expectedBracket, actualBracket); - } - } -} diff --git a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs new file mode 100644 index 0000000000..b6ba5b748a --- /dev/null +++ b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs @@ -0,0 +1,158 @@ +// 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 System.Threading; +using System.Threading.Tasks; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Tests.Beatmaps.IO; +using osu.Game.Tests.Visual; + +namespace osu.Game.Tests.Beatmaps +{ + [HeadlessTest] + public class TestSceneBeatmapDifficultyCache : OsuTestScene + { + public const double BASE_STARS = 5.55; + + private BeatmapSetInfo importedSet; + + [Resolved] + private BeatmapManager beatmaps { get; set; } + + private TestBeatmapDifficultyCache difficultyCache; + + private IBindable starDifficultyBindable; + private Queue> starDifficultyChangesQueue; + + [BackgroundDependencyLoader] + private void load(OsuGameBase osu) + { + importedSet = ImportBeatmapTest.LoadQuickOszIntoOsu(osu).Result; + } + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("setup difficulty cache", () => + { + SelectedMods.Value = Array.Empty(); + + Child = difficultyCache = new TestBeatmapDifficultyCache(); + + starDifficultyChangesQueue = new Queue>(); + starDifficultyBindable = difficultyCache.GetBindableDifficulty(importedSet.Beatmaps.First()); + starDifficultyBindable.BindValueChanged(starDifficultyChangesQueue.Enqueue); + }); + + AddAssert($"star difficulty -> {BASE_STARS}", () => + starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS && + starDifficultyChangesQueue.Count == 0); + } + + [Test] + public void TestStarDifficultyChangesOnModSettings() + { + OsuModDoubleTime dt = null; + + AddStep("change selected mod to DT", () => SelectedMods.Value = new[] { dt = new OsuModDoubleTime { SpeedChange = { Value = 1.5 } } }); + AddAssert($"star difficulty -> {BASE_STARS + 1.5}", () => + starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.5 && + starDifficultyChangesQueue.Count == 0); + + AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 1.25); + AddAssert($"star difficulty -> {BASE_STARS + 1.25}", () => + starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.25 && + starDifficultyChangesQueue.Count == 0); + + AddStep("change selected mod to NC", () => SelectedMods.Value = new[] { new OsuModNightcore { SpeedChange = { Value = 1.75 } } }); + AddAssert($"star difficulty -> {BASE_STARS + 1.75}", () => + starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.75 && + starDifficultyChangesQueue.Count == 0); + } + + [Test] + public void TestKeyEqualsWithDifferentModInstances() + { + var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + + Assert.That(key1, Is.EqualTo(key2)); + Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode())); + } + + [Test] + public void TestKeyEqualsWithDifferentModOrder() + { + var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHardRock(), new OsuModHidden() }); + var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModHidden(), new OsuModHardRock() }); + + Assert.That(key1, Is.EqualTo(key2)); + Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode())); + } + + [Test] + public void TestKeyDoesntEqualWithDifferentModSettings() + { + var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } }); + var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } }); + + Assert.That(key1, Is.Not.EqualTo(key2)); + Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode())); + } + + [Test] + public void TestKeyEqualWithMatchingModSettings() + { + var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } }); + var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = 1234 }, new RulesetInfo { ID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } }); + + Assert.That(key1, Is.EqualTo(key2)); + Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode())); + } + + [TestCase(1.3, DifficultyRating.Easy)] + [TestCase(1.993, DifficultyRating.Easy)] + [TestCase(1.998, DifficultyRating.Normal)] + [TestCase(2.4, DifficultyRating.Normal)] + [TestCase(2.693, DifficultyRating.Normal)] + [TestCase(2.698, DifficultyRating.Hard)] + [TestCase(3.5, DifficultyRating.Hard)] + [TestCase(3.993, DifficultyRating.Hard)] + [TestCase(3.997, DifficultyRating.Insane)] + [TestCase(5.0, DifficultyRating.Insane)] + [TestCase(5.292, DifficultyRating.Insane)] + [TestCase(5.297, DifficultyRating.Expert)] + [TestCase(6.2, DifficultyRating.Expert)] + [TestCase(6.493, DifficultyRating.Expert)] + [TestCase(6.498, DifficultyRating.ExpertPlus)] + [TestCase(8.3, DifficultyRating.ExpertPlus)] + public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket) + { + var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating); + + Assert.AreEqual(expectedBracket, actualBracket); + } + + private class TestBeatmapDifficultyCache : BeatmapDifficultyCache + { + protected override Task ComputeValueAsync(DifficultyCacheLookup lookup, CancellationToken token = default) + { + var rateAdjust = lookup.OrderedMods.OfType().SingleOrDefault(); + if (rateAdjust != null) + return Task.FromResult(new StarDifficulty(BASE_STARS + rateAdjust.SpeedChange.Value, 0)); + + return Task.FromResult(new StarDifficulty(BASE_STARS, 0)); + } + } + } +} From eb6c6830bcd977430a710efaf21e65f38fa2c5f9 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 17 Aug 2021 05:45:03 +0300 Subject: [PATCH 032/103] Add visual test slider for changing star difficulty in beatmap wedge --- .../Visual/SongSelect/TestSceneBeatmapInfoWedge.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs index a416fd4daf..2b38c4f936 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; @@ -65,6 +66,12 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("show", () => { infoWedge.Show(); }); + AddSliderStep("change star difficulty", 0, 11.9, 5.55, v => + { + foreach (var hasCurrentValue in infoWedge.Info.ChildrenOfType>()) + hasCurrentValue.Current.Value = new StarDifficulty(v, 0); + }); + foreach (var rulesetInfo in rulesets.AvailableRulesets) { var instance = rulesetInfo.CreateInstance(); From adb4fd5a2bcdf08ebc6bfe47bc45ba7c41e2c8c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 12:31:33 +0900 Subject: [PATCH 033/103] Load only sections content asynchronously, showing the header initially --- osu.Game/Overlays/SettingsPanel.cs | 150 ++++++++++++++++------------- 1 file changed, 82 insertions(+), 68 deletions(-) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 6593b6cb1e..fea797287e 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using osuTK; using osuTK.Graphics; using osu.Framework.Allocation; @@ -61,6 +62,10 @@ namespace osu.Game.Overlays private LoadingLayer loading; + private readonly List loadableSections = new List(); + + private Task sectionsLoadingTask; + protected SettingsPanel(bool showSidebar) { this.showSidebar = showSidebar; @@ -96,7 +101,7 @@ namespace osu.Game.Overlays } }; - SectionsContainer = new SettingsSectionsContainer + Add(SectionsContainer = new SettingsSectionsContainer { Masking = true, RelativeSizeAxes = Axes.Both, @@ -113,8 +118,8 @@ namespace osu.Game.Overlays Bottom = 20 }, }, - Footer = CreateFooter() - }; + Footer = CreateFooter().With(f => f.Alpha = 0) + }); if (showSidebar) { @@ -124,76 +129,13 @@ namespace osu.Game.Overlays CreateSections()?.ForEach(AddSection); } - private void ensureContentLoaded() - { - if (SectionsContainer.LoadState > LoadState.NotLoaded) - return; - - LoadComponentAsync(SectionsContainer, d => - { - ContentContainer.Add(d); - d.FadeInFromZero(750, Easing.OutQuint); - loading.Hide(); - - searchTextBox.Current.BindValueChanged(term => SectionsContainer.SearchContainer.SearchTerm = term.NewValue, true); - searchTextBox.TakeFocus(); - - if (Sidebar == null) - return; - - LoadComponentsAsync(createSidebarButtons(), buttons => - { - float delay = 0; - - foreach (var button in buttons) - { - Sidebar.Add(button); - - button.FadeOut() - .Delay(delay) - .FadeInFromZero(1000, Easing.OutQuint); - - delay += 30; - } - - SectionsContainer.SelectedSection.BindValueChanged(section => - { - if (selectedSidebarButton != null) - selectedSidebarButton.Selected = false; - - selectedSidebarButton = Sidebar.Children.Single(b => b.Section == section.NewValue); - selectedSidebarButton.Selected = true; - }, true); - }); - }); - } - - private IEnumerable createSidebarButtons() - { - foreach (var section in SectionsContainer) - { - yield return new SidebarButton - { - Section = section, - Action = () => - { - if (!SectionsContainer.IsLoaded) - return; - - SectionsContainer.ScrollTo(section); - Sidebar.State = ExpandedState.Contracted; - }, - }; - } - } - protected void AddSection(SettingsSection section) { if (IsLoaded) // just to keep things simple. can be accommodated for if we ever need it. throw new InvalidOperationException("All sections must be added before the panel is loaded."); - SectionsContainer.Add(section); + loadableSections.Add(section); } protected virtual Drawable CreateHeader() => new Container(); @@ -210,7 +152,7 @@ namespace osu.Game.Overlays // this is done as there is still a brief stutter during load completion which is more visible if the transition is in progress. // the eventual goal would be to remove the need for this by splitting up load into smaller work pieces, or fixing the remaining // load complete overheads. - Scheduler.AddDelayed(ensureContentLoaded, TRANSITION_LENGTH / 3); + Scheduler.AddDelayed(loadSections, TRANSITION_LENGTH / 3); Sidebar?.MoveToX(0, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(1, TRANSITION_LENGTH, Easing.OutQuint); @@ -250,6 +192,78 @@ namespace osu.Game.Overlays Padding = new MarginPadding { Top = GetToolbarHeight?.Invoke() ?? 0 }; } + private const double fade_in_duration = 1000; + + private void loadSections() + { + if (sectionsLoadingTask != null) + return; + + sectionsLoadingTask = LoadComponentsAsync(loadableSections, sections => + { + SectionsContainer.AddRange(sections); + SectionsContainer.Footer.FadeInFromZero(fade_in_duration, Easing.OutQuint); + SectionsContainer.SearchContainer.FadeInFromZero(fade_in_duration, Easing.OutQuint); + + loading.Hide(); + + searchTextBox.Current.BindValueChanged(term => SectionsContainer.SearchContainer.SearchTerm = term.NewValue, true); + searchTextBox.TakeFocus(); + + loadSidebarButtons(); + }); + } + + private void loadSidebarButtons() + { + if (Sidebar == null) + return; + + LoadComponentsAsync(createSidebarButtons(), buttons => + { + float delay = 0; + + foreach (var button in buttons) + { + Sidebar.Add(button); + + button.FadeOut() + .Delay(delay) + .FadeInFromZero(fade_in_duration, Easing.OutQuint); + + delay += 40; + } + + SectionsContainer.SelectedSection.BindValueChanged(section => + { + if (selectedSidebarButton != null) + selectedSidebarButton.Selected = false; + + selectedSidebarButton = Sidebar.Children.Single(b => b.Section == section.NewValue); + selectedSidebarButton.Selected = true; + }, true); + }); + } + + private IEnumerable createSidebarButtons() + { + foreach (var section in SectionsContainer) + { + yield return new SidebarButton + { + Section = section, + Action = () => + { + if (!SectionsContainer.IsLoaded) + return; + + SectionsContainer.ScrollTo(section); + Sidebar.State = ExpandedState.Contracted; + }, + }; + } + } + private class NonMaskedContent : Container { // masking breaks the pan-out transform with nested sub-settings panels. From 212842c5373bda3b369e1ea9d9d7535637634684 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 12:38:44 +0900 Subject: [PATCH 034/103] Fix initial `LayoutSettings` animation in a more reliable way --- .../Sections/Graphics/LayoutSettings.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 277e344d84..d29f5fef39 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -175,16 +175,14 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics scalingMode.BindValueChanged(mode => { scalingSettings.ClearTransforms(); - scalingSettings.AutoSizeDuration = transition_duration; scalingSettings.AutoSizeEasing = Easing.OutQuint; - scalingSettings.AutoSizeAxes = mode.NewValue != ScalingMode.Off ? Axes.Y : Axes.None; - if (mode.NewValue == ScalingMode.Off) - scalingSettings.ResizeHeightTo(0, transition_duration, Easing.OutQuint); + updateScalingModeVisibility(); + }); - scalingSettings.ForEach(s => s.TransferValueOnCommit = mode.NewValue == ScalingMode.Everything); - }, true); + // initial update bypasses transforms + updateScalingModeVisibility(); void updateResolutionDropdown() { @@ -193,6 +191,15 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics else resolutionDropdown.Hide(); } + + void updateScalingModeVisibility() + { + if (scalingMode.Value == ScalingMode.Off) + scalingSettings.ResizeHeightTo(0, transition_duration, Easing.OutQuint); + + scalingSettings.AutoSizeAxes = scalingMode.Value != ScalingMode.Off ? Axes.Y : Axes.None; + scalingSettings.ForEach(s => s.TransferValueOnCommit = scalingMode.Value == ScalingMode.Everything); + } } private void bindPreviewEvent(Bindable bindable) From bc86bafc0898b2d6d288ef81b2f3a10f4eb1331d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 12:48:30 +0900 Subject: [PATCH 035/103] Fix `RestoreDefaultValueButton`'s colour weirdness --- osu.Game/Graphics/UserInterface/OsuButton.cs | 1 + osu.Game/Overlays/RestoreDefaultValueButton.cs | 11 ++++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index cd9ca9f87f..82a3e73b84 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -36,6 +36,7 @@ namespace osu.Game.Graphics.UserInterface public Color4 BackgroundColour { + get => backgroundColour ?? Color4.White; set { backgroundColour = value; diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 62f5222012..87a294cc10 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -45,8 +45,6 @@ namespace osu.Game.Overlays } } - private Color4 buttonColour; - private bool hovering; public RestoreDefaultValueButton() @@ -61,12 +59,11 @@ namespace osu.Game.Overlays private void load(OsuColour colour) { BackgroundColour = colour.Yellow; - buttonColour = colour.Yellow; Content.Width = 0.33f; Content.CornerRadius = 3; Content.EdgeEffect = new EdgeEffectParameters { - Colour = buttonColour.Opacity(0.1f), + Colour = BackgroundColour.Opacity(0.1f), Type = EdgeEffectType.Glow, Radius = 2, }; @@ -87,7 +84,7 @@ namespace osu.Game.Overlays // avoid unnecessary transforms on first display. Alpha = currentAlpha; - Colour = currentColour; + Background.Colour = currentColour; } public LocalisableString TooltipText => "revert to default"; @@ -108,7 +105,7 @@ namespace osu.Game.Overlays public void UpdateState() => Scheduler.AddOnce(updateState); private float currentAlpha => current.IsDefault ? 0f : hovering && !current.Disabled ? 1f : 0.65f; - private ColourInfo currentColour => current.Disabled ? Color4.Gray : buttonColour; + private ColourInfo currentColour => current.Disabled ? Color4.Gray : BackgroundColour; private void updateState() { @@ -116,7 +113,7 @@ namespace osu.Game.Overlays return; this.FadeTo(currentAlpha, 200, Easing.OutQuint); - this.FadeColour(currentColour, 200, Easing.OutQuint); + Background.FadeColour(currentColour, 200, Easing.OutQuint); } } } From 72dd18732d44efb3c24e732fa59be8cae0f52e9f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 16:37:18 +0900 Subject: [PATCH 036/103] Fix regressed tests --- osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs index 8632bfe681..57ba051214 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneKeyBindingPanel.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Settings [SetUpSteps] public void SetUpSteps() { - AddUntilStep("wait for load", () => panel.ChildrenOfType().Any()); + AddUntilStep("wait for load", () => panel.ChildrenOfType().Any()); AddStep("Scroll to top", () => panel.ChildrenOfType().First().ScrollToTop()); AddWaitStep("wait for scroll", 5); } From 4b198d14eb4dd473cf042c940d0955bbdc69411a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 17:05:20 +0900 Subject: [PATCH 037/103] Initial refactor of RoomSubScreen --- .../Multiplayer/TestSceneMultiplayer.cs | 13 + .../TestSceneMultiplayerMatchSubScreen.cs | 34 +- .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 126 +++++-- .../Multiplayer/MultiplayerMatchSubScreen.cs | 349 +++++++++--------- .../Playlists/PlaylistsRoomSubScreen.cs | 8 + 5 files changed, 302 insertions(+), 228 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index e618b28f40..035bdbea1c 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -83,6 +83,19 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("load multiplayer", () => LoadScreen(multiplayerScreen)); AddUntilStep("wait for multiplayer to load", () => multiplayerScreen.IsLoaded); AddUntilStep("wait for lounge to load", () => this.ChildrenOfType().FirstOrDefault()?.IsLoaded == true); + + createRoom(() => new Room + { + Name = { Value = "Test Room" }, + Playlist = + { + new PlaylistItem + { + Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo }, + } + } + }); } [Test] diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs index ea10fc1b8b..21364fe154 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerMatchSubScreen.cs @@ -59,23 +59,6 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("wait for load", () => screen.IsCurrentScreen()); } - [Test] - public void TestSettingValidity() - { - AddAssert("create button not enabled", () => !this.ChildrenOfType().Single().Enabled.Value); - - AddStep("set playlist", () => - { - SelectedRoom.Value.Playlist.Add(new PlaylistItem - { - Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, - Ruleset = { Value = new OsuRuleset().RulesetInfo }, - }); - }); - - AddAssert("create button enabled", () => this.ChildrenOfType().Single().Enabled.Value); - } - [Test] public void TestCreatedRoom() { @@ -97,6 +80,23 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("wait for join", () => Client.Room != null); } + [Test] + public void TestSettingValidity() + { + AddAssert("create button not enabled", () => !this.ChildrenOfType().Single().Enabled.Value); + + AddStep("set playlist", () => + { + SelectedRoom.Value.Playlist.Add(new PlaylistItem + { + Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo }, + }); + }); + + AddAssert("create button enabled", () => this.ChildrenOfType().Single().Enabled.Value); + } + [Test] public void TestStartMatchWhileSpectating() { diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 243d2abf74..8de8e5e897 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -19,6 +19,7 @@ using osu.Game.Online.Rooms; using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Rulesets.Mods; +using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match.Components; namespace osu.Game.Screens.OnlinePlay.Match @@ -31,8 +32,6 @@ namespace osu.Game.Screens.OnlinePlay.Match public override bool DisallowExternalBeatmapRulesetChanges => true; - private readonly ModSelectOverlay userModsSelectOverlay; - /// /// A container that provides controls for selection of user mods. /// This will be shown/hidden automatically when applicable. @@ -58,49 +57,106 @@ namespace osu.Game.Screens.OnlinePlay.Match private IBindable> managerUpdated; [Cached] - protected OnlinePlayBeatmapAvailabilityTracker BeatmapAvailabilityTracker { get; } + protected OnlinePlayBeatmapAvailabilityTracker BeatmapAvailabilityTracker { get; private set; } protected IBindable BeatmapAvailability => BeatmapAvailabilityTracker.Availability; - protected RoomSubScreen() + private readonly Room room; + + private ModSelectOverlay userModsSelectOverlay; + + protected RoomSubScreen(Room room) { + this.room = room; + Padding = new MarginPadding { Top = Header.HEIGHT }; - AddRangeInternal(new Drawable[] + BeatmapAvailabilityTracker = new OnlinePlayBeatmapAvailabilityTracker { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(@"3e3a44") // This is super temporary. - }, - BeatmapAvailabilityTracker = new OnlinePlayBeatmapAvailabilityTracker - { - SelectedItem = { BindTarget = SelectedItem } - }, - new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Depth = float.MinValue, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING }, - Child = userModsSelectOverlay = new UserModSelectOverlay - { - SelectedMods = { BindTarget = UserMods }, - IsValidMod = _ => false - } - }, - }); + SelectedItem = { BindTarget = SelectedItem } + }; } - protected override void ClearInternal(bool disposeChildren = true) => - throw new InvalidOperationException($"{nameof(RoomSubScreen)}'s children should not be cleared as it will remove required components"); - [BackgroundDependencyLoader] private void load(AudioManager audio) { sampleStart = audio.Samples.Get(@"SongSelect/confirm-selection"); + + InternalChildren = new Drawable[] + { + BeatmapAvailabilityTracker, + new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + // Padded main content (drawable room + main content) + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 60 }, + // Main content + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] + { + CreateDrawableRoom(room), + }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 10, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex(@"3e3a44") // This is super temporary. + }, + }, + CreateMainContent(), + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = userModsSelectOverlay = new UserModSelectOverlay + { + SelectedMods = { BindTarget = UserMods }, + IsValidMod = _ => false + } + }, + } + } + } + } + } + } + }, + // Footer + new[] + { + CreateFooter() + } + } + } + }; } protected override void LoadComplete() @@ -257,6 +313,12 @@ namespace osu.Game.Screens.OnlinePlay.Match track.Looping = false; } + protected abstract DrawableRoom CreateDrawableRoom(Room room); + + protected abstract Drawable CreateMainContent(); + + protected abstract Drawable CreateFooter(); + private class UserModSelectOverlay : LocalPlayerModSelectOverlay { } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 6277afa8bb..da766c9e25 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -22,6 +22,7 @@ using osu.Game.Overlays.Dialog; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.OnlinePlay.Components; +using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.OnlinePlay.Multiplayer.Match; @@ -58,10 +59,11 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [CanBeNull] private IDisposable readyClickOperation; - private GridContainer mainContent; + // private GridContainer mainContent; private MultiplayerMatchSettingsOverlay settingsOverlay; public MultiplayerMatchSubScreen(Room room) + : base(room) { Room = room; @@ -72,191 +74,16 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [BackgroundDependencyLoader] private void load() { - AddRangeInternal(new Drawable[] - { - mainContent = new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding - { - Horizontal = HORIZONTAL_OVERFLOW_PADDING + 55, - Vertical = 20 - }, - Child = new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - }, - Content = new[] - { - new Drawable[] - { - new MultiplayerMatchHeader - { - OpenSettings = () => settingsOverlay.Show() - } - }, - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 5, Vertical = 10 }, - Child = new GridContainer - { - RelativeSizeAxes = Axes.Both, - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 400), - new Dimension(), - new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 600), - }, - Content = new[] - { - new Drawable[] - { - // Main left column - new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] { new ParticipantsListHeader() }, - new Drawable[] - { - new ParticipantsList - { - RelativeSizeAxes = Axes.Both - }, - } - } - }, - // Spacer - null, - // Main right column - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new[] - { - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new OverlinedHeader("Beatmap"), - new BeatmapSelectionControl { RelativeSizeAxes = Axes.X } - } - }, - UserModsSection = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 10 }, - Children = new Drawable[] - { - new OverlinedHeader("Extra mods"), - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - new UserModSelectButton - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Width = 90, - Text = "Select", - Action = ShowUserModSelect, - }, - new ModDisplay - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Current = UserMods, - Scale = new Vector2(0.8f), - }, - } - } - } - } - } - } - } - } - } - } - }, - new Drawable[] - { - new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] { new OverlinedHeader("Chat") }, - new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } - } - } - } - }, - } - } - }, - new Drawable[] - { - new MultiplayerMatchFooter - { - OnReadyClick = onReadyClick, - OnSpectateClick = onSpectateClick - } - } - }, - RowDimensions = new[] - { - new Dimension(), - new Dimension(GridSizeMode.AutoSize), - } - }, - settingsOverlay = new MultiplayerMatchSettingsOverlay - { - RelativeSizeAxes = Axes.Both, - State = { Value = client.Room == null ? Visibility.Visible : Visibility.Hidden } - } - }); - if (client.Room == null) { // A new room is being created. // The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed. - mainContent.Hide(); + // mainContent.Hide(); settingsOverlay.State.BindValueChanged(visibility => { - if (visibility.NewValue == Visibility.Hidden) - mainContent.Show(); + // if (visibility.NewValue == Visibility.Hidden) + // mainContent.Show(); }, true); } } @@ -303,6 +130,170 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList(); } + protected override DrawableRoom CreateDrawableRoom(Room room) => new DrawableRoom(room); + + protected override Drawable CreateMainContent() => new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding + { + Horizontal = HORIZONTAL_OVERFLOW_PADDING + 55, + Vertical = 20 + }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + }, + Content = new[] + { + new Drawable[] + { + new MultiplayerMatchHeader + { + OpenSettings = () => settingsOverlay.Show() + } + }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 5, Vertical = 10 }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 400), + new Dimension(), + new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 600), + }, + Content = new[] + { + new Drawable[] + { + // Main left column + new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] { new ParticipantsListHeader() }, + new Drawable[] + { + new ParticipantsList + { + RelativeSizeAxes = Axes.Both + }, + } + } + }, + // Spacer + null, + // Main right column + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new OverlinedHeader("Beatmap"), + new BeatmapSelectionControl { RelativeSizeAxes = Axes.X } + } + }, + UserModsSection = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 10 }, + Children = new Drawable[] + { + new OverlinedHeader("Extra mods"), + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new UserModSelectButton + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Width = 90, + Text = "Select", + Action = ShowUserModSelect, + }, + new ModDisplay + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Current = UserMods, + Scale = new Vector2(0.8f), + }, + } + } + } + } + } + } + } + } + } + } + }, + new Drawable[] + { + new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] { new OverlinedHeader("Chat") }, + new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } + } + } + } + }, + } + }, + settingsOverlay = new MultiplayerMatchSettingsOverlay + { + RelativeSizeAxes = Axes.Both, + // State = { Value = client.Room == null ? Visibility.Visible : Visibility.Hidden } + } + } + }; + + protected override Drawable CreateFooter() => new MultiplayerMatchFooter + { + OnReadyClick = onReadyClick, + OnSpectateClick = onSpectateClick + }; + [Resolved(canBeNull: true)] private DialogOverlay dialogOverlay { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index 682b055766..8ca592ee2c 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -14,6 +14,7 @@ using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Components; +using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.Play; @@ -45,6 +46,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private SelectionPollingComponent selectionPollingComponent; public PlaylistsRoomSubScreen(Room room) + : base(room) { Title = room.RoomID.Value == null ? "New playlist" : room.Name.Value; Activity.Value = new UserActivity.InLobby(room); @@ -295,5 +297,11 @@ namespace osu.Game.Screens.OnlinePlay.Playlists { Exited = () => leaderboard.RefreshScores() }); + + protected override DrawableRoom CreateDrawableRoom(Room room) => new DrawableRoom(room); + + protected override Drawable CreateMainContent() => Empty(); + + protected override Drawable CreateFooter() => Empty(); } } From 6416e64e06a1695d03e3b524a1094de772bae2b3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 17:13:25 +0900 Subject: [PATCH 038/103] Adjust sizings and paddings --- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 11 ++++++++++- .../Multiplayer/MultiplayerMatchSubScreen.cs | 4 ++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 8de8e5e897..7513ffa0f3 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -88,6 +88,11 @@ namespace osu.Game.Screens.OnlinePlay.Match new GridContainer { RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize) + }, Content = new[] { // Padded main content (drawable room + main content) @@ -96,7 +101,11 @@ namespace osu.Game.Screens.OnlinePlay.Match new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 60 }, + Padding = new MarginPadding + { + Horizontal = WaveOverlayContainer.WIDTH_PADDING, + Bottom = 30 + }, // Main content Child = new GridContainer { diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index da766c9e25..0a7ddb1254 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -142,8 +142,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { - Horizontal = HORIZONTAL_OVERFLOW_PADDING + 55, - Vertical = 20 + Horizontal = 10, + Vertical = 10 }, Child = new GridContainer { From 5d72c5911af23537b27addcd5b64e66022d0da40 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 17:14:21 +0900 Subject: [PATCH 039/103] Rename MatchSettingsOverlay and related classes Because "match" is a multiplayer-only concept. --- .../Playlists/TestScenePlaylistsMatchSettingsOverlay.cs | 2 +- .../Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs | 4 ++-- .../{MatchSettingsOverlay.cs => RoomSettingsOverlay.cs} | 2 +- .../Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs | 2 +- ...atchSettingsOverlay.cs => PlaylistsRoomSettingsOverlay.cs} | 2 +- .../Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) rename osu.Game/Screens/OnlinePlay/Match/Components/{MatchSettingsOverlay.cs => RoomSettingsOverlay.cs} (97%) rename osu.Game/Screens/OnlinePlay/Playlists/{PlaylistsMatchSettingsOverlay.cs => PlaylistsRoomSettingsOverlay.cs} (99%) diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs index 98882b659c..04b44efd32 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsMatchSettingsOverlay.cs @@ -110,7 +110,7 @@ namespace osu.Game.Tests.Visual.Playlists AddUntilStep("error not displayed", () => !settings.ErrorText.IsPresent); } - private class TestRoomSettings : PlaylistsMatchSettingsOverlay + private class TestRoomSettings : PlaylistsRoomSettingsOverlay { public TriangleButton ApplyButton => ((MatchSettings)Settings).ApplyButton; diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs index 9fc29049ef..ee93e728ac 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs @@ -96,7 +96,7 @@ namespace osu.Game.Tests.Visual.Playlists AddStep("move mouse to create button", () => { - InputManager.MoveMouseTo(this.ChildrenOfType().Single()); + InputManager.MoveMouseTo(this.ChildrenOfType().Single()); }); AddStep("click", () => InputManager.Click(MouseButton.Left)); @@ -147,7 +147,7 @@ namespace osu.Game.Tests.Visual.Playlists AddStep("create room", () => { - InputManager.MoveMouseTo(match.ChildrenOfType().Single()); + InputManager.MoveMouseTo(match.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs similarity index 97% rename from osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs rename to osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs index 2676453a7e..bcefd5a333 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs @@ -14,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Match.Components { - public abstract class MatchSettingsOverlay : FocusedOverlayContainer, IKeyBindingHandler + public abstract class RoomSettingsOverlay : FocusedOverlayContainer, IKeyBindingHandler { protected const float TRANSITION_DURATION = 350; protected const float FIELD_PADDING = 45; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index 5f3921d742..3a95ac00a6 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -26,7 +26,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { - public class MultiplayerMatchSettingsOverlay : MatchSettingsOverlay + public class MultiplayerMatchSettingsOverlay : RoomSettingsOverlay { private MatchSettings settings; diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs similarity index 99% rename from osu.Game/Screens/OnlinePlay/Playlists/PlaylistsMatchSettingsOverlay.cs rename to osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs index 2640f99ea5..d28f886be4 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs @@ -22,7 +22,7 @@ using osuTK; namespace osu.Game.Screens.OnlinePlay.Playlists { - public class PlaylistsMatchSettingsOverlay : MatchSettingsOverlay + public class PlaylistsRoomSettingsOverlay : RoomSettingsOverlay { public Action EditPlaylist; diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index 8ca592ee2c..c2f92d7e00 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private readonly IBindable isIdle = new BindableBool(); - private MatchSettingsOverlay settingsOverlay; + private RoomSettingsOverlay settingsOverlay; private MatchLeaderboard leaderboard; private OverlinedHeader participantsHeader; private GridContainer mainContent; @@ -237,7 +237,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists new Dimension(GridSizeMode.AutoSize), } }, - settingsOverlay = new PlaylistsMatchSettingsOverlay + settingsOverlay = new PlaylistsRoomSettingsOverlay { RelativeSizeAxes = Axes.Both, EditPlaylist = () => From c0b388cd74e864f6654d161e4bd631ca36408b0c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 17:50:30 +0900 Subject: [PATCH 040/103] Fix regression in `ModSettingsChangeTracker` --- osu.Game/Overlays/Settings/SettingsItem.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index c35690151c..6621caef4e 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -119,19 +119,19 @@ namespace osu.Game.Overlays.Settings }, }, }; - } - [BackgroundDependencyLoader] - private void load() - { - // all bindable logic is in constructor intentionally to support "CreateSettingsControls" being used in a context it is + // IMPORTANT: all bindable logic is in constructor intentionally to support "CreateSettingsControls" being used in a context it is // never loaded, but requires bindable storage. if (controlWithCurrent == null) throw new ArgumentException(@$"Control created via {nameof(CreateControl)} must implement {nameof(IHasCurrentValue)}"); controlWithCurrent.Current.ValueChanged += _ => SettingChanged?.Invoke(); controlWithCurrent.Current.DisabledChanged += _ => updateDisabled(); + } + [BackgroundDependencyLoader] + private void load() + { // intentionally done before LoadComplete to avoid overhead. if (ShowsDefaultIndicator) { From 6840ec671684501b2ca47675d17e4405fdd7a55e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 17:58:24 +0900 Subject: [PATCH 041/103] Actually show the room in the sub screen --- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 7513ffa0f3..afd7112b22 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -113,13 +113,15 @@ namespace osu.Game.Screens.OnlinePlay.Match RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Absolute, 10) }, Content = new[] { new Drawable[] { - CreateDrawableRoom(room), + CreateDrawableRoom(room).With(d => d.MatchingFilter = true), }, + null, new Drawable[] { new Container From 590d814881e71dcb4ad353f40e7a5164df8adb41 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 18:24:04 +0900 Subject: [PATCH 042/103] Move RoomSettingsOverlay to RoomSubScreen --- .../Match/Components/RoomSettingsOverlay.cs | 8 +- .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 109 ++++++++++++------ .../Multiplayer/MultiplayerMatchSubScreen.cs | 44 +------ .../Playlists/PlaylistsRoomSubScreen.cs | 2 + 4 files changed, 82 insertions(+), 81 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs index bcefd5a333..5f0ce0feed 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs @@ -27,11 +27,15 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components protected abstract bool IsLoading { get; } + protected RoomSettingsOverlay() + { + RelativeSizeAxes = Axes.Both; + Masking = true; + } + [BackgroundDependencyLoader] private void load() { - Masking = true; - Add(Settings = CreateSettings()); } diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index afd7112b22..a79f9421a7 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -64,6 +64,7 @@ namespace osu.Game.Screens.OnlinePlay.Match private readonly Room room; private ModSelectOverlay userModsSelectOverlay; + private RoomSettingsOverlay settingsOverlay; protected RoomSubScreen(Room room) { @@ -82,6 +83,8 @@ namespace osu.Game.Screens.OnlinePlay.Match { sampleStart = audio.Samples.Get(@"SongSelect/confirm-selection"); + Drawable mainContent; + InternalChildren = new Drawable[] { BeatmapAvailabilityTracker, @@ -106,59 +109,62 @@ namespace osu.Game.Screens.OnlinePlay.Match Horizontal = WaveOverlayContainer.WIDTH_PADDING, Bottom = 30 }, - // Main content - Child = new GridContainer + Children = new[] { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] + mainContent = new GridContainer { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Absolute, 10) - }, - Content = new[] - { - new Drawable[] + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] { - CreateDrawableRoom(room).With(d => d.MatchingFilter = true), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Absolute, 10) }, - null, - new Drawable[] + Content = new[] { - new Container + new Drawable[] { - RelativeSizeAxes = Axes.Both, - Children = new[] + CreateDrawableRoom(room).With(d => d.MatchingFilter = true), + }, + null, + new Drawable[] + { + new Container { - new Container + RelativeSizeAxes = Axes.Both, + Children = new[] { - RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 10, - Child = new Box + new Container { RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(@"3e3a44") // This is super temporary. + Masking = true, + CornerRadius = 10, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex(@"3e3a44") // This is super temporary. + }, }, - }, - CreateMainContent(), - new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = userModsSelectOverlay = new UserModSelectOverlay + CreateMainContent(), + new Container { - SelectedMods = { BindTarget = UserMods }, - IsValidMod = _ => false - } - }, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = userModsSelectOverlay = new UserModSelectOverlay + { + SelectedMods = { BindTarget = UserMods }, + IsValidMod = _ => false + } + }, + } } } } - } - } - } + }, + settingsOverlay = CreateRoomSettingsOverlay() + }, + }, }, // Footer new[] @@ -168,6 +174,19 @@ namespace osu.Game.Screens.OnlinePlay.Match } } }; + + if (room.RoomID.Value == null) + { + // A new room is being created. + // The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed. + mainContent.Hide(); + + settingsOverlay.State.BindValueChanged(visibility => + { + if (visibility.NewValue == Visibility.Hidden) + mainContent.Show(); + }, true); + } } protected override void LoadComplete() @@ -184,12 +203,24 @@ namespace osu.Game.Screens.OnlinePlay.Match public override bool OnBackButton() { + if (room.RoomID.Value == null) + { + // room has not been created yet; exit immediately. + return base.OnBackButton(); + } + if (userModsSelectOverlay.State.Value == Visibility.Visible) { userModsSelectOverlay.Hide(); return true; } + if (settingsOverlay.State.Value == Visibility.Visible) + { + settingsOverlay.Hide(); + return true; + } + return base.OnBackButton(); } @@ -330,6 +361,8 @@ namespace osu.Game.Screens.OnlinePlay.Match protected abstract Drawable CreateFooter(); + protected abstract RoomSettingsOverlay CreateRoomSettingsOverlay(); + private class UserModSelectOverlay : LocalPlayerModSelectOverlay { } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 0a7ddb1254..1b9c2092dd 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -60,7 +60,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer private IDisposable readyClickOperation; // private GridContainer mainContent; - private MultiplayerMatchSettingsOverlay settingsOverlay; public MultiplayerMatchSubScreen(Room room) : base(room) @@ -71,23 +70,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Activity.Value = new UserActivity.InLobby(room); } - [BackgroundDependencyLoader] - private void load() - { - if (client.Room == null) - { - // A new room is being created. - // The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed. - // mainContent.Hide(); - - settingsOverlay.State.BindValueChanged(visibility => - { - // if (visibility.NewValue == Visibility.Hidden) - // mainContent.Show(); - }, true); - } - } - protected override void LoadComplete() { base.LoadComplete(); @@ -159,7 +141,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { new MultiplayerMatchHeader { - OpenSettings = () => settingsOverlay.Show() + // OpenSettings = () => settingsOverlay.Show() } }, new Drawable[] @@ -280,11 +262,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer }, } }, - settingsOverlay = new MultiplayerMatchSettingsOverlay - { - RelativeSizeAxes = Axes.Both, - // State = { Value = client.Room == null ? Visibility.Visible : Visibility.Hidden } - } } }; @@ -294,28 +271,13 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer OnSpectateClick = onSpectateClick }; + protected override RoomSettingsOverlay CreateRoomSettingsOverlay() => new MultiplayerMatchSettingsOverlay(); + [Resolved(canBeNull: true)] private DialogOverlay dialogOverlay { get; set; } private bool exitConfirmed; - public override bool OnBackButton() - { - if (client.Room == null) - { - // room has not been created yet; exit immediately. - return base.OnBackButton(); - } - - if (settingsOverlay.State.Value == Visibility.Visible) - { - settingsOverlay.Hide(); - return true; - } - - return base.OnBackButton(); - } - public override bool OnExiting(IScreen next) { // the room may not be left immediately after a disconnection due to async flow, diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index c2f92d7e00..7af74e7e64 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -303,5 +303,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists protected override Drawable CreateMainContent() => Empty(); protected override Drawable CreateFooter() => Empty(); + + protected override RoomSettingsOverlay CreateRoomSettingsOverlay() => new PlaylistsRoomSettingsOverlay(); } } From d66f7cb6b597ce62acd5460771958bfc59c1c97f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Aug 2021 19:21:22 +0900 Subject: [PATCH 043/103] Fix tests by allowing retrieval with files where required --- osu.Game.Tests/Skins/IO/ImportSkinTest.cs | 16 ++++++++-------- osu.Game/Skinning/SkinManager.cs | 10 ++++++++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs index 8124bd4199..bab8dfc983 100644 --- a/osu.Game.Tests/Skins/IO/ImportSkinTest.cs +++ b/osu.Game.Tests/Skins/IO/ImportSkinTest.cs @@ -50,10 +50,10 @@ namespace osu.Game.Tests.Skins.IO var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin", "skinner"), "skin2.osk")); Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID)); - Assert.That(osu.Dependencies.Get().GetAllUserSkins().Count, Is.EqualTo(1)); + Assert.That(osu.Dependencies.Get().GetAllUserSkins(true).Count, Is.EqualTo(1)); // the first should be overwritten by the second import. - Assert.That(osu.Dependencies.Get().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID)); + Assert.That(osu.Dependencies.Get().GetAllUserSkins(true).First().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID)); } finally { @@ -76,10 +76,10 @@ namespace osu.Game.Tests.Skins.IO var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk(string.Empty, string.Empty), "download.osk")); Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID)); - Assert.That(osu.Dependencies.Get().GetAllUserSkins().Count, Is.EqualTo(2)); + Assert.That(osu.Dependencies.Get().GetAllUserSkins(true).Count, Is.EqualTo(2)); - Assert.That(osu.Dependencies.Get().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID)); - Assert.That(osu.Dependencies.Get().GetAllUserSkins().Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID)); + Assert.That(osu.Dependencies.Get().GetAllUserSkins(true).First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID)); + Assert.That(osu.Dependencies.Get().GetAllUserSkins(true).Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID)); } finally { @@ -101,10 +101,10 @@ namespace osu.Game.Tests.Skins.IO var imported2 = await loadSkinIntoOsu(osu, new ZipArchiveReader(createOsk("test skin v2.1", "skinner"), "skin2.osk")); Assert.That(imported2.ID, Is.Not.EqualTo(imported.ID)); - Assert.That(osu.Dependencies.Get().GetAllUserSkins().Count, Is.EqualTo(2)); + Assert.That(osu.Dependencies.Get().GetAllUserSkins(true).Count, Is.EqualTo(2)); - Assert.That(osu.Dependencies.Get().GetAllUserSkins().First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID)); - Assert.That(osu.Dependencies.Get().GetAllUserSkins().Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID)); + Assert.That(osu.Dependencies.Get().GetAllUserSkins(true).First().Files.First().FileInfoID, Is.EqualTo(imported.Files.First().FileInfoID)); + Assert.That(osu.Dependencies.Get().GetAllUserSkins(true).Last().Files.First().FileInfoID, Is.EqualTo(imported2.Files.First().FileInfoID)); } finally { diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index fca1670419..51aaac1f79 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -95,7 +95,7 @@ namespace osu.Game.Skinning /// A newly allocated list of available . public List GetAllUsableSkins() { - var userSkins = GetAllUserSkins(); + var userSkins = GetAllUserSkins(false); userSkins.Insert(0, DefaultSkin.SkinInfo); userSkins.Insert(1, DefaultLegacySkin.SkinInfo); return userSkins; @@ -105,7 +105,13 @@ namespace osu.Game.Skinning /// Returns a list of all usable s that have been loaded by the user. /// /// A newly allocated list of available . - public List GetAllUserSkins() => ModelStore.Items.Where(s => !s.DeletePending).ToList(); + public List GetAllUserSkins(bool includeFiles = false) + { + if (includeFiles) + return ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList(); + + return ModelStore.Items.Where(s => !s.DeletePending).ToList(); + } public void SelectRandomSkin() { From 47d4a2e97f70de9b1cc307554de19b45eaa3a107 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Aug 2021 20:05:26 +0900 Subject: [PATCH 044/103] Make SettingsOverlay protected --- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 10 +++++----- .../Multiplayer/MultiplayerMatchSubScreen.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index a79f9421a7..3addf57048 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -64,7 +64,7 @@ namespace osu.Game.Screens.OnlinePlay.Match private readonly Room room; private ModSelectOverlay userModsSelectOverlay; - private RoomSettingsOverlay settingsOverlay; + protected RoomSettingsOverlay SettingsOverlay { get; private set; } protected RoomSubScreen(Room room) { @@ -162,7 +162,7 @@ namespace osu.Game.Screens.OnlinePlay.Match } } }, - settingsOverlay = CreateRoomSettingsOverlay() + SettingsOverlay = CreateRoomSettingsOverlay() }, }, }, @@ -181,7 +181,7 @@ namespace osu.Game.Screens.OnlinePlay.Match // The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed. mainContent.Hide(); - settingsOverlay.State.BindValueChanged(visibility => + SettingsOverlay.State.BindValueChanged(visibility => { if (visibility.NewValue == Visibility.Hidden) mainContent.Show(); @@ -215,9 +215,9 @@ namespace osu.Game.Screens.OnlinePlay.Match return true; } - if (settingsOverlay.State.Value == Visibility.Visible) + if (SettingsOverlay.State.Value == Visibility.Visible) { - settingsOverlay.Hide(); + SettingsOverlay.Hide(); return true; } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 1b9c2092dd..09c2a22850 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -141,7 +141,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer { new MultiplayerMatchHeader { - // OpenSettings = () => settingsOverlay.Show() + OpenSettings = () => SettingsOverlay.Show() } }, new Drawable[] From 58ecee543ad546c7c1e1f91ae6fb1187920f0b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 17 Aug 2021 23:00:10 +0200 Subject: [PATCH 045/103] Trim redundant default argument value --- osu.Game/Skinning/SkinManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index 51aaac1f79..0f805990b9 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -95,7 +95,7 @@ namespace osu.Game.Skinning /// A newly allocated list of available . public List GetAllUsableSkins() { - var userSkins = GetAllUserSkins(false); + var userSkins = GetAllUserSkins(); userSkins.Insert(0, DefaultSkin.SkinInfo); userSkins.Insert(1, DefaultLegacySkin.SkinInfo); return userSkins; From 8c5d99ab21c71fe5e1c743835c8b5245c8b17246 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 04:16:57 +0300 Subject: [PATCH 046/103] Override `CreateInstance()` in osu! bindable subclasses Three bindables are left which don't have this overriden due to them already not having a value-only constructor and not supporting `GetBoundCopy()` properly: - `BeatmapDifficultyCache.BindableStarDifficulty`. - `TotalScoreBindable` - `TotalScoreStringBindable` I could add support for them by passing the required data to them, as they seem to be able to have that shared, but I'm hesitant to support something which was already broken and never used, not sure. --- osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs | 2 +- osu.Game/Rulesets/Mods/DifficultyBindable.cs | 2 +- osu.Game/Screens/Edit/BindableBeatDivisor.cs | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs index 186514e868..3978378c3a 100644 --- a/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs +++ b/osu.Game/Rulesets/Mods/DifficultyAdjustSettingsControl.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Mods { // Intercept and extract the internal number bindable from DifficultyBindable. // This will provide bounds and precision specifications for the slider bar. - difficultyBindable = ((DifficultyBindable)value).GetBoundCopy(); + difficultyBindable = (DifficultyBindable)value.GetBoundCopy(); sliderDisplayCurrent.BindTo(difficultyBindable.CurrentNumber); base.Current = difficultyBindable; diff --git a/osu.Game/Rulesets/Mods/DifficultyBindable.cs b/osu.Game/Rulesets/Mods/DifficultyBindable.cs index 664b88eef4..e4304795f2 100644 --- a/osu.Game/Rulesets/Mods/DifficultyBindable.cs +++ b/osu.Game/Rulesets/Mods/DifficultyBindable.cs @@ -128,6 +128,6 @@ namespace osu.Game.Rulesets.Mods ExtendedLimits.UnbindFrom(otherDifficultyBindable.ExtendedLimits); } - public new DifficultyBindable GetBoundCopy() => new DifficultyBindable { BindTarget = this }; + protected override Bindable CreateInstance() => new DifficultyBindable(); } } diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs index ff33f0c70d..dfe2992a7c 100644 --- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs +++ b/osu.Game/Screens/Edit/BindableBeatDivisor.cs @@ -41,6 +41,8 @@ namespace osu.Game.Screens.Edit protected override int DefaultMaxValue => VALID_DIVISORS.Last(); protected override int DefaultPrecision => 1; + protected override Bindable CreateInstance() => new BindableBeatDivisor(); + /// /// Retrieves the appropriate colour for a beat divisor. /// From 5671820d92011d83f3d170df01e0f5f07fcc1837 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Aug 2021 10:35:34 +0900 Subject: [PATCH 047/103] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index ec223f98c2..24d07b4588 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d4dba9330f..928620b32e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 7e514afe74..77f9052e85 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -93,7 +93,7 @@ - + From f5923508564b8d24f3d9ca475c7144aa466b9332 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 04:59:08 +0300 Subject: [PATCH 048/103] Fix config pollution in HUD overlay test scene --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 51 ++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 3017428039..4f15032c62 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -19,6 +19,8 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneHUDOverlay : OsuManualInputManagerTestScene { + private OsuConfigManager localConfig; + private HUDOverlay hudOverlay; [Cached] @@ -31,8 +33,14 @@ namespace osu.Game.Tests.Visual.Gameplay private Drawable hideTarget => hudOverlay.KeyCounter; private FillFlowContainer keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().First(); - [Resolved] - private OsuConfigManager config { get; set; } + [BackgroundDependencyLoader] + private void load() + { + Dependencies.Cache(localConfig = new OsuConfigManager(LocalStorage)); + } + + [SetUpSteps] + public void SetUp() => Schedule(() => localConfig.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always)); [Test] public void TestComboCounterIncrementing() @@ -85,11 +93,7 @@ namespace osu.Game.Tests.Visual.Gameplay { createNew(); - HUDVisibilityMode originalConfigValue = HUDVisibilityMode.HideDuringGameplay; - - AddStep("get original config value", () => originalConfigValue = config.Get(OsuSetting.HUDVisibilityMode)); - - AddStep("set hud to never show", () => config.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Never)); + AddStep("set hud to never show", () => localConfig.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Never)); AddUntilStep("wait for fade", () => !hideTarget.IsPresent); @@ -98,37 +102,28 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("stop trigering", () => InputManager.ReleaseKey(Key.ControlLeft)); AddUntilStep("wait for fade", () => !hideTarget.IsPresent); - - AddStep("set original config value", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue)); } [Test] public void TestExternalHideDoesntAffectConfig() { - HUDVisibilityMode originalConfigValue = HUDVisibilityMode.HideDuringGameplay; - createNew(); - AddStep("get original config value", () => originalConfigValue = config.Get(OsuSetting.HUDVisibilityMode)); - AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); - AddAssert("config unchanged", () => originalConfigValue == config.Get(OsuSetting.HUDVisibilityMode)); + AddAssert("config unchanged", () => localConfig.GetBindable(OsuSetting.HUDVisibilityMode).IsDefault); AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true); - AddAssert("config unchanged", () => originalConfigValue == config.Get(OsuSetting.HUDVisibilityMode)); + AddAssert("config unchanged", () => localConfig.GetBindable(OsuSetting.HUDVisibilityMode).IsDefault); } [Test] public void TestChangeHUDVisibilityOnHiddenKeyCounter() { - bool keyCounterVisibleValue = false; - createNew(); - AddStep("save keycounter visible value", () => keyCounterVisibleValue = config.Get(OsuSetting.KeyOverlay)); - AddStep("set keycounter visible false", () => + AddStep("hide key overlay", () => { - config.SetValue(OsuSetting.KeyOverlay, false); + localConfig.SetValue(OsuSetting.KeyOverlay, false); hudOverlay.KeyCounter.AlwaysVisible.Value = false; }); @@ -139,24 +134,16 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true); AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent); AddAssert("key counters still hidden", () => !keyCounterFlow.IsPresent); - - AddStep("return value", () => config.SetValue(OsuSetting.KeyOverlay, keyCounterVisibleValue)); } [Test] public void TestHiddenHUDDoesntBlockSkinnableComponentsLoad() { - HUDVisibilityMode originalConfigValue = default; - - AddStep("get original config value", () => originalConfigValue = config.Get(OsuSetting.HUDVisibilityMode)); - - AddStep("set hud to never show", () => config.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Never)); + AddStep("set hud to never show", () => localConfig.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Never)); createNew(); AddUntilStep("wait for hud load", () => hudOverlay.IsLoaded); AddUntilStep("skinnable components loaded", () => hudOverlay.ChildrenOfType().Single().ComponentsLoaded); - - AddStep("set original config value", () => config.SetValue(OsuSetting.HUDVisibilityMode, originalConfigValue)); } private void createNew(Action action = null) @@ -175,5 +162,11 @@ namespace osu.Game.Tests.Visual.Gameplay Child = hudOverlay; }); } + + protected override void Dispose(bool isDisposing) + { + localConfig?.Dispose(); + base.Dispose(isDisposing); + } } } From 1fdaefef99d4b79cba8cbc428fb7d55cd5597cc9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Aug 2021 12:45:08 +0900 Subject: [PATCH 049/103] Revert unnecessary changes --- osu.Game/Overlays/SettingsPanel.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index fea797287e..376e36ea4e 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; -using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; @@ -180,7 +179,7 @@ namespace osu.Game.Overlays protected override void OnFocus(FocusEvent e) { - searchTextBox?.TakeFocus(); + searchTextBox.TakeFocus(); base.OnFocus(e); } @@ -274,8 +273,6 @@ namespace osu.Game.Overlays { public SearchContainer SearchContainer; - public new ScheduledDelegate Schedule(Action action) => Scheduler.AddDelayed(action, TransformDelay); - protected override FlowContainer CreateScrollContentContainer() => SearchContainer = new SearchContainer { From 5441fab6922bc05344b3797898502742d7d89dda Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Aug 2021 12:45:14 +0900 Subject: [PATCH 050/103] Avoid scheduling focus operation when not required --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 4a42027964..06a40e7245 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -25,7 +25,7 @@ namespace osu.Game.Graphics.UserInterface if (!allowImmediateFocus) return; - Schedule(() => GetContainingInputManager().ChangeFocus(this)); + Scheduler.Add(() => GetContainingInputManager().ChangeFocus(this), false); } public bool HoldFocus From 6ed3e469f7549b0346314d31e606d2ff942e542c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 06:50:01 +0300 Subject: [PATCH 051/103] Fix wrong attribute used for setup method --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 4f15032c62..290ba3317b 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -39,7 +39,7 @@ namespace osu.Game.Tests.Visual.Gameplay Dependencies.Cache(localConfig = new OsuConfigManager(LocalStorage)); } - [SetUpSteps] + [SetUp] public void SetUp() => Schedule(() => localConfig.SetValue(OsuSetting.HUDVisibilityMode, HUDVisibilityMode.Always)); [Test] From c66abf85f71d4a755262c805f06bccf7782b54d5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 14:04:44 +0900 Subject: [PATCH 052/103] Remove match header --- .../Match/MultiplayerMatchHeader.cs | 106 ------------------ .../Multiplayer/MultiplayerMatchSubScreen.cs | 14 --- 2 files changed, 120 deletions(-) delete mode 100644 osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchHeader.cs diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchHeader.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchHeader.cs deleted file mode 100644 index bb351d06d3..0000000000 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchHeader.cs +++ /dev/null @@ -1,106 +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 System; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Online.API; -using osu.Game.Screens.OnlinePlay.Match.Components; -using osu.Game.Users.Drawables; -using osuTK; -using FontWeight = osu.Game.Graphics.FontWeight; -using OsuColour = osu.Game.Graphics.OsuColour; -using OsuFont = osu.Game.Graphics.OsuFont; - -namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match -{ - public class MultiplayerMatchHeader : OnlinePlayComposite - { - public const float HEIGHT = 50; - - public Action OpenSettings; - - private UpdateableAvatar avatar; - private LinkFlowContainer hostText; - private Button openSettingsButton; - - [Resolved] - private IAPIProvider api { get; set; } - - public MultiplayerMatchHeader() - { - RelativeSizeAxes = Axes.X; - Height = HEIGHT; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - InternalChildren = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - avatar = new UpdateableAvatar - { - Size = new Vector2(50), - Masking = true, - CornerRadius = 10, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new OsuSpriteText - { - Font = OsuFont.GetFont(size: 30), - Current = { BindTarget = RoomName } - }, - hostText = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 20)) - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - } - } - } - } - }, - openSettingsButton = new PurpleTriangleButton - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Size = new Vector2(150, HEIGHT), - Text = "Open settings", - Action = () => OpenSettings?.Invoke(), - Alpha = 0 - } - }; - - Host.BindValueChanged(host => - { - avatar.User = host.NewValue; - - hostText.Clear(); - - if (host.NewValue != null) - { - hostText.AddText("hosted by "); - hostText.AddUserLink(host.NewValue, s => s.Font = s.Font.With(weight: FontWeight.SemiBold)); - } - - openSettingsButton.Alpha = host.NewValue?.Equals(api.LocalUser.Value) == true ? 1 : 0; - }, true); - } - } -} diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 09c2a22850..93377b221f 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -59,8 +59,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [CanBeNull] private IDisposable readyClickOperation; - // private GridContainer mainContent; - public MultiplayerMatchSubScreen(Room room) : base(room) { @@ -130,20 +128,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Child = new GridContainer { RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - }, Content = new[] { - new Drawable[] - { - new MultiplayerMatchHeader - { - OpenSettings = () => SettingsOverlay.Show() - } - }, new Drawable[] { new Container From 3d88a745cd2f5184e114447c329b89f45ca339ca Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 18 Aug 2021 14:27:05 +0900 Subject: [PATCH 053/103] Fix osu editor transforms not specified in the absolute time --- .../Edit/DrawableOsuEditorRuleset.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditorRuleset.cs b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditorRuleset.cs index d4f1602a46..c89527d8bd 100644 --- a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditorRuleset.cs +++ b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditorRuleset.cs @@ -64,11 +64,14 @@ namespace osu.Game.Rulesets.Osu.Edit if (hitObject is DrawableHitCircle circle) { - circle.ApproachCircle - .FadeOutFromOne(EDITOR_HIT_OBJECT_FADE_OUT_EXTENSION * 4) - .Expire(); + using (circle.BeginAbsoluteSequence(circle.HitStateUpdateTime)) + { + circle.ApproachCircle + .FadeOutFromOne(EDITOR_HIT_OBJECT_FADE_OUT_EXTENSION * 4) + .Expire(); - circle.ApproachCircle.ScaleTo(1.1f, 300, Easing.OutQuint); + circle.ApproachCircle.ScaleTo(1.1f, 300, Easing.OutQuint); + } } if (hitObject is IHasMainCirclePiece mainPieceContainer) From 0853554c2403700be54db9763466788bd19379f8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 15:11:52 +0900 Subject: [PATCH 054/103] Fix settings overlay not being initially visible --- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 3addf57048..9e729515d2 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -162,7 +162,10 @@ namespace osu.Game.Screens.OnlinePlay.Match } } }, - SettingsOverlay = CreateRoomSettingsOverlay() + SettingsOverlay = CreateRoomSettingsOverlay().With(s => + { + s.State.Value = room.RoomID.Value == null ? Visibility.Visible : Visibility.Hidden; + }) }, }, }, From 704af94d399517093b084809c7144d165f57965c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 15:12:16 +0900 Subject: [PATCH 055/103] Add edit button to room panel --- .../Lounge/Components/DrawableRoom.cs | 20 ++++--- .../Match/DrawableMultiplayerRoom.cs | 54 +++++++++++++++++++ .../Multiplayer/MultiplayerMatchSubScreen.cs | 5 +- 3 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 osu.Game/Screens/OnlinePlay/Multiplayer/Match/DrawableMultiplayerRoom.cs diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs index c8ecd65574..4e81739dc4 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs @@ -124,17 +124,23 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } } + public bool FilteringActive { get; set; } + + protected readonly Container ButtonsContainer = new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X + }; + private readonly Bindable roomCategory = new Bindable(); + private readonly Bindable hasPassword = new Bindable(); private RecentParticipantsList recentParticipantsList; private RoomSpecialCategoryPill specialCategoryPill; - - public bool FilteringActive { get; set; } - private PasswordProtectedIcon passwordIcon; - private readonly Bindable hasPassword = new Bindable(); - public DrawableRoom(Room room) { Room = room; @@ -289,13 +295,15 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components Origin = Anchor.CentreRight, AutoSizeAxes = Axes.X, RelativeSizeAxes = Axes.Y, + Spacing = new Vector2(5), Padding = new MarginPadding { Right = 10, - Vertical = 5 + Vertical = 20, }, Children = new Drawable[] { + ButtonsContainer, recentParticipantsList = new RecentParticipantsList { Anchor = Anchor.CentreRight, diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/DrawableMultiplayerRoom.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/DrawableMultiplayerRoom.cs new file mode 100644 index 0000000000..84ae6108f6 --- /dev/null +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/DrawableMultiplayerRoom.cs @@ -0,0 +1,54 @@ +// 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.Bindables; +using osu.Framework.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.Rooms; +using osu.Game.Screens.OnlinePlay.Lounge.Components; +using osu.Game.Screens.OnlinePlay.Match.Components; +using osu.Game.Users; +using osuTK; + +namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match +{ + public class DrawableMultiplayerRoom : DrawableRoom + { + public Action OnEdit; + + [Resolved] + private IAPIProvider api { get; set; } + + private readonly IBindable host = new Bindable(); + + private Drawable editButton; + + public DrawableMultiplayerRoom(Room room) + : base(room) + { + host.BindTo(room.Host); + } + + [BackgroundDependencyLoader] + private void load() + { + ButtonsContainer.Add(editButton = new PurpleTriangleButton + { + RelativeSizeAxes = Axes.Y, + Size = new Vector2(100, 1), + Text = "Edit", + Action = () => OnEdit?.Invoke() + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + host.BindValueChanged(h => editButton.Alpha = h.NewValue?.Equals(api.LocalUser.Value) == true ? 1 : 0, true); + } + + protected override bool ShouldBeConsideredForInput(Drawable child) => true; + } +} diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 93377b221f..3cbc6c36b6 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -110,7 +110,10 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList(); } - protected override DrawableRoom CreateDrawableRoom(Room room) => new DrawableRoom(room); + protected override DrawableRoom CreateDrawableRoom(Room room) => new DrawableMultiplayerRoom(room) + { + OnEdit = () => SettingsOverlay.Show() + }; protected override Drawable CreateMainContent() => new Container { From 1ae4a1910a135a8c1084d332bbf2650fa13abdf2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 09:17:42 +0300 Subject: [PATCH 056/103] Cache mod settings rather than fetching everytime --- osu.Game/Rulesets/Mods/Mod.cs | 36 +++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index a99ddc6924..8c2a8a8e8b 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; +using JetBrains.Annotations; using Newtonsoft.Json; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; @@ -129,6 +130,17 @@ namespace osu.Game.Rulesets.Mods [JsonIgnore] public virtual Type[] IncompatibleMods => Array.Empty(); + private IReadOnlyList settingsBacking; + + /// + /// A list of the all settings within this mod. + /// + internal IReadOnlyList Settings => + settingsBacking ??= this.GetSettingsSourceProperties() + .Select(p => p.Item2.GetValue(this)) + .Cast() + .ToList(); + /// /// Creates a copy of this initialised to a default state. /// @@ -191,10 +203,7 @@ namespace osu.Game.Rulesets.Mods if (ReferenceEquals(this, other)) return true; return GetType() == other.GetType() && - this.GetSettingsSourceProperties().All(pair => - EqualityComparer.Default.Equals( - ModUtils.GetSettingUnderlyingValue(pair.Item2.GetValue(this)), - ModUtils.GetSettingUnderlyingValue(pair.Item2.GetValue(other)))); + Settings.SequenceEqual(other.Settings, ModSettingsEqualityComparer.Default); } public override int GetHashCode() @@ -203,8 +212,8 @@ namespace osu.Game.Rulesets.Mods hashCode.Add(GetType()); - foreach (var (_, prop) in this.GetSettingsSourceProperties()) - hashCode.Add(ModUtils.GetSettingUnderlyingValue(prop.GetValue(this))); + foreach (var setting in Settings) + hashCode.Add(ModUtils.GetSettingUnderlyingValue(setting)); return hashCode.ToHashCode(); } @@ -213,5 +222,20 @@ namespace osu.Game.Rulesets.Mods /// Reset all custom settings for this mod back to their defaults. /// public virtual void ResetSettingsToDefaults() => CopyFrom((Mod)Activator.CreateInstance(GetType())); + + private class ModSettingsEqualityComparer : IEqualityComparer + { + public static ModSettingsEqualityComparer Default { get; } = new ModSettingsEqualityComparer(); + + public bool Equals(IBindable x, IBindable y) + { + object xValue = x == null ? null : ModUtils.GetSettingUnderlyingValue(x); + object yValue = y == null ? null : ModUtils.GetSettingUnderlyingValue(y); + + return EqualityComparer.Default.Equals(xValue, yValue); + } + + public int GetHashCode(IBindable obj) => ModUtils.GetSettingUnderlyingValue(obj).GetHashCode(); + } } } From 96b6670d1fe2e3018acdfe8ee0dd98a0981b5f6f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 09:18:03 +0300 Subject: [PATCH 057/103] Add mod benchmark --- osu.Game.Benchmarks/BenchmarkMod.cs | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 osu.Game.Benchmarks/BenchmarkMod.cs diff --git a/osu.Game.Benchmarks/BenchmarkMod.cs b/osu.Game.Benchmarks/BenchmarkMod.cs new file mode 100644 index 0000000000..050ddf36d5 --- /dev/null +++ b/osu.Game.Benchmarks/BenchmarkMod.cs @@ -0,0 +1,34 @@ +// 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 BenchmarkDotNet.Attributes; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Benchmarks +{ + public class BenchmarkMod : BenchmarkTest + { + private OsuModDoubleTime mod; + + [Params(1, 10, 100)] + public int Times { get; set; } + + [GlobalSetup] + public void GlobalSetup() + { + mod = new OsuModDoubleTime(); + } + + [Benchmark] + public int ModHashCode() + { + var hashCode = new HashCode(); + + for (int i = 0; i < Times; i++) + hashCode.Add(mod); + + return hashCode.ToHashCode(); + } + } +} From c5268c9a99d820d16534fc912e15cd02a1d08894 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 15:16:48 +0900 Subject: [PATCH 058/103] Simplify by reusing same room panel --- .../DrawableMatchRoom.cs} | 6 +++--- .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 19 ++++++++++--------- .../Multiplayer/MultiplayerMatchSubScreen.cs | 6 ------ .../Playlists/PlaylistsRoomSubScreen.cs | 3 --- 4 files changed, 13 insertions(+), 21 deletions(-) rename osu.Game/Screens/OnlinePlay/{Multiplayer/Match/DrawableMultiplayerRoom.cs => Match/DrawableMatchRoom.cs} (89%) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/DrawableMultiplayerRoom.cs b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs similarity index 89% rename from osu.Game/Screens/OnlinePlay/Multiplayer/Match/DrawableMultiplayerRoom.cs rename to osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs index 84ae6108f6..f7b4dd6920 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/DrawableMultiplayerRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs @@ -12,9 +12,9 @@ using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Users; using osuTK; -namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match +namespace osu.Game.Screens.OnlinePlay.Match { - public class DrawableMultiplayerRoom : DrawableRoom + public class DrawableMatchRoom : DrawableRoom { public Action OnEdit; @@ -25,7 +25,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match private Drawable editButton; - public DrawableMultiplayerRoom(Room room) + public DrawableMatchRoom(Room room) : base(room) { host.BindTo(room.Host); diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 9e729515d2..8dc5c0cc4a 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -19,7 +19,6 @@ using osu.Game.Online.Rooms; using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Rulesets.Mods; -using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match.Components; namespace osu.Game.Screens.OnlinePlay.Match @@ -64,7 +63,7 @@ namespace osu.Game.Screens.OnlinePlay.Match private readonly Room room; private ModSelectOverlay userModsSelectOverlay; - protected RoomSettingsOverlay SettingsOverlay { get; private set; } + private RoomSettingsOverlay settingsOverlay; protected RoomSubScreen(Room room) { @@ -123,7 +122,11 @@ namespace osu.Game.Screens.OnlinePlay.Match { new Drawable[] { - CreateDrawableRoom(room).With(d => d.MatchingFilter = true), + new DrawableMatchRoom(room) + { + MatchingFilter = true, + OnEdit = () => settingsOverlay.Show() + } }, null, new Drawable[] @@ -162,7 +165,7 @@ namespace osu.Game.Screens.OnlinePlay.Match } } }, - SettingsOverlay = CreateRoomSettingsOverlay().With(s => + settingsOverlay = CreateRoomSettingsOverlay().With(s => { s.State.Value = room.RoomID.Value == null ? Visibility.Visible : Visibility.Hidden; }) @@ -184,7 +187,7 @@ namespace osu.Game.Screens.OnlinePlay.Match // The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed. mainContent.Hide(); - SettingsOverlay.State.BindValueChanged(visibility => + settingsOverlay.State.BindValueChanged(visibility => { if (visibility.NewValue == Visibility.Hidden) mainContent.Show(); @@ -218,9 +221,9 @@ namespace osu.Game.Screens.OnlinePlay.Match return true; } - if (SettingsOverlay.State.Value == Visibility.Visible) + if (settingsOverlay.State.Value == Visibility.Visible) { - SettingsOverlay.Hide(); + settingsOverlay.Hide(); return true; } @@ -358,8 +361,6 @@ namespace osu.Game.Screens.OnlinePlay.Match track.Looping = false; } - protected abstract DrawableRoom CreateDrawableRoom(Room room); - protected abstract Drawable CreateMainContent(); protected abstract Drawable CreateFooter(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 3cbc6c36b6..73c8053c1a 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -22,7 +22,6 @@ using osu.Game.Overlays.Dialog; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.OnlinePlay.Components; -using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.OnlinePlay.Multiplayer.Match; @@ -110,11 +109,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList(); } - protected override DrawableRoom CreateDrawableRoom(Room room) => new DrawableMultiplayerRoom(room) - { - OnEdit = () => SettingsOverlay.Show() - }; - protected override Drawable CreateMainContent() => new Container { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index 7af74e7e64..c655f49820 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -14,7 +14,6 @@ using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Components; -using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.Play; @@ -298,8 +297,6 @@ namespace osu.Game.Screens.OnlinePlay.Playlists Exited = () => leaderboard.RefreshScores() }); - protected override DrawableRoom CreateDrawableRoom(Room room) => new DrawableRoom(room); - protected override Drawable CreateMainContent() => Empty(); protected override Drawable CreateFooter() => Empty(); From 228ad98b39ad6056eb387ed9e478b4de92db02fa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 15:27:23 +0900 Subject: [PATCH 059/103] Remove extra corner radius on DrawableRoom --- osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs index 4e81739dc4..b627dfbb8e 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs @@ -149,7 +149,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components Height = height; Masking = true; - CornerRadius = corner_radius + SELECTION_BORDER_WIDTH / 2; + CornerRadius = corner_radius; EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, From 744b6749d18ca282ba3eb6426b950ecd5cb071e7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 15:29:01 +0900 Subject: [PATCH 060/103] Resolve room settings layout issues --- .../Match/Components/RoomSettingsOverlay.cs | 3 +++ osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs index eec512347b..86687d7da8 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs @@ -31,6 +31,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components { RelativeSizeAxes = Axes.Both; Masking = true; + CornerRadius = 10; } [BackgroundDependencyLoader] @@ -47,12 +48,14 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components { base.PopIn(); Settings.MoveToY(0, TRANSITION_DURATION, Easing.OutQuint); + Settings.FadeIn(TRANSITION_DURATION / 2); } protected override void PopOut() { base.PopOut(); Settings.MoveToY(-1, TRANSITION_DURATION, Easing.InSine); + Settings.Delay(TRANSITION_DURATION / 2).FadeOut(TRANSITION_DURATION / 2); } public bool OnPressed(GlobalAction action) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 8dc5c0cc4a..9c7b255213 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -165,10 +165,16 @@ namespace osu.Game.Screens.OnlinePlay.Match } } }, - settingsOverlay = CreateRoomSettingsOverlay().With(s => + new Container { - s.State.Value = room.RoomID.Value == null ? Visibility.Visible : Visibility.Hidden; - }) + RelativeSizeAxes = Axes.Both, + // Resolves 1px masking errors between the settings overlay and the room panel. + Padding = new MarginPadding(-1), + Child = settingsOverlay = CreateRoomSettingsOverlay().With(s => + { + s.State.Value = room.RoomID.Value == null ? Visibility.Visible : Visibility.Hidden; + }) + } }, }, }, From 90a1be2e6158b2f2cb7bdb6533d0fa22e77056aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 15:54:33 +0900 Subject: [PATCH 061/103] Move paddings up one level --- .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 7 +- .../Multiplayer/MultiplayerMatchSubScreen.cs | 216 ++++++++---------- 2 files changed, 106 insertions(+), 117 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 9c7b255213..8e6cfe2acb 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -147,7 +147,12 @@ namespace osu.Game.Screens.OnlinePlay.Match Colour = Color4Extensions.FromHex(@"3e3a44") // This is super temporary. }, }, - CreateMainContent(), + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(10), + Child = CreateMainContent(), + }, new Container { Anchor = Anchor.BottomLeft, diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 73c8053c1a..b9bcb27d60 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -109,115 +109,99 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList(); } - protected override Drawable CreateMainContent() => new Container + protected override Drawable CreateMainContent() => new GridContainer { RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + Content = new[] { - new Container + new Drawable[] { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding - { - Horizontal = 10, - Vertical = 10 - }, - Child = new GridContainer + new Container { RelativeSizeAxes = Axes.Both, - Content = new[] + Padding = new MarginPadding { Horizontal = 5, Vertical = 10 }, + Child = new GridContainer { - new Drawable[] + RelativeSizeAxes = Axes.Both, + ColumnDimensions = new[] { - new Container + new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 400), + new Dimension(), + new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 600), + }, + Content = new[] + { + new Drawable[] { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 5, Vertical = 10 }, - Child = new GridContainer + // Main left column + new GridContainer { RelativeSizeAxes = Axes.Both, - ColumnDimensions = new[] + RowDimensions = new[] { - new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 400), - new Dimension(), - new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 600), + new Dimension(GridSizeMode.AutoSize) }, Content = new[] { + new Drawable[] { new ParticipantsListHeader() }, new Drawable[] { - // Main left column - new GridContainer + new ParticipantsList { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] { new ParticipantsListHeader() }, - new Drawable[] - { - new ParticipantsList - { - RelativeSizeAxes = Axes.Both - }, - } - } + RelativeSizeAxes = Axes.Both }, - // Spacer - null, - // Main right column - new FillFlowContainer + } + } + }, + // Spacer + null, + // Main right column + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new[] + { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new[] + new OverlinedHeader("Beatmap"), + new BeatmapSelectionControl { RelativeSizeAxes = Axes.X } + } + }, + UserModsSection = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 10 }, + Children = new Drawable[] + { + new OverlinedHeader("Extra mods"), + new FillFlowContainer { - new FillFlowContainer + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + new UserModSelectButton { - new OverlinedHeader("Beatmap"), - new BeatmapSelectionControl { RelativeSizeAxes = Axes.X } - } - }, - UserModsSection = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 10 }, - Children = new Drawable[] + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Width = 90, + Text = "Select", + Action = ShowUserModSelect, + }, + new ModDisplay { - new OverlinedHeader("Extra mods"), - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - new UserModSelectButton - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Width = 90, - Text = "Select", - Action = ShowUserModSelect, - }, - new ModDisplay - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Current = UserMods, - Scale = new Vector2(0.8f), - }, - } - } - } + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Current = UserMods, + Scale = new Vector2(0.8f), + }, } } } @@ -225,27 +209,27 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer } } } - }, - new Drawable[] - { - new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] { new OverlinedHeader("Chat") }, - new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } - } - } } - }, + } } }, - } + new Drawable[] + { + new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] { new OverlinedHeader("Chat") }, + new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } + } + } + } + }, }; protected override Drawable CreateFooter() => new MultiplayerMatchFooter @@ -444,19 +428,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer } } - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (client != null) - { - client.RoomUpdated -= onRoomUpdated; - client.LoadRequested -= onLoadRequested; - } - - modSettingChangeTracker?.Dispose(); - } - public void PresentBeatmap(WorkingBeatmap beatmap, RulesetInfo ruleset) { if (!this.IsCurrentScreen()) @@ -472,5 +443,18 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer this.Push(new MultiplayerMatchSongSelect(beatmap, ruleset)); } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (client != null) + { + client.RoomUpdated -= onRoomUpdated; + client.LoadRequested -= onLoadRequested; + } + + modSettingChangeTracker?.Dispose(); + } } } From 568f1fd345fd7f51660623c90916036aa84dbdce Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 16:09:00 +0900 Subject: [PATCH 062/103] Fix initial RoomId state not being handled correctly --- .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 49 ++++++++++--------- .../Multiplayer/MultiplayerMatchSubScreen.cs | 4 -- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 8e6cfe2acb..ae92ab92c1 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -44,6 +44,8 @@ namespace osu.Game.Screens.OnlinePlay.Match /// protected readonly Bindable> UserMods = new Bindable>(Array.Empty()); + protected readonly IBindable RoomId = new Bindable(); + [Resolved] private MusicController music { get; set; } @@ -60,14 +62,15 @@ namespace osu.Game.Screens.OnlinePlay.Match protected IBindable BeatmapAvailability => BeatmapAvailabilityTracker.Availability; - private readonly Room room; + public readonly Room Room; private ModSelectOverlay userModsSelectOverlay; private RoomSettingsOverlay settingsOverlay; + private Drawable mainContent; protected RoomSubScreen(Room room) { - this.room = room; + Room = room; Padding = new MarginPadding { Top = Header.HEIGHT }; @@ -75,6 +78,8 @@ namespace osu.Game.Screens.OnlinePlay.Match { SelectedItem = { BindTarget = SelectedItem } }; + + RoomId.BindTo(room.RoomID); } [BackgroundDependencyLoader] @@ -82,8 +87,6 @@ namespace osu.Game.Screens.OnlinePlay.Match { sampleStart = audio.Samples.Get(@"SongSelect/confirm-selection"); - Drawable mainContent; - InternalChildren = new Drawable[] { BeatmapAvailabilityTracker, @@ -122,7 +125,7 @@ namespace osu.Game.Screens.OnlinePlay.Match { new Drawable[] { - new DrawableMatchRoom(room) + new DrawableMatchRoom(Room) { MatchingFilter = true, OnEdit = () => settingsOverlay.Show() @@ -175,10 +178,7 @@ namespace osu.Game.Screens.OnlinePlay.Match RelativeSizeAxes = Axes.Both, // Resolves 1px masking errors between the settings overlay and the room panel. Padding = new MarginPadding(-1), - Child = settingsOverlay = CreateRoomSettingsOverlay().With(s => - { - s.State.Value = room.RoomID.Value == null ? Visibility.Visible : Visibility.Hidden; - }) + Child = settingsOverlay = CreateRoomSettingsOverlay() } }, }, @@ -191,25 +191,28 @@ namespace osu.Game.Screens.OnlinePlay.Match } } }; - - if (room.RoomID.Value == null) - { - // A new room is being created. - // The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed. - mainContent.Hide(); - - settingsOverlay.State.BindValueChanged(visibility => - { - if (visibility.NewValue == Visibility.Hidden) - mainContent.Show(); - }, true); - } } protected override void LoadComplete() { base.LoadComplete(); + RoomId.BindValueChanged(id => + { + if (id.NewValue == null) + { + // A new room is being created. + // The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed. + mainContent.Hide(); + settingsOverlay.Show(); + } + else + { + mainContent.Show(); + settingsOverlay.Hide(); + } + }, true); + SelectedItem.BindValueChanged(_ => Scheduler.AddOnce(selectedItemChanged)); managerUpdated = beatmapManager.ItemUpdated.GetBoundCopy(); @@ -220,7 +223,7 @@ namespace osu.Game.Screens.OnlinePlay.Match public override bool OnBackButton() { - if (room.RoomID.Value == null) + if (Room.RoomID.Value == null) { // room has not been created yet; exit immediately. return base.OnBackButton(); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index b9bcb27d60..f8e5d7d901 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -42,8 +42,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer public override string ShortTitle => "room"; - public readonly Room Room; - [Resolved] private MultiplayerClient client { get; set; } @@ -61,8 +59,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer public MultiplayerMatchSubScreen(Room room) : base(room) { - Room = room; - Title = room.RoomID.Value == null ? "New room" : room.Name.Value; Activity.Value = new UserActivity.InLobby(room); } From 66e11fe75eb0424af82fc03c384d372df7304fc2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 16:09:15 +0900 Subject: [PATCH 063/103] Initial integration of playlists with the new structure --- .../Playlists/PlaylistsRoomSubScreen.cs | 390 ++++++++---------- 1 file changed, 166 insertions(+), 224 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index c655f49820..bf0107d3c3 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -30,18 +30,13 @@ namespace osu.Game.Screens.OnlinePlay.Playlists public override string ShortTitle => "playlist"; - [Resolved(typeof(Room), nameof(Room.RoomID))] - private Bindable roomId { get; set; } - - [Resolved(typeof(Room), nameof(Room.Playlist))] - private BindableList playlist { get; set; } + [Resolved] + private IAPIProvider api { get; set; } private readonly IBindable isIdle = new BindableBool(); - private RoomSettingsOverlay settingsOverlay; private MatchLeaderboard leaderboard; private OverlinedHeader participantsHeader; - private GridContainer mainContent; private SelectionPollingComponent selectionPollingComponent; public PlaylistsRoomSubScreen(Room room) @@ -57,231 +52,21 @@ namespace osu.Game.Screens.OnlinePlay.Playlists if (idleTracker != null) isIdle.BindTo(idleTracker.IsIdle); - AddRangeInternal(new Drawable[] - { - selectionPollingComponent = new SelectionPollingComponent(), - mainContent = new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding - { - Horizontal = 105, - Vertical = 20 - }, - Child = new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - }, - Content = new[] - { - new Drawable[] { new Match.Components.Header() }, - new Drawable[] - { - participantsHeader = new OverlinedHeader("Participants") - { - ShowLine = false - } - }, - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 5 }, - Child = new ParticipantsDisplay(Direction.Horizontal) - { - Details = { BindTarget = participantsHeader.Details } - } - } - }, - new Drawable[] - { - new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Right = 5 }, - Child = new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] { new OverlinedPlaylistHeader(), }, - new Drawable[] - { - new DrawableRoomPlaylistWithResults - { - RelativeSizeAxes = Axes.Both, - Items = { BindTarget = playlist }, - SelectedItem = { BindTarget = SelectedItem }, - RequestShowResults = item => - { - Debug.Assert(roomId.Value != null); - ParentScreen?.Push(new PlaylistsResultsScreen(null, roomId.Value.Value, item, false)); - } - } - }, - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - } - } - }, - null, - new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new[] - { - UserModsSection = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Bottom = 10 }, - Children = new Drawable[] - { - new OverlinedHeader("Extra mods"), - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - new UserModSelectButton - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Width = 90, - Text = "Select", - Action = ShowUserModSelect, - }, - new ModDisplay - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Current = UserMods, - Scale = new Vector2(0.8f), - }, - } - } - } - }, - }, - new Drawable[] - { - new OverlinedHeader("Leaderboard") - }, - new Drawable[] { leaderboard = new MatchLeaderboard { RelativeSizeAxes = Axes.Both }, }, - new Drawable[] { new OverlinedHeader("Chat"), }, - new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Relative, size: 0.4f, minSize: 120), - } - }, - null - }, - }, - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 400), - new Dimension(), - new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 600), - new Dimension(), - } - } - } - }, - } - } - }, - new Drawable[] - { - new Footer { OnStart = StartPlay } - } - }, - RowDimensions = new[] - { - new Dimension(), - new Dimension(GridSizeMode.AutoSize), - } - }, - settingsOverlay = new PlaylistsRoomSettingsOverlay - { - RelativeSizeAxes = Axes.Both, - EditPlaylist = () => - { - if (this.IsCurrentScreen()) - this.Push(new PlaylistsSongSelect()); - }, - State = { Value = roomId.Value == null ? Visibility.Visible : Visibility.Hidden } - } - }); - - if (roomId.Value == null) - { - // A new room is being created. - // The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed. - mainContent.Hide(); - - settingsOverlay.State.BindValueChanged(visibility => - { - if (visibility.NewValue == Visibility.Hidden) - mainContent.Show(); - }, true); - } + AddInternal(selectionPollingComponent = new SelectionPollingComponent()); } - [Resolved] - private IAPIProvider api { get; set; } - protected override void LoadComplete() { base.LoadComplete(); isIdle.BindValueChanged(_ => updatePollingRate(), true); - - roomId.BindValueChanged(id => + RoomId.BindValueChanged(id => { - if (id.NewValue == null) - settingsOverlay.Show(); - else + if (id.NewValue != null) { - settingsOverlay.Hide(); - // Set the first playlist item. // This is scheduled since updating the room and playlist may happen in an arbitrary order (via Room.CopyFrom()). - Schedule(() => SelectedItem.Value = playlist.FirstOrDefault()); + Schedule(() => SelectedItem.Value = Room.Playlist.FirstOrDefault()); } }, true); } @@ -297,10 +82,167 @@ namespace osu.Game.Screens.OnlinePlay.Playlists Exited = () => leaderboard.RefreshScores() }); - protected override Drawable CreateMainContent() => Empty(); + protected override Drawable CreateMainContent() => new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + }, + Content = new[] + { + new Drawable[] { new Match.Components.Header() }, + new Drawable[] + { + participantsHeader = new OverlinedHeader("Participants") + { + ShowLine = false + } + }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 5 }, + Child = new ParticipantsDisplay(Direction.Horizontal) + { + Details = { BindTarget = participantsHeader.Details } + } + } + }, + new Drawable[] + { + new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = 5 }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] { new OverlinedPlaylistHeader(), }, + new Drawable[] + { + new DrawableRoomPlaylistWithResults + { + RelativeSizeAxes = Axes.Both, + Items = { BindTarget = Room.Playlist }, + SelectedItem = { BindTarget = SelectedItem }, + RequestShowResults = item => + { + Debug.Assert(RoomId.Value != null); + ParentScreen?.Push(new PlaylistsResultsScreen(null, RoomId.Value.Value, item, false)); + } + } + }, + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + } + } + }, + null, + new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new[] + { + UserModsSection = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Bottom = 10 }, + Children = new Drawable[] + { + new OverlinedHeader("Extra mods"), + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new UserModSelectButton + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Width = 90, + Text = "Select", + Action = ShowUserModSelect, + }, + new ModDisplay + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Current = UserMods, + Scale = new Vector2(0.8f), + }, + } + } + } + }, + }, + new Drawable[] + { + new OverlinedHeader("Leaderboard") + }, + new Drawable[] { leaderboard = new MatchLeaderboard { RelativeSizeAxes = Axes.Both }, }, + new Drawable[] { new OverlinedHeader("Chat"), }, + new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Relative, size: 0.4f, minSize: 120), + } + }, + null + }, + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 400), + new Dimension(), + new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 600), + new Dimension(), + } + } + } + }, + }; - protected override Drawable CreateFooter() => Empty(); + protected override Drawable CreateFooter() => new Footer + { + OnStart = StartPlay + }; - protected override RoomSettingsOverlay CreateRoomSettingsOverlay() => new PlaylistsRoomSettingsOverlay(); + protected override RoomSettingsOverlay CreateRoomSettingsOverlay() => new PlaylistsRoomSettingsOverlay + { + EditPlaylist = () => + { + if (this.IsCurrentScreen()) + this.Push(new PlaylistsSongSelect()); + }, + }; } } From 87a5922f0eef0eb69becbdf3a1ea1b12d3ceb501 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 16:26:45 +0900 Subject: [PATCH 064/103] Remove participants from playlists screen --- .../Playlists/PlaylistsRoomSubScreen.cs | 193 +++++++----------- 1 file changed, 76 insertions(+), 117 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index bf0107d3c3..d799f09972 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -36,7 +36,6 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private readonly IBindable isIdle = new BindableBool(); private MatchLeaderboard leaderboard; - private OverlinedHeader participantsHeader; private SelectionPollingComponent selectionPollingComponent; public PlaylistsRoomSubScreen(Room room) @@ -85,150 +84,110 @@ namespace osu.Game.Screens.OnlinePlay.Playlists protected override Drawable CreateMainContent() => new GridContainer { RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - }, Content = new[] { - new Drawable[] { new Match.Components.Header() }, - new Drawable[] - { - participantsHeader = new OverlinedHeader("Participants") - { - ShowLine = false - } - }, new Drawable[] { new Container { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 5 }, - Child = new ParticipantsDisplay(Direction.Horizontal) + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = 5 }, + Child = new GridContainer { - Details = { BindTarget = participantsHeader.Details } + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] { new OverlinedPlaylistHeader(), }, + new Drawable[] + { + new DrawableRoomPlaylistWithResults + { + RelativeSizeAxes = Axes.Both, + Items = { BindTarget = Room.Playlist }, + SelectedItem = { BindTarget = SelectedItem }, + RequestShowResults = item => + { + Debug.Assert(RoomId.Value != null); + ParentScreen?.Push(new PlaylistsResultsScreen(null, RoomId.Value.Value, item, false)); + } + } + }, + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + } } - } - }, - new Drawable[] - { + }, + null, new GridContainer { RelativeSizeAxes = Axes.Both, Content = new[] { - new Drawable[] + new[] { - new Container + UserModsSection = new FillFlowContainer { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Right = 5 }, - Child = new GridContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Bottom = 10 }, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Content = new[] + new OverlinedHeader("Extra mods"), + new FillFlowContainer { - new Drawable[] { new OverlinedPlaylistHeader(), }, - new Drawable[] + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] { - new DrawableRoomPlaylistWithResults + new UserModSelectButton { - RelativeSizeAxes = Axes.Both, - Items = { BindTarget = Room.Playlist }, - SelectedItem = { BindTarget = SelectedItem }, - RequestShowResults = item => - { - Debug.Assert(RoomId.Value != null); - ParentScreen?.Push(new PlaylistsResultsScreen(null, RoomId.Value.Value, item, false)); - } - } - }, - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Width = 90, + Text = "Select", + Action = ShowUserModSelect, + }, + new ModDisplay + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Current = UserMods, + Scale = new Vector2(0.8f), + }, + } } } }, - null, - new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new[] - { - UserModsSection = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Bottom = 10 }, - Children = new Drawable[] - { - new OverlinedHeader("Extra mods"), - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - new UserModSelectButton - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Width = 90, - Text = "Select", - Action = ShowUserModSelect, - }, - new ModDisplay - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Current = UserMods, - Scale = new Vector2(0.8f), - }, - } - } - } - }, - }, - new Drawable[] - { - new OverlinedHeader("Leaderboard") - }, - new Drawable[] { leaderboard = new MatchLeaderboard { RelativeSizeAxes = Axes.Both }, }, - new Drawable[] { new OverlinedHeader("Chat"), }, - new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Relative, size: 0.4f, minSize: 120), - } - }, - null }, + new Drawable[] + { + new OverlinedHeader("Leaderboard") + }, + new Drawable[] { leaderboard = new MatchLeaderboard { RelativeSizeAxes = Axes.Both }, }, + new Drawable[] { new OverlinedHeader("Chat"), }, + new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } }, - ColumnDimensions = new[] + RowDimensions = new[] { - new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 400), - new Dimension(), - new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 600), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), new Dimension(), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Relative, size: 0.4f, minSize: 120), } - } - } + }, + }, }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 400), + new Dimension(), + new Dimension(GridSizeMode.Relative, size: 0.5f, maxSize: 600), + } }; protected override Drawable CreateFooter() => new Footer From 6dc96fdb830b78dc11e539ebeb24b20e7619b615 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 16:35:18 +0900 Subject: [PATCH 065/103] Disable edit button in playlists --- .../TestScenePlaylistsRoomSubScreen.cs | 7 +++-- .../OnlinePlay/Match/DrawableMatchRoom.cs | 26 +++++++++++++------ .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 11 ++++++-- .../Playlists/PlaylistsRoomSubScreen.cs | 2 +- 4 files changed, 31 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs index ee93e728ac..b8df90be2b 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs @@ -19,7 +19,6 @@ using osu.Game.Screens.OnlinePlay.Playlists; using osu.Game.Screens.Play; using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Visual.OnlinePlay; -using osu.Game.Users; using osuTK.Input; namespace osu.Game.Tests.Visual.Playlists @@ -66,7 +65,7 @@ namespace osu.Game.Tests.Visual.Playlists { SelectedRoom.Value.RoomID.Value = 1; SelectedRoom.Value.Name.Value = "my awesome room"; - SelectedRoom.Value.Host.Value = new User { Id = 2, Username = "peppy" }; + SelectedRoom.Value.Host.Value = API.LocalUser.Value; SelectedRoom.Value.RecentParticipants.Add(SelectedRoom.Value.Host.Value); SelectedRoom.Value.EndDate.Value = DateTimeOffset.Now.AddMinutes(5); SelectedRoom.Value.Playlist.Add(new PlaylistItem @@ -86,7 +85,7 @@ namespace osu.Game.Tests.Visual.Playlists AddStep("set room properties", () => { SelectedRoom.Value.Name.Value = "my awesome room"; - SelectedRoom.Value.Host.Value = new User { Id = 2, Username = "peppy" }; + SelectedRoom.Value.Host.Value = API.LocalUser.Value; SelectedRoom.Value.Playlist.Add(new PlaylistItem { Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, @@ -137,7 +136,7 @@ namespace osu.Game.Tests.Visual.Playlists AddStep("load room", () => { SelectedRoom.Value.Name.Value = "my awesome room"; - SelectedRoom.Value.Host.Value = new User { Id = 2, Username = "peppy" }; + SelectedRoom.Value.Host.Value = API.LocalUser.Value; SelectedRoom.Value.Playlist.Add(new PlaylistItem { Beatmap = { Value = importedSet.Beatmaps[0] }, diff --git a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs index f7b4dd6920..ead219bee2 100644 --- a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -22,31 +23,40 @@ namespace osu.Game.Screens.OnlinePlay.Match private IAPIProvider api { get; set; } private readonly IBindable host = new Bindable(); + private readonly bool allowEdit; + [CanBeNull] private Drawable editButton; - public DrawableMatchRoom(Room room) + public DrawableMatchRoom(Room room, bool allowEdit = true) : base(room) { + this.allowEdit = allowEdit; + host.BindTo(room.Host); } [BackgroundDependencyLoader] private void load() { - ButtonsContainer.Add(editButton = new PurpleTriangleButton + if (allowEdit) { - RelativeSizeAxes = Axes.Y, - Size = new Vector2(100, 1), - Text = "Edit", - Action = () => OnEdit?.Invoke() - }); + ButtonsContainer.Add(editButton = new PurpleTriangleButton + { + RelativeSizeAxes = Axes.Y, + Size = new Vector2(100, 1), + Text = "Edit", + Action = () => OnEdit?.Invoke() + }); + } } protected override void LoadComplete() { base.LoadComplete(); - host.BindValueChanged(h => editButton.Alpha = h.NewValue?.Equals(api.LocalUser.Value) == true ? 1 : 0, true); + + if (editButton != null) + host.BindValueChanged(h => editButton.Alpha = h.NewValue?.Equals(api.LocalUser.Value) == true ? 1 : 0, true); } protected override bool ShouldBeConsideredForInput(Drawable child) => true; diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index ae92ab92c1..e95b4b221e 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -63,14 +63,21 @@ namespace osu.Game.Screens.OnlinePlay.Match protected IBindable BeatmapAvailability => BeatmapAvailabilityTracker.Availability; public readonly Room Room; + private readonly bool allowEdit; private ModSelectOverlay userModsSelectOverlay; private RoomSettingsOverlay settingsOverlay; private Drawable mainContent; - protected RoomSubScreen(Room room) + /// + /// Creates a new . + /// + /// The . + /// Whether to allow editing room settings post-creation. + protected RoomSubScreen(Room room, bool allowEdit = true) { Room = room; + this.allowEdit = allowEdit; Padding = new MarginPadding { Top = Header.HEIGHT }; @@ -125,7 +132,7 @@ namespace osu.Game.Screens.OnlinePlay.Match { new Drawable[] { - new DrawableMatchRoom(Room) + new DrawableMatchRoom(Room, allowEdit) { MatchingFilter = true, OnEdit = () => settingsOverlay.Show() diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index d799f09972..9855d1cb95 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private SelectionPollingComponent selectionPollingComponent; public PlaylistsRoomSubScreen(Room room) - : base(room) + : base(room, false) // Editing is temporarily not allowed. { Title = room.RoomID.Value == null ? "New playlist" : room.Name.Value; Activity.Value = new UserActivity.InLobby(room); From 5faf2df9b459bd00d669ff13db6d1f93a412a8d4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 16:42:49 +0900 Subject: [PATCH 066/103] Revert unintentional change --- .../Visual/Multiplayer/TestSceneMultiplayer.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 035bdbea1c..e618b28f40 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -83,19 +83,6 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("load multiplayer", () => LoadScreen(multiplayerScreen)); AddUntilStep("wait for multiplayer to load", () => multiplayerScreen.IsLoaded); AddUntilStep("wait for lounge to load", () => this.ChildrenOfType().FirstOrDefault()?.IsLoaded == true); - - createRoom(() => new Room - { - Name = { Value = "Test Room" }, - Playlist = - { - new PlaylistItem - { - Beatmap = { Value = beatmaps.GetWorkingBeatmap(importedSet.Beatmaps.First(b => b.RulesetID == 0)).BeatmapInfo }, - Ruleset = { Value = new OsuRuleset().RulesetInfo }, - } - } - }); } [Test] From 74d6c2652023e2f603c053ded54bac6b768aa551 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 11:03:35 +0300 Subject: [PATCH 067/103] Refactor star rating display layout with flexibility in mind --- .../TestSceneStarRatingDisplay.cs | 11 ++-- .../Beatmaps/Drawables/StarRatingDisplay.cs | 63 ++++++++++++++----- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs index a8bc5664f3..7883049df2 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs @@ -8,17 +8,15 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; -using osu.Game.Graphics.Containers; using osuTK; namespace osu.Game.Tests.Visual.UserInterface { public class TestSceneStarRatingDisplay : OsuTestScene { - [TestCase(52f, 20f)] - [TestCase(52f, 16f)] - [TestCase(50f, 14f)] - public void TestDisplay(float width, float height) + [TestCase(StarRatingDisplaySize.Regular)] + [TestCase(StarRatingDisplaySize.Small)] + public void TestDisplay(StarRatingDisplaySize size) { AddStep("load displays", () => { @@ -36,11 +34,10 @@ namespace osu.Game.Tests.Visual.UserInterface AutoSizeAxes = Axes.Both, Spacing = new Vector2(2f), Direction = FillDirection.Vertical, - ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplay(new StarDifficulty(i * (i >= 11 ? 25f : 1f) + j * 0.1f, 0)) + ChildrenEnumerable = Enumerable.Range(0, 10).Select(j => new StarRatingDisplay(new StarDifficulty(i * (i >= 11 ? 25f : 1f) + j * 0.1f, 0), size) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(width, height), }), }) }; diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index 2c40aebbe1..ed2fee23d5 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -44,40 +44,63 @@ namespace osu.Game.Beatmaps.Drawables /// Creates a new using an already computed . /// /// The already computed to display. - public StarRatingDisplay(StarDifficulty starDifficulty) + /// The size of the star rating display. + public StarRatingDisplay(StarDifficulty starDifficulty, StarRatingDisplaySize size = StarRatingDisplaySize.Regular) { Current.Value = starDifficulty; - Size = new Vector2(52f, 20f); + AutoSizeAxes = Axes.Both; InternalChild = new CircularContainer { Masking = true, - RelativeSizeAxes = Axes.Both, + AutoSizeAxes = Axes.Both, Children = new Drawable[] { background = new Box { RelativeSizeAxes = Axes.Both, }, - starIcon = new SpriteIcon + new GridContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Margin = new MarginPadding { Right = 30f }, - Icon = FontAwesome.Solid.Star, - Size = new Vector2(8f), + AutoSizeAxes = Axes.Both, + Margin = size == StarRatingDisplaySize.Small + ? new MarginPadding { Horizontal = 7f } + : new MarginPadding { Horizontal = 8f, Vertical = 2f }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Absolute, 3f), + new Dimension(GridSizeMode.AutoSize, minSize: 25f), + }, + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, + Content = new[] + { + new[] + { + starIcon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(8f), + }, + Empty(), + starsText = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Bottom = 1.5f }, + // todo: this should be size: 12f, but to match up with the design, it needs to be 14.4f + // see https://github.com/ppy/osu-framework/issues/3271. + Font = OsuFont.Torus.With(size: 14.4f, weight: FontWeight.Bold), + Shadow = false, + } + } + } }, - starsText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Margin = new MarginPadding { Left = 10f, Bottom = 2f }, - // todo: this should be size: 12f, but to match up with the design, it needs to be 14.4f - // see https://github.com/ppy/osu-framework/issues/3271. - Font = OsuFont.Torus.With(size: 14.4f, weight: FontWeight.Bold), - Shadow = false, - } } }; } @@ -97,4 +120,10 @@ namespace osu.Game.Beatmaps.Drawables }, true); } } + + public enum StarRatingDisplaySize + { + Small, + Regular, + } } From 9220d17202fb032110d7804a29ae109e5520692f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 17:28:20 +0900 Subject: [PATCH 068/103] Adjust paddings/spacings --- .../Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs | 2 +- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 2 +- .../OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs index 86687d7da8..80a22880d4 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/RoomSettingsOverlay.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components public abstract class RoomSettingsOverlay : FocusedOverlayContainer, IKeyBindingHandler { protected const float TRANSITION_DURATION = 350; - protected const float FIELD_PADDING = 45; + protected const float FIELD_PADDING = 25; protected OnlinePlayComposite Settings { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index e95b4b221e..e1412c894c 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -160,7 +160,7 @@ namespace osu.Game.Screens.OnlinePlay.Match new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding(10), + Padding = new MarginPadding(20), Child = CreateMainContent(), }, new Container diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs index d28f886be4..3eea59006a 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSettingsOverlay.cs @@ -193,7 +193,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists Child = new GridContainer { RelativeSizeAxes = Axes.X, - Height = 500, + Height = 448, Content = new[] { new Drawable[] From 5e91ec73e3bf888f5aaf305478d5fceb317106ec Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 11:36:27 +0300 Subject: [PATCH 069/103] Handle star rating range display sizing --- .../Beatmaps/Drawables/StarRatingDisplay.cs | 22 ++++++++++++++++--- .../Components/StarRatingRangeDisplay.cs | 4 ++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index ed2fee23d5..192ebe79d7 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -51,6 +51,23 @@ namespace osu.Game.Beatmaps.Drawables AutoSizeAxes = Axes.Both; + MarginPadding margin = default; + + switch (size) + { + case StarRatingDisplaySize.Small: + margin = new MarginPadding { Horizontal = 7f }; + break; + + case StarRatingDisplaySize.Range: + margin = new MarginPadding { Horizontal = 8f }; + break; + + case StarRatingDisplaySize.Regular: + margin = new MarginPadding { Horizontal = 8f, Vertical = 2f }; + break; + } + InternalChild = new CircularContainer { Masking = true, @@ -66,9 +83,7 @@ namespace osu.Game.Beatmaps.Drawables Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Both, - Margin = size == StarRatingDisplaySize.Small - ? new MarginPadding { Horizontal = 7f } - : new MarginPadding { Horizontal = 8f, Vertical = 2f }, + Margin = margin, ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize), @@ -124,6 +139,7 @@ namespace osu.Game.Beatmaps.Drawables public enum StarRatingDisplaySize { Small, + Range, Regular, } } diff --git a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs index 8e62153225..7b14acf924 100644 --- a/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs +++ b/osu.Game/Screens/OnlinePlay/Components/StarRatingRangeDisplay.cs @@ -64,8 +64,8 @@ namespace osu.Game.Screens.OnlinePlay.Components AutoSizeAxes = Axes.Both, Children = new Drawable[] { - minDisplay = new StarRatingDisplay(default) { Size = new Vector2(52f, 16f) }, - maxDisplay = new StarRatingDisplay(default) { Size = new Vector2(52f, 16f) } + minDisplay = new StarRatingDisplay(default, StarRatingDisplaySize.Range), + maxDisplay = new StarRatingDisplay(default, StarRatingDisplaySize.Range) } } }; From d2df09432f040d29ae08a92b2104c8d4fca5eda2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 11:49:33 +0300 Subject: [PATCH 070/103] Center the star rating display text rather than left --- osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index 192ebe79d7..25cde5fb82 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -105,8 +105,8 @@ namespace osu.Game.Beatmaps.Drawables Empty(), starsText = new OsuSpriteText { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, Margin = new MarginPadding { Bottom = 1.5f }, // todo: this should be size: 12f, but to match up with the design, it needs to be 14.4f // see https://github.com/ppy/osu-framework/issues/3271. From 28e2b6cec7cff82d007d44a7aa2026ff0679ed73 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Aug 2021 18:34:09 +0900 Subject: [PATCH 071/103] Add transform test for fun --- .../TestSceneStarRatingDisplay.cs | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs index 7883049df2..052251d5a8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs @@ -3,6 +3,7 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Utils; @@ -44,6 +45,31 @@ namespace osu.Game.Tests.Visual.UserInterface }); } + [Test] + public void TestSpectrum() + { + StarRatingDisplay starRating = null; + + BindableDouble starRatingNumeric; + + AddStep("load display", () => + { + Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1)) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(3f), + }; + }); + + AddStep("transform over spectrum", () => + { + starRatingNumeric = new BindableDouble(); + starRatingNumeric.BindValueChanged(val => starRating.Current.Value = new StarDifficulty(val.NewValue, 1)); + this.TransformBindableTo(starRatingNumeric, 10, 10000, Easing.OutQuint); + }); + } + [Test] public void TestChangingStarRatingDisplay() { From 8172ffc401a5ff0abe8a779cc7fd2dba8aee3448 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 18 Aug 2021 13:12:58 +0300 Subject: [PATCH 072/103] Fix lounge sub screen loading layer displaying in the background --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 8bed3d6049..24aad8c124 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -84,7 +84,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge InternalChildren = new Drawable[] { ListingPollingComponent = CreatePollingComponent().With(c => c.Filter.BindTarget = filter), - loadingLayer = new LoadingLayer(true), new Container { RelativeSizeAxes = Axes.Both, @@ -162,6 +161,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge Filter = { BindTarget = filter } } }, + loadingLayer = new LoadingLayer(true), } }, } From 63af67f61b5a69918b34ae7f4dc764deffa7b747 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 20:21:29 +0900 Subject: [PATCH 073/103] Cleanup around footers --- .../Multiplayer/TestSceneMatchHeader.cs | 55 ------------- .../OnlinePlay/Match/Components/Footer.cs | 48 ----------- .../OnlinePlay/Match/Components/Header.cs | 79 ------------------- .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 29 ++++++- .../Match/MultiplayerMatchFooter.cs | 63 ++++++--------- .../Multiplayer/MultiplayerMatchSubScreen.cs | 22 +++--- .../Playlists/PlaylistsRoomFooter.cs | 32 ++++++++ .../Playlists/PlaylistsRoomSubScreen.cs | 25 +++--- 8 files changed, 103 insertions(+), 250 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs delete mode 100644 osu.Game/Screens/OnlinePlay/Match/Components/Footer.cs delete mode 100644 osu.Game/Screens/OnlinePlay/Match/Components/Header.cs create mode 100644 osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomFooter.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs deleted file mode 100644 index 71ba5db481..0000000000 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs +++ /dev/null @@ -1,55 +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 NUnit.Framework; -using osu.Game.Beatmaps; -using osu.Game.Online.Rooms; -using osu.Game.Rulesets.Osu; -using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Screens.OnlinePlay.Match.Components; -using osu.Game.Tests.Visual.OnlinePlay; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual.Multiplayer -{ - public class TestSceneMatchHeader : OnlinePlayTestScene - { - [SetUp] - public new void Setup() => Schedule(() => - { - SelectedRoom.Value = new Room - { - Name = { Value = "A very awesome room" }, - Host = { Value = new User { Id = 2, Username = "peppy" } }, - Playlist = - { - new PlaylistItem - { - Beatmap = - { - Value = new BeatmapInfo - { - Metadata = new BeatmapMetadata - { - Title = "Title", - Artist = "Artist", - AuthorString = "Author", - }, - Version = "Version", - Ruleset = new OsuRuleset().RulesetInfo - } - }, - RequiredMods = - { - new OsuModDoubleTime(), - new OsuModNoFail(), - new OsuModRelax(), - } - } - } - }; - - Child = new Header(); - }); - } -} diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/Footer.cs b/osu.Game/Screens/OnlinePlay/Match/Components/Footer.cs deleted file mode 100644 index e91c46beed..0000000000 --- a/osu.Game/Screens/OnlinePlay/Match/Components/Footer.cs +++ /dev/null @@ -1,48 +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 System; -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.Game.Graphics; -using osu.Game.Screens.OnlinePlay.Playlists; -using osuTK; - -namespace osu.Game.Screens.OnlinePlay.Match.Components -{ - public class Footer : CompositeDrawable - { - public const float HEIGHT = 50; - - public Action OnStart; - - private readonly Drawable background; - - public Footer() - { - RelativeSizeAxes = Axes.X; - Height = HEIGHT; - - InternalChildren = new[] - { - background = new Box { RelativeSizeAxes = Axes.Both }, - new PlaylistsReadyButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(600, 50), - Action = () => OnStart?.Invoke() - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = Color4Extensions.FromHex(@"28242d"); - } - } -} diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/Header.cs b/osu.Game/Screens/OnlinePlay/Match/Components/Header.cs deleted file mode 100644 index a2d11c54c1..0000000000 --- a/osu.Game/Screens/OnlinePlay/Match/Components/Header.cs +++ /dev/null @@ -1,79 +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.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Users.Drawables; -using osuTK; - -namespace osu.Game.Screens.OnlinePlay.Match.Components -{ - public class Header : OnlinePlayComposite - { - public const float HEIGHT = 50; - - private UpdateableAvatar avatar; - private LinkFlowContainer hostText; - - public Header() - { - RelativeSizeAxes = Axes.X; - Height = HEIGHT; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - avatar = new UpdateableAvatar - { - Size = new Vector2(50), - Masking = true, - CornerRadius = 10, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new OsuSpriteText - { - Font = OsuFont.GetFont(size: 30), - Current = { BindTarget = RoomName } - }, - hostText = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 20)) - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - } - } - } - } - }; - - Host.BindValueChanged(host => - { - avatar.User = host.NewValue; - - hostText.Clear(); - - if (host.NewValue != null) - { - hostText.AddText("hosted by "); - hostText.AddUserLink(host.NewValue, s => s.Font = s.Font.With(weight: FontWeight.SemiBold)); - } - }, true); - } - } -} diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index e1412c894c..42d76e5a15 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -103,7 +103,7 @@ namespace osu.Game.Screens.OnlinePlay.Match RowDimensions = new[] { new Dimension(), - new Dimension(GridSizeMode.AutoSize) + new Dimension(GridSizeMode.Absolute, 50) }, Content = new[] { @@ -154,7 +154,7 @@ namespace osu.Game.Screens.OnlinePlay.Match Child = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(@"3e3a44") // This is super temporary. + Colour = Color4Extensions.FromHex(@"3e3a44") // Temporary. }, }, new Container @@ -191,9 +191,21 @@ namespace osu.Game.Screens.OnlinePlay.Match }, }, // Footer - new[] + new Drawable[] { - CreateFooter() + new Container + { + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex(@"28242d") // Temporary. + }, + CreateFooter() + } + } } } } @@ -382,10 +394,19 @@ namespace osu.Game.Screens.OnlinePlay.Match track.Looping = false; } + /// + /// Creates the main centred content. + /// protected abstract Drawable CreateMainContent(); + /// + /// Creates the footer content. + /// protected abstract Drawable CreateFooter(); + /// + /// Creates the room settings overlay. + /// protected abstract RoomSettingsOverlay CreateRoomSettingsOverlay(); private class UserModSelectOverlay : LocalPlayerModSelectOverlay diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs index d4f5428bfb..9e8d51e64e 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs @@ -2,18 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System; -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.Game.Graphics; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { public class MultiplayerMatchFooter : CompositeDrawable { - public const float HEIGHT = 50; private const float ready_button_width = 600; private const float spectate_button_width = 200; @@ -27,54 +22,42 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match set => spectateButton.OnSpectateClick = value; } - private readonly Drawable background; private readonly MultiplayerReadyButton readyButton; private readonly MultiplayerSpectateButton spectateButton; public MultiplayerMatchFooter() { - RelativeSizeAxes = Axes.X; - Height = HEIGHT; + RelativeSizeAxes = Axes.Both; - InternalChildren = new[] + InternalChild = new GridContainer { - background = new Box { RelativeSizeAxes = Axes.Both }, - new GridContainer + RelativeSizeAxes = Axes.Both, + Content = new[] { - RelativeSizeAxes = Axes.Both, - Content = new[] + new Drawable[] { - new Drawable[] + null, + spectateButton = new MultiplayerSpectateButton { - null, - spectateButton = new MultiplayerSpectateButton - { - RelativeSizeAxes = Axes.Both, - }, - null, - readyButton = new MultiplayerReadyButton - { - RelativeSizeAxes = Axes.Both, - }, - null - } - }, - ColumnDimensions = new[] - { - new Dimension(), - new Dimension(maxSize: spectate_button_width), - new Dimension(GridSizeMode.Absolute, 10), - new Dimension(maxSize: ready_button_width), - new Dimension() + RelativeSizeAxes = Axes.Both, + }, + null, + readyButton = new MultiplayerReadyButton + { + RelativeSizeAxes = Axes.Both, + }, + null } + }, + ColumnDimensions = new[] + { + new Dimension(), + new Dimension(maxSize: spectate_button_width), + new Dimension(GridSizeMode.Absolute, 10), + new Dimension(maxSize: ready_button_width), + new Dimension() } }; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = Color4Extensions.FromHex(@"28242d"); - } } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index f8e5d7d901..3f5837cbbe 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -94,17 +94,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer }, true); } - protected override void UpdateMods() - { - if (SelectedItem.Value == null || client.LocalUser == null) - return; - - // update local mods based on room's reported status for the local user (omitting the base call implementation). - // this makes the server authoritative, and avoids the local user potentially setting mods that the server is not aware of (ie. if the match was started during the selection being changed). - var ruleset = Ruleset.Value.CreateInstance(); - Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList(); - } - protected override Drawable CreateMainContent() => new GridContainer { RelativeSizeAxes = Axes.Both, @@ -236,6 +225,17 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer protected override RoomSettingsOverlay CreateRoomSettingsOverlay() => new MultiplayerMatchSettingsOverlay(); + protected override void UpdateMods() + { + if (SelectedItem.Value == null || client.LocalUser == null) + return; + + // update local mods based on room's reported status for the local user (omitting the base call implementation). + // this makes the server authoritative, and avoids the local user potentially setting mods that the server is not aware of (ie. if the match was started during the selection being changed). + var ruleset = Ruleset.Value.CreateInstance(); + Mods.Value = client.LocalUser.Mods.Select(m => m.ToMod(ruleset)).Concat(SelectedItem.Value.RequiredMods).ToList(); + } + [Resolved(canBeNull: true)] private DialogOverlay dialogOverlay { get; set; } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomFooter.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomFooter.cs new file mode 100644 index 0000000000..3eb1cde0a4 --- /dev/null +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomFooter.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 System; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osuTK; + +namespace osu.Game.Screens.OnlinePlay.Playlists +{ + public class PlaylistsRoomFooter : CompositeDrawable + { + public Action OnStart; + + public PlaylistsRoomFooter() + { + RelativeSizeAxes = Axes.Both; + + InternalChildren = new[] + { + new PlaylistsReadyButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + Size = new Vector2(600, 1), + Action = () => OnStart?.Invoke() + } + }; + } + } +} diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index 9855d1cb95..27de781d5f 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -20,7 +20,6 @@ using osu.Game.Screens.Play; using osu.Game.Screens.Play.HUD; using osu.Game.Users; using osuTK; -using Footer = osu.Game.Screens.OnlinePlay.Match.Components.Footer; namespace osu.Game.Screens.OnlinePlay.Playlists { @@ -70,17 +69,6 @@ namespace osu.Game.Screens.OnlinePlay.Playlists }, true); } - private void updatePollingRate() - { - selectionPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 30000 : 5000; - Logger.Log($"Polling adjusted (selection: {selectionPollingComponent.TimeBetweenPolls.Value})"); - } - - protected override Screen CreateGameplayScreen() => new PlayerLoader(() => new PlaylistsPlayer(SelectedItem.Value) - { - Exited = () => leaderboard.RefreshScores() - }); - protected override Drawable CreateMainContent() => new GridContainer { RelativeSizeAxes = Axes.Both, @@ -190,7 +178,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists } }; - protected override Drawable CreateFooter() => new Footer + protected override Drawable CreateFooter() => new PlaylistsRoomFooter { OnStart = StartPlay }; @@ -203,5 +191,16 @@ namespace osu.Game.Screens.OnlinePlay.Playlists this.Push(new PlaylistsSongSelect()); }, }; + + private void updatePollingRate() + { + selectionPollingComponent.TimeBetweenPolls.Value = isIdle.Value ? 30000 : 5000; + Logger.Log($"Polling adjusted (selection: {selectionPollingComponent.TimeBetweenPolls.Value})"); + } + + protected override Screen CreateGameplayScreen() => new PlayerLoader(() => new PlaylistsPlayer(SelectedItem.Value) + { + Exited = () => leaderboard.RefreshScores() + }); } } From eadf02933a735ea97ce8dbd69fb6a35f2318525d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 20:53:17 +0900 Subject: [PATCH 074/103] Split lounge-specific implementation from DrawableRoom --- .../Multiplayer/TestSceneDrawableRoom.cs | 7 +- .../TestSceneLoungeRoomsContainer.cs | 3 +- .../Multiplayer/TestSceneMultiplayer.cs | 4 +- .../TestSceneMultiplayerLoungeSubScreen.cs | 13 +- .../Lounge/Components/DrawableRoom.cs | 263 ++---------------- .../Lounge/Components/RoomsContainer.cs | 22 +- .../OnlinePlay/Lounge/DrawableLoungeRoom.cs | 225 +++++++++++++++ .../Screens/OnlinePlay/Match/RoomSubScreen.cs | 1 - 8 files changed, 269 insertions(+), 269 deletions(-) create mode 100644 osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs index 299bbacf08..489ece3271 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs @@ -10,11 +10,11 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Framework.Utils; -using osu.Game.Graphics.UserInterface; using osu.Game.Online.Rooms; using osu.Game.Online.Rooms.RoomStatuses; using osu.Game.Overlays; using osu.Game.Rulesets.Osu; +using osu.Game.Screens.OnlinePlay.Lounge; using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Tests.Beatmaps; using osu.Game.Users; @@ -159,10 +159,7 @@ namespace osu.Game.Tests.Visual.Multiplayer })); } - var drawableRoom = new DrawableRoom(room) { MatchingFilter = true }; - drawableRoom.Action = () => drawableRoom.State = drawableRoom.State == SelectionState.Selected ? SelectionState.NotSelected : SelectionState.Selected; - - return drawableRoom; + return new DrawableLoungeRoom(room) { MatchingFilter = true }; } } } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index 7e822f898e..b23638e514 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -9,6 +9,7 @@ using osu.Framework.Testing; using osu.Game.Online.Rooms; using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Osu; +using osu.Game.Screens.OnlinePlay.Lounge; using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Tests.Visual.OnlinePlay; using osuTK.Input; @@ -150,6 +151,6 @@ namespace osu.Game.Tests.Visual.Multiplayer private bool checkRoomSelected(Room room) => SelectedRoom.Value == room; private Room getRoomInFlow(int index) => - (container.ChildrenOfType>().First().FlowingChildren.ElementAt(index) as DrawableRoom)?.Room; + (container.ChildrenOfType>().First().FlowingChildren.ElementAt(index) as DrawableRoom)?.Room; } } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index e618b28f40..6c1aed71e6 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -236,8 +236,8 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("select room", () => InputManager.Key(Key.Down)); AddStep("join room", () => InputManager.Key(Key.Enter)); - DrawableRoom.PasswordEntryPopover passwordEntryPopover = null; - AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType().FirstOrDefault()) != null); + DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null; + AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType().FirstOrDefault()) != null); AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType().First().Text = "password"); AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType().First().TriggerClick()); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs index c66d5429d6..4ec02a6ec8 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs @@ -9,7 +9,6 @@ using osu.Framework.Testing; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Rooms; using osu.Game.Screens.OnlinePlay.Lounge; -using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Multiplayer; using osu.Game.Tests.Visual.OnlinePlay; using osuTK.Input; @@ -59,20 +58,20 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("select room", () => InputManager.Key(Key.Down)); AddStep("attempt join room", () => InputManager.Key(Key.Enter)); - AddUntilStep("password prompt appeared", () => InputManager.ChildrenOfType().Any()); + AddUntilStep("password prompt appeared", () => InputManager.ChildrenOfType().Any()); AddStep("exit screen", () => Stack.Exit()); - AddUntilStep("password prompt hidden", () => !InputManager.ChildrenOfType().Any()); + AddUntilStep("password prompt hidden", () => !InputManager.ChildrenOfType().Any()); } [Test] public void TestJoinRoomWithPassword() { - DrawableRoom.PasswordEntryPopover passwordEntryPopover = null; + DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null; AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true)); AddStep("select room", () => InputManager.Key(Key.Down)); AddStep("attempt join room", () => InputManager.Key(Key.Enter)); - AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType().FirstOrDefault()) != null); + AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType().FirstOrDefault()) != null); AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType().First().Text = "password"); AddStep("press join room button", () => passwordEntryPopover.ChildrenOfType().First().TriggerClick()); @@ -83,12 +82,12 @@ namespace osu.Game.Tests.Visual.Multiplayer [Test] public void TestJoinRoomWithPasswordViaKeyboardOnly() { - DrawableRoom.PasswordEntryPopover passwordEntryPopover = null; + DrawableLoungeRoom.PasswordEntryPopover passwordEntryPopover = null; AddStep("add room", () => RoomManager.AddRooms(1, withPassword: true)); AddStep("select room", () => InputManager.Key(Key.Down)); AddStep("attempt join room", () => InputManager.Key(Key.Enter)); - AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType().FirstOrDefault()) != null); + AddUntilStep("password prompt appeared", () => (passwordEntryPopover = InputManager.ChildrenOfType().FirstOrDefault()) != null); AddStep("enter password in text box", () => passwordEntryPopover.ChildrenOfType().First().Text = "password"); AddStep("press enter", () => InputManager.Key(Key.Enter)); diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs index b627dfbb8e..c5b8bffbc6 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs @@ -1,32 +1,19 @@ // 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; using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; using osu.Framework.Bindables; -using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Bindings; -using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Graphics.UserInterfaceV2; -using osu.Game.Input.Bindings; using osu.Game.Online.Rooms; using osu.Game.Overlays; using osu.Game.Screens.OnlinePlay.Components; @@ -35,104 +22,17 @@ using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Lounge.Components { - public class DrawableRoom : OsuClickableContainer, IStateful, IFilterable, IHasContextMenu, IHasPopover, IKeyBindingHandler + public class DrawableRoom : CompositeDrawable { - public const float SELECTION_BORDER_WIDTH = 4; - private const float corner_radius = 10; - private const float transition_duration = 60; + protected const float CORNER_RADIUS = 10; private const float height = 100; - public event Action StateChanged; - - protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new HoverSounds(); - - private Drawable selectionBox; - - [Resolved(canBeNull: true)] - private LoungeSubScreen loungeScreen { get; set; } + public readonly Room Room; [Resolved] private BeatmapManager beatmaps { get; set; } - [Resolved(canBeNull: true)] - private Bindable selectedRoom { get; set; } - - [Resolved(canBeNull: true)] - private LoungeSubScreen lounge { get; set; } - - public readonly Room Room; - - private SelectionState state; - - private Sample sampleSelect; - private Sample sampleJoin; - - public SelectionState State - { - get => state; - set - { - if (value == state) - return; - - state = value; - - if (selectionBox != null) - { - if (state == SelectionState.Selected) - selectionBox.FadeIn(transition_duration); - else - selectionBox.FadeOut(transition_duration); - } - - StateChanged?.Invoke(State); - } - } - - public IEnumerable FilterTerms => new[] { Room.Name.Value }; - - private bool matchingFilter; - - public bool MatchingFilter - { - get => matchingFilter; - set - { - matchingFilter = value; - - if (!IsLoaded) - return; - - if (matchingFilter) - this.FadeIn(200); - else - Hide(); - } - } - - private int numberOfAvatars = 7; - - public int NumberOfAvatars - { - get => numberOfAvatars; - set - { - numberOfAvatars = value; - - if (recentParticipantsList != null) - recentParticipantsList.NumberOfCircles = value; - } - } - - public bool FilteringActive { get; set; } - - protected readonly Container ButtonsContainer = new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X - }; + protected Container ButtonsContainer { get; private set; } private readonly Bindable roomCategory = new Bindable(); private readonly Bindable hasPassword = new Bindable(); @@ -149,7 +49,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components Height = height; Masking = true; - CornerRadius = corner_radius; + CornerRadius = CORNER_RADIUS; EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, @@ -159,9 +59,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colours, AudioManager audio) + private void load(OverlayColourProvider colours) { - Children = new Drawable[] + InternalChildren = new Drawable[] { // This resolves internal 1px gaps due to applying the (parenting) corner radius and masking across multiple filling background sprites. new Box @@ -183,7 +83,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components { RelativeSizeAxes = Axes.Both, Masking = true, - CornerRadius = corner_radius, + CornerRadius = CORNER_RADIUS, Children = new Drawable[] { new GridContainer @@ -303,7 +203,13 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components }, Children = new Drawable[] { - ButtonsContainer, + ButtonsContainer = new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X + }, recentParticipantsList = new RecentParticipantsList { Anchor = Anchor.CentreRight, @@ -316,36 +222,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components }, }, }, - new StatusColouredContainer(transition_duration) - { - RelativeSizeAxes = Axes.Both, - Child = selectionBox = new Container - { - RelativeSizeAxes = Axes.Both, - Alpha = state == SelectionState.Selected ? 1 : 0, - Masking = true, - CornerRadius = corner_radius, - BorderThickness = SELECTION_BORDER_WIDTH, - BorderColour = Color4.White, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - } - } - }, - }; - - sampleSelect = audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select"); - sampleJoin = audio.Samples.Get($@"UI/{HoverSampleSet.Submit.GetDescription()}-select"); - } - - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - return new CachedModelDependencyContainer(base.CreateChildDependencies(parent)) - { - Model = { Value = Room } }; } @@ -353,11 +229,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components { base.LoadComplete(); - if (matchingFilter) - this.FadeInFromZero(transition_duration); - else - Alpha = 0; - roomCategory.BindTo(Room.Category); roomCategory.BindValueChanged(c => { @@ -371,57 +242,26 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components hasPassword.BindValueChanged(v => passwordIcon.Alpha = v.NewValue ? 1 : 0, true); } - public Popover GetPopover() => new PasswordEntryPopover(Room) { JoinRequested = lounge.Join }; - - public MenuItem[] ContextMenuItems => new MenuItem[] + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - new OsuMenuItem("Create copy", MenuItemType.Standard, () => + return new CachedModelDependencyContainer(base.CreateChildDependencies(parent)) { - lounge?.Open(Room.DeepClone()); - }) - }; - - public bool OnPressed(GlobalAction action) - { - if (selectedRoom.Value != Room) - return false; - - switch (action) - { - case GlobalAction.Select: - TriggerClick(); - return true; - } - - return false; + Model = { Value = Room } + }; } - public void OnReleased(GlobalAction action) + private int numberOfAvatars = 7; + + public int NumberOfAvatars { - } - - protected override bool ShouldBeConsideredForInput(Drawable child) => state == SelectionState.Selected || child is HoverSounds; - - protected override bool OnClick(ClickEvent e) - { - if (Room != selectedRoom.Value) + get => numberOfAvatars; + set { - sampleSelect?.Play(); - selectedRoom.Value = Room; - return true; + numberOfAvatars = value; + + if (recentParticipantsList != null) + recentParticipantsList.NumberOfCircles = value; } - - if (Room.HasPassword.Value) - { - sampleJoin?.Play(); - this.ShowPopover(); - return true; - } - - sampleJoin?.Play(); - lounge?.Join(Room, null); - - return base.OnClick(e); } private class RoomNameText : OsuSpriteText @@ -508,52 +348,5 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components }; } } - - public class PasswordEntryPopover : OsuPopover - { - private readonly Room room; - - public Action JoinRequested; - - public PasswordEntryPopover(Room room) - { - this.room = room; - } - - private OsuPasswordTextBox passwordTextbox; - - [BackgroundDependencyLoader] - private void load() - { - Child = new FillFlowContainer - { - Margin = new MarginPadding(10), - Spacing = new Vector2(5), - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new Drawable[] - { - passwordTextbox = new OsuPasswordTextBox - { - Width = 200, - }, - new TriangleButton - { - Width = 80, - Text = "Join Room", - Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text) - } - } - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox)); - passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text); - } - } } } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs index e243477a8c..be5558ed0b 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs @@ -15,7 +15,6 @@ using osu.Framework.Input.Events; using osu.Framework.Threading; using osu.Game.Extensions; using osu.Game.Graphics.Cursor; -using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Online.Rooms; using osuTK; @@ -26,7 +25,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components { private readonly IBindableList rooms = new BindableList(); - private readonly FillFlowContainer roomFlow; + private readonly FillFlowContainer roomFlow; public IReadOnlyList Rooms => roomFlow.FlowingChildren.Cast().ToArray(); @@ -56,7 +55,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = roomFlow = new FillFlowContainer + Child = roomFlow = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -74,16 +73,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components rooms.BindTo(roomManager.Rooms); Filter?.BindValueChanged(criteria => applyFilterCriteria(criteria.NewValue), true); - - selectedRoom.BindValueChanged(selection => - { - updateSelection(); - }, true); } - private void updateSelection() => - roomFlow.Children.ForEach(r => r.State = r.Room == selectedRoom.Value ? SelectionState.Selected : SelectionState.NotSelected); - private void applyFilterCriteria(FilterCriteria criteria) { roomFlow.Children.ForEach(r => @@ -122,22 +113,17 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components { foreach (var room in rooms) { - roomFlow.Add(new DrawableRoom(room)); + roomFlow.Add(new DrawableLoungeRoom(room)); } applyFilterCriteria(Filter?.Value); - - updateSelection(); } private void removeRooms(IEnumerable rooms) { foreach (var r in rooms) { - var toRemove = roomFlow.Single(d => d.Room == r); - toRemove.Action = null; - - roomFlow.Remove(toRemove); + roomFlow.RemoveAll(d => d.Room == r); // selection may have a lease due to being in a sub screen. if (!selectedRoom.Disabled) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs new file mode 100644 index 0000000000..764d4e9d3a --- /dev/null +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -0,0 +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 System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; +using osu.Game.Graphics.UserInterfaceV2; +using osu.Game.Input.Bindings; +using osu.Game.Online.Rooms; +using osu.Game.Screens.OnlinePlay.Components; +using osu.Game.Screens.OnlinePlay.Lounge.Components; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.OnlinePlay.Lounge +{ + /// + /// A with lounge-specific interactions such as selection and hover sounds. + /// + public class DrawableLoungeRoom : DrawableRoom, IFilterable, IHasContextMenu, IHasPopover, IKeyBindingHandler + { + private const float transition_duration = 60; + private const float selection_border_width = 4; + + [Resolved(canBeNull: true)] + private LoungeSubScreen lounge { get; set; } + + [Resolved(canBeNull: true)] + private Bindable selectedRoom { get; set; } + + private Sample sampleSelect; + private Sample sampleJoin; + private Drawable selectionBox; + + public DrawableLoungeRoom(Room room) + : base(room) + { + } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + sampleSelect = audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select"); + sampleJoin = audio.Samples.Get($@"UI/{HoverSampleSet.Submit.GetDescription()}-select"); + + AddRangeInternal(new Drawable[] + { + new StatusColouredContainer(transition_duration) + { + RelativeSizeAxes = Axes.Both, + Child = selectionBox = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = CORNER_RADIUS, + BorderThickness = selection_border_width, + BorderColour = Color4.White, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + } + } + }, + new HoverSounds() + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (matchingFilter) + this.FadeInFromZero(transition_duration); + else + Alpha = 0; + + selectedRoom.BindValueChanged(updateSelectedRoom, true); + } + + private void updateSelectedRoom(ValueChangedEvent selected) + { + if (selected.NewValue == Room) + selectionBox.FadeIn(transition_duration); + else + selectionBox.FadeOut(transition_duration); + } + + public bool FilteringActive { get; set; } + + public IEnumerable FilterTerms => new[] { Room.Name.Value }; + + private bool matchingFilter; + + public bool MatchingFilter + { + get => matchingFilter; + set + { + matchingFilter = value; + + if (!IsLoaded) + return; + + if (matchingFilter) + this.FadeIn(200); + else + Hide(); + } + } + + public Popover GetPopover() => new PasswordEntryPopover(Room) { JoinRequested = lounge.Join }; + + public MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("Create copy", MenuItemType.Standard, () => + { + lounge?.Open(Room.DeepClone()); + }) + }; + + public bool OnPressed(GlobalAction action) + { + if (selectedRoom.Value != Room) + return false; + + switch (action) + { + case GlobalAction.Select: + TriggerClick(); + return true; + } + + return false; + } + + public void OnReleased(GlobalAction action) + { + } + + protected override bool ShouldBeConsideredForInput(Drawable child) => selectedRoom.Value == Room || child is HoverSounds; + + protected override bool OnClick(ClickEvent e) + { + if (Room != selectedRoom.Value) + { + sampleSelect?.Play(); + selectedRoom.Value = Room; + return true; + } + + if (Room.HasPassword.Value) + { + sampleJoin?.Play(); + this.ShowPopover(); + return true; + } + + sampleJoin?.Play(); + lounge?.Join(Room, null); + + return base.OnClick(e); + } + + public class PasswordEntryPopover : OsuPopover + { + private readonly Room room; + + public Action JoinRequested; + + public PasswordEntryPopover(Room room) + { + this.room = room; + } + + private OsuPasswordTextBox passwordTextbox; + + [BackgroundDependencyLoader] + private void load() + { + Child = new FillFlowContainer + { + Margin = new MarginPadding(10), + Spacing = new Vector2(5), + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + passwordTextbox = new OsuPasswordTextBox + { + Width = 200, + }, + new TriangleButton + { + Width = 80, + Text = "Join Room", + Action = () => JoinRequested?.Invoke(room, passwordTextbox.Text) + } + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + Schedule(() => GetContainingInputManager().ChangeFocus(passwordTextbox)); + passwordTextbox.OnCommit += (_, __) => JoinRequested?.Invoke(room, passwordTextbox.Text); + } + } + } +} diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 42d76e5a15..81fae558c8 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -134,7 +134,6 @@ namespace osu.Game.Screens.OnlinePlay.Match { new DrawableMatchRoom(Room, allowEdit) { - MatchingFilter = true, OnEdit = () => settingsOverlay.Show() } }, From e9221f012635c9e63a7049d8c7a046681b65b0a6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 21:00:11 +0900 Subject: [PATCH 075/103] Cleanup unnecessary implementation --- osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs index ead219bee2..b3e6292f45 100644 --- a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs @@ -58,7 +58,5 @@ namespace osu.Game.Screens.OnlinePlay.Match if (editButton != null) host.BindValueChanged(h => editButton.Alpha = h.NewValue?.Equals(api.LocalUser.Value) == true ? 1 : 0, true); } - - protected override bool ShouldBeConsideredForInput(Drawable child) => true; } } From d40023bcc1ff1e612a48dd78f60b32e31c8e868e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Aug 2021 21:09:34 +0900 Subject: [PATCH 076/103] Hide border by default --- osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs index 764d4e9d3a..4e106b844c 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/DrawableLoungeRoom.cs @@ -63,6 +63,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge Child = selectionBox = new Container { RelativeSizeAxes = Axes.Both, + Alpha = 0, Masking = true, CornerRadius = CORNER_RADIUS, BorderThickness = selection_border_width, From 61675eefe0a5fecb4f01661ad717e49b1d398a87 Mon Sep 17 00:00:00 2001 From: Davran Dilshat Date: Wed, 18 Aug 2021 17:36:57 +0100 Subject: [PATCH 077/103] Add length limit to match settings textboxes --- .../Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs index 61bb39d0c5..7bad661cf4 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs @@ -48,6 +48,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components { BackgroundUnfocused = Color4.Black; BackgroundFocused = Color4.Black; + LengthLimit = 100; } } @@ -63,6 +64,7 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components { BackgroundUnfocused = Color4.Black; BackgroundFocused = Color4.Black; + LengthLimit = 255; } } From 43cbd10a38a8c148ba03a62caf46bcf9c9b73758 Mon Sep 17 00:00:00 2001 From: Davran Dilshat Date: Wed, 18 Aug 2021 18:30:50 +0100 Subject: [PATCH 078/103] change limit to be on actual usage site --- .../Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs | 2 -- .../Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs index 7bad661cf4..61bb39d0c5 100644 --- a/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Match/Components/MatchSettingsOverlay.cs @@ -48,7 +48,6 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components { BackgroundUnfocused = Color4.Black; BackgroundFocused = Color4.Black; - LengthLimit = 100; } } @@ -64,7 +63,6 @@ namespace osu.Game.Screens.OnlinePlay.Match.Components { BackgroundUnfocused = Color4.Black; BackgroundFocused = Color4.Black; - LengthLimit = 255; } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs index 338d2c9e84..53d494106b 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchSettingsOverlay.cs @@ -136,6 +136,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { RelativeSizeAxes = Axes.X, TabbableContentContainer = this, + LengthLimit = 100, }, }, new Section("Room visibility") @@ -195,6 +196,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { RelativeSizeAxes = Axes.X, TabbableContentContainer = this, + LengthLimit = 255, }, }, } From ffbe8ddfa4ed5a97c02e9c296479549482224714 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 04:23:02 +0300 Subject: [PATCH 079/103] Refactor lounge sub screen layout for better loading screen appearance --- .../OnlinePlay/Lounge/LoungeSubScreen.cs | 117 ++++++++---------- 1 file changed, 51 insertions(+), 66 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 24aad8c124..ee9331b71a 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -76,6 +76,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [BackgroundDependencyLoader(true)] private void load([CanBeNull] IdleTracker idleTracker) { + const float controls_area_height = 25f; + if (idleTracker != null) isIdle.BindTo(idleTracker.IsIdle); @@ -84,86 +86,69 @@ namespace osu.Game.Screens.OnlinePlay.Lounge InternalChildren = new Drawable[] { ListingPollingComponent = CreatePollingComponent().With(c => c.Filter.BindTarget = filter), - new Container + scrollContainer = new OsuScrollContainer { + Name = @"Scrollable rooms container", RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { - Left = WaveOverlayContainer.WIDTH_PADDING, - Right = WaveOverlayContainer.WIDTH_PADDING, + Horizontal = WaveOverlayContainer.WIDTH_PADDING, + Top = Header.HEIGHT + controls_area_height + 20, }, - Child = new GridContainer + ScrollbarOverlapsContent = false, + Child = roomsContainer = new RoomsContainer { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] + Filter = { BindTarget = filter } + } + }, + loadingLayer = new LoadingLayer(true), + new FillFlowContainer + { + Name = @"Header area flow", + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Horizontal = WaveOverlayContainer.WIDTH_PADDING }, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new Container { - new Dimension(GridSizeMode.Absolute, Header.HEIGHT), - new Dimension(GridSizeMode.Absolute, 25), - new Dimension(GridSizeMode.Absolute, 20) + RelativeSizeAxes = Axes.X, + Height = Header.HEIGHT, + Child = searchTextBox = new LoungeSearchTextBox + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.X, + Width = 0.6f, + }, }, - Content = new[] + new Container { - new Drawable[] + RelativeSizeAxes = Axes.X, + Height = controls_area_height, + Children = new Drawable[] { - searchTextBox = new LoungeSearchTextBox + Buttons.WithChild(CreateNewRoomButton().With(d => { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.X, - Width = 0.6f, - }, - }, - new Drawable[] - { - new Container + d.Anchor = Anchor.BottomLeft; + d.Origin = Anchor.BottomLeft; + d.Size = new Vector2(150, 37.5f); + d.Action = () => Open(); + })), + new FillFlowContainer { - RelativeSizeAxes = Axes.Both, - Depth = float.MinValue, // Contained filters should appear over the top of rooms. - Children = new Drawable[] + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10), + ChildrenEnumerable = CreateFilterControls().Select(f => f.With(d => { - Buttons.WithChild(CreateNewRoomButton().With(d => - { - d.Anchor = Anchor.BottomLeft; - d.Origin = Anchor.BottomLeft; - d.Size = new Vector2(150, 37.5f); - d.Action = () => Open(); - })), - new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10), - ChildrenEnumerable = CreateFilterControls().Select(f => f.With(d => - { - d.Anchor = Anchor.TopRight; - d.Origin = Anchor.TopRight; - })) - } - } + d.Anchor = Anchor.TopRight; + d.Origin = Anchor.TopRight; + })) } - }, - null, - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - scrollContainer = new OsuScrollContainer - { - RelativeSizeAxes = Axes.Both, - ScrollbarOverlapsContent = false, - Child = roomsContainer = new RoomsContainer - { - Filter = { BindTarget = filter } - } - }, - loadingLayer = new LoadingLayer(true), - } - }, } } }, From 0e2f3dff4dda07cd8b388d952f92172a657e9f83 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 05:09:49 +0300 Subject: [PATCH 080/103] Fix rooms scroll container not masking properly due to padding --- .../Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index ee9331b71a..0664e44a73 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -86,20 +86,24 @@ namespace osu.Game.Screens.OnlinePlay.Lounge InternalChildren = new Drawable[] { ListingPollingComponent = CreatePollingComponent().With(c => c.Filter.BindTarget = filter), - scrollContainer = new OsuScrollContainer + new Container { - Name = @"Scrollable rooms container", + Name = @"Rooms area", RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Horizontal = WaveOverlayContainer.WIDTH_PADDING, Top = Header.HEIGHT + controls_area_height + 20, }, - ScrollbarOverlapsContent = false, - Child = roomsContainer = new RoomsContainer + Child = scrollContainer = new OsuScrollContainer { - Filter = { BindTarget = filter } - } + RelativeSizeAxes = Axes.Both, + ScrollbarOverlapsContent = false, + Child = roomsContainer = new RoomsContainer + { + Filter = { BindTarget = filter } + } + }, }, loadingLayer = new LoadingLayer(true), new FillFlowContainer From f4ae587a3385c63f90295c02fb118c9af55935eb Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 06:24:06 +0300 Subject: [PATCH 081/103] Extract room request handling logic to its own class --- ...stRequestHandlingMultiplayerRoomManager.cs | 138 ++-------------- .../OnlinePlay/TestRoomRequestsHandler.cs | 147 ++++++++++++++++++ 2 files changed, 159 insertions(+), 126 deletions(-) create mode 100644 osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs diff --git a/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs b/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs index c3a944f93c..5de518990a 100644 --- a/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs +++ b/osu.Game/Tests/Visual/Multiplayer/TestRequestHandlingMultiplayerRoomManager.cs @@ -1,150 +1,36 @@ // 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 osu.Framework.Allocation; using osu.Game.Online.API; -using osu.Game.Online.API.Requests; using osu.Game.Online.Rooms; -using osu.Game.Rulesets.Scoring; -using osu.Game.Scoring; using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Multiplayer; +using osu.Game.Tests.Visual.OnlinePlay; namespace osu.Game.Tests.Visual.Multiplayer { /// - /// A for use in multiplayer test scenes. Should generally not be used by itself outside of a . + /// A for use in multiplayer test scenes, backed by a . + /// Should generally not be used by itself outside of a . /// - /// - /// This implementation will pretend to be a server, handling room retrieval and manipulation requests - /// and returning a roughly expected state, without the need for a server to be running. - /// public class TestRequestHandlingMultiplayerRoomManager : MultiplayerRoomManager { - [Resolved] - private IAPIProvider api { get; set; } + public IReadOnlyList ServerSideRooms => handler.ServerSideRooms; - [Resolved] - private OsuGameBase game { get; set; } - - public IReadOnlyList ServerSideRooms => serverSideRooms; - private readonly List serverSideRooms = new List(); - - private int currentRoomId; - private int currentPlaylistItemId; + private readonly TestRoomRequestsHandler handler = new TestRoomRequestsHandler(); [BackgroundDependencyLoader] - private void load() + private void load(IAPIProvider api, OsuGameBase game) { - int currentScoreId = 0; - - // Handling here is pretending to be a server, while also updating the local state to match - // how the server would eventually respond and update the RoomManager. - ((DummyAPIAccess)api).HandleRequest = req => - { - switch (req) - { - case CreateRoomRequest createRoomRequest: - var apiRoom = new Room(); - - apiRoom.CopyFrom(createRoomRequest.Room); - - // Passwords are explicitly not copied between rooms. - apiRoom.HasPassword.Value = !string.IsNullOrEmpty(createRoomRequest.Room.Password.Value); - apiRoom.Password.Value = createRoomRequest.Room.Password.Value; - - AddServerSideRoom(apiRoom); - - var responseRoom = new APICreatedRoom(); - responseRoom.CopyFrom(createResponseRoom(apiRoom, false)); - - createRoomRequest.TriggerSuccess(responseRoom); - return true; - - case JoinRoomRequest joinRoomRequest: - { - var room = ServerSideRooms.Single(r => r.RoomID.Value == joinRoomRequest.Room.RoomID.Value); - - if (joinRoomRequest.Password != room.Password.Value) - { - joinRoomRequest.TriggerFailure(new InvalidOperationException("Invalid password.")); - return true; - } - - joinRoomRequest.TriggerSuccess(); - return true; - } - - case PartRoomRequest partRoomRequest: - partRoomRequest.TriggerSuccess(); - return true; - - case GetRoomsRequest getRoomsRequest: - var roomsWithoutParticipants = new List(); - - foreach (var r in ServerSideRooms) - roomsWithoutParticipants.Add(createResponseRoom(r, false)); - - getRoomsRequest.TriggerSuccess(roomsWithoutParticipants); - return true; - - case GetRoomRequest getRoomRequest: - getRoomRequest.TriggerSuccess(createResponseRoom(ServerSideRooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId), true)); - return true; - - case GetBeatmapSetRequest getBeatmapSetRequest: - var onlineReq = new GetBeatmapSetRequest(getBeatmapSetRequest.ID, getBeatmapSetRequest.Type); - onlineReq.Success += res => getBeatmapSetRequest.TriggerSuccess(res); - onlineReq.Failure += e => getBeatmapSetRequest.TriggerFailure(e); - - // Get the online API from the game's dependencies. - game.Dependencies.Get().Queue(onlineReq); - return true; - - case CreateRoomScoreRequest createRoomScoreRequest: - createRoomScoreRequest.TriggerSuccess(new APIScoreToken { ID = 1 }); - return true; - - case SubmitRoomScoreRequest submitRoomScoreRequest: - submitRoomScoreRequest.TriggerSuccess(new MultiplayerScore - { - ID = currentScoreId++, - Accuracy = 1, - EndedAt = DateTimeOffset.Now, - Passed = true, - Rank = ScoreRank.S, - MaxCombo = 1000, - TotalScore = 1000000, - User = api.LocalUser.Value, - Statistics = new Dictionary() - }); - return true; - } - - return false; - }; + ((DummyAPIAccess)api).HandleRequest = request => handler.HandleRequest(request, api.LocalUser.Value, game); } - public void AddServerSideRoom(Room room) - { - room.RoomID.Value ??= currentRoomId++; - for (int i = 0; i < room.Playlist.Count; i++) - room.Playlist[i].ID = currentPlaylistItemId++; - - serverSideRooms.Add(room); - } - - private Room createResponseRoom(Room room, bool withParticipants) - { - var responseRoom = new Room(); - responseRoom.CopyFrom(room); - responseRoom.Password.Value = null; - if (!withParticipants) - responseRoom.RecentParticipants.Clear(); - return responseRoom; - } + /// + /// Adds a room to a local "server-side" list that's returned when a is fired. + /// + /// The room. + public void AddServerSideRoom(Room room) => handler.AddServerSideRoom(room); } } diff --git a/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs b/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs new file mode 100644 index 0000000000..7f975c9985 --- /dev/null +++ b/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs @@ -0,0 +1,147 @@ +// 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 osu.Framework.Allocation; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.Rooms; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; +using osu.Game.Screens.OnlinePlay.Components; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.OnlinePlay +{ + /// + /// Represents a handler which pretends to be a server, handling room retrieval and manipulation requests + /// and returning a roughly expected state, without the need for a server to be running. + /// + public class TestRoomRequestsHandler + { + public IReadOnlyList ServerSideRooms => serverSideRooms; + + private readonly List serverSideRooms = new List(); + + private int currentRoomId; + private int currentPlaylistItemId; + private int currentScoreId; + + /// + /// Handles an API request, while also updating the local state to match + /// how the server would eventually respond and update an . + /// + /// The API request to handle. + /// The local user to store in responses where required. + /// The game base for cases where actual online requests need to be sent. + /// Whether the request was successfully handled. + public bool HandleRequest(APIRequest request, User localUser, OsuGameBase game) + { + switch (request) + { + case CreateRoomRequest createRoomRequest: + var apiRoom = new Room(); + + apiRoom.CopyFrom(createRoomRequest.Room); + + // Passwords are explicitly not copied between rooms. + apiRoom.HasPassword.Value = !string.IsNullOrEmpty(createRoomRequest.Room.Password.Value); + apiRoom.Password.Value = createRoomRequest.Room.Password.Value; + + AddServerSideRoom(apiRoom); + + var responseRoom = new APICreatedRoom(); + responseRoom.CopyFrom(createResponseRoom(apiRoom, false)); + + createRoomRequest.TriggerSuccess(responseRoom); + return true; + + case JoinRoomRequest joinRoomRequest: + { + var room = ServerSideRooms.Single(r => r.RoomID.Value == joinRoomRequest.Room.RoomID.Value); + + if (joinRoomRequest.Password != room.Password.Value) + { + joinRoomRequest.TriggerFailure(new InvalidOperationException("Invalid password.")); + return true; + } + + joinRoomRequest.TriggerSuccess(); + return true; + } + + case PartRoomRequest partRoomRequest: + partRoomRequest.TriggerSuccess(); + return true; + + case GetRoomsRequest getRoomsRequest: + var roomsWithoutParticipants = new List(); + + foreach (var r in ServerSideRooms) + roomsWithoutParticipants.Add(createResponseRoom(r, false)); + + getRoomsRequest.TriggerSuccess(roomsWithoutParticipants); + return true; + + case GetRoomRequest getRoomRequest: + getRoomRequest.TriggerSuccess(createResponseRoom(ServerSideRooms.Single(r => r.RoomID.Value == getRoomRequest.RoomId), true)); + return true; + + case GetBeatmapSetRequest getBeatmapSetRequest: + var onlineReq = new GetBeatmapSetRequest(getBeatmapSetRequest.ID, getBeatmapSetRequest.Type); + onlineReq.Success += res => getBeatmapSetRequest.TriggerSuccess(res); + onlineReq.Failure += e => getBeatmapSetRequest.TriggerFailure(e); + + // Get the online API from the game's dependencies. + game.Dependencies.Get().Queue(onlineReq); + return true; + + case CreateRoomScoreRequest createRoomScoreRequest: + createRoomScoreRequest.TriggerSuccess(new APIScoreToken { ID = 1 }); + return true; + + case SubmitRoomScoreRequest submitRoomScoreRequest: + submitRoomScoreRequest.TriggerSuccess(new MultiplayerScore + { + ID = currentScoreId++, + Accuracy = 1, + EndedAt = DateTimeOffset.Now, + Passed = true, + Rank = ScoreRank.S, + MaxCombo = 1000, + TotalScore = 1000000, + User = localUser, + Statistics = new Dictionary() + }); + return true; + } + + return false; + } + + /// + /// Adds a room to a local "server-side" list that's returned when a is fired. + /// + /// The room. + public void AddServerSideRoom(Room room) + { + room.RoomID.Value ??= currentRoomId++; + for (int i = 0; i < room.Playlist.Count; i++) + room.Playlist[i].ID = currentPlaylistItemId++; + + serverSideRooms.Add(room); + } + + private Room createResponseRoom(Room room, bool withParticipants) + { + var responseRoom = new Room(); + responseRoom.CopyFrom(room); + responseRoom.Password.Value = null; + if (!withParticipants) + responseRoom.RecentParticipants.Clear(); + return responseRoom; + } + } +} From 49bc3a8250aeb0d5875f0461ef07eada7c82d915 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 06:25:47 +0300 Subject: [PATCH 082/103] Refactor playlists room manager to handle dummy API requests --- .../TestSceneLoungeRoomsContainer.cs | 4 +- .../TestSceneMultiplayerLoungeSubScreen.cs | 2 +- .../TestScenePlaylistsLoungeSubScreen.cs | 2 +- .../TestScenePlaylistsRoomSubScreen.cs | 13 -- .../Visual/OnlinePlay/BasicTestRoomManager.cs | 111 ------------------ .../OnlinePlayTestSceneDependencies.cs | 2 +- .../TestRequestHandlingRoomManager.cs | 76 ++++++++++++ 7 files changed, 81 insertions(+), 129 deletions(-) delete mode 100644 osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs create mode 100644 osu.Game/Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index 7e822f898e..d253b7f8cf 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { public class TestSceneLoungeRoomsContainer : OnlinePlayTestScene { - protected new BasicTestRoomManager RoomManager => (BasicTestRoomManager)base.RoomManager; + protected new TestRequestHandlingRoomManager RoomManager => (TestRequestHandlingRoomManager)base.RoomManager; private RoomsContainer container; @@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("add rooms", () => RoomManager.AddRooms(3)); AddAssert("has 3 rooms", () => container.Rooms.Count == 3); - AddStep("remove first room", () => RoomManager.Rooms.Remove(RoomManager.Rooms.FirstOrDefault())); + AddStep("remove first room", () => RoomManager.RemoveRoom(RoomManager.Rooms.FirstOrDefault())); AddAssert("has 2 rooms", () => container.Rooms.Count == 2); AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0)); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs index c66d5429d6..cc05bc24aa 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayerLoungeSubScreen.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { public class TestSceneMultiplayerLoungeSubScreen : OnlinePlayTestScene { - protected new BasicTestRoomManager RoomManager => (BasicTestRoomManager)base.RoomManager; + protected new TestRequestHandlingRoomManager RoomManager => (TestRequestHandlingRoomManager)base.RoomManager; private LoungeSubScreen loungeScreen; diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs index aff0e7ba4b..f432a6436e 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Playlists { public class TestScenePlaylistsLoungeSubScreen : OnlinePlayTestScene { - protected new BasicTestRoomManager RoomManager => (BasicTestRoomManager)base.RoomManager; + protected new TestRequestHandlingRoomManager RoomManager => (TestRequestHandlingRoomManager)base.RoomManager; private LoungeSubScreen loungeScreen; diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs index 9fc29049ef..28090be1f6 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs @@ -11,7 +11,6 @@ using osu.Framework.Platform; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; -using osu.Game.Online.API; using osu.Game.Online.Rooms; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; @@ -36,18 +35,6 @@ namespace osu.Game.Tests.Visual.Playlists { Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default)); - - ((DummyAPIAccess)API).HandleRequest = req => - { - switch (req) - { - case CreateRoomScoreRequest createRoomScoreRequest: - createRoomScoreRequest.TriggerSuccess(new APIScoreToken { ID = 1 }); - return true; - } - - return false; - }; } [SetUpSteps] diff --git a/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs b/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs deleted file mode 100644 index 55fbb9f1a6..0000000000 --- a/osu.Game/Tests/Visual/OnlinePlay/BasicTestRoomManager.cs +++ /dev/null @@ -1,111 +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 System; -using System.Linq; -using osu.Framework.Bindables; -using osu.Game.Beatmaps; -using osu.Game.Online.Rooms; -using osu.Game.Rulesets; -using osu.Game.Screens.OnlinePlay; -using osu.Game.Screens.OnlinePlay.Components; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual.OnlinePlay -{ - /// - /// A very simple for use in online play test scenes. - /// - public class BasicTestRoomManager : IRoomManager - { - public event Action RoomsUpdated; - - public readonly BindableList Rooms = new BindableList(); - - public Action JoinRoomRequested; - - public IBindable InitialRoomsReceived { get; } = new Bindable(true); - - IBindableList IRoomManager.Rooms => Rooms; - - private int currentRoomId; - - public void CreateRoom(Room room, Action onSuccess = null, Action onError = null) - { - room.RoomID.Value ??= Rooms.Select(r => r.RoomID.Value).Where(id => id != null).Select(id => id.Value).DefaultIfEmpty().Max() + 1; - onSuccess?.Invoke(room); - - AddOrUpdateRoom(room); - } - - public void AddOrUpdateRoom(Room room) - { - var existing = Rooms.FirstOrDefault(r => r.RoomID.Value != null && r.RoomID.Value == room.RoomID.Value); - - if (existing != null) - existing.CopyFrom(room); - else - Rooms.Add(room); - - RoomsUpdated?.Invoke(); - } - - public void RemoveRoom(Room room) - { - Rooms.Remove(room); - RoomsUpdated?.Invoke(); - } - - public void ClearRooms() - { - Rooms.Clear(); - RoomsUpdated?.Invoke(); - } - - public void JoinRoom(Room room, string password, Action onSuccess = null, Action onError = null) - { - JoinRoomRequested?.Invoke(room, password); - onSuccess?.Invoke(room); - } - - public void PartRoom() - { - } - - public void AddRooms(int count, RulesetInfo ruleset = null, bool withPassword = false) - { - for (int i = 0; i < count; i++) - { - var room = new Room - { - RoomID = { Value = currentRoomId }, - Position = { Value = currentRoomId }, - Name = { Value = $"Room {currentRoomId}" }, - Host = { Value = new User { Username = "Host" } }, - EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) }, - Category = { Value = i % 2 == 0 ? RoomCategory.Spotlight : RoomCategory.Normal }, - Password = { Value = withPassword ? "password" : string.Empty } - }; - - if (ruleset != null) - { - room.Playlist.Add(new PlaylistItem - { - Ruleset = { Value = ruleset }, - Beatmap = - { - Value = new BeatmapInfo - { - Metadata = new BeatmapMetadata() - } - } - }); - } - - CreateRoom(room); - - currentRoomId++; - } - } - } -} diff --git a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs index e39711b7ce..defc971eef 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/OnlinePlayTestSceneDependencies.cs @@ -71,6 +71,6 @@ namespace osu.Game.Tests.Visual.OnlinePlay drawableComponents.Add(drawable); } - protected virtual IRoomManager CreateRoomManager() => new BasicTestRoomManager(); + protected virtual IRoomManager CreateRoomManager() => new TestRequestHandlingRoomManager(); } } diff --git a/osu.Game/Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs b/osu.Game/Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs new file mode 100644 index 0000000000..4c7fc0e18f --- /dev/null +++ b/osu.Game/Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs @@ -0,0 +1,76 @@ +// 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.Game.Beatmaps; +using osu.Game.Online.API; +using osu.Game.Online.Rooms; +using osu.Game.Rulesets; +using osu.Game.Screens.OnlinePlay.Components; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.OnlinePlay +{ + /// + /// A very simple for use in online play test scenes. + /// + public class TestRequestHandlingRoomManager : RoomManager + { + public Action JoinRoomRequested; + + private int currentRoomId; + + private readonly TestRoomRequestsHandler handler = new TestRoomRequestsHandler(); + + [BackgroundDependencyLoader] + private void load(IAPIProvider api, OsuGameBase game) + { + ((DummyAPIAccess)api).HandleRequest = request => handler.HandleRequest(request, api.LocalUser.Value, game); + } + + public override void JoinRoom(Room room, string password = null, Action onSuccess = null, Action onError = null) + { + JoinRoomRequested?.Invoke(room, password); + base.JoinRoom(room, password, onSuccess, onError); + } + + public void AddRooms(int count, RulesetInfo ruleset = null, bool withPassword = false) + { + for (int i = 0; i < count; i++) + { + var room = new Room + { + RoomID = { Value = -currentRoomId }, + Name = { Value = $@"Room {currentRoomId}" }, + Host = { Value = new User { Username = @"Host" } }, + EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) }, + Category = { Value = i % 2 == 0 ? RoomCategory.Spotlight : RoomCategory.Normal }, + }; + + if (withPassword) + room.Password.Value = @"password"; + + if (ruleset != null) + { + room.Playlist.Add(new PlaylistItem + { + Ruleset = { Value = ruleset }, + Beatmap = + { + Value = new BeatmapInfo + { + Metadata = new BeatmapMetadata() + } + } + }); + } + + CreateRoom(room); + + currentRoomId++; + } + } + } +} From 47ef33e7316bc93b7f001da29a3d9f8196e685d7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 06:28:31 +0300 Subject: [PATCH 083/103] Fix playlists lounge sub screen test potentially failing --- .../Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs index aff0e7ba4b..509b62f69f 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsLoungeSubScreen.cs @@ -37,6 +37,7 @@ namespace osu.Game.Tests.Visual.Playlists AddStep("reset mouse", () => InputManager.ReleaseButton(MouseButton.Left)); AddStep("add rooms", () => RoomManager.AddRooms(30)); + AddUntilStep("wait for rooms", () => roomsContainer.Rooms.Count == 30); AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.Rooms[0])); @@ -53,6 +54,7 @@ namespace osu.Game.Tests.Visual.Playlists public void TestScrollSelectedIntoView() { AddStep("add rooms", () => RoomManager.AddRooms(30)); + AddUntilStep("wait for rooms", () => roomsContainer.Rooms.Count == 30); AddUntilStep("first room is not masked", () => checkRoomVisible(roomsContainer.Rooms[0])); From 5fc29328cf1411bea9bc4f4c093ec32b6849087d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 06:30:22 +0300 Subject: [PATCH 084/103] Remove unused using Uh..... --- .../Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs b/osu.Game/Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs index 4c7fc0e18f..d88fd68b20 100644 --- a/osu.Game/Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs +++ b/osu.Game/Tests/Visual/OnlinePlay/TestRequestHandlingRoomManager.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.API; From 072560ba3e583d5660f3df7d76999bca1264e390 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 07:17:42 +0300 Subject: [PATCH 085/103] Remove leftover unused using --- osu.Game/Rulesets/Mods/Mod.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs index 8c2a8a8e8b..9f3b5eaf5b 100644 --- a/osu.Game/Rulesets/Mods/Mod.cs +++ b/osu.Game/Rulesets/Mods/Mod.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; -using JetBrains.Annotations; using Newtonsoft.Json; using osu.Framework.Bindables; using osu.Framework.Extensions.TypeExtensions; From 6d57a240acf5cd9528b2f688e4a5e4c0388eaaf6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 07:17:22 +0300 Subject: [PATCH 086/103] Add animation support for the star rating display --- .../Beatmaps/Drawables/StarRatingDisplay.cs | 35 +++++++++++++++---- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs index 25cde5fb82..c239fda455 100644 --- a/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs +++ b/osu.Game/Beatmaps/Drawables/StarRatingDisplay.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; @@ -22,6 +23,7 @@ namespace osu.Game.Beatmaps.Drawables /// public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue { + private readonly bool animated; private readonly Box background; private readonly SpriteIcon starIcon; private readonly OsuSpriteText starsText; @@ -34,6 +36,14 @@ namespace osu.Game.Beatmaps.Drawables set => current.Current = value; } + private readonly Bindable displayedStars = new BindableDouble(); + + /// + /// The currently displayed stars of this display wrapped in a bindable. + /// This bindable gets transformed on change rather than instantaneous, if animation is enabled. + /// + public IBindable DisplayedStars => displayedStars; + [Resolved] private OsuColour colours { get; set; } @@ -45,8 +55,11 @@ namespace osu.Game.Beatmaps.Drawables /// /// The already computed to display. /// The size of the star rating display. - public StarRatingDisplay(StarDifficulty starDifficulty, StarRatingDisplaySize size = StarRatingDisplaySize.Regular) + /// Whether the star rating display will perform transforms on change rather than updating instantaneously. + public StarRatingDisplay(StarDifficulty starDifficulty, StarRatingDisplaySize size = StarRatingDisplaySize.Regular, bool animated = false) { + this.animated = animated; + Current.Value = starDifficulty; AutoSizeAxes = Axes.Both; @@ -112,7 +125,7 @@ namespace osu.Game.Beatmaps.Drawables // see https://github.com/ppy/osu-framework/issues/3271. Font = OsuFont.Torus.With(size: 14.4f, weight: FontWeight.Bold), Shadow = false, - } + }, } } }, @@ -126,12 +139,22 @@ namespace osu.Game.Beatmaps.Drawables Current.BindValueChanged(c => { - starsText.Text = c.NewValue.Stars.ToString("0.00"); + if (animated) + this.TransformBindableTo(displayedStars, c.NewValue.Stars, 750, Easing.OutQuint); + else + displayedStars.Value = c.NewValue.Stars; + }); - background.Colour = colours.ForStarDifficulty(c.NewValue.Stars); + displayedStars.Value = Current.Value.Stars; - starIcon.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); - starsText.Colour = c.NewValue.Stars >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); + displayedStars.BindValueChanged(s => + { + starsText.Text = s.NewValue.ToLocalisableString("0.00"); + + background.Colour = colours.ForStarDifficulty(s.NewValue); + + starIcon.Colour = s.NewValue >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4Extensions.FromHex("303d47"); + starsText.Colour = s.NewValue >= 6.5 ? colours.Orange1 : colourProvider?.Background5 ?? Color4.Black.Opacity(0.75f); }, true); } } From 25e6317e7f1a51dc6cd15edbafaccb10d499a4d1 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 07:18:02 +0300 Subject: [PATCH 087/103] Use animated star display in beatmap info wedge and synchronise bar --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 83 +++++++-------------- 1 file changed, 26 insertions(+), 57 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 14c32f2348..1e1f362d71 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -21,7 +21,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Game.Configuration; @@ -157,7 +156,7 @@ namespace osu.Game.Screens.Select public BeatmapSetOnlineStatusPill StatusPill { get; private set; } public FillFlowContainer MapperContainer { get; private set; } - private DifficultyColourBar difficultyColourBar; + private Container difficultyColourBar; private StarRatingDisplay starRatingDisplay; private ILocalisedBindableString titleBinding; @@ -182,7 +181,7 @@ namespace osu.Game.Screens.Select private IBindable starDifficulty; [BackgroundDependencyLoader] - private void load(LocalisationManager localisation, BeatmapDifficultyCache difficultyCache) + private void load(OsuColour colours, LocalisationManager localisation, BeatmapDifficultyCache difficultyCache) { var beatmapInfo = beatmap.BeatmapInfo; var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); @@ -194,10 +193,26 @@ namespace osu.Game.Screens.Select Children = new Drawable[] { - difficultyColourBar = new DifficultyColourBar + difficultyColourBar = new Container { RelativeSizeAxes = Axes.Y, - Width = 20, + Width = 20f, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Width = 0.7f, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Alpha = 0.5f, + X = 0.7f, + Width = 1 - 0.7f, + } + } }, new FillFlowContainer { @@ -230,7 +245,7 @@ namespace osu.Game.Screens.Select Shear = wedged_container_shear, Children = new Drawable[] { - starRatingDisplay = new StarRatingDisplay(default) + starRatingDisplay = new StarRatingDisplay(default, animated: true) { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, @@ -292,11 +307,14 @@ namespace osu.Game.Screens.Select titleBinding.BindValueChanged(_ => setMetadata(metadata.Source)); artistBinding.BindValueChanged(_ => setMetadata(metadata.Source), true); + starRatingDisplay.DisplayedStars.BindValueChanged(s => + { + difficultyColourBar.Colour = colours.ForStarDifficulty(s.NewValue); + }, true); + starDifficulty = difficultyCache.GetBindableDifficulty(beatmapInfo, (cancellationSource = new CancellationTokenSource()).Token); starDifficulty.BindValueChanged(s => { - difficultyColourBar.Current.Value = s.NewValue ?? default; - starRatingDisplay.FadeIn(transition_duration); starRatingDisplay.Current.Value = s.NewValue ?? default; }); @@ -480,55 +498,6 @@ namespace osu.Game.Screens.Select }; } } - - public class DifficultyColourBar : Container, IHasCurrentValue - { - private readonly BindableWithCurrent current = new BindableWithCurrent(); - - public Bindable Current - { - get => current.Current; - set => current.Current = value; - } - - [Resolved] - private OsuColour colours { get; set; } - - [BackgroundDependencyLoader] - private void load() - { - const float full_opacity_ratio = 0.7f; - - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Width = full_opacity_ratio, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.Both, - Alpha = 0.5f, - X = full_opacity_ratio, - Width = 1 - full_opacity_ratio, - } - }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - Current.BindValueChanged(c => - { - this.FadeColour(colours.ForStarDifficulty(c.NewValue.Stars), transition_duration, Easing.OutQuint); - }, true); - - FinishTransforms(true); - } - } } } } From 65c0ae757bfeb80bf3fe324d80a9cb19dc6d0fcc Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 07:18:18 +0300 Subject: [PATCH 088/103] Merge spectrum test case --- .../TestSceneStarRatingDisplay.cs | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs index 052251d5a8..2806e6d347 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneStarRatingDisplay.cs @@ -3,7 +3,6 @@ using System.Linq; using NUnit.Framework; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Utils; @@ -50,32 +49,7 @@ namespace osu.Game.Tests.Visual.UserInterface { StarRatingDisplay starRating = null; - BindableDouble starRatingNumeric; - - AddStep("load display", () => - { - Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1)) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(3f), - }; - }); - - AddStep("transform over spectrum", () => - { - starRatingNumeric = new BindableDouble(); - starRatingNumeric.BindValueChanged(val => starRating.Current.Value = new StarDifficulty(val.NewValue, 1)); - this.TransformBindableTo(starRatingNumeric, 10, 10000, Easing.OutQuint); - }); - } - - [Test] - public void TestChangingStarRatingDisplay() - { - StarRatingDisplay starRating = null; - - AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1)) + AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1), animated: true) { Anchor = Anchor.Centre, Origin = Anchor.Centre, From 6bfae25cda203f6bf5482281b7aa3f4568f52225 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 19 Aug 2021 08:30:27 +0300 Subject: [PATCH 089/103] Apply 5px vertical spacing on fill flow Regressed, was margin { bottom = 5f } from the star rating display creation method, which I've partly inlined. --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 1e1f362d71..17a26eb7ee 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -243,6 +243,7 @@ namespace osu.Game.Screens.Select Padding = new MarginPadding { Top = 14, Right = shear_width / 2 }, AutoSizeAxes = Axes.Both, Shear = wedged_container_shear, + Spacing = new Vector2(0f, 5f), Children = new Drawable[] { starRatingDisplay = new StarRatingDisplay(default, animated: true) From 6469eaa427cf038725f05e93d88065e5f4135449 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Aug 2021 15:52:51 +0900 Subject: [PATCH 090/103] Fix background not updated in room --- .../Lounge/Components/DrawableRoom.cs | 10 +++--- .../OnlinePlay/Match/DrawableMatchRoom.cs | 2 ++ .../OnlinePlay/Match/RoomBackgroundSprite.cs | 33 +++++++++++++++++++ 3 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 osu.Game/Screens/OnlinePlay/Match/RoomBackgroundSprite.cs diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs index c5b8bffbc6..bbec9aa21d 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs @@ -61,7 +61,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components [BackgroundDependencyLoader] private void load(OverlayColourProvider colours) { - InternalChildren = new Drawable[] + InternalChildren = new[] { // This resolves internal 1px gaps due to applying the (parenting) corner radius and masking across multiple filling background sprites. new Box @@ -69,10 +69,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components RelativeSizeAxes = Axes.Both, Colour = colours.Background5, }, - new OnlinePlayBackgroundSprite + CreateBackground().With(d => { - RelativeSizeAxes = Axes.Both - }, + d.RelativeSizeAxes = Axes.Both; + }), new Container { Name = @"Room content", @@ -264,6 +264,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components } } + protected virtual Drawable CreateBackground() => new OnlinePlayBackgroundSprite(); + private class RoomNameText : OsuSpriteText { [Resolved(typeof(Room), nameof(Online.Rooms.Room.Name))] diff --git a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs index b3e6292f45..0924773338 100644 --- a/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Match/DrawableMatchRoom.cs @@ -58,5 +58,7 @@ namespace osu.Game.Screens.OnlinePlay.Match if (editButton != null) host.BindValueChanged(h => editButton.Alpha = h.NewValue?.Equals(api.LocalUser.Value) == true ? 1 : 0, true); } + + protected override Drawable CreateBackground() => new RoomBackgroundSprite(); } } diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomBackgroundSprite.cs b/osu.Game/Screens/OnlinePlay/Match/RoomBackgroundSprite.cs new file mode 100644 index 0000000000..97262dd229 --- /dev/null +++ b/osu.Game/Screens/OnlinePlay/Match/RoomBackgroundSprite.cs @@ -0,0 +1,33 @@ +// 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.Beatmaps.Drawables; + +namespace osu.Game.Screens.OnlinePlay.Match +{ + public class RoomBackgroundSprite : RoomSubScreenComposite + { + protected readonly BeatmapSetCoverType BeatmapSetCoverType; + private UpdateableBeatmapBackgroundSprite sprite; + + public RoomBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) + { + BeatmapSetCoverType = beatmapSetCoverType; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = sprite = new UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType) { RelativeSizeAxes = Axes.Both }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + SelectedItem.BindValueChanged(item => sprite.Beatmap.Value = item.NewValue?.Beatmap.Value, true); + } + } +} From 1fd746524d1963f96333cec766110acc5cbc4e2f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 19 Aug 2021 16:09:17 +0900 Subject: [PATCH 091/103] Remove realtime room category, fix end-date showing for realtime --- .../Visual/Multiplayer/TestSceneDrawableRoom.cs | 8 +------- osu.Game/Online/Rooms/RoomCategory.cs | 1 - .../OnlinePlay/Lounge/Components/DrawableRoom.cs | 12 ++++++++++-- .../Multiplayer/MultiplayerLoungeSubScreen.cs | 1 - 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs index 489ece3271..8ca578b592 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoom.cs @@ -108,12 +108,6 @@ namespace osu.Game.Tests.Visual.Multiplayer EndDate = { Value = DateTimeOffset.Now }, }), createDrawableRoom(new Room - { - Name = { Value = "Room 4 (realtime)" }, - Status = { Value = new RoomStatusOpen() }, - Category = { Value = RoomCategory.Realtime }, - }), - createDrawableRoom(new Room { Name = { Value = "Room 4 (spotlight)" }, Status = { Value = new RoomStatusOpen() }, @@ -134,7 +128,7 @@ namespace osu.Game.Tests.Visual.Multiplayer { Name = { Value = "Room with password" }, Status = { Value = new RoomStatusOpen() }, - Category = { Value = RoomCategory.Realtime }, + Type = { Value = MatchType.HeadToHead }, })); AddAssert("password icon hidden", () => Precision.AlmostEquals(0, drawableRoom.ChildrenOfType().Single().Alpha)); diff --git a/osu.Game/Online/Rooms/RoomCategory.cs b/osu.Game/Online/Rooms/RoomCategory.cs index bb9f1298d3..a1dcfa5fd9 100644 --- a/osu.Game/Online/Rooms/RoomCategory.cs +++ b/osu.Game/Online/Rooms/RoomCategory.cs @@ -8,6 +8,5 @@ namespace osu.Game.Online.Rooms // used for osu-web deserialization so names shouldn't be changed. Normal, Spotlight, - Realtime, } } diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs index bbec9aa21d..106211c833 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/DrawableRoom.cs @@ -34,12 +34,14 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components protected Container ButtonsContainer { get; private set; } + private readonly Bindable roomType = new Bindable(); private readonly Bindable roomCategory = new Bindable(); private readonly Bindable hasPassword = new Bindable(); private RecentParticipantsList recentParticipantsList; private RoomSpecialCategoryPill specialCategoryPill; private PasswordProtectedIcon passwordIcon; + private EndDateInfo endDateInfo; public DrawableRoom(Room room) { @@ -144,10 +146,10 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft }, - new EndDateInfo + endDateInfo = new EndDateInfo { Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft + Origin = Anchor.CentreLeft, }, } }, @@ -238,6 +240,12 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components specialCategoryPill.Hide(); }, true); + roomType.BindTo(Room.Type); + roomType.BindValueChanged(t => + { + endDateInfo.Alpha = t.NewValue == MatchType.Playlists ? 1 : 0; + }, true); + hasPassword.BindTo(Room.HasPassword); hasPassword.BindValueChanged(v => passwordIcon.Alpha = v.NewValue ? 1 : 0, true); } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index d152fc3913..6c3dfe7382 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -50,7 +50,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer protected override Room CreateNewRoom() => new Room { Name = { Value = $"{api.LocalUser}'s awesome room" }, - Category = { Value = RoomCategory.Realtime }, Type = { Value = MatchType.HeadToHead }, }; From 4d1582d721e0af061117f2ad49fded615be7f003 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Aug 2021 18:14:45 +0900 Subject: [PATCH 092/103] Play settings hide animation if visible when exiting `RoomSubScreen` --- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index 81fae558c8..ec56edaa4d 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -244,6 +244,7 @@ namespace osu.Game.Screens.OnlinePlay.Match if (Room.RoomID.Value == null) { // room has not been created yet; exit immediately. + settingsOverlay.Hide(); return base.OnBackButton(); } From 4afc808ffcf32c1930f7a1bd256b62926b6c65e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Aug 2021 18:25:40 +0900 Subject: [PATCH 093/103] Remove horizontal transitions for now They look bad with the current toolbar implementation. We can probably add them back once the toolbar is moved to the lounge. --- osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs index e1bd889088..49cc77a5d8 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySubScreen.cs @@ -23,12 +23,6 @@ namespace osu.Game.Screens.OnlinePlay RelativeSizeAxes = Axes.Both; } - public const float X_SHIFT = 200; - - public const double X_MOVE_DURATION = 800; - - public const double RESUME_TRANSITION_DELAY = DISAPPEAR_DURATION / 2; - public const double APPEAR_DURATION = 800; public const double DISAPPEAR_DURATION = 500; @@ -36,28 +30,23 @@ namespace osu.Game.Screens.OnlinePlay public override void OnEntering(IScreen last) { this.FadeInFromZero(APPEAR_DURATION, Easing.OutQuint); - this.FadeInFromZero(APPEAR_DURATION, Easing.OutQuint); - this.MoveToX(X_SHIFT).MoveToX(0, X_MOVE_DURATION, Easing.OutQuint); } public override bool OnExiting(IScreen next) { this.FadeOut(DISAPPEAR_DURATION, Easing.OutQuint); - this.MoveToX(X_SHIFT, X_MOVE_DURATION, Easing.OutQuint); return false; } public override void OnResuming(IScreen last) { - this.Delay(RESUME_TRANSITION_DELAY).FadeIn(APPEAR_DURATION, Easing.OutQuint); - this.MoveToX(0, X_MOVE_DURATION, Easing.OutQuint); + this.FadeIn(APPEAR_DURATION, Easing.OutQuint); } public override void OnSuspending(IScreen next) { this.FadeOut(DISAPPEAR_DURATION, Easing.OutQuint); - this.MoveToX(-X_SHIFT, X_MOVE_DURATION, Easing.OutQuint); } public override string ToString() => Title; From 675e2e34baf1d6796e96b7911bac786352538853 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Aug 2021 19:02:05 +0900 Subject: [PATCH 094/103] Add padding between beatmap panel and edit button --- .../OnlinePlay/Multiplayer/Match/BeatmapSelectionControl.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/BeatmapSelectionControl.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/BeatmapSelectionControl.cs index 56b87302c2..2e94e51385 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/BeatmapSelectionControl.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/BeatmapSelectionControl.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Screens; using osu.Game.Online.API; using osu.Game.Screens.OnlinePlay.Match.Components; +using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { @@ -35,6 +36,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, + Spacing = new Vector2(5), Children = new Drawable[] { beatmapPanelContainer = new Container From be774980440e89cbbc8451ef215138bf1a3046da Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Aug 2021 19:02:31 +0900 Subject: [PATCH 095/103] Move chat to right column in multiplayer match screen --- .../Multiplayer/MultiplayerMatchSubScreen.cs | 106 ++++++++---------- 1 file changed, 47 insertions(+), 59 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 3f5837cbbe..6a41403aff 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -141,79 +141,67 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer // Spacer null, // Main right column - new FillFlowContainer + new GridContainer { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new[] + RelativeSizeAxes = Axes.Both, + Content = new[] { - new FillFlowContainer + new Drawable[] { new OverlinedHeader("Beatmap") }, + new Drawable[] { new BeatmapSelectionControl { RelativeSizeAxes = Axes.X } }, + new[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + UserModsSection = new FillFlowContainer { - new OverlinedHeader("Beatmap"), - new BeatmapSelectionControl { RelativeSizeAxes = Axes.X } - } - }, - UserModsSection = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 10 }, - Children = new Drawable[] - { - new OverlinedHeader("Extra mods"), - new FillFlowContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 10 }, + Children = new Drawable[] { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] + new OverlinedHeader("Extra mods"), + new FillFlowContainer { - new UserModSelectButton + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Width = 90, - Text = "Select", - Action = ShowUserModSelect, - }, - new ModDisplay - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Current = UserMods, - Scale = new Vector2(0.8f), - }, - } + new UserModSelectButton + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Width = 90, + Text = "Select", + Action = ShowUserModSelect, + }, + new ModDisplay + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Current = UserMods, + Scale = new Vector2(0.8f), + }, + } + }, } - } - } + }, + }, + new Drawable[] { new OverlinedHeader("Chat") { Margin = new MarginPadding { Vertical = 5 }, }, }, + new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(), } - } + }, } } } } }, - new Drawable[] - { - new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] { new OverlinedHeader("Chat") }, - new Drawable[] { new MatchChatDisplay { RelativeSizeAxes = Axes.Both } } - } - } - } }, }; From 16aecfe934c9d893e694af1429ad0cede7c2d679 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Aug 2021 19:02:54 +0900 Subject: [PATCH 096/103] Start free mod selection area hidden on screen display --- .../Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs | 1 + osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index 6a41403aff..3a012787a4 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -155,6 +155,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Margin = new MarginPadding { Top = 10 }, + Alpha = 0, Children = new Drawable[] { new OverlinedHeader("Extra mods"), diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs index 27de781d5f..729ddbef8c 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs @@ -120,6 +120,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Alpha = 0, Margin = new MarginPadding { Bottom = 10 }, Children = new Drawable[] { From 8fce5911a951dbe1cbc6884e0f596e2e5d50763b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Aug 2021 19:08:46 +0900 Subject: [PATCH 097/103] Adjust spacing and padding of footer buttons --- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 9 +++++++-- .../Multiplayer/Match/MultiplayerMatchFooter.cs | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index ec56edaa4d..10df7cbadc 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -195,14 +195,19 @@ namespace osu.Game.Screens.OnlinePlay.Match new Container { RelativeSizeAxes = Axes.Both, - Children = new[] + Children = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, Colour = Color4Extensions.FromHex(@"28242d") // Temporary. }, - CreateFooter() + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(5), + Child = CreateFooter() + }, } } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs index 9e8d51e64e..036e37ddfd 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Match/MultiplayerMatchFooter.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match { new Dimension(), new Dimension(maxSize: spectate_button_width), - new Dimension(GridSizeMode.Absolute, 10), + new Dimension(GridSizeMode.Absolute, 5), new Dimension(maxSize: ready_button_width), new Dimension() } From a65cd36a5f25296b5348f483208ad37458437841 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Aug 2021 19:19:46 +0900 Subject: [PATCH 098/103] Move some constants to `const`s --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 17a26eb7ee..297a16dd1d 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -73,17 +73,19 @@ namespace osu.Game.Screens.Select ruleset.BindValueChanged(_ => updateDisplay()); } + private const double animation_duration = 800; + protected override void PopIn() { - this.MoveToX(0, 800, Easing.OutQuint); - this.RotateTo(0, 800, Easing.OutQuint); + this.MoveToX(0, animation_duration, Easing.OutQuint); + this.RotateTo(0, animation_duration, Easing.OutQuint); this.FadeIn(transition_duration); } protected override void PopOut() { - this.MoveToX(-100, 800, Easing.In); - this.RotateTo(10, 800, Easing.In); + this.MoveToX(-100, animation_duration, Easing.In); + this.RotateTo(10, animation_duration, Easing.In); this.FadeOut(transition_duration * 2, Easing.In); } @@ -191,6 +193,8 @@ namespace osu.Game.Screens.Select titleBinding = localisation.GetLocalisedString(new RomanisableString(metadata.TitleUnicode, metadata.Title)); artistBinding = localisation.GetLocalisedString(new RomanisableString(metadata.ArtistUnicode, metadata.Artist)); + const float top_height = 0.7f; + Children = new Drawable[] { difficultyColourBar = new Container @@ -202,15 +206,15 @@ namespace osu.Game.Screens.Select new Box { RelativeSizeAxes = Axes.Both, - Width = 0.7f, + Width = top_height, }, new Box { RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.Both, Alpha = 0.5f, - X = 0.7f, - Width = 1 - 0.7f, + X = top_height, + Width = 1 - top_height, } } }, From 5f1948d040b054a4ec68e964166b2c61aedb2d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 19 Aug 2021 22:31:11 +0200 Subject: [PATCH 099/103] Add failing test case --- .../Visual/Settings/TestSceneSettingsItem.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs index df59b9284b..d9cce69ee3 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs @@ -76,5 +76,23 @@ namespace osu.Game.Tests.Visual.Settings AddStep("restore default", () => sliderBar.Current.SetDefault()); AddUntilStep("restore button hidden", () => restoreDefaultValueButton.Alpha == 0); } + + [Test] + public void TestWarningTextVisibility() + { + SettingsNumberBox numberBox = null; + + AddStep("create settings item", () => Child = numberBox = new SettingsNumberBox()); + AddAssert("warning text not created", () => !numberBox.ChildrenOfType().Any()); + + AddStep("set warning text", () => numberBox.WarningText = "this is a warning!"); + AddAssert("warning text created", () => numberBox.ChildrenOfType().Single().Alpha == 1); + + AddStep("unset warning text", () => numberBox.WarningText = default); + AddAssert("warning text hidden", () => numberBox.ChildrenOfType().Single().Alpha == 0); + + AddStep("set warning text again", () => numberBox.WarningText = "another warning!"); + AddAssert("warning text shown again", () => numberBox.ChildrenOfType().Single().Alpha == 1); + } } } From 143b8df1b2018d1b5efb169581d199064780cdf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 19 Aug 2021 22:33:05 +0200 Subject: [PATCH 100/103] Fix backwards warning text presence check --- osu.Game/Overlays/Settings/SettingsItem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 6621caef4e..5282217013 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Settings { set { - bool hasValue = string.IsNullOrWhiteSpace(value.ToString()); + bool hasValue = !string.IsNullOrWhiteSpace(value.ToString()); if (warningText == null) { @@ -76,7 +76,7 @@ namespace osu.Game.Overlays.Settings FlowContent.Add(warningText = new SettingsNoticeText(colours) { Margin = new MarginPadding { Bottom = 5 } }); } - warningText.Alpha = hasValue ? 0 : 1; + warningText.Alpha = hasValue ? 1 : 0; warningText.Text = value.ToString(); // TODO: Remove ToString() call after TextFlowContainer supports localisation (see https://github.com/ppy/osu-framework/issues/4636). } } From 4d9c415e730ecc488d9b4f7a9758fc208ff4968c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 20 Aug 2021 04:37:35 +0300 Subject: [PATCH 101/103] Remove unnecessary queue in beatmap difficulty cache tests --- .../TestSceneBeatmapDifficultyCache.cs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs index b6ba5b748a..6856e466cf 100644 --- a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs +++ b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs @@ -32,7 +32,6 @@ namespace osu.Game.Tests.Beatmaps private TestBeatmapDifficultyCache difficultyCache; private IBindable starDifficultyBindable; - private Queue> starDifficultyChangesQueue; [BackgroundDependencyLoader] private void load(OsuGameBase osu) @@ -49,14 +48,10 @@ namespace osu.Game.Tests.Beatmaps Child = difficultyCache = new TestBeatmapDifficultyCache(); - starDifficultyChangesQueue = new Queue>(); starDifficultyBindable = difficultyCache.GetBindableDifficulty(importedSet.Beatmaps.First()); - starDifficultyBindable.BindValueChanged(starDifficultyChangesQueue.Enqueue); }); - AddAssert($"star difficulty -> {BASE_STARS}", () => - starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS && - starDifficultyChangesQueue.Count == 0); + AddAssert($"star difficulty -> {BASE_STARS}", () => starDifficultyBindable.Value?.Stars == BASE_STARS); } [Test] @@ -65,19 +60,13 @@ namespace osu.Game.Tests.Beatmaps OsuModDoubleTime dt = null; AddStep("change selected mod to DT", () => SelectedMods.Value = new[] { dt = new OsuModDoubleTime { SpeedChange = { Value = 1.5 } } }); - AddAssert($"star difficulty -> {BASE_STARS + 1.5}", () => - starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.5 && - starDifficultyChangesQueue.Count == 0); + AddAssert($"star difficulty -> {BASE_STARS + 1.5}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.5); AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 1.25); - AddAssert($"star difficulty -> {BASE_STARS + 1.25}", () => - starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.25 && - starDifficultyChangesQueue.Count == 0); + AddAssert($"star difficulty -> {BASE_STARS + 1.25}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.25); AddStep("change selected mod to NC", () => SelectedMods.Value = new[] { new OsuModNightcore { SpeedChange = { Value = 1.75 } } }); - AddAssert($"star difficulty -> {BASE_STARS + 1.75}", () => - starDifficultyChangesQueue.Dequeue().NewValue?.Stars == BASE_STARS + 1.75 && - starDifficultyChangesQueue.Count == 0); + AddAssert($"star difficulty -> {BASE_STARS + 1.75}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.75); } [Test] From d98742522b339b4c92a49406bd9df7fe052b4225 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 20 Aug 2021 04:40:03 +0300 Subject: [PATCH 102/103] Remove unused using directive --- osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs index 6856e466cf..bdf4fb8d0c 100644 --- a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs +++ b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; From 73b40a6244abacb48bbf34f537f7ac11343c0e84 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 20 Aug 2021 05:29:30 +0300 Subject: [PATCH 103/103] Switch to until step to account for asynchronous operations --- .../Beatmaps/TestSceneBeatmapDifficultyCache.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs index bdf4fb8d0c..da457c9e8f 100644 --- a/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs +++ b/osu.Game.Tests/Beatmaps/TestSceneBeatmapDifficultyCache.cs @@ -50,7 +50,7 @@ namespace osu.Game.Tests.Beatmaps starDifficultyBindable = difficultyCache.GetBindableDifficulty(importedSet.Beatmaps.First()); }); - AddAssert($"star difficulty -> {BASE_STARS}", () => starDifficultyBindable.Value?.Stars == BASE_STARS); + AddUntilStep($"star difficulty -> {BASE_STARS}", () => starDifficultyBindable.Value?.Stars == BASE_STARS); } [Test] @@ -59,13 +59,13 @@ namespace osu.Game.Tests.Beatmaps OsuModDoubleTime dt = null; AddStep("change selected mod to DT", () => SelectedMods.Value = new[] { dt = new OsuModDoubleTime { SpeedChange = { Value = 1.5 } } }); - AddAssert($"star difficulty -> {BASE_STARS + 1.5}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.5); + AddUntilStep($"star difficulty -> {BASE_STARS + 1.5}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.5); AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 1.25); - AddAssert($"star difficulty -> {BASE_STARS + 1.25}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.25); + AddUntilStep($"star difficulty -> {BASE_STARS + 1.25}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.25); AddStep("change selected mod to NC", () => SelectedMods.Value = new[] { new OsuModNightcore { SpeedChange = { Value = 1.75 } } }); - AddAssert($"star difficulty -> {BASE_STARS + 1.75}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.75); + AddUntilStep($"star difficulty -> {BASE_STARS + 1.75}", () => starDifficultyBindable.Value?.Stars == BASE_STARS + 1.75); } [Test]