From 320c4abb66ba388bb19d04bb22b64cd4b56fa181 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 31 Jul 2022 20:13:06 -0700 Subject: [PATCH 001/248] Add failing online play non-current sub screen onexiting test --- .../Navigation/TestSceneScreenNavigation.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 8fce43f9b0..7ee0998281 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -26,6 +26,7 @@ using osu.Game.Rulesets.Osu.Mods; using osu.Game.Scoring; using osu.Game.Screens.Menu; using osu.Game.Screens.OnlinePlay.Lounge; +using osu.Game.Screens.OnlinePlay.Match.Components; using osu.Game.Screens.OnlinePlay.Playlists; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; @@ -79,7 +80,25 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for return to playlist screen", () => playlistScreen.CurrentSubScreen is PlaylistsRoomSubScreen); + AddStep("go back to song select", () => + { + InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); + InputManager.Click(MouseButton.Left); + }); + + AddUntilStep("wait for song select", () => (playlistScreen.CurrentSubScreen as PlaylistsSongSelect)?.BeatmapSetsLoaded == true); + + AddStep("press home button", () => + { + InputManager.MoveMouseTo(Game.Toolbar.ChildrenOfType().Single()); + InputManager.Click(MouseButton.Left); + }); + + AddAssert("confirmation dialog shown", () => Game.ChildrenOfType().Single().CurrentDialog is not null); + pushEscape(); + pushEscape(); + AddAssert("confirmation dialog shown", () => Game.ChildrenOfType().Single().CurrentDialog is not null); AddStep("confirm exit", () => InputManager.Key(Key.Enter)); From 1dbb2a4d376a61d744292967e077cd20eb0b7780 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 1 Aug 2022 07:52:07 -0700 Subject: [PATCH 002/248] Fix online play screen only accounting for current sub screen onexiting blocks --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 61ea7d68ee..ad52363c95 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -147,9 +147,14 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - var subScreen = screenStack.CurrentScreen as Drawable; - if (subScreen?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) - return true; + while (screenStack.CurrentScreen is not LoungeSubScreen) + { + var lastSubScreen = screenStack.CurrentScreen; + if (((Drawable)lastSubScreen)?.IsLoaded == true) + screenStack.Exit(); + + if (lastSubScreen == screenStack.CurrentScreen) return true; + } RoomManager.PartRoom(); From 9c611019b37d770355ccee2c23088238ac47d8e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20K=C3=A4llberg?= Date: Tue, 11 Oct 2022 09:30:32 +0200 Subject: [PATCH 003/248] Toolbar localisation --- osu.Game/Localisation/HomeStrings.cs | 24 +++++++++++++++++++ osu.Game/Localisation/RulesetStrings.cs | 20 ++++++++++++++++ .../Overlays/Toolbar/ToolbarHomeButton.cs | 5 ++-- .../Toolbar/ToolbarRulesetTabButton.cs | 4 +++- 4 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Localisation/HomeStrings.cs create mode 100644 osu.Game/Localisation/RulesetStrings.cs diff --git a/osu.Game/Localisation/HomeStrings.cs b/osu.Game/Localisation/HomeStrings.cs new file mode 100644 index 0000000000..4a2cea00ca --- /dev/null +++ b/osu.Game/Localisation/HomeStrings.cs @@ -0,0 +1,24 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class HomeStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.Home"; + + /// + /// "home" + /// + public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"home"); + + /// + /// "return to the main menu" + /// + public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} \ No newline at end of file diff --git a/osu.Game/Localisation/RulesetStrings.cs b/osu.Game/Localisation/RulesetStrings.cs new file mode 100644 index 0000000000..201831cd91 --- /dev/null +++ b/osu.Game/Localisation/RulesetStrings.cs @@ -0,0 +1,20 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class RulesetStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.Ruleset"; + + /// + /// "play some" + /// + + public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"play some"); + + private static string getKey(string key) => $"{prefix}:{key}"; + } +} \ No newline at end of file diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index f170ec84ac..52fa83e37a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -5,6 +5,7 @@ using osu.Framework.Allocation; using osu.Game.Input.Bindings; +using osu.Game.Localisation; namespace osu.Game.Overlays.Toolbar { @@ -19,8 +20,8 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader] private void load() { - TooltipMain = "home"; - TooltipSub = "return to the main menu"; + TooltipMain = HomeStrings.HeaderTitle; + TooltipSub = HomeStrings.HeaderDescription; SetIcon("Icons/Hexacons/home"); } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index 31c6802fda..101bba95cc 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -9,6 +9,8 @@ using osu.Game.Rulesets; using osuTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Input.Events; +using osu.Framework.Localisation; +using osu.Game.Localisation; namespace osu.Game.Overlays.Toolbar { @@ -29,7 +31,7 @@ namespace osu.Game.Overlays.Toolbar var rInstance = value.CreateInstance(); ruleset.TooltipMain = rInstance.Description; - ruleset.TooltipSub = $"play some {rInstance.Description}"; + ruleset.TooltipSub = LocalisableString.Format("{0} {1}", RulesetStrings.HeaderDescription, ($"{rInstance.Description}")); ruleset.SetIcon(rInstance.CreateIcon()); } From 63e651130af1954d7f8ce5ac1923a95abb2bc926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20K=C3=A4llberg?= Date: Tue, 11 Oct 2022 10:59:07 +0200 Subject: [PATCH 004/248] Grouped localisation strings --- osu.Game/Localisation/HomeStrings.cs | 24 ------------------- osu.Game/Localisation/RulesetStrings.cs | 20 ---------------- osu.Game/Localisation/ToolbarStrings.cs | 16 +++++++++++++ .../Overlays/Toolbar/ToolbarHomeButton.cs | 4 ++-- .../Toolbar/ToolbarRulesetTabButton.cs | 8 +++---- 5 files changed, 22 insertions(+), 50 deletions(-) delete mode 100644 osu.Game/Localisation/HomeStrings.cs delete mode 100644 osu.Game/Localisation/RulesetStrings.cs diff --git a/osu.Game/Localisation/HomeStrings.cs b/osu.Game/Localisation/HomeStrings.cs deleted file mode 100644 index 4a2cea00ca..0000000000 --- a/osu.Game/Localisation/HomeStrings.cs +++ /dev/null @@ -1,24 +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.Localisation; - -namespace osu.Game.Localisation -{ - public static class HomeStrings - { - private const string prefix = @"osu.Game.Resources.Localisation.Home"; - - /// - /// "home" - /// - public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"home"); - - /// - /// "return to the main menu" - /// - public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); - - private static string getKey(string key) => $"{prefix}:{key}"; - } -} \ No newline at end of file diff --git a/osu.Game/Localisation/RulesetStrings.cs b/osu.Game/Localisation/RulesetStrings.cs deleted file mode 100644 index 201831cd91..0000000000 --- a/osu.Game/Localisation/RulesetStrings.cs +++ /dev/null @@ -1,20 +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.Localisation; - -namespace osu.Game.Localisation -{ - public static class RulesetStrings - { - private const string prefix = @"osu.Game.Resources.Localisation.Ruleset"; - - /// - /// "play some" - /// - - public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"play some"); - - private static string getKey(string key) => $"{prefix}:{key}"; - } -} \ No newline at end of file diff --git a/osu.Game/Localisation/ToolbarStrings.cs b/osu.Game/Localisation/ToolbarStrings.cs index 6dc8a1e50c..b76c643332 100644 --- a/osu.Game/Localisation/ToolbarStrings.cs +++ b/osu.Game/Localisation/ToolbarStrings.cs @@ -19,6 +19,22 @@ namespace osu.Game.Localisation /// public static LocalisableString Connecting => new TranslatableString(getKey(@"connecting"), @"Connecting..."); + /// + /// "home" + /// + public static LocalisableString HomeHeaderTitle => new TranslatableString(getKey(@"header_title"), @"home"); + + /// + /// "return to the main menu" + /// + public static LocalisableString HomeHeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); + + /// + /// "play some" + /// + + public static LocalisableString RulesetHeaderDescription => new TranslatableString(getKey(@"header_description"), @"play some"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs index 52fa83e37a..959706b805 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarHomeButton.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Toolbar [BackgroundDependencyLoader] private void load() { - TooltipMain = HomeStrings.HeaderTitle; - TooltipSub = HomeStrings.HeaderDescription; + TooltipMain = ToolbarStrings.HomeHeaderTitle; + TooltipSub = ToolbarStrings.HomeHeaderDescription; SetIcon("Icons/Hexacons/home"); } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index 101bba95cc..bffd8b96e5 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -3,14 +3,14 @@ #nullable disable +using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.UserInterface; -using osu.Game.Rulesets; -using osuTK.Graphics; -using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Localisation; +using osu.Game.Rulesets; +using osuTK.Graphics; namespace osu.Game.Overlays.Toolbar { @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Toolbar var rInstance = value.CreateInstance(); ruleset.TooltipMain = rInstance.Description; - ruleset.TooltipSub = LocalisableString.Format("{0} {1}", RulesetStrings.HeaderDescription, ($"{rInstance.Description}")); + ruleset.TooltipSub = LocalisableString.Format("{0} {1}", ToolbarStrings.RulesetHeaderDescription, ($"{rInstance.Description}")); ruleset.SetIcon(rInstance.CreateIcon()); } From 8b033bf9f79e50b6d752e1da867357ae21fe94bb Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 05:13:54 +0300 Subject: [PATCH 005/248] Allow localisable strings --- .../Visual/UserInterface/TestSceneCommentEditor.cs | 13 +++++++------ osu.Game/Overlays/Comments/CommentEditor.cs | 11 ++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 99e1702870..596518a015 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Localisation; using osu.Game.Overlays; using osu.Game.Overlays.Comments; using osuTK; @@ -121,15 +122,15 @@ namespace osu.Game.Tests.Visual.UserInterface Scheduler.AddDelayed(() => IsLoading = false, 1000); } - protected override string FooterText => @"Footer text. And it is pretty long. Cool."; - protected override string CommitButtonText => @"Commit"; - protected override string TextBoxPlaceholder => @"This text box is empty"; + protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; + protected override LocalisableString CommitButtonText => @"Commit"; + protected override LocalisableString TextBoxPlaceholder => @"This text box is empty"; } private partial class TestCancellableCommentEditor : CancellableCommentEditor { public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; - protected override string FooterText => @"Wow, another one. Sicc"; + protected override LocalisableString FooterText => @"Wow, another one. Sicc"; public bool Cancelled { get; private set; } @@ -138,8 +139,8 @@ namespace osu.Game.Tests.Visual.UserInterface OnCancel = () => Cancelled = true; } - protected override string CommitButtonText => @"Save"; - protected override string TextBoxPlaceholder => @"Multiline textboxes soon"; + protected override LocalisableString CommitButtonText => @"Save"; + protected override LocalisableString TextBoxPlaceholder => @"Multiline textboxes soon"; } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 72edd1877e..f79439452b 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -17,6 +17,7 @@ using System.Collections.Generic; using System; using osuTK; using osu.Framework.Bindables; +using osu.Framework.Localisation; namespace osu.Game.Overlays.Comments { @@ -32,11 +33,11 @@ namespace osu.Game.Overlays.Comments set => commitButton.IsLoading = value; } - protected abstract string FooterText { get; } + protected abstract LocalisableString FooterText { get; } - protected abstract string CommitButtonText { get; } + protected abstract LocalisableString CommitButtonText { get; } - protected abstract string TextBoxPlaceholder { get; } + protected abstract LocalisableString TextBoxPlaceholder { get; } protected FillFlowContainer ButtonsContainer { get; private set; } @@ -177,7 +178,7 @@ namespace osu.Game.Overlays.Comments protected override IEnumerable EffectTargets => new[] { background }; - private readonly string text; + private readonly LocalisableString text; [Resolved] private OverlayColourProvider colourProvider { get; set; } @@ -186,7 +187,7 @@ namespace osu.Game.Overlays.Comments private Box background; private Box blockedBackground; - public CommitButton(string text) + public CommitButton(LocalisableString text) { this.text = text; From d20dc3668ec790d3d0fea7ad85c8a52db60a305b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 05:17:44 +0300 Subject: [PATCH 006/248] Enable nullability --- .../UserInterface/TestSceneCommentEditor.cs | 8 +++---- .../Comments/CancellableCommentEditor.cs | 4 +--- osu.Game/Overlays/Comments/CommentEditor.cs | 22 +++++++++---------- 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 596518a015..e5fbb8c5d0 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -21,8 +19,8 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); - private TestCommentEditor commentEditor; - private TestCancellableCommentEditor cancellableCommentEditor; + private TestCommentEditor commentEditor = null!; + private TestCancellableCommentEditor cancellableCommentEditor = null!; [SetUp] public void SetUp() => Schedule(() => @@ -109,7 +107,7 @@ namespace osu.Game.Tests.Visual.UserInterface public new Bindable Current => base.Current; public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; - public string CommittedText { get; private set; } + public string? CommittedText { get; private set; } public TestCommentEditor() { diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 2b597d5638..8f6863b949 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Framework.Allocation; @@ -19,7 +17,7 @@ namespace osu.Game.Overlays.Comments { public abstract partial class CancellableCommentEditor : CommentEditor { - public Action OnCancel; + public Action? OnCancel; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index f79439452b..b7fc4f097c 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; @@ -25,7 +23,7 @@ namespace osu.Game.Overlays.Comments { private const int side_padding = 8; - public Action OnCommit; + public Action? OnCommit; public bool IsLoading { @@ -39,11 +37,11 @@ namespace osu.Game.Overlays.Comments protected abstract LocalisableString TextBoxPlaceholder { get; } - protected FillFlowContainer ButtonsContainer { get; private set; } + protected FillFlowContainer ButtonsContainer { get; private set; } = null!; protected readonly Bindable Current = new Bindable(); - private CommitButton commitButton; + private CommitButton commitButton = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -80,7 +78,7 @@ namespace osu.Game.Overlays.Comments }, new Container { - Name = "Footer", + Name = @"Footer", RelativeSizeAxes = Axes.X, Height = 35, Padding = new MarginPadding { Horizontal = side_padding }, @@ -95,7 +93,7 @@ namespace osu.Game.Overlays.Comments }, ButtonsContainer = new FillFlowContainer { - Name = "Buttons", + Name = @"Buttons", Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, @@ -140,7 +138,7 @@ namespace osu.Game.Overlays.Comments protected override Color4 SelectionColour => Color4.Gray; - private OsuSpriteText placeholder; + private OsuSpriteText placeholder = null!; public EditorTextBox() { @@ -181,11 +179,11 @@ namespace osu.Game.Overlays.Comments private readonly LocalisableString text; [Resolved] - private OverlayColourProvider colourProvider { get; set; } + private OverlayColourProvider colourProvider { get; set; } = null!; - private OsuSpriteText drawableText; - private Box background; - private Box blockedBackground; + private OsuSpriteText drawableText = null!; + private Box background = null!; + private Box blockedBackground = null!; public CommitButton(LocalisableString text) { From 25ddd20b2e2195ae209baa52d83b7a209377a134 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 05:44:40 +0300 Subject: [PATCH 007/248] Allow OsuButton be auto-sized --- osu.Game/Graphics/UserInterface/OsuButton.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index fa61b06cff..69e8dfef84 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -175,6 +175,17 @@ namespace osu.Game.Graphics.UserInterface base.OnMouseUp(e); } + public new Axes AutoSizeAxes + { + get => base.AutoSizeAxes; + set + { + base.AutoSizeAxes = value; + Content.RelativeSizeAxes = ~value; + Content.AutoSizeAxes = value; + } + } + protected virtual SpriteText CreateText() => new OsuSpriteText { Depth = -1, From a874345da04f513ba14b17978b3236debf34e32b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 05:46:30 +0300 Subject: [PATCH 008/248] Rebase CancelButton to RoundedButton --- .../Comments/CancellableCommentEditor.cs | 50 +++++-------------- 1 file changed, 12 insertions(+), 38 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 8f6863b949..499c158ccd 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -2,15 +2,12 @@ // 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.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; 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.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -30,45 +27,22 @@ namespace osu.Game.Overlays.Comments }); } - private partial class CancelButton : OsuHoverContainer + private sealed partial class CancelButton : RoundedButton { - protected override IEnumerable EffectTargets => new[] { background }; - - private readonly Box background; - public CancelButton() - : base(HoverSampleSet.Button) { - AutoSizeAxes = Axes.Both; - Child = new CircularContainer - { - Masking = true, - Height = 25, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both - }, - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Margin = new MarginPadding { Horizontal = 20 }, - Text = CommonStrings.ButtonsCancel - } - } - }; + Height = 25; + AutoSizeAxes = Axes.X; } - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + protected override SpriteText CreateText() => new OsuSpriteText { - IdleColour = colourProvider.Light4; - HoverColour = colourProvider.Light3; - } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Margin = new MarginPadding { Horizontal = 20 }, + Text = CommonStrings.ButtonsCancel + }; } } } From 894fb98fa25092af9e614408090c66e87576287c Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 06:17:02 +0300 Subject: [PATCH 009/248] Rebase CommitButton to RoundedButton --- osu.Game/Overlays/Comments/CommentEditor.cs | 124 +++++++++----------- 1 file changed, 57 insertions(+), 67 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index b7fc4f097c..0dbcf0ff03 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -11,11 +11,12 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.Sprites; using osuTK.Graphics; using osu.Game.Graphics.UserInterface; -using System.Collections.Generic; using System; using osuTK; using osu.Framework.Bindables; +using osu.Framework.Input.Events; using osu.Framework.Localisation; +using osu.Game.Graphics.UserInterfaceV2; namespace osu.Game.Overlays.Comments { @@ -99,8 +100,9 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(5, 0), - Child = commitButton = new CommitButton(CommitButtonText) + Child = commitButton = new CommitButton { + Text = CommitButtonText, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Action = () => @@ -118,7 +120,7 @@ namespace osu.Game.Overlays.Comments textBox.OnCommit += (_, _) => { - if (commitButton.IsBlocked.Value) + if (commitButton.IsLoading) return; commitButton.TriggerClick(); @@ -166,84 +168,72 @@ namespace osu.Game.Overlays.Comments }; } - private partial class CommitButton : LoadingButton + private sealed partial class CommitButton : RoundedButton { private const int duration = 200; - + private bool isLoading; + private readonly LoadingSpinner spinner; public readonly BindableBool IsBlocked = new BindableBool(); + private OsuSpriteText text = null!; - public override bool PropagatePositionalInputSubTree => !IsBlocked.Value && base.PropagatePositionalInputSubTree; - - protected override IEnumerable EffectTargets => new[] { background }; - - private readonly LocalisableString text; - - [Resolved] - private OverlayColourProvider colourProvider { get; set; } = null!; - - private OsuSpriteText drawableText = null!; - private Box background = null!; - private Box blockedBackground = null!; - - public CommitButton(LocalisableString text) + public CommitButton() { - this.text = text; - - AutoSizeAxes = Axes.Both; - LoadingAnimationSize = new Vector2(10); - } - - [BackgroundDependencyLoader] - private void load() - { - IdleColour = colourProvider.Light4; - HoverColour = colourProvider.Light3; - blockedBackground.Colour = colourProvider.Background5; + Height = 25; + AutoSizeAxes = Axes.X; + Add(spinner = new LoadingSpinner + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(12), + Depth = -2, + }); } protected override void LoadComplete() { base.LoadComplete(); - IsBlocked.BindValueChanged(onBlockedStateChanged, true); - } - - private void onBlockedStateChanged(ValueChangedEvent isBlocked) - { - drawableText.FadeColour(isBlocked.NewValue ? colourProvider.Foreground1 : Color4.White, duration, Easing.OutQuint); - background.FadeTo(isBlocked.NewValue ? 0 : 1, duration, Easing.OutQuint); - } - - protected override Drawable CreateContent() => new CircularContainer - { - Masking = true, - Height = 25, - AutoSizeAxes = Axes.X, - Children = new Drawable[] + IsBlocked.BindValueChanged(e => { - blockedBackground = new Box - { - RelativeSizeAxes = Axes.Both - }, - background = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0 - }, - drawableText = new OsuSpriteText - { - AlwaysPresent = true, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Margin = new MarginPadding { Horizontal = 20 }, - Text = text, - } - } + Enabled.Value = !IsLoading && !e.NewValue; + }, true); + } + + protected override SpriteText CreateText() => text = new OsuSpriteText + { + AlwaysPresent = true, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Margin = new MarginPadding { Horizontal = 20 }, }; - protected override void OnLoadStarted() => drawableText.FadeOut(duration, Easing.OutQuint); + public bool IsLoading + { + get => isLoading; + set + { + isLoading = value; + Enabled.Value = !value && !IsBlocked.Value; + spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); + text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); + } + } - protected override void OnLoadFinished() => drawableText.FadeIn(duration, Easing.OutQuint); + protected override bool OnClick(ClickEvent e) + { + if (!Enabled.Value) + return false; + + try + { + return base.OnClick(e); + } + finally + { + // run afterwards as this will disable this button. + IsLoading = true; + } + } } } } From af0ee9dbd65f37fa867bce18395324ce5400f5da Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 06:19:54 +0300 Subject: [PATCH 010/248] Make spinner a little bigger --- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 0dbcf0ff03..862b131cea 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(12), + Size = new Vector2(14), Depth = -2, }); } From 472d9274b6d8ccc5846f3f7c91fcffa2ef1f9474 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 06:23:25 +0300 Subject: [PATCH 011/248] Reorder members --- osu.Game/Overlays/Comments/CommentEditor.cs | 31 +++++++++++---------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 862b131cea..784aa33ed9 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -171,11 +171,26 @@ namespace osu.Game.Overlays.Comments private sealed partial class CommitButton : RoundedButton { private const int duration = 200; - private bool isLoading; + private readonly LoadingSpinner spinner; - public readonly BindableBool IsBlocked = new BindableBool(); private OsuSpriteText text = null!; + public readonly BindableBool IsBlocked = new BindableBool(); + + private bool isLoading; + + public bool IsLoading + { + get => isLoading; + set + { + isLoading = value; + Enabled.Value = !value && !IsBlocked.Value; + spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); + text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); + } + } + public CommitButton() { Height = 25; @@ -207,18 +222,6 @@ namespace osu.Game.Overlays.Comments Margin = new MarginPadding { Horizontal = 20 }, }; - public bool IsLoading - { - get => isLoading; - set - { - isLoading = value; - Enabled.Value = !value && !IsBlocked.Value; - spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); - text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); - } - } - protected override bool OnClick(ClickEvent e) { if (!Enabled.Value) From cfffe5f00272fd453817db9bf20664e669c745c2 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 14:20:38 +0300 Subject: [PATCH 012/248] Avoid null string --- osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index e5fbb8c5d0..aa55cf9930 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); - AddAssert("no text committed", () => commentEditor.CommittedText == null); + AddAssert("no text committed", () => commentEditor.CommittedText.Length == 0); AddAssert("button is not loading", () => !commentEditor.IsLoading); } @@ -107,7 +107,7 @@ namespace osu.Game.Tests.Visual.UserInterface public new Bindable Current => base.Current; public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; - public string? CommittedText { get; private set; } + public string CommittedText { get; private set; } = string.Empty; public TestCommentEditor() { From 6c126f5223d8a3b523019af48bf0bb6ac92fce18 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 14:25:51 +0300 Subject: [PATCH 013/248] Remove useless local actions on click --- .../UserInterface/TestSceneCommentEditor.cs | 1 + osu.Game/Overlays/Comments/CommentEditor.cs | 17 ----------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index aa55cf9930..fd124f676f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -116,6 +116,7 @@ namespace osu.Game.Tests.Visual.UserInterface private void onCommit(string value) { + IsLoading = true; CommittedText = value; Scheduler.AddDelayed(() => IsLoading = false, 1000); } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 784aa33ed9..ec112b8547 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -14,7 +14,6 @@ using osu.Game.Graphics.UserInterface; using System; using osuTK; using osu.Framework.Bindables; -using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterfaceV2; @@ -221,22 +220,6 @@ namespace osu.Game.Overlays.Comments Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), Margin = new MarginPadding { Horizontal = 20 }, }; - - protected override bool OnClick(ClickEvent e) - { - if (!Enabled.Value) - return false; - - try - { - return base.OnClick(e); - } - finally - { - // run afterwards as this will disable this button. - IsLoading = true; - } - } } } } From 84aaf5fedf9bccc3ee712acffb04f0cc133b33d4 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 14:37:35 +0300 Subject: [PATCH 014/248] Change ways to access submit button state --- .../UserInterface/TestSceneCommentEditor.cs | 10 ++++---- osu.Game/Overlays/Comments/CommentEditor.cs | 23 +++++++++---------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index fd124f676f..81cc5c9572 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); AddAssert("text committed", () => commentEditor.CommittedText == "text"); - AddAssert("button is loading", () => commentEditor.IsLoading); + AddAssert("button is loading", () => commentEditor.IsSubmitting); } [Test] @@ -67,7 +67,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); AddAssert("no text committed", () => commentEditor.CommittedText.Length == 0); - AddAssert("button is not loading", () => !commentEditor.IsLoading); + AddAssert("button is not loading", () => !commentEditor.IsSubmitting); } [Test] @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddAssert("text committed", () => commentEditor.CommittedText == "some other text"); - AddAssert("button is loading", () => commentEditor.IsLoading); + AddAssert("button is loading", () => commentEditor.IsSubmitting); } [Test] @@ -116,9 +116,9 @@ namespace osu.Game.Tests.Visual.UserInterface private void onCommit(string value) { - IsLoading = true; + CommitButton.IsLoading = true; CommittedText = value; - Scheduler.AddDelayed(() => IsLoading = false, 1000); + Scheduler.AddDelayed(() => CommitButton.IsLoading = false, 1000); } protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index ec112b8547..8e95975139 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -25,11 +25,10 @@ namespace osu.Game.Overlays.Comments public Action? OnCommit; - public bool IsLoading - { - get => commitButton.IsLoading; - set => commitButton.IsLoading = value; - } + /// + /// Is the editor waiting for submit action to complete? + /// + public bool IsSubmitting => CommitButton.IsLoading; protected abstract LocalisableString FooterText { get; } @@ -41,7 +40,7 @@ namespace osu.Game.Overlays.Comments protected readonly Bindable Current = new Bindable(); - private CommitButton commitButton = null!; + protected EditorCommitButton CommitButton = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -99,7 +98,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(5, 0), - Child = commitButton = new CommitButton + Child = CommitButton = new EditorCommitButton { Text = CommitButtonText, Anchor = Anchor.CentreRight, @@ -119,10 +118,10 @@ namespace osu.Game.Overlays.Comments textBox.OnCommit += (_, _) => { - if (commitButton.IsLoading) + if (CommitButton.IsLoading) return; - commitButton.TriggerClick(); + CommitButton.TriggerClick(); }; } @@ -130,7 +129,7 @@ namespace osu.Game.Overlays.Comments { base.LoadComplete(); - Current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); + Current.BindValueChanged(text => CommitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } private partial class EditorTextBox : BasicTextBox @@ -167,7 +166,7 @@ namespace osu.Game.Overlays.Comments }; } - private sealed partial class CommitButton : RoundedButton + protected sealed partial class EditorCommitButton : RoundedButton { private const int duration = 200; @@ -190,7 +189,7 @@ namespace osu.Game.Overlays.Comments } } - public CommitButton() + public EditorCommitButton() { Height = 25; AutoSizeAxes = Axes.X; From e30d97c94e4bd2c163046cdfbcfc192424cfe149 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Tue, 29 Nov 2022 14:39:59 +0300 Subject: [PATCH 015/248] Comments --- osu.Game/Overlays/Comments/CommentEditor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 8e95975139..be196c2085 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Comments public Action? OnCommit; /// - /// Is the editor waiting for submit action to complete? + /// Whether editor is waiting for submit action to complete. /// public bool IsSubmitting => CommitButton.IsLoading; @@ -177,6 +177,9 @@ namespace osu.Game.Overlays.Comments private bool isLoading; + /// + /// Whether loading spinner shown. + /// public bool IsLoading { get => isLoading; From 956acbc86fd148d73e273f71ff7761b1e1c4bf63 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:11:54 +0300 Subject: [PATCH 016/248] Use fixed width --- osu.Game/Overlays/Comments/CancellableCommentEditor.cs | 2 +- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 499c158ccd..b22a9d6c6c 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -31,8 +31,8 @@ namespace osu.Game.Overlays.Comments { public CancelButton() { + Width = 90; Height = 25; - AutoSizeAxes = Axes.X; } protected override SpriteText CreateText() => new OsuSpriteText diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index be196c2085..9755f45036 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -194,8 +194,8 @@ namespace osu.Game.Overlays.Comments public EditorCommitButton() { + Width = 90; Height = 25; - AutoSizeAxes = Axes.X; Add(spinner = new LoadingSpinner { Anchor = Anchor.Centre, From f4a8ac60a8c2643e1008e40477998f8563b44a4d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:12:10 +0300 Subject: [PATCH 017/248] Revert autosizing in OsuButton --- osu.Game/Graphics/UserInterface/OsuButton.cs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuButton.cs b/osu.Game/Graphics/UserInterface/OsuButton.cs index 69e8dfef84..fa61b06cff 100644 --- a/osu.Game/Graphics/UserInterface/OsuButton.cs +++ b/osu.Game/Graphics/UserInterface/OsuButton.cs @@ -175,17 +175,6 @@ namespace osu.Game.Graphics.UserInterface base.OnMouseUp(e); } - public new Axes AutoSizeAxes - { - get => base.AutoSizeAxes; - set - { - base.AutoSizeAxes = value; - Content.RelativeSizeAxes = ~value; - Content.AutoSizeAxes = value; - } - } - protected virtual SpriteText CreateText() => new OsuSpriteText { Depth = -1, From 642e0ac718ed41d8400c4b3c53fbf4a15403574f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:25:18 +0300 Subject: [PATCH 018/248] Increase footer height to look better with default buttons --- osu.Game/Overlays/Comments/CommentEditor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 9755f45036..bb2d42b8c2 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.Comments { Name = @"Footer", RelativeSizeAxes = Axes.X, - Height = 35, + Height = 40, Padding = new MarginPadding { Horizontal = side_padding }, Children = new Drawable[] { @@ -87,7 +87,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), + Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), Text = FooterText }, ButtonsContainer = new FillFlowContainer From 5ea824534b9688cb412969acf48e03613fcc738a Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:25:59 +0300 Subject: [PATCH 019/248] Use default button --- .../Comments/CancellableCommentEditor.cs | 28 ++++--------------- osu.Game/Overlays/Comments/CommentEditor.cs | 13 ++------- 2 files changed, 7 insertions(+), 34 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index b22a9d6c6c..7418ba344b 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -4,9 +4,6 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Resources.Localisation.Web; @@ -19,30 +16,15 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load() { - ButtonsContainer.Add(new CancelButton + ButtonsContainer.Add(new RoundedButton { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Action = () => OnCancel?.Invoke() + Action = () => OnCancel?.Invoke(), + Text = CommonStrings.ButtonsCancel, + Width = 100, + Height = 30, }); } - - private sealed partial class CancelButton : RoundedButton - { - public CancelButton() - { - Width = 90; - Height = 25; - } - - protected override SpriteText CreateText() => new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Margin = new MarginPadding { Horizontal = 20 }, - Text = CommonStrings.ButtonsCancel - }; - } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index bb2d42b8c2..c9e1f6d224 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -194,8 +194,8 @@ namespace osu.Game.Overlays.Comments public EditorCommitButton() { - Width = 90; - Height = 25; + Width = 100; + Height = 30; Add(spinner = new LoadingSpinner { Anchor = Anchor.Centre, @@ -213,15 +213,6 @@ namespace osu.Game.Overlays.Comments Enabled.Value = !IsLoading && !e.NewValue; }, true); } - - protected override SpriteText CreateText() => text = new OsuSpriteText - { - AlwaysPresent = true, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Margin = new MarginPadding { Horizontal = 20 }, - }; } } } From f0922d34bb4e1a69df7af0ee34d0a1171f47e2fb Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:30:00 +0300 Subject: [PATCH 020/248] Fix cancel test failure --- osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 81cc5c9572..61c3fc54ad 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -95,7 +95,7 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("click cancel button", () => { - InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); + InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer[1]); InputManager.Click(MouseButton.Left); }); From a8422961dc1ae152bd50ca1583326ba82cd09c20 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:30:57 +0300 Subject: [PATCH 021/248] Rename button spinner prop again --- .../UserInterface/TestSceneCommentEditor.cs | 4 ++-- osu.Game/Overlays/Comments/CommentEditor.cs | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 61c3fc54ad..43dcba99df 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -116,9 +116,9 @@ namespace osu.Game.Tests.Visual.UserInterface private void onCommit(string value) { - CommitButton.IsLoading = true; + CommitButton.IsLoadingSpinnerShown = true; CommittedText = value; - Scheduler.AddDelayed(() => CommitButton.IsLoading = false, 1000); + Scheduler.AddDelayed(() => CommitButton.IsLoadingSpinnerShown = false, 1000); } protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index c9e1f6d224..458b4b2a2d 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Comments /// /// Whether editor is waiting for submit action to complete. /// - public bool IsSubmitting => CommitButton.IsLoading; + public bool IsSubmitting => CommitButton.IsLoadingSpinnerShown; protected abstract LocalisableString FooterText { get; } @@ -118,7 +118,7 @@ namespace osu.Game.Overlays.Comments textBox.OnCommit += (_, _) => { - if (CommitButton.IsLoading) + if (CommitButton.IsLoadingSpinnerShown) return; CommitButton.TriggerClick(); @@ -171,21 +171,21 @@ namespace osu.Game.Overlays.Comments private const int duration = 200; private readonly LoadingSpinner spinner; - private OsuSpriteText text = null!; + private readonly OsuSpriteText text = null!; public readonly BindableBool IsBlocked = new BindableBool(); - private bool isLoading; + private bool isLoadingSpinnerShown; /// /// Whether loading spinner shown. /// - public bool IsLoading + public bool IsLoadingSpinnerShown { - get => isLoading; + get => isLoadingSpinnerShown; set { - isLoading = value; + isLoadingSpinnerShown = value; Enabled.Value = !value && !IsBlocked.Value; spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); @@ -210,7 +210,7 @@ namespace osu.Game.Overlays.Comments base.LoadComplete(); IsBlocked.BindValueChanged(e => { - Enabled.Value = !IsLoading && !e.NewValue; + Enabled.Value = !IsLoadingSpinnerShown && !e.NewValue; }, true); } } From bedc771e9988584312d1e02356a7d300095c563a Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:32:01 +0300 Subject: [PATCH 022/248] Remove useless check --- osu.Game/Overlays/Comments/CommentEditor.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 458b4b2a2d..eb74b7dd38 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -116,13 +116,7 @@ namespace osu.Game.Overlays.Comments } }); - textBox.OnCommit += (_, _) => - { - if (CommitButton.IsLoadingSpinnerShown) - return; - - CommitButton.TriggerClick(); - }; + textBox.OnCommit += (_, _) => CommitButton.TriggerClick(); } protected override void LoadComplete() From 1cc7ffce39e83cf78deeb2e62dd0b77cecd597ad Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:40:47 +0300 Subject: [PATCH 023/248] Keep button's text --- osu.Game/Overlays/Comments/CommentEditor.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index eb74b7dd38..b101eaa427 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -165,7 +165,7 @@ namespace osu.Game.Overlays.Comments private const int duration = 200; private readonly LoadingSpinner spinner; - private readonly OsuSpriteText text = null!; + private SpriteText text = null!; public readonly BindableBool IsBlocked = new BindableBool(); @@ -207,6 +207,11 @@ namespace osu.Game.Overlays.Comments Enabled.Value = !IsLoadingSpinnerShown && !e.NewValue; }, true); } + + protected override SpriteText CreateText() + { + return text = base.CreateText(); + } } } } From 43628903a7ec896de1ed47779fee79cfc409e301 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:57:09 +0300 Subject: [PATCH 024/248] Make spinner bigger --- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index b101eaa427..3ca5941e7c 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -194,7 +194,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(14), + Size = new Vector2(16), Depth = -2, }); } From 1763618488a0ca76327a3013668db928c87a1c63 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 30 Nov 2022 13:58:03 +0300 Subject: [PATCH 025/248] Fix spinner presense check & field click --- .../UserInterface/TestSceneCommentEditor.cs | 21 +++++++++++++------ osu.Game/Overlays/Comments/CommentEditor.cs | 5 ----- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 43dcba99df..a0a1c2481f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -1,12 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.Comments; using osuTK; @@ -44,15 +49,16 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("click on text box", () => { - InputManager.MoveMouseTo(commentEditor); + InputManager.MoveMouseTo(commentEditor.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); AddStep("enter text", () => commentEditor.Current.Value = "text"); AddStep("press Enter", () => InputManager.Key(Key.Enter)); + AddUntilStep("button is loading", () => commentEditor.ButtonLoading); AddAssert("text committed", () => commentEditor.CommittedText == "text"); - AddAssert("button is loading", () => commentEditor.IsSubmitting); + AddUntilStep("button is not loading", () => !commentEditor.ButtonLoading); } [Test] @@ -60,14 +66,14 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("click on text box", () => { - InputManager.MoveMouseTo(commentEditor); + InputManager.MoveMouseTo(commentEditor.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); AddStep("press Enter", () => InputManager.Key(Key.Enter)); + AddAssert("button is not loading", () => !commentEditor.ButtonLoading); AddAssert("no text committed", () => commentEditor.CommittedText.Length == 0); - AddAssert("button is not loading", () => !commentEditor.IsSubmitting); } [Test] @@ -75,7 +81,7 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("click on text box", () => { - InputManager.MoveMouseTo(commentEditor); + InputManager.MoveMouseTo(commentEditor.ChildrenOfType().Single()); InputManager.Click(MouseButton.Left); }); AddStep("enter text", () => commentEditor.Current.Value = "some other text"); @@ -86,8 +92,9 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); + AddUntilStep("button is loading", () => commentEditor.ButtonLoading); AddAssert("text committed", () => commentEditor.CommittedText == "some other text"); - AddAssert("button is loading", () => commentEditor.IsSubmitting); + AddUntilStep("button is not loading", () => !commentEditor.ButtonLoading); } [Test] @@ -109,6 +116,8 @@ namespace osu.Game.Tests.Visual.UserInterface public string CommittedText { get; private set; } = string.Empty; + public bool ButtonLoading => CommitButton.ChildrenOfType().Single().IsPresent && !CommitButton.ChildrenOfType().Single().IsPresent; + public TestCommentEditor() { OnCommit = onCommit; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 3ca5941e7c..092a92f935 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -25,11 +25,6 @@ namespace osu.Game.Overlays.Comments public Action? OnCommit; - /// - /// Whether editor is waiting for submit action to complete. - /// - public bool IsSubmitting => CommitButton.IsLoadingSpinnerShown; - protected abstract LocalisableString FooterText { get; } protected abstract LocalisableString CommitButtonText { get; } From b6a6db1160342731d21f0da0645f1d0303461214 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 12:29:23 +0100 Subject: [PATCH 026/248] Add dynamic BPM counter to SkinEditor --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 52 +++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 osu.Game/Screens/Play/HUD/BPMCounter.cs diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs new file mode 100644 index 0000000000..fec36f915d --- /dev/null +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -0,0 +1,52 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Localisation; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Skinning; + +namespace osu.Game.Screens.Play.HUD +{ + public partial class BPMCounter : RollingCounter, ISkinnableDrawable + { + [Resolved] + private IBindable beatmap { get; set; } = null!; + + [Resolved] + protected IGameplayClock GameplayClock { get; private set; } = null!; + + [BackgroundDependencyLoader] + private void load(OsuColour colour) + { + Colour = colour.BlueLighter; + Current.Value = DisplayedCount = 0; + } + + protected override void Update() + { + base.Update(); + + //We dont want it going to 0 when we pause. so we block the updates + if (GameplayClock.IsPaused.Value) return; + + // We want to check Rate every update to cover windup/down + Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(GameplayClock.CurrentTime).BPM * GameplayClock.Rate; + } + + protected override OsuSpriteText CreateSpriteText() + => base.CreateSpriteText().With(s => s.Font = s.Font.With(size: 20f, fixedWidth: true)); + + protected override LocalisableString FormatCount(double count) + { + return $@"{count:0} BPM"; + } + + public bool UsesFixedAnchor { get; set; } + } +} From f69c08496931804c47c50a8197996383087547df Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 17:08:00 +0100 Subject: [PATCH 027/248] Add roll duration --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index fec36f915d..83569c13d9 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -15,6 +15,8 @@ namespace osu.Game.Screens.Play.HUD { public partial class BPMCounter : RollingCounter, ISkinnableDrawable { + protected override double RollingDuration => 750; + [Resolved] private IBindable beatmap { get; set; } = null!; From 9eef74b8d89ed7f8125af41be3e7dba840cd5f73 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 5 Dec 2022 19:34:03 +0100 Subject: [PATCH 028/248] Add new counter to skin deserialisation test --- .../Archives/modified-default-20221205.osk | Bin 0 -> 1644 bytes osu.Game.Tests/Skins/SkinDeserialisationTest.cs | 4 +++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Resources/Archives/modified-default-20221205.osk diff --git a/osu.Game.Tests/Resources/Archives/modified-default-20221205.osk b/osu.Game.Tests/Resources/Archives/modified-default-20221205.osk new file mode 100644 index 0000000000000000000000000000000000000000..ae421fc323baa8b1931a18e06e4d368adeb41352 GIT binary patch literal 1644 zcmWIWW@Zs#U|`^2csRQ?bn^awlY>BB5Hm=GfuT4%GfyuwFY{@?VHcC5fa_;F*O{7Y z&iNc}njtw;a_2;eDPg^4W#OLwrp@WM6Z*G=2M8(~#$S7L_;<~}-+%wD)QXUmi0Tde ztx$bqr9`)5zifh`Z$@If;XKC9841;FZ%;9-coJ>9WOCZ?2Hmpo6->DuIx{3z-PR~< zJJQzDCcHgvL&32fg{QNV%jBh^_%wc>xXaPzskx;w^U1TLe6!L&sJdT_oAZ0Mf8yVc z-1uywCWCZVC!GrLPwnazR7$l+PLO^PalbLN1&*>wnVcw2$w_kd8LP z(%_)WLf*w*CA~a7Jv=%*x=Dp6B&8&z9!@bfGUyGx#2EQ5X3DIHN%1V3>`nBo_4nKG zE4`Z;9y4i1_@tQ;lV;9;K6Cms{?di>tS@Y>I(TztW#!DumsN@e*PC2QL=w2B?8st7 zbvdKo73JrQ3=E+H3=CpGm-{AW=6Qs=IOpdUVBAW9GiaCw#S|&IoJEk%(o1>I~fDSL??x26q>phM{Ew-74tr?be;Fp11*l$ zHaz>9H#)7BbnEw*cv4r8nXqg@N!v*SjZ@K@Kg3t)eU)7?Q){VA`|mfc+YbG_S;zYO zYsK4x=1NivIgia~TN_n5^$3UkwtBP6`dgCEezE!*7gMD6(DT5y-JGJON^`aLU0wFh zL;C4#LFqvEb5ajaHT_kQODL7top#A-w&)z;tmM~6axc_qKRM+f`{Y;J6_ww?@4VOX zemN>zZXjsG^0C=S;8XB9@52>W#lKFzo>K1A*1DfT?QWUgo4xN}-2Gtt!}hh1{4eIk zSC<)7B_Fu8{lsh)f1P^Ihvj30V_@ZZ~@>AVQ{RPwiIsWwjzx0d$y!^Uf zSs%m`uHAYw<557y!a1_5R(J|Mc^@@r&*DRB-_N{TbH7owU~Smlviw#)Ux8juRoR9} znTHlj_3sEY3HfODK7RaaW$65B13s_&vp-*rKaf!U@8Br|ujPfa6D-w%ew)p(B{Bl2rwO;Voi)Z4fNuyD!{zNq}X*^(IVBiNPjo|#e z^x)K-)Z`Lynm8I9n|;VYr1pDwO6@zRTVGB$@@w6eJ2vA?p8g}}wdH0r)RuZW3jY5c zlxwclY-ld2$p2l%@_CWpyEW|>&gHbMsfcbUZPr<-RWtud!}4r37GZ6hX_bns9BV&t z2+dVL8t{6Ot`@Ih&X(R=>Sk4~L57-aEb`NOkBMFn3vsjsGqZ`LW`W`=;U=f$H{l&EfbuG28E+4RM_}%t6^3{@uE57zW zF!8mRvq?zii}S0X?T2qIh-)v=xa2eK*_QhZ{;JU%qYiUQKXGl`l`I`mcc<2SN7FXO z3%4v*zLJZ&RCw&irj}W$X75dt>`yNG_HUYVURSrfgW=a2p&eV2uWfyv_)2L01!Loa zTaVi=T#1){KgqseU+AS{J8s>L2+M3MVbe%WJ>?i1Df=~E{fqu(p;`JeErI0`ix{k* zt*=gh=Ca{Ed!9tay^|Yc9)4(g{7Et@?t_cG&;4Gt{^~6npYlJwI(r|Og&CPd7;u-e zz{rAtMi2!nbJ2C77g|s~3=ECWp}OEj7`j&UQUjrNAuz#UFGJAHKu=x>Gxh*03$(-* T;LXYgQosU)pMZ1 From 4ab7ef9af9ca0eae3b6b47c26de162d59dde16e5 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Mon, 5 Dec 2022 15:12:50 -0500 Subject: [PATCH 029/248] Show distance snap for first juice stream object. Fixes #18469 --- osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index bbdffbf39c..fbe897b484 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -188,7 +188,8 @@ namespace osu.Game.Rulesets.Catch.Edit if (EditorBeatmap.PlacementObject.Value is JuiceStream) { // Juice stream path is not subject to snapping. - return null; + if (((JuiceStream)EditorBeatmap.PlacementObject.Value).Distance != 0) + return null; } double timeAtCursor = ((CatchPlayfield)Playfield).TimeAtScreenSpacePosition(inputManager.CurrentState.Mouse.Position); From fc630165fd612baa3043ff35d50651c5c8ed5d09 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Tue, 6 Dec 2022 15:08:21 +0100 Subject: [PATCH 030/248] Adjust formatting of BPM text --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 46 ++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index 83569c13d9..8d3cab40b0 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -4,12 +4,15 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Skinning; +using osuTK; namespace osu.Game.Screens.Play.HUD { @@ -46,7 +49,48 @@ namespace osu.Game.Screens.Play.HUD protected override LocalisableString FormatCount(double count) { - return $@"{count:0} BPM"; + return $@"{count:0}"; + } + + protected override IHasText CreateText() => new TextComponent(); + + private partial class TextComponent : CompositeDrawable, IHasText + { + public LocalisableString Text + { + get => text.Text; + set => text.Text = value; + } + + private readonly OsuSpriteText text; + + public TextComponent() + { + AutoSizeAxes = Axes.Both; + + InternalChild = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(2), + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.Numeric.With(size: 16, fixedWidth: true) + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.Numeric.With(size: 8, fixedWidth: true), + Text = @"BPM", + Padding = new MarginPadding { Bottom = 1.5f }, // align baseline better + } + } + }; + } } public bool UsesFixedAnchor { get; set; } From cd46ca31f9af73541e05f515018847a588b52775 Mon Sep 17 00:00:00 2001 From: OliBomby Date: Wed, 7 Dec 2022 09:51:22 +0100 Subject: [PATCH 031/248] Add segmend end completions to SliderPath --- osu.Game/Rulesets/Objects/SliderPath.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index ddc121eb5b..46c41f0b5a 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -41,6 +41,7 @@ namespace osu.Game.Rulesets.Objects private readonly List calculatedPath = new List(); private readonly List cumulativeLength = new List(); + private readonly List segmentEnds = new List(); private readonly Cached pathCache = new Cached(); private double calculatedLength; @@ -191,6 +192,16 @@ namespace osu.Game.Rulesets.Objects return pointsInCurrentSegment; } + /// + /// Returns the progress values at which segments of the path end. + /// + public IEnumerable GetSegmentEnds() + { + ensureValid(); + + return segmentEnds.Select(i => cumulativeLength[i] / calculatedLength); + } + private void invalidate() { pathCache.Invalidate(); @@ -211,6 +222,7 @@ namespace osu.Game.Rulesets.Objects private void calculatePath() { calculatedPath.Clear(); + segmentEnds.Clear(); if (ControlPoints.Count == 0) return; @@ -236,6 +248,9 @@ namespace osu.Game.Rulesets.Objects calculatedPath.Add(t); } + // Remember the index of the segment end + segmentEnds.Add(calculatedPath.Count - 1); + // Start the new segment at the current vertex start = i; } From 98a312ca9661c8d6a61141a4be57265a93b79a2a Mon Sep 17 00:00:00 2001 From: OliBomby Date: Thu, 3 Nov 2022 15:16:31 +0100 Subject: [PATCH 032/248] Fix segmentEnds incorrect on shortened paths --- osu.Game/Rulesets/Objects/SliderPath.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index 46c41f0b5a..2340cbd6c3 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -316,6 +316,10 @@ namespace osu.Game.Rulesets.Objects { cumulativeLength.RemoveAt(cumulativeLength.Count - 1); calculatedPath.RemoveAt(pathEndIndex--); + + // Shorten the last segment to the expected distance + if (segmentEnds.Count > 0) + segmentEnds[^1]--; } } From b06a7daf26e3656e10346b2059aa0800bab00cdb Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Tue, 20 Dec 2022 23:40:00 +0000 Subject: [PATCH 033/248] append date to score export filename --- osu.Game/Scoring/ScoreInfoExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Scoring/ScoreInfoExtensions.cs b/osu.Game/Scoring/ScoreInfoExtensions.cs index 7979ca8aaa..3cfdbe87c3 100644 --- a/osu.Game/Scoring/ScoreInfoExtensions.cs +++ b/osu.Game/Scoring/ScoreInfoExtensions.cs @@ -12,6 +12,6 @@ namespace osu.Game.Scoring /// /// A user-presentable display title representing this score. /// - public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()}"; + public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()} ({scoreInfo.Date.LocalDateTime:yyyy-MM-dd})"; } } From 498d00935bff763f0d5a7fcb5344f177e510ddb6 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Fri, 23 Dec 2022 23:01:04 +0000 Subject: [PATCH 034/248] limit date appending to `LegacyScoreExporter` only --- osu.Game/Database/LegacyExporter.cs | 2 +- osu.Game/Database/LegacyScoreExporter.cs | 20 ++++++++++++++++++++ osu.Game/Scoring/ScoreInfoExtensions.cs | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 374f9f557a..02219c4dfa 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Database /// Exports an item to a legacy (.zip based) package. /// /// The item to export. - public void Export(TModel item) + public virtual void Export(TModel item) { string itemFilename = item.GetDisplayString().GetValidFilename(); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 6fa02b957d..fc80693765 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -3,11 +3,13 @@ #nullable disable +using System.Collections.Generic; using System.IO; using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Scoring; +using osu.Game.Utils; namespace osu.Game.Database { @@ -15,9 +17,27 @@ namespace osu.Game.Database { protected override string FileExtension => ".osr"; + private readonly Storage exportStorage; + public LegacyScoreExporter(Storage storage) : base(storage) { + exportStorage = storage.GetStorageForDirectory(@"exports"); + } + + private string GetScoreExportString(ScoreInfo score) => $"{score.GetDisplayString()} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + + public override void Export(ScoreInfo score) + { + string scoreExportTitle = GetScoreExportString(score).GetValidFilename(); + + IEnumerable existingExports = exportStorage.GetFiles("", $"{scoreExportTitle}*{FileExtension}"); + + string scoreExportFilename = NamingUtils.GetNextBestFilename(existingExports, $"{scoreExportTitle}{FileExtension}"); + using (var stream = exportStorage.CreateFileSafely(scoreExportFilename)) + ExportModelTo(score, stream); + + exportStorage.PresentFileExternally(scoreExportFilename); } public override void ExportModelTo(ScoreInfo model, Stream outputStream) diff --git a/osu.Game/Scoring/ScoreInfoExtensions.cs b/osu.Game/Scoring/ScoreInfoExtensions.cs index 3cfdbe87c3..7979ca8aaa 100644 --- a/osu.Game/Scoring/ScoreInfoExtensions.cs +++ b/osu.Game/Scoring/ScoreInfoExtensions.cs @@ -12,6 +12,6 @@ namespace osu.Game.Scoring /// /// A user-presentable display title representing this score. /// - public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()} ({scoreInfo.Date.LocalDateTime:yyyy-MM-dd})"; + public static string GetDisplayTitle(this IScoreInfo scoreInfo) => $"{scoreInfo.User.Username} playing {scoreInfo.Beatmap.GetDisplayTitle()}"; } } From d392d1a5c08daa0d3f857e75f1d18fbbb160138c Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sat, 24 Dec 2022 22:18:42 +0000 Subject: [PATCH 035/248] override a sub-method instead of the whole `Export()` --- osu.Game/Database/LegacyExporter.cs | 10 +++++----- osu.Game/Database/LegacyScoreExporter.cs | 22 +++++----------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 02219c4dfa..3f305fb420 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -33,17 +33,17 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } + protected virtual string GetItemExportString(TModel item) => item.GetDisplayString().GetValidFilename(); + /// /// Exports an item to a legacy (.zip based) package. /// /// The item to export. - public virtual void Export(TModel item) + public void Export(TModel item) { - string itemFilename = item.GetDisplayString().GetValidFilename(); + IEnumerable existingExports = exportStorage.GetFiles("", $"{GetItemExportString(item)}*{FileExtension}"); - IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); - - string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{GetItemExportString(item)}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index fc80693765..e176449fd0 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -3,13 +3,11 @@ #nullable disable -using System.Collections.Generic; using System.IO; using System.Linq; using osu.Framework.Platform; using osu.Game.Extensions; using osu.Game.Scoring; -using osu.Game.Utils; namespace osu.Game.Database { @@ -17,27 +15,17 @@ namespace osu.Game.Database { protected override string FileExtension => ".osr"; - private readonly Storage exportStorage; - public LegacyScoreExporter(Storage storage) : base(storage) { - exportStorage = storage.GetStorageForDirectory(@"exports"); } - private string GetScoreExportString(ScoreInfo score) => $"{score.GetDisplayString()} ({score.Date.LocalDateTime:yyyy-MM-dd})"; - - public override void Export(ScoreInfo score) + protected override string GetItemExportString(ScoreInfo score) { - string scoreExportTitle = GetScoreExportString(score).GetValidFilename(); - - IEnumerable existingExports = exportStorage.GetFiles("", $"{scoreExportTitle}*{FileExtension}"); - - string scoreExportFilename = NamingUtils.GetNextBestFilename(existingExports, $"{scoreExportTitle}{FileExtension}"); - using (var stream = exportStorage.CreateFileSafely(scoreExportFilename)) - ExportModelTo(score, stream); - - exportStorage.PresentFileExternally(scoreExportFilename); + string scoreString = score.GetDisplayString(); + string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + + return filename.GetValidFilename(); } public override void ExportModelTo(ScoreInfo model, Stream outputStream) From 5232588a1f07529814a36439880585db96b225bd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 24 Dec 2022 20:04:45 -0800 Subject: [PATCH 036/248] Use `PerformFromScreen` to exit sub screens instead --- .../Navigation/TestSceneScreenNavigation.cs | 2 +- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 89cd766842..66c4cf8686 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -83,7 +83,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("go back to song select", () => { - InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); + InputManager.MoveMouseTo(playlistScreen.ChildrenOfType().Single(b => b.Text == "Edit playlist")); InputManager.Click(MouseButton.Left); }); diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index ff888710fe..4a3549b33e 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -45,6 +45,9 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] protected IAPIProvider API { get; private set; } + [Resolved(canBeNull: true)] + private IPerformFromScreenRunner performer { get; set; } + protected OnlinePlayScreen() { Anchor = Anchor.Centre; @@ -148,13 +151,17 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - while (screenStack.CurrentScreen is not LoungeSubScreen) + if (screenStack.CurrentScreen is not LoungeSubScreen) { - var lastSubScreen = screenStack.CurrentScreen; - if (((Drawable)lastSubScreen)?.IsLoaded == true) - screenStack.Exit(); + if (performer != null) + { + performer.PerformFromScreen(_ => e.Destination.MakeCurrent(), new[] { typeof(LoungeSubScreen) }); + return true; + } - if (lastSubScreen == screenStack.CurrentScreen) return true; + // TODO: make isolated tests work with IPerformFromScreenRunner + if ((screenStack.CurrentScreen as Drawable)?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) + return true; } RoomManager.PartRoom(); From 2c2f347e2585c00742f8ad852550b2938805bd75 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 09:57:42 -0800 Subject: [PATCH 037/248] Add context menus to overlay panels/cards --- .../Beatmaps/Drawables/Cards/BeatmapCard.cs | 9 ++++- osu.Game/Overlays/Chat/DrawableUsername.cs | 5 +-- osu.Game/Overlays/News/NewsCard.cs | 9 ++++- osu.Game/Overlays/OnlineOverlay.cs | 10 ++++-- osu.Game/Users/UserPanel.cs | 36 +++++++++++++++++-- 5 files changed, 60 insertions(+), 9 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 00f9a6b3d5..7e5b734979 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -5,6 +5,8 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; @@ -14,7 +16,7 @@ using osu.Game.Overlays; namespace osu.Game.Beatmaps.Drawables.Cards { - public abstract partial class BeatmapCard : OsuClickableContainer + public abstract partial class BeatmapCard : OsuClickableContainer, IHasContextMenu { public const float TRANSITION_DURATION = 400; public const float CORNER_RADIUS = 10; @@ -96,5 +98,10 @@ namespace osu.Game.Beatmaps.Drawables.Cards throw new ArgumentOutOfRangeException(nameof(size), size, @"Unsupported card size"); } } + + public MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("View beatmap", MenuItemType.Highlighted, Action), + }; } } diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 6bae498a6c..8005677dc2 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -20,6 +20,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; +using osu.Game.Resources.Localisation.Web; using osuTK; using osuTK.Graphics; @@ -148,11 +149,11 @@ namespace osu.Game.Overlays.Chat List items = new List { - new OsuMenuItem("View Profile", MenuItemType.Highlighted, openUserProfile) + new OsuMenuItem("View profile", MenuItemType.Highlighted, openUserProfile) }; if (!user.Equals(api.LocalUser.Value)) - items.Add(new OsuMenuItem("Start Chat", MenuItemType.Standard, openUserChannel)); + items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, openUserChannel)); return items.ToArray(); } diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index e0be5cc4a9..f18ce7ff06 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -12,16 +12,18 @@ 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.Events; using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.News { - public partial class NewsCard : OsuHoverContainer + public partial class NewsCard : OsuHoverContainer, IHasContextMenu { protected override IEnumerable EffectTargets => new[] { background }; @@ -161,5 +163,10 @@ namespace osu.Game.Overlays.News DateTimeOffset IHasCustomTooltip.TooltipContent => date; } + + public MenuItem[] ContextMenuItems => new MenuItem[] + { + new OsuMenuItem("View news in browser", MenuItemType.Highlighted, Action), + }; } } diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index 0e0ce56446..ff225bd4ab 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -7,6 +7,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online; @@ -46,10 +47,15 @@ namespace osu.Game.Overlays Children = new Drawable[] { Header.With(h => h.Depth = float.MinValue), - content = new PopoverContainer + new OsuContextMenuContainer { RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y + AutoSizeAxes = Axes.Y, + Child = content = new PopoverContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + } } } } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 2f7232d5ea..2e9a870399 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; @@ -15,7 +16,10 @@ using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Containers; using JetBrains.Annotations; +using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Online.Chat; +using osu.Game.Resources.Localisation.Web; namespace osu.Game.Users { @@ -44,6 +48,15 @@ namespace osu.Game.Users [Resolved(canBeNull: true)] private UserProfileOverlay profileOverlay { get; set; } + [Resolved] + private IAPIProvider api { get; set; } + + [Resolved] + private ChannelManager channelManager { get; set; } + + [Resolved] + private ChatOverlay chatOverlay { get; set; } + [Resolved(canBeNull: true)] protected OverlayColourProvider ColourProvider { get; private set; } @@ -89,9 +102,26 @@ namespace osu.Game.Users Text = User.Username, }; - public MenuItem[] ContextMenuItems => new MenuItem[] + public MenuItem[] ContextMenuItems { - new OsuMenuItem("View Profile", MenuItemType.Highlighted, ViewProfile), - }; + get + { + List items = new List + { + new OsuMenuItem("View profile", MenuItemType.Highlighted, ViewProfile) + }; + + if (!User.Equals(api.LocalUser.Value)) + { + items.Add(new OsuMenuItem(UsersStrings.CardSendMessage, MenuItemType.Standard, () => + { + channelManager?.OpenPrivateChannel(User); + chatOverlay?.Show(); + })); + } + + return items.ToArray(); + } + } } } From b9dfb8b60208c51073352c071fd45c6db6a44f43 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 10:07:42 -0800 Subject: [PATCH 038/248] Add localisation for context menu strings --- .../Beatmaps/Drawables/Cards/BeatmapCard.cs | 3 ++- osu.Game/Localisation/ContextMenuStrings.cs | 24 +++++++++++++++++++ osu.Game/Overlays/Chat/DrawableUsername.cs | 3 ++- osu.Game/Users/UserPanel.cs | 3 ++- 4 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Localisation/ContextMenuStrings.cs diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs index 7e5b734979..94b2956b4e 100644 --- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs +++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs @@ -13,6 +13,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; +using osu.Game.Localisation; namespace osu.Game.Beatmaps.Drawables.Cards { @@ -101,7 +102,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards public MenuItem[] ContextMenuItems => new MenuItem[] { - new OsuMenuItem("View beatmap", MenuItemType.Highlighted, Action), + new OsuMenuItem(ContextMenuStrings.ViewBeatmap, MenuItemType.Highlighted, Action), }; } } diff --git a/osu.Game/Localisation/ContextMenuStrings.cs b/osu.Game/Localisation/ContextMenuStrings.cs new file mode 100644 index 0000000000..8bc213016b --- /dev/null +++ b/osu.Game/Localisation/ContextMenuStrings.cs @@ -0,0 +1,24 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class ContextMenuStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.ContextMenu"; + + /// + /// "View profile" + /// + public static LocalisableString ViewProfile => new TranslatableString(getKey(@"view_profile"), @"View profile"); + + /// + /// "View beatmap" + /// + public static LocalisableString ViewBeatmap => new TranslatableString(getKey(@"view_beatmap"), @"View beatmap"); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Overlays/Chat/DrawableUsername.cs b/osu.Game/Overlays/Chat/DrawableUsername.cs index 8005677dc2..8cd16047f3 100644 --- a/osu.Game/Overlays/Chat/DrawableUsername.cs +++ b/osu.Game/Overlays/Chat/DrawableUsername.cs @@ -17,6 +17,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; @@ -149,7 +150,7 @@ namespace osu.Game.Overlays.Chat List items = new List { - new OsuMenuItem("View profile", MenuItemType.Highlighted, openUserProfile) + new OsuMenuItem(ContextMenuStrings.ViewProfile, MenuItemType.Highlighted, openUserProfile) }; if (!user.Equals(api.LocalUser.Value)) diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 2e9a870399..5c070bae3b 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -20,6 +20,7 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; +using osu.Game.Localisation; namespace osu.Game.Users { @@ -108,7 +109,7 @@ namespace osu.Game.Users { List items = new List { - new OsuMenuItem("View profile", MenuItemType.Highlighted, ViewProfile) + new OsuMenuItem(ContextMenuStrings.ViewProfile, MenuItemType.Highlighted, ViewProfile) }; if (!User.Equals(api.LocalUser.Value)) From 272288c9aa2e6b8a04be72392960ab9fe33ae3a0 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sun, 25 Dec 2022 21:50:56 +0000 Subject: [PATCH 039/248] fix code style and naming --- osu.Game/Database/LegacyExporter.cs | 8 +++++--- osu.Game/Database/LegacyScoreExporter.cs | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Database/LegacyExporter.cs b/osu.Game/Database/LegacyExporter.cs index 3f305fb420..09d6913dd9 100644 --- a/osu.Game/Database/LegacyExporter.cs +++ b/osu.Game/Database/LegacyExporter.cs @@ -33,7 +33,7 @@ namespace osu.Game.Database UserFileStorage = storage.GetStorageForDirectory(@"files"); } - protected virtual string GetItemExportString(TModel item) => item.GetDisplayString().GetValidFilename(); + protected virtual string GetFilename(TModel item) => item.GetDisplayString(); /// /// Exports an item to a legacy (.zip based) package. @@ -41,9 +41,11 @@ namespace osu.Game.Database /// The item to export. public void Export(TModel item) { - IEnumerable existingExports = exportStorage.GetFiles("", $"{GetItemExportString(item)}*{FileExtension}"); + string itemFilename = GetFilename(item).GetValidFilename(); - string filename = NamingUtils.GetNextBestFilename(existingExports, $"{GetItemExportString(item)}{FileExtension}"); + IEnumerable existingExports = exportStorage.GetFiles("", $"{itemFilename}*{FileExtension}"); + + string filename = NamingUtils.GetNextBestFilename(existingExports, $"{itemFilename}{FileExtension}"); using (var stream = exportStorage.CreateFileSafely(filename)) ExportModelTo(item, stream); diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index e176449fd0..7c0ba7c6ee 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -20,12 +20,12 @@ namespace osu.Game.Database { } - protected override string GetItemExportString(ScoreInfo score) + protected override string GetFilename(ScoreInfo score) { string scoreString = score.GetDisplayString(); string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; - - return filename.GetValidFilename(); + + return filename; } public override void ExportModelTo(ScoreInfo model, Stream outputStream) From 1a571e1c7f36b86c81c68486245f11ef19a884a0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 15:03:08 -0800 Subject: [PATCH 040/248] Remove nullable disable on user panel --- osu.Game/Users/UserPanel.cs | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 5c070bae3b..e2dc511391 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Framework.Allocation; @@ -15,7 +13,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Containers; -using JetBrains.Annotations; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; @@ -32,11 +29,11 @@ namespace osu.Game.Users /// Perform an action in addition to showing the user's profile. /// This should be used to perform auxiliary tasks and not as a primary action for clicking a user panel (to maintain a consistent UX). /// - public new Action Action; + public new Action? Action; - protected Action ViewProfile { get; private set; } + protected Action ViewProfile { get; private set; } = null!; - protected Drawable Background { get; private set; } + protected Drawable Background { get; private set; } = null!; protected UserPanel(APIUser user) : base(HoverSampleSet.Button) @@ -46,23 +43,23 @@ namespace osu.Game.Users User = user; } - [Resolved(canBeNull: true)] - private UserProfileOverlay profileOverlay { get; set; } + [Resolved] + private UserProfileOverlay? profileOverlay { get; set; } [Resolved] - private IAPIProvider api { get; set; } + private IAPIProvider api { get; set; } = null!; [Resolved] - private ChannelManager channelManager { get; set; } + private ChannelManager? channelManager { get; set; } [Resolved] - private ChatOverlay chatOverlay { get; set; } - - [Resolved(canBeNull: true)] - protected OverlayColourProvider ColourProvider { get; private set; } + private ChatOverlay? chatOverlay { get; set; } [Resolved] - protected OsuColour Colours { get; private set; } + protected OverlayColourProvider? ColourProvider { get; private set; } + + [Resolved] + protected OsuColour Colours { get; private set; } = null!; [BackgroundDependencyLoader] private void load() @@ -93,7 +90,6 @@ namespace osu.Game.Users }; } - [NotNull] protected abstract Drawable CreateLayout(); protected OsuSpriteText CreateUsername() => new OsuSpriteText From 0dba25e0abce94fe01ead03dfc30e511f511c8b0 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 25 Dec 2022 21:56:22 -0800 Subject: [PATCH 041/248] Refactor to just exit sub screens until lounge sub screen Co-Authored-By: Salman Ahmed --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 4a3549b33e..3d80248306 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -45,9 +45,6 @@ namespace osu.Game.Screens.OnlinePlay [Resolved] protected IAPIProvider API { get; private set; } - [Resolved(canBeNull: true)] - private IPerformFromScreenRunner performer { get; set; } - protected OnlinePlayScreen() { Anchor = Anchor.Centre; @@ -151,17 +148,13 @@ namespace osu.Game.Screens.OnlinePlay public override bool OnExiting(ScreenExitEvent e) { - if (screenStack.CurrentScreen is not LoungeSubScreen) + while (screenStack.CurrentScreen != null && screenStack.CurrentScreen is not LoungeSubScreen) { - if (performer != null) - { - performer.PerformFromScreen(_ => e.Destination.MakeCurrent(), new[] { typeof(LoungeSubScreen) }); + var subScreen = (Screen)screenStack.CurrentScreen; + if (subScreen.IsLoaded && subScreen.OnExiting(e)) return true; - } - // TODO: make isolated tests work with IPerformFromScreenRunner - if ((screenStack.CurrentScreen as Drawable)?.IsLoaded == true && screenStack.CurrentScreen.OnExiting(e)) - return true; + subScreen.Exit(); } RoomManager.PartRoom(); From 84e3858a86bf6a613456ab37e8e73f406287a602 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 26 Dec 2022 15:37:46 -0800 Subject: [PATCH 042/248] Move context menu / popover container one level to account for header --- osu.Game/Overlays/OnlineOverlay.cs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/OnlineOverlay.cs b/osu.Game/Overlays/OnlineOverlay.cs index ff225bd4ab..4fdf7cb2b6 100644 --- a/osu.Game/Overlays/OnlineOverlay.cs +++ b/osu.Game/Overlays/OnlineOverlay.cs @@ -39,25 +39,30 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, ScrollbarVisible = false, - Child = new FillFlowContainer + Child = new OsuContextMenuContainer { - AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Children = new Drawable[] + AutoSizeAxes = Axes.Y, + Child = new PopoverContainer { - Header.With(h => h.Depth = float.MinValue), - new OsuContextMenuContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = content = new PopoverContainer + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y + Header.With(h => h.Depth = float.MinValue), + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + } } } - } + }, } }, Loading = new LoadingLayer(true) From 8bc8b0d0af3f2f8b8e043e4ffc85a660c64f6bac Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Mon, 26 Dec 2022 15:38:07 -0800 Subject: [PATCH 043/248] Remove redundant context menu container --- .../BeatmapSet/BeatmapSetHeaderContent.cs | 182 +++++++++--------- 1 file changed, 88 insertions(+), 94 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs index 0318dad0e3..3eec4b4731 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeaderContent.cs @@ -9,7 +9,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; -using osu.Game.Graphics.Cursor; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; @@ -91,118 +90,113 @@ namespace osu.Game.Overlays.BeatmapSet }, }, }, - new OsuContextMenuContainer + new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Child = new Container + Padding = new MarginPadding { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding + Vertical = BeatmapSetOverlay.Y_PADDING, + Left = BeatmapSetOverlay.X_PADDING, + Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, + }, + Children = new Drawable[] + { + fadeContent = new FillFlowContainer { - Vertical = BeatmapSetOverlay.Y_PADDING, - Left = BeatmapSetOverlay.X_PADDING, - Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, - }, - Children = new Drawable[] - { - fadeContent = new FillFlowContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new Container { - new Container + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = Picker = new BeatmapPicker(), + }, + new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 15 }, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = Picker = new BeatmapPicker(), - }, - new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = 15 }, - Children = new Drawable[] + title = new OsuSpriteText { - title = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true) - }, - externalLink = new ExternalLinkButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font - }, - explicitContent = new ExplicitContentBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10, Bottom = 4 }, - }, - spotlight = new SpotlightBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10, Bottom = 4 }, - } + Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true) + }, + externalLink = new ExternalLinkButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font + }, + explicitContent = new ExplicitContentBeatmapBadge + { + Alpha = 0f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 10, Bottom = 4 }, + }, + spotlight = new SpotlightBeatmapBadge + { + Alpha = 0f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 10, Bottom = 4 }, } - }, - new FillFlowContainer + } + }, + new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Bottom = 20 }, + Children = new Drawable[] { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Bottom = 20 }, - Children = new Drawable[] + artist = new OsuSpriteText { - artist = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true), - }, - featuredArtist = new FeaturedArtistBeatmapBadge - { - Alpha = 0f, - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 10 } - } + Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true), + }, + featuredArtist = new FeaturedArtistBeatmapBadge + { + Alpha = 0f, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 10 } } - }, - new Container + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = author = new AuthorInfo(), + }, + beatmapAvailability = new BeatmapAvailability(), + new Container + { + RelativeSizeAxes = Axes.X, + Height = buttons_height, + Margin = new MarginPadding { Top = 10 }, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = author = new AuthorInfo(), - }, - beatmapAvailability = new BeatmapAvailability(), - new Container - { - RelativeSizeAxes = Axes.X, - Height = buttons_height, - Margin = new MarginPadding { Top = 10 }, - Children = new Drawable[] + favouriteButton = new FavouriteButton { - favouriteButton = new FavouriteButton - { - BeatmapSet = { BindTarget = BeatmapSet } - }, - downloadButtonsContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, - Spacing = new Vector2(buttons_spacing), - }, + BeatmapSet = { BindTarget = BeatmapSet } + }, + downloadButtonsContainer = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, + Spacing = new Vector2(buttons_spacing), }, }, }, }, - } - }, + }, + } }, loading = new LoadingSpinner { From a0690e7ffb1bb1f2ea81ea65090a4b0b890b619b Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Mon, 26 Dec 2022 22:23:31 +0000 Subject: [PATCH 044/248] replay menus remembers expanded state no messing with readonly fields --- .../NonVisual/SessionStaticsTest.cs | 6 ++++++ osu.Game/Configuration/SessionStatics.cs | 4 ++++ .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 19 ++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/NonVisual/SessionStaticsTest.cs b/osu.Game.Tests/NonVisual/SessionStaticsTest.cs index 5c8254b947..499c0e5d34 100644 --- a/osu.Game.Tests/NonVisual/SessionStaticsTest.cs +++ b/osu.Game.Tests/NonVisual/SessionStaticsTest.cs @@ -24,12 +24,16 @@ namespace osu.Game.Tests.NonVisual sessionStatics.SetValue(Static.MutedAudioNotificationShownOnce, true); sessionStatics.SetValue(Static.LowBatteryNotificationShownOnce, true); sessionStatics.SetValue(Static.LastHoverSoundPlaybackTime, (double?)1d); + sessionStatics.SetValue(Static.ReplayPlaybackSettingExpanded, false); + sessionStatics.SetValue(Static.ReplayVisualSettingsExpanded, true); sessionStatics.SetValue(Static.SeasonalBackgrounds, new APISeasonalBackgrounds { EndDate = new DateTimeOffset(2022, 1, 1, 0, 0, 0, TimeSpan.Zero) }); Assert.IsFalse(sessionStatics.GetBindable(Static.LoginOverlayDisplayed).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.LastHoverSoundPlaybackTime).IsDefault); + Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayPlaybackSettingExpanded).IsDefault); + Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayVisualSettingsExpanded).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.SeasonalBackgrounds).IsDefault); sessionStatics.ResetAfterInactivity(); @@ -39,6 +43,8 @@ namespace osu.Game.Tests.NonVisual Assert.IsTrue(sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce).IsDefault); // some statics should not reset despite inactivity. Assert.IsFalse(sessionStatics.GetBindable(Static.LastHoverSoundPlaybackTime).IsDefault); + Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayPlaybackSettingExpanded).IsDefault); + Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayVisualSettingsExpanded).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.SeasonalBackgrounds).IsDefault); } } diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index 12a30a0c84..f08658f182 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -20,6 +20,8 @@ namespace osu.Game.Configuration SetDefault(Static.MutedAudioNotificationShownOnce, false); SetDefault(Static.LowBatteryNotificationShownOnce, false); SetDefault(Static.LastHoverSoundPlaybackTime, (double?)null); + SetDefault(Static.ReplayPlaybackSettingExpanded, true); + SetDefault(Static.ReplayVisualSettingsExpanded, false); SetDefault(Static.SeasonalBackgrounds, null); } @@ -42,6 +44,8 @@ namespace osu.Game.Configuration LoginOverlayDisplayed, MutedAudioNotificationShownOnce, LowBatteryNotificationShownOnce, + ReplayPlaybackSettingExpanded, + ReplayVisualSettingsExpanded, /// /// Info about seasonal backgrounds available fetched from API - see . diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index 5f6f040959..c4f07f77cd 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -3,12 +3,15 @@ #nullable disable +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osuTK; using osu.Game.Screens.Play.PlayerSettings; using osuTK.Input; +using osu.Game.Configuration; +using osu.Framework.Allocation; namespace osu.Game.Screens.Play.HUD { @@ -16,6 +19,10 @@ namespace osu.Game.Screens.Play.HUD { private const int fade_duration = 200; + private Bindable playbackMenuExpanded; + + private Bindable visualMenuExpanded; + public bool ReplayLoaded; public readonly PlaybackSettings PlaybackSettings; @@ -42,11 +49,21 @@ namespace osu.Game.Screens.Play.HUD //CollectionSettings = new CollectionSettings(), //DiscussionSettings = new DiscussionSettings(), PlaybackSettings = new PlaybackSettings(), - VisualSettings = new VisualSettings { Expanded = { Value = false } } + VisualSettings = new VisualSettings() } }; } + [BackgroundDependencyLoader] + private void load(SessionStatics statics) + { + playbackMenuExpanded = statics.GetBindable(Static.ReplayPlaybackSettingExpanded); + visualMenuExpanded = statics.GetBindable(Static.ReplayVisualSettingsExpanded); + + PlaybackSettings.Expanded.BindTo(playbackMenuExpanded); + VisualSettings.Expanded.BindTo(visualMenuExpanded); + } + protected override void PopIn() => this.FadeIn(fade_duration); protected override void PopOut() => this.FadeOut(fade_duration); From 9021cf7be6b4b6f271f7159c215e13878f95c3ec Mon Sep 17 00:00:00 2001 From: sw1tchbl4d3 Date: Wed, 28 Dec 2022 11:42:34 +0100 Subject: [PATCH 045/248] Allow aspect ratios smaller than the default in taiko --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index 79c5c36e08..d42aaddf9e 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.UI float height = default_relative_height; - if (LockPlayfieldAspect.Value) + if (LockPlayfieldAspect.Value && Parent.ChildSize.X / Parent.ChildSize.Y > default_aspect) height *= Math.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect; Height = height; From b40d114e76dd447438e105f4b91aa9c3441b1496 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 28 Dec 2022 15:00:57 -0800 Subject: [PATCH 046/248] Remove context menu from news card for now --- osu.Game/Overlays/News/NewsCard.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Overlays/News/NewsCard.cs b/osu.Game/Overlays/News/NewsCard.cs index f18ce7ff06..e0be5cc4a9 100644 --- a/osu.Game/Overlays/News/NewsCard.cs +++ b/osu.Game/Overlays/News/NewsCard.cs @@ -12,18 +12,16 @@ 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.Events; using osu.Framework.Platform; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.News { - public partial class NewsCard : OsuHoverContainer, IHasContextMenu + public partial class NewsCard : OsuHoverContainer { protected override IEnumerable EffectTargets => new[] { background }; @@ -163,10 +161,5 @@ namespace osu.Game.Overlays.News DateTimeOffset IHasCustomTooltip.TooltipContent => date; } - - public MenuItem[] ContextMenuItems => new MenuItem[] - { - new OsuMenuItem("View news in browser", MenuItemType.Highlighted, Action), - }; } } From 608d8ee7d40bc52370bd116401b23741715d505e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 12:13:44 +0100 Subject: [PATCH 047/248] Add `UserProfile` model to be used in user profile overlay As `APIUser` implements `IEquatable`, attempting to replace an `APIUser` with another `APIUser` with the same online ID has no effect on the user profile overlay. This is a significant hurdle in implementing support for viewing the profile for different rulesets, as in that case the profile is basically reloaded for the same user, but slightly different data. To facilitate this, wrap `APIUser` in a new `UserProfile` class. This will mean that the equality rules can be changed locally to the user profile overlay without impacting other components that depend on the `APIUser` equality rules. The ruleset that the user profile is being displayed with will eventually be added to `UserProfile`, too. --- osu.Game/Overlays/Profile/UserProfile.cs | 25 ++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 osu.Game/Overlays/Profile/UserProfile.cs diff --git a/osu.Game/Overlays/Profile/UserProfile.cs b/osu.Game/Overlays/Profile/UserProfile.cs new file mode 100644 index 0000000000..12a469ddf9 --- /dev/null +++ b/osu.Game/Overlays/Profile/UserProfile.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Profile +{ + /// + /// Contains data about a profile presented on the . + /// + public class UserProfile + { + /// + /// The user whose profile is being presented. + /// + public APIUser User { get; } + + // TODO: add ruleset + + public UserProfile(APIUser user) + { + User = user; + } + } +} From d7294ac3e63e101831af267c45098e75202d6f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 14:56:19 +0100 Subject: [PATCH 048/248] Substitute `APIUser` for `UserProfile` in overlay --- .../Online/TestSceneHistoricalSection.cs | 5 +++-- .../Online/TestScenePlayHistorySubsection.cs | 21 +++++++++---------- .../Online/TestSceneUserProfileHeader.cs | 18 ++++++++-------- .../Visual/Online/TestSceneUserRanks.cs | 3 ++- .../Profile/Header/BottomHeaderContainer.cs | 4 ++-- .../Profile/Header/CentreHeaderContainer.cs | 14 ++++++------- .../Header/Components/FollowersButton.cs | 5 ++--- .../Profile/Header/Components/LevelBadge.cs | 4 ++-- .../Header/Components/LevelProgressBar.cs | 4 ++-- .../Components/MappingSubscribersButton.cs | 5 ++--- .../Header/Components/MessageUserButton.cs | 11 ++++++---- .../Components/OverlinedTotalPlayTime.cs | 12 +++++------ .../Profile/Header/DetailHeaderContainer.cs | 11 +++++----- .../Profile/Header/MedalHeaderContainer.cs | 4 ++-- .../Profile/Header/TopHeaderContainer.cs | 9 ++++---- osu.Game/Overlays/Profile/ProfileHeader.cs | 17 +++++++-------- osu.Game/Overlays/Profile/ProfileSection.cs | 3 +-- .../Beatmaps/PaginatedBeatmapContainer.cs | 2 +- .../Profile/Sections/BeatmapsSection.cs | 14 ++++++------- .../Historical/ChartProfileSubsection.cs | 10 ++++----- .../PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- .../Historical/PlayHistorySubsection.cs | 4 ++-- .../Sections/Historical/ReplaysSubsection.cs | 4 ++-- .../Profile/Sections/HistoricalSection.cs | 8 +++---- .../Profile/Sections/Kudosu/KudosuInfo.cs | 9 ++++---- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 4 ++-- .../Profile/Sections/KudosuSection.cs | 4 ++-- .../Sections/PaginatedProfileSubsection.cs | 16 +++++++------- .../Profile/Sections/ProfileSubsection.cs | 7 +++---- .../Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- .../Overlays/Profile/Sections/RanksSection.cs | 6 +++--- .../PaginatedRecentActivityContainer.cs | 4 ++-- .../Profile/Sections/RecentSection.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 7 ++++--- 34 files changed, 130 insertions(+), 129 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 28f0e6ff9c..92bb41b7d5 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; +using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; namespace osu.Game.Tests.Visual.Online @@ -37,8 +38,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.User.Value = new APIUser { Id = 2 }); - AddStep("Show WubWoofWolf", () => section.User.Value = new APIUser { Id = 39828 }); + AddStep("Show peppy", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 2 })); + AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 39828 })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index 15e411b9d8..a486d77f97 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Overlays.Profile.Sections.Historical; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -14,6 +12,7 @@ using System.Linq; using osu.Framework.Testing; using osu.Framework.Graphics.Shapes; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Profile; namespace osu.Game.Tests.Visual.Online { @@ -22,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); - private readonly Bindable user = new Bindable(); + private readonly Bindable user = new Bindable(); private readonly PlayHistorySubsection section; public TestScenePlayHistorySubsection() @@ -45,49 +44,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => user.Value = user_with_null_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_null_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => user.Value = user_with_empty_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_empty_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => user.Value = user_with_one_value); + AddStep("Load user", () => user.Value = new UserProfile(user_with_one_value)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => user.Value = user_with_two_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_two_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => user.Value = user_with_constant_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_constant_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => user.Value = user_with_zero_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_zero_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => user.Value = user_with_filled_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_filled_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -95,7 +94,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => user.Value = user_with_missing_values); + AddStep("Load user", () => user.Value = new UserProfile(user_with_missing_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index bfd6372e6f..4caab98f63 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -29,33 +29,33 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.User.Value = TestSceneUserProfileOverlay.TEST_USER); + AddStep("Show example user", () => header.UserProfile.Value = new UserProfile(TestSceneUserProfileOverlay.TEST_USER)); } [Test] public void TestOnlineState() { - AddStep("Show online user", () => header.User.Value = new APIUser + AddStep("Show online user", () => header.UserProfile.Value = new UserProfile(new APIUser { Id = 1001, Username = "IAmOnline", LastVisit = DateTimeOffset.Now, IsOnline = true, - }); + })); - AddStep("Show offline user", () => header.User.Value = new APIUser + AddStep("Show offline user", () => header.UserProfile.Value = new UserProfile(new APIUser { Id = 1002, Username = "IAmOffline", LastVisit = DateTimeOffset.Now.AddDays(-10), IsOnline = false, - }); + })); } [Test] public void TestRankedState() { - AddStep("Show ranked user", () => header.User.Value = new APIUser + AddStep("Show ranked user", () => header.UserProfile.Value = new UserProfile(new APIUser { Id = 2001, Username = "RankedUser", @@ -70,9 +70,9 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() }, } - }); + })); - AddStep("Show unranked user", () => header.User.Value = new APIUser + AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfile(new APIUser { Id = 2002, Username = "UnrankedUser", @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 85).ToArray() }, } - }); + })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index fdbd8a4325..184b969279 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -10,6 +10,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; +using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; namespace osu.Game.Tests.Visual.Online @@ -44,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.User.Value = new APIUser { Id = 124493 }); + AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfile(new APIUser { Id = 124493 })); } } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index f5c7a3f87a..64a333dff7 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private LinkFlowContainer topLinkContainer = null!; private LinkFlowContainer bottomLinkContainer = null!; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header } }; - User.BindValueChanged(user => updateDisplay(user.NewValue)); + UserProfile.BindValueChanged(user => updateDisplay(user.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 5e4e1184a4..701c4a1464 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private OverlinedInfoContainer hiddenDetailGlobal = null!; private OverlinedInfoContainer hiddenDetailCountry = null!; @@ -53,15 +53,15 @@ namespace osu.Game.Overlays.Profile.Header { new FollowersButton { - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, new MappingSubscribersButton { - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, new MessageUserButton { - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, } }, @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Size = new Vector2(40), - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, expandedDetailContainer = new Container { @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Profile.Header Child = new LevelProgressBar { RelativeSizeAxes = Axes.Both, - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } } }, hiddenDetailContainer = new FillFlowContainer @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Profile.Header expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); }); - User.BindValueChanged(user => updateDisplay(user.NewValue)); + UserProfile.BindValueChanged(userProfile => updateDisplay(userProfile.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index c0bcec622a..48e9718a7c 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -5,14 +5,13 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; @@ -22,7 +21,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load() { // todo: when friending/unfriending is implemented, the APIAccess.Friends list should be updated accordingly. - User.BindValueChanged(user => SetValue(user.NewValue?.FollowerCount ?? 0), true); + UserProfile.BindValueChanged(user => SetValue(user.NewValue?.User.FollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 8f84e69bac..f68c9838a0 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; private set; } @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - User.BindValueChanged(user => updateLevel(user.NewValue)); + UserProfile.BindValueChanged(user => updateLevel(user.NewValue?.User)); } private void updateLevel(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index ea5ca0c8bd..e3100c5af5 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; } @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - User.BindValueChanged(user => updateProgress(user.NewValue)); + UserProfile.BindValueChanged(user => updateProgress(user.NewValue?.User)); } private void updateProgress(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index c600f7622a..29b42cb223 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -5,14 +5,13 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; @@ -21,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load() { - User.BindValueChanged(user => SetValue(user.NewValue?.MappingFollowerCount ?? 0), true); + UserProfile.BindValueChanged(user => SetValue(user.NewValue?.User.MappingFollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 3266e3c308..f57b43c3a4 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Resources.Localisation.Web; using osuTK; @@ -16,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; @@ -49,12 +48,16 @@ namespace osu.Game.Overlays.Profile.Header.Components { if (!Content.IsPresent) return; - channelManager?.OpenPrivateChannel(User.Value); + channelManager?.OpenPrivateChannel(UserProfile.Value?.User); userOverlay?.Hide(); chatOverlay?.Show(); }; - User.ValueChanged += e => Content.Alpha = e.NewValue != null && !e.NewValue.PMFriendsOnly && apiProvider.LocalUser.Value.Id != e.NewValue.Id ? 1 : 0; + UserProfile.ValueChanged += e => + { + var user = e.NewValue?.User; + Content.Alpha = user != null && !user.PMFriendsOnly && apiProvider.LocalUser.Value.Id != user.Id ? 1 : 0; + }; } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index e9e277acd3..1de13ba7c7 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -7,14 +7,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; set; } @@ -36,13 +35,14 @@ namespace osu.Game.Overlays.Profile.Header.Components LineColour = colourProvider.Highlight1, }; - User.BindValueChanged(updateTime, true); + UserProfile.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent user) + private void updateTime(ValueChangedEvent userProfile) { - TooltipText = (user.NewValue?.Statistics?.PlayTime ?? 0) / 3600 + " hours"; - info.Content = formatTime(user.NewValue?.Statistics?.PlayTime); + int? playTime = userProfile.NewValue?.User.Statistics?.PlayTime; + TooltipText = (playTime ?? 0) / 3600 + " hours"; + info.Content = formatTime(playTime); } private string formatTime(int? secondsNull) diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 95fead1246..8b9a90c9a3 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Leaderboards; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Resources.Localisation.Web; @@ -30,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private bool expanded = true; @@ -61,7 +60,7 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Y; - User.ValueChanged += e => updateDisplay(e.NewValue); + UserProfile.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] { @@ -99,7 +98,7 @@ namespace osu.Game.Overlays.Profile.Header { new OverlinedTotalPlayTime { - User = { BindTarget = User } + UserProfile = { BindTarget = UserProfile } }, medalInfo = new OverlinedInfoContainer { @@ -171,8 +170,10 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay(APIUser? user) + private void updateDisplay(UserProfile? userProfile) { + var user = userProfile?.User; + medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 79f9eba57d..b41c60ed4e 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -20,14 +20,14 @@ namespace osu.Game.Overlays.Profile.Header { private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { Alpha = 0; AutoSizeAxes = Axes.Y; - User.ValueChanged += e => updateDisplay(e.NewValue); + UserProfile.ValueChanged += e => updateDisplay(e.NewValue?.User); InternalChildren = new Drawable[] { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index a6501f567f..69258c914f 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -15,7 +15,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Resources.Localisation.Web; using osu.Game.Users.Drawables; @@ -27,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); [Resolved] private IAPIProvider api { get; set; } = null!; @@ -171,11 +170,13 @@ namespace osu.Game.Overlays.Profile.Header } }; - User.BindValueChanged(user => updateUser(user.NewValue)); + UserProfile.BindValueChanged(user => updateUser(user.NewValue)); } - private void updateUser(APIUser? user) + private void updateUser(UserProfile? userProfile) { + var user = userProfile?.User; + avatar.User = user; usernameText.Text = user?.Username ?? string.Empty; openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}"; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 2b8d2503e0..447e9148e8 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header; using osu.Game.Resources.Localisation.Web; using osu.Game.Users; @@ -20,7 +19,7 @@ namespace osu.Game.Overlays.Profile { private UserCoverBackground coverContainer = null!; - public Bindable User = new Bindable(); + public Bindable UserProfile = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -29,7 +28,7 @@ namespace osu.Game.Overlays.Profile { ContentSidePadding = UserProfileOverlay.CONTENT_X_MARGIN; - User.ValueChanged += e => updateDisplay(e.NewValue); + UserProfile.ValueChanged += e => updateDisplay(e.NewValue); TabControl.AddItem(LayoutStrings.HeaderUsersShow); @@ -73,34 +72,34 @@ namespace osu.Game.Overlays.Profile new TopHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, detailHeaderContainer = new DetailHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, new MedalHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, new BottomHeaderContainer { RelativeSizeAxes = Axes.X, - User = { BindTarget = User }, + UserProfile = { BindTarget = UserProfile }, }, } }; protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(APIUser? user) => coverContainer.User = user; + private void updateDisplay(UserProfile? userProfile) => coverContainer.User = userProfile?.User; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 62b40545df..97b8f2b13f 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -13,7 +13,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile { @@ -29,7 +28,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index e327d71d25..3b1f26ee7d 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) : base(user, headerText) { this.type = type; diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index 3b304a79ef..19d0da2cef 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -18,13 +18,13 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedBeatmapContainer(BeatmapSetType.Favourite, User, UsersStrings.ShowExtraBeatmapsFavouriteTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Ranked, User, UsersStrings.ShowExtraBeatmapsRankedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Loved, User, UsersStrings.ShowExtraBeatmapsLovedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Guest, User, UsersStrings.ShowExtraBeatmapsGuestTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Pending, User, UsersStrings.ShowExtraBeatmapsPendingTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, UsersStrings.ShowExtraBeatmapsGraveyardTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Nominated, User, UsersStrings.ShowExtraBeatmapsNominatedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Favourite, UserProfile, UsersStrings.ShowExtraBeatmapsFavouriteTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Ranked, UserProfile, UsersStrings.ShowExtraBeatmapsRankedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Loved, UserProfile, UsersStrings.ShowExtraBeatmapsLovedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Guest, UserProfile, UsersStrings.ShowExtraBeatmapsGuestTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Pending, UserProfile, UsersStrings.ShowExtraBeatmapsPendingTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, UserProfile, UsersStrings.ShowExtraBeatmapsGraveyardTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Nominated, UserProfile, UsersStrings.ShowExtraBeatmapsNominatedTitle), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index c532c693ec..724733c7a9 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable user, LocalisableString headerText) - : base(user, headerText) + protected ChartProfileSubsection(Bindable userProfile, LocalisableString headerText) + : base(userProfile, headerText) { } @@ -41,12 +41,12 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(onUserChanged, true); + UserProfile.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { - var values = GetValues(e.NewValue); + var values = GetValues(e.NewValue?.User); if (values == null || values.Length <= 1) { diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 515c1fd146..5851262229 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable user) - : base(user, UsersStrings.ShowExtraHistoricalMostPlayedTitle) + public PaginatedMostPlayedBeatmapContainer(Bindable userProfile) + : base(userProfile, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index c8a6b1da31..5fa58dbdab 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable user) - : base(user, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) + public PlayHistorySubsection(Bindable userProfile) + : base(userProfile, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index ac7c616a64..04e70afa36 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable user) - : base(user, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) + public ReplaysSubsection(Bindable userProfile) + : base(userProfile, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs index 19f7a32d4d..eecdffad19 100644 --- a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs +++ b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs @@ -20,10 +20,10 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new PlayHistorySubsection(User), - new PaginatedMostPlayedBeatmapContainer(User), - new PaginatedScoreContainer(ScoreType.Recent, User, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), - new ReplaysSubsection(User) + new PlayHistorySubsection(UserProfile), + new PaginatedMostPlayedBeatmapContainer(UserProfile), + new PaginatedScoreContainer(ScoreType.Recent, UserProfile, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), + new ReplaysSubsection(UserProfile) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index acf4827dfd..7fd0759fac 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -14,17 +14,16 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.LocalisationExtensions; using osu.Game.Resources.Localisation.Web; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable user = new Bindable(); + private readonly Bindable userProfile = new Bindable(); - public KudosuInfo(Bindable user) + public KudosuInfo(Bindable userProfile) { - this.user.BindTo(user); + this.userProfile.BindTo(userProfile); CountSection total; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -32,7 +31,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu CornerRadius = 3; Child = total = new CountTotal(); - this.user.ValueChanged += u => total.Count = u.NewValue?.Kudosu.Total ?? 0; + this.userProfile.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; } protected override bool OnClick(ClickEvent e) => true; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index c5de810f22..6addd86894 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,8 +14,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable user) - : base(user, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) + public PaginatedKudosuHistoryContainer(Bindable userProfile) + : base(userProfile, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index 482a853c44..b884f8854a 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs @@ -18,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new KudosuInfo(User), - new PaginatedKudosuHistoryContainer(User), + new KudosuInfo(UserProfile), + new PaginatedKudosuHistoryContainer(UserProfile), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index f32221747c..d77844fd56 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -46,8 +46,8 @@ namespace osu.Game.Overlays.Profile.Sections private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable user, LocalisableString? headerText = null, LocalisableString? missingText = null) - : base(user, headerText, CounterVisibilityState.AlwaysVisible) + protected PaginatedProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, LocalisableString? missingText = null) + : base(userProfile, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; } @@ -89,10 +89,10 @@ namespace osu.Game.Overlays.Profile.Sections protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(onUserChanged, true); + UserProfile.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { loadCancellation?.Cancel(); retrievalRequest?.Cancel(); @@ -100,23 +100,23 @@ namespace osu.Game.Overlays.Profile.Sections CurrentPage = null; ItemsContainer.Clear(); - if (e.NewValue != null) + if (e.NewValue?.User != null) { showMore(); - SetCount(GetCount(e.NewValue)); + SetCount(GetCount(e.NewValue.User)); } } private void showMore() { - if (User.Value == null) + if (UserProfile.Value?.User == null) return; loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(User.Value, CurrentPage.Value); + retrievalRequest = CreateRequest(UserProfile.Value.User, CurrentPage.Value); retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 0a0e1a9298..5df8688659 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -6,24 +6,23 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable User = new Bindable(); + protected readonly Bindable UserProfile = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable user, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; - User.BindTo(user); + UserProfile.BindTo(userProfile); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 3ef0275f50..cdd1738c8e 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable user, LocalisableString headerText) - : base(user, headerText) + public PaginatedScoreContainer(ScoreType type, Bindable userProfile, LocalisableString headerText) + : base(userProfile, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index ce831b30a8..f8d1d82300 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -18,9 +18,9 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedScoreContainer(ScoreType.Pinned, User, UsersStrings.ShowExtraTopRanksPinnedTitle), - new PaginatedScoreContainer(ScoreType.Best, User, UsersStrings.ShowExtraTopRanksBestTitle), - new PaginatedScoreContainer(ScoreType.Firsts, User, UsersStrings.ShowExtraTopRanksFirstTitle) + new PaginatedScoreContainer(ScoreType.Pinned, UserProfile, UsersStrings.ShowExtraTopRanksPinnedTitle), + new PaginatedScoreContainer(ScoreType.Best, UserProfile, UsersStrings.ShowExtraTopRanksBestTitle), + new PaginatedScoreContainer(ScoreType.Firsts, UserProfile, UsersStrings.ShowExtraTopRanksFirstTitle) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 4e5b11d79f..c08ea58b5a 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable user) - : base(user, missingText: EventsStrings.Empty) + public PaginatedRecentActivityContainer(Bindable userProfile) + : base(userProfile, missingText: EventsStrings.Empty) { } diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index e29dc7f635..6a90b7d1e3 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedRecentActivityContainer(User), + new PaginatedRecentActivityContainer(UserProfile), }; } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 1a7c4173ab..4fcfc7dc3c 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays Show(); - if (user.OnlineID == Header?.User.Value?.Id) + if (user.OnlineID == Header?.UserProfile.Value?.User.Id) return; if (sectionsContainer != null) @@ -134,7 +134,8 @@ namespace osu.Game.Overlays { Debug.Assert(sections != null && sectionsContainer != null && tabs != null); - Header.User.Value = user; + var userProfile = new UserProfile(user); + Header.UserProfile.Value = userProfile; if (user.ProfileOrder != null) { @@ -144,7 +145,7 @@ namespace osu.Game.Overlays if (sec != null) { - sec.User.Value = user; + sec.UserProfile.Value = userProfile; sectionsContainer.Add(sec); tabs.AddItem(sec); From ae3a211da727babd94791cfce7a021fe1bacdb44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 16:11:56 +0100 Subject: [PATCH 049/248] Rewrite user profile overlay test to not depend on online API --- .../Online/TestSceneUserProfileOverlay.cs | 96 ++++++++----------- 1 file changed, 38 insertions(+), 58 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 35c7e7bf28..446e13a8a3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -4,9 +4,12 @@ using System; using System.Linq; using NUnit.Framework; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; -using osu.Game.Overlays.Profile; using osu.Game.Users; namespace osu.Game.Tests.Visual.Online @@ -14,9 +17,41 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public partial class TestSceneUserProfileOverlay : OsuTestScene { - protected override bool UseOnlineAPI => true; + private DummyAPIAccess dummyAPI => (DummyAPIAccess)API; - private readonly TestUserProfileOverlay profile; + private UserProfileOverlay profile = null!; + + [SetUpSteps] + public void SetUp() + { + AddStep("create profile overlay", () => Child = profile = new UserProfileOverlay()); + } + + [Test] + public void TestBlank() + { + AddStep("show overlay", () => profile.Show()); + } + + [Test] + public void TestActualUser() + { + AddStep("set up request handling", () => + { + dummyAPI.HandleRequest = req => + { + if (req is GetUserRequest getUserRequest) + { + getUserRequest.TriggerSuccess(TEST_USER); + return true; + } + + return false; + }; + }); + AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 })); + AddToggleStep("toggle visibility", visible => profile.State.Value = visible ? Visibility.Visible : Visibility.Hidden); + } public static readonly APIUser TEST_USER = new APIUser { @@ -64,60 +99,5 @@ namespace osu.Game.Tests.Visual.Online Colour = "ff0000", Achievements = Array.Empty(), }; - - public TestSceneUserProfileOverlay() - { - Add(profile = new TestUserProfileOverlay()); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - AddStep("Show offline dummy", () => profile.ShowUser(TEST_USER)); - - AddStep("Show null dummy", () => profile.ShowUser(new APIUser - { - Username = @"Null", - Id = 1, - })); - - AddStep("Show ppy", () => profile.ShowUser(new APIUser - { - Username = @"peppy", - Id = 2, - IsSupporter = true, - CountryCode = CountryCode.AU, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg" - })); - - AddStep("Show flyte", () => profile.ShowUser(new APIUser - { - Username = @"flyte", - Id = 3103765, - CountryCode = CountryCode.JP, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg" - })); - - AddStep("Show bancho", () => profile.ShowUser(new APIUser - { - Username = @"BanchoBot", - Id = 3, - IsBot = true, - CountryCode = CountryCode.SH, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c4.jpg" - })); - - AddStep("Show ppy from username", () => profile.ShowUser(new APIUser { Username = @"peppy" })); - AddStep("Show flyte from username", () => profile.ShowUser(new APIUser { Username = @"flyte" })); - - AddStep("Hide", profile.Hide); - AddStep("Show without reload", profile.Show); - } - - private partial class TestUserProfileOverlay : UserProfileOverlay - { - public new ProfileHeader Header => base.Header; - } } } From 4dd7727f71a420ea7058ad5a0f0d133371faaf49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 16:12:39 +0100 Subject: [PATCH 050/248] Remove test-specific workaround in overlay --- osu.Game/Overlays/UserProfileOverlay.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 4fcfc7dc3c..5ec92efdbb 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -116,15 +116,6 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); - // Check arbitrarily whether this user has already been populated. - // This is only generally used by tests, but should be quite safe unless we want to force a refresh on loading a previous user in the future. - if (user is APIUser apiUser && apiUser.JoinDate != default) - { - userReq = null; - userLoadComplete(apiUser); - return; - } - userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID) : new GetUserRequest(user.Username); userReq.Success += userLoadComplete; API.Queue(userReq); From 1722f3a125255174ddf9db18db6126b7023f3823 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 17:53:50 +0100 Subject: [PATCH 051/248] Add ruleset to `UserProfile` --- .../Visual/Online/TestSceneHistoricalSection.cs | 5 +++-- .../Online/TestScenePlayHistorySubsection.cs | 17 +++++++++-------- .../Visual/Online/TestSceneUserProfileHeader.cs | 11 ++++++----- .../Visual/Online/TestSceneUserRanks.cs | 3 ++- osu.Game/Overlays/Profile/UserProfile.cs | 9 +++++++-- osu.Game/Overlays/UserProfileOverlay.cs | 15 +++++++++++---- 6 files changed, 38 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 92bb41b7d5..438e191650 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -11,6 +11,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; +using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual.Online { @@ -38,8 +39,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 2 })); - AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 39828 })); + AddStep("Show peppy", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 2 }, new OsuRuleset().RulesetInfo)); + AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 39828 }, new OsuRuleset().RulesetInfo)); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index a486d77f97..5c6ffdcd80 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -13,6 +13,7 @@ using osu.Framework.Testing; using osu.Framework.Graphics.Shapes; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile; +using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual.Online { @@ -44,49 +45,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_null_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_null_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_empty_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_empty_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_one_value)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_one_value, new OsuRuleset().RulesetInfo)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_two_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_two_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_constant_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_constant_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_zero_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_zero_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_filled_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_filled_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -94,7 +95,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_missing_values)); + AddStep("Load user", () => user.Value = new UserProfile(user_with_missing_values, new OsuRuleset().RulesetInfo)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 4caab98f63..6458f54183 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -9,6 +9,7 @@ using osu.Framework.Testing; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Profile; +using osu.Game.Rulesets.Osu; using osu.Game.Users; namespace osu.Game.Tests.Visual.Online @@ -29,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.UserProfile.Value = new UserProfile(TestSceneUserProfileOverlay.TEST_USER)); + AddStep("Show example user", () => header.UserProfile.Value = new UserProfile(TestSceneUserProfileOverlay.TEST_USER, new OsuRuleset().RulesetInfo)); } [Test] @@ -41,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online Username = "IAmOnline", LastVisit = DateTimeOffset.Now, IsOnline = true, - })); + }, new OsuRuleset().RulesetInfo)); AddStep("Show offline user", () => header.UserProfile.Value = new UserProfile(new APIUser { @@ -49,7 +50,7 @@ namespace osu.Game.Tests.Visual.Online Username = "IAmOffline", LastVisit = DateTimeOffset.Now.AddDays(-10), IsOnline = false, - })); + }, new OsuRuleset().RulesetInfo)); } [Test] @@ -70,7 +71,7 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() }, } - })); + }, new OsuRuleset().RulesetInfo)); AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfile(new APIUser { @@ -86,7 +87,7 @@ namespace osu.Game.Tests.Visual.Online Data = Enumerable.Range(2345, 85).ToArray() }, } - })); + }, new OsuRuleset().RulesetInfo)); } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 184b969279..ab53551ea1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -12,6 +12,7 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; +using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual.Online { @@ -45,7 +46,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfile(new APIUser { Id = 124493 })); + AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfile(new APIUser { Id = 124493 }, new OsuRuleset().RulesetInfo)); } } } diff --git a/osu.Game/Overlays/Profile/UserProfile.cs b/osu.Game/Overlays/Profile/UserProfile.cs index 12a469ddf9..60fc5a0492 100644 --- a/osu.Game/Overlays/Profile/UserProfile.cs +++ b/osu.Game/Overlays/Profile/UserProfile.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile { @@ -15,11 +16,15 @@ namespace osu.Game.Overlays.Profile /// public APIUser User { get; } - // TODO: add ruleset + /// + /// The ruleset that the user profile is being shown with. + /// + public RulesetInfo Ruleset { get; } - public UserProfile(APIUser user) + public UserProfile(APIUser user, RulesetInfo ruleset) { User = user; + Ruleset = ruleset; } } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 5ec92efdbb..2625d85636 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -15,6 +16,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile; using osu.Game.Overlays.Profile.Sections; +using osu.Game.Rulesets; using osu.Game.Users; using osuTK; using osuTK.Graphics; @@ -29,6 +31,9 @@ namespace osu.Game.Overlays private ProfileSectionsContainer? sectionsContainer; private ProfileSectionTabControl? tabs; + [Resolved] + private RulesetStore rulesets { get; set; } = null!; + public const float CONTENT_X_MARGIN = 70; public UserProfileOverlay() @@ -40,7 +45,7 @@ namespace osu.Game.Overlays protected override Color4 BackgroundColour => ColourProvider.Background6; - public void ShowUser(IUser user) + public void ShowUser(IUser user, IRulesetInfo? ruleset = null) { if (user.OnlineID == APIUser.SYSTEM_USER_ID) return; @@ -117,15 +122,17 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID) : new GetUserRequest(user.Username); - userReq.Success += userLoadComplete; + userReq.Success += u => userLoadComplete(u, ruleset); API.Queue(userReq); } - private void userLoadComplete(APIUser user) + private void userLoadComplete(APIUser user, IRulesetInfo? ruleset) { Debug.Assert(sections != null && sectionsContainer != null && tabs != null); - var userProfile = new UserProfile(user); + var actualRuleset = rulesets.GetRuleset(ruleset?.ShortName ?? user.PlayMode).AsNonNull(); + + var userProfile = new UserProfile(user, actualRuleset); Header.UserProfile.Value = userProfile; if (user.ProfileOrder != null) From 7683ab68b034796e1dad3f3a5d63eef71bca450c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 18:03:44 +0100 Subject: [PATCH 052/248] Use `UserProfile` in profile ruleset selector --- .../Online/TestSceneProfileRulesetSelector.cs | 26 +++++++++---------- .../Components/ProfileRulesetSelector.cs | 12 ++++++--- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index a4d8238fa3..a176557d92 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -11,6 +11,7 @@ using osu.Framework.Bindables; using osu.Game.Overlays; using osu.Framework.Allocation; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Profile; namespace osu.Game.Tests.Visual.Online { @@ -21,26 +22,25 @@ namespace osu.Game.Tests.Visual.Online public TestSceneProfileRulesetSelector() { - ProfileRulesetSelector selector; - var user = new Bindable(); + var userProfile = new Bindable(); - Child = selector = new ProfileRulesetSelector + Child = new ProfileRulesetSelector { Anchor = Anchor.Centre, Origin = Anchor.Centre, - User = { BindTarget = user } + UserProfile = { BindTarget = userProfile } }; + AddStep("User on osu ruleset", () => userProfile.Value = new UserProfile(new APIUser { Id = 0, PlayMode = "osu" }, new OsuRuleset().RulesetInfo)); + AddStep("User on taiko ruleset", () => userProfile.Value = new UserProfile(new APIUser { Id = 1, PlayMode = "osu" }, new TaikoRuleset().RulesetInfo)); + AddStep("User on catch ruleset", () => userProfile.Value = new UserProfile(new APIUser { Id = 2, PlayMode = "osu" }, new CatchRuleset().RulesetInfo)); + AddStep("User on mania ruleset", () => userProfile.Value = new UserProfile(new APIUser { Id = 3, PlayMode = "osu" }, new ManiaRuleset().RulesetInfo)); - AddStep("set osu! as default", () => selector.SetDefaultRuleset(new OsuRuleset().RulesetInfo)); - AddStep("set taiko as default", () => selector.SetDefaultRuleset(new TaikoRuleset().RulesetInfo)); - AddStep("set catch as default", () => selector.SetDefaultRuleset(new CatchRuleset().RulesetInfo)); - AddStep("set mania as default", () => selector.SetDefaultRuleset(new ManiaRuleset().RulesetInfo)); + AddStep("User with osu as default", () => userProfile.Value = new UserProfile(new APIUser { Id = 0, PlayMode = "osu" }, new OsuRuleset().RulesetInfo)); + AddStep("User with taiko as default", () => userProfile.Value = new UserProfile(new APIUser { Id = 1, PlayMode = "taiko" }, new OsuRuleset().RulesetInfo)); + AddStep("User with catch as default", () => userProfile.Value = new UserProfile(new APIUser { Id = 2, PlayMode = "fruits" }, new OsuRuleset().RulesetInfo)); + AddStep("User with mania as default", () => userProfile.Value = new UserProfile(new APIUser { Id = 3, PlayMode = "mania" }, new OsuRuleset().RulesetInfo)); - AddStep("User with osu as default", () => user.Value = new APIUser { Id = 0, PlayMode = "osu" }); - AddStep("User with taiko as default", () => user.Value = new APIUser { Id = 1, PlayMode = "taiko" }); - AddStep("User with catch as default", () => user.Value = new APIUser { Id = 2, PlayMode = "fruits" }); - AddStep("User with mania as default", () => user.Value = new APIUser { Id = 3, PlayMode = "mania" }); - AddStep("null user", () => user.Value = null); + AddStep("null user", () => userProfile.Value = null); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 684ce9088e..fff6ead528 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -4,19 +4,25 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.UserInterface; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile.Header.Components { public partial class ProfileRulesetSelector : OverlayRulesetSelector { - public readonly Bindable User = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu").AsNonNull()), true); + + UserProfile.BindValueChanged(userProfile => updateState(userProfile.NewValue), true); + } + + private void updateState(UserProfile? userProfile) + { + Current.Value = userProfile?.Ruleset; + SetDefaultRuleset(Rulesets.GetRuleset(userProfile?.User.PlayMode ?? @"osu").AsNonNull()); } public void SetDefaultRuleset(RulesetInfo ruleset) From a2e726502f8c549361f4fcbfba5cebe9a2e5db4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 18:44:03 +0100 Subject: [PATCH 053/248] Add ruleset selector to profile overlay --- .../Visual/Online/TestSceneUserProfileOverlay.cs | 1 + .../Profile/Header/Components/ProfileRulesetSelector.cs | 4 +++- osu.Game/Overlays/Profile/ProfileHeader.cs | 8 ++++++++ osu.Game/Overlays/TabControlOverlayHeader.cs | 8 ++++---- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 446e13a8a3..393fcd6d70 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -98,6 +98,7 @@ namespace osu.Game.Tests.Visual.Online Title = "osu!volunteer", Colour = "ff0000", Achievements = Array.Empty(), + PlayMode = "osu" }; } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index fff6ead528..cdd0ed0b0a 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -1,9 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.UserInterface; +using osu.Game.Extensions; using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile.Header.Components @@ -21,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private void updateState(UserProfile? userProfile) { - Current.Value = userProfile?.Ruleset; + Current.Value = Items.SingleOrDefault(ruleset => userProfile?.Ruleset.MatchesOnlineID(ruleset) == true); SetDefaultRuleset(Rulesets.GetRuleset(userProfile?.User.PlayMode ?? @"osu").AsNonNull()); } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 447e9148e8..059469230c 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Overlays.Profile.Header; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Resources.Localisation.Web; using osu.Game.Users; @@ -35,6 +36,13 @@ namespace osu.Game.Overlays.Profile // todo: pending implementation. // TabControl.AddItem(LayoutStrings.HeaderUsersModding); + TabControlContainer.Add(new ProfileRulesetSelector + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + UserProfile = { BindTarget = UserProfile } + }); + // Haphazardly guaranteed by OverlayHeader constructor (see CreateBackground / CreateContent). Debug.Assert(centreHeaderContainer != null); Debug.Assert(detailHeaderContainer != null); diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index cad94eba71..8613bac40c 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -23,10 +23,10 @@ namespace osu.Game.Overlays /// The type of item to be represented by tabs. public abstract partial class TabControlOverlayHeader : OverlayHeader, IHasCurrentValue { - protected OsuTabControl TabControl; + protected OsuTabControl TabControl { get; } + protected Container TabControlContainer { get; } private readonly Box controlBackground; - private readonly Container tabControlContainer; private readonly BindableWithCurrent current = new BindableWithCurrent(); public Bindable Current @@ -41,7 +41,7 @@ namespace osu.Game.Overlays set { base.ContentSidePadding = value; - tabControlContainer.Padding = new MarginPadding { Horizontal = value }; + TabControlContainer.Padding = new MarginPadding { Horizontal = value }; } } @@ -57,7 +57,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, }, - tabControlContainer = new Container + TabControlContainer = new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, From c759b743dc2c27bea5686ace7a9ebb34e045073f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 19:12:50 +0100 Subject: [PATCH 054/248] Add support for switching rulesets on profile overlay --- .../Profile/Header/Components/ProfileRulesetSelector.cs | 9 +++++++++ .../Sections/Beatmaps/PaginatedBeatmapContainer.cs | 4 ++-- .../Historical/PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- .../Sections/Kudosu/PaginatedKudosuHistoryContainer.cs | 5 ++--- .../Profile/Sections/PaginatedProfileSubsection.cs | 6 +++--- .../Profile/Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- .../Sections/Recent/PaginatedRecentActivityContainer.cs | 5 ++--- osu.Game/Overlays/UserProfileOverlay.cs | 5 +++-- 8 files changed, 25 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index cdd0ed0b0a..2214112577 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics.UserInterface; @@ -12,6 +13,9 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class ProfileRulesetSelector : OverlayRulesetSelector { + [Resolved] + private UserProfileOverlay? profileOverlay { get; set; } + public readonly Bindable UserProfile = new Bindable(); protected override void LoadComplete() @@ -19,6 +23,11 @@ namespace osu.Game.Overlays.Profile.Header.Components base.LoadComplete(); UserProfile.BindValueChanged(userProfile => updateState(userProfile.NewValue), true); + Current.BindValueChanged(ruleset => + { + if (UserProfile.Value != null && !ruleset.NewValue.Equals(UserProfile.Value.Ruleset)) + profileOverlay?.ShowUser(UserProfile.Value.User, ruleset.NewValue); + }); } private void updateState(UserProfile? userProfile) diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 3b1f26ee7d..be7a3039f1 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -64,8 +64,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps } } - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => - new GetUserBeatmapsRequest(user.Id, type, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) => + new GetUserBeatmapsRequest(userProfile.User.Id, type, pagination); protected override Drawable? CreateDrawableItem(APIBeatmapSet model) => model.OnlineID > 0 ? new BeatmapCardNormal(model) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 5851262229..3d1458ddf5 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -29,8 +29,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override int GetCount(APIUser user) => user.BeatmapPlayCountsCount; - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => - new GetUserMostPlayedBeatmapsRequest(user.Id, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) => + new GetUserMostPlayedBeatmapsRequest(userProfile.User.Id, pagination); protected override Drawable CreateDrawableItem(APIUserMostPlayedBeatmap mostPlayed) => new DrawableMostPlayedBeatmap(mostPlayed); diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index 6addd86894..f65b334a9d 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -8,7 +8,6 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API; using System.Collections.Generic; using osu.Game.Resources.Localisation.Web; -using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Kudosu { @@ -19,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { } - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) - => new GetUserKudosuHistoryRequest(user.Id, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) + => new GetUserKudosuHistoryRequest(userProfile.User.Id, pagination); protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item); } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index d77844fd56..654cc9ff7b 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -109,14 +109,14 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { - if (UserProfile.Value?.User == null) + if (UserProfile.Value == null) return; loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(UserProfile.Value.User, CurrentPage.Value); + retrievalRequest = CreateRequest(UserProfile.Value, CurrentPage.Value); retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); @@ -154,7 +154,7 @@ namespace osu.Game.Overlays.Profile.Sections { } - protected abstract APIRequest> CreateRequest(APIUser user, PaginationParameters pagination); + protected abstract APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination); protected abstract Drawable? CreateDrawableItem(TModel model); diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index cdd1738c8e..aba63cc25d 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -60,8 +60,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks base.OnItemsReceived(items); } - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => - new GetUserScoresRequest(user.Id, type, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) => + new GetUserScoresRequest(userProfile.User.Id, type, pagination, userProfile.Ruleset); private int drawableItemIndex; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index c08ea58b5a..74247572ed 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -10,7 +10,6 @@ using System.Collections.Generic; using osuTK; using osu.Framework.Allocation; using osu.Game.Resources.Localisation.Web; -using APIUser = osu.Game.Online.API.Requests.Responses.APIUser; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -27,8 +26,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent ItemsContainer.Spacing = new Vector2(0, 8); } - protected override APIRequest> CreateRequest(APIUser user, PaginationParameters pagination) => - new GetUserRecentActivitiesRequest(user.Id, pagination); + protected override APIRequest> CreateRequest(UserProfile userProfile, PaginationParameters pagination) => + new GetUserRecentActivitiesRequest(userProfile.User.Id, pagination); protected override Drawable CreateDrawableItem(APIRecentActivity model) => new DrawableRecentActivity(model); } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 2625d85636..185119c631 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; +using osu.Game.Extensions; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; @@ -52,7 +53,7 @@ namespace osu.Game.Overlays Show(); - if (user.OnlineID == Header?.UserProfile.Value?.User.Id) + if (user.OnlineID == Header.UserProfile.Value?.User.Id && ruleset?.MatchesOnlineID(Header.UserProfile.Value?.Ruleset) == true) return; if (sectionsContainer != null) @@ -121,7 +122,7 @@ namespace osu.Game.Overlays sectionsContainer.ScrollToTop(); - userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID) : new GetUserRequest(user.Username); + userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID, ruleset) : new GetUserRequest(user.Username, ruleset); userReq.Success += u => userLoadComplete(u, ruleset); API.Queue(userReq); } From a124c967dfd96a671640b24734f9e9c10d574f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 30 Dec 2022 20:13:23 +0100 Subject: [PATCH 055/248] Add proper offline & loading state handling to user profile overlay --- .../Online/TestSceneUserProfileOverlay.cs | 25 +++++++++++++++++++ osu.Game/Overlays/UserProfileOverlay.cs | 18 +++++++++++++ 2 files changed, 43 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 393fcd6d70..d3d9dcb990 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -51,6 +51,31 @@ namespace osu.Game.Tests.Visual.Online }); AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 })); AddToggleStep("toggle visibility", visible => profile.State.Value = visible ? Visibility.Visible : Visibility.Hidden); + AddStep("log out", () => dummyAPI.Logout()); + AddStep("log back in", () => dummyAPI.Login("username", "password")); + } + + [Test] + public void TestLoading() + { + GetUserRequest pendingRequest = null!; + + AddStep("set up request handling", () => + { + dummyAPI.HandleRequest = req => + { + if (req is GetUserRequest getUserRequest) + { + pendingRequest = getUserRequest; + return true; + } + + return false; + }; + }); + AddStep("show user", () => profile.ShowUser(new APIUser { Id = 1 })); + AddWaitStep("wait some", 3); + AddStep("complete request", () => pendingRequest.TriggerSuccess(TEST_USER)); } public static readonly APIUser TEST_USER = new APIUser diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 185119c631..155833e0c6 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -13,6 +13,8 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Extensions; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile; @@ -26,6 +28,11 @@ namespace osu.Game.Overlays { public partial class UserProfileOverlay : FullscreenOverlay { + protected override Container Content => onlineViewContainer; + + private readonly OnlineViewContainer onlineViewContainer; + private readonly LoadingLayer loadingLayer; + private ProfileSection? lastSection; private ProfileSection[]? sections; private GetUserRequest? userReq; @@ -40,6 +47,14 @@ namespace osu.Game.Overlays public UserProfileOverlay() : base(OverlayColourScheme.Pink) { + base.Content.AddRange(new Drawable[] + { + onlineViewContainer = new OnlineViewContainer($"Sign in to view the {Header.Title.Title}") + { + RelativeSizeAxes = Axes.Both + }, + loadingLayer = new LoadingLayer(true) + }); } protected override ProfileHeader CreateHeader() => new ProfileHeader(); @@ -125,6 +140,7 @@ namespace osu.Game.Overlays userReq = user.OnlineID > 1 ? new GetUserRequest(user.OnlineID, ruleset) : new GetUserRequest(user.Username, ruleset); userReq.Success += u => userLoadComplete(u, ruleset); API.Queue(userReq); + loadingLayer.Show(); } private void userLoadComplete(APIUser user, IRulesetInfo? ruleset) @@ -151,6 +167,8 @@ namespace osu.Game.Overlays } } } + + loadingLayer.Hide(); } private partial class ProfileSectionTabControl : OverlayTabControl From 387326db0d2b0c307e642649b065771ee7e7c682 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 6 Jan 2023 22:51:57 +0300 Subject: [PATCH 056/248] Make commit action abstract --- .../Visual/UserInterface/TestSceneCommentEditor.cs | 12 ++++++------ osu.Game/Overlays/Comments/CommentEditor.cs | 13 ++++--------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index a0a1c2481f..aeaca5ac21 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -118,12 +118,7 @@ namespace osu.Game.Tests.Visual.UserInterface public bool ButtonLoading => CommitButton.ChildrenOfType().Single().IsPresent && !CommitButton.ChildrenOfType().Single().IsPresent; - public TestCommentEditor() - { - OnCommit = onCommit; - } - - private void onCommit(string value) + protected override void OnCommit(string value) { CommitButton.IsLoadingSpinnerShown = true; CommittedText = value; @@ -138,6 +133,7 @@ namespace osu.Game.Tests.Visual.UserInterface private partial class TestCancellableCommentEditor : CancellableCommentEditor { public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; + protected override LocalisableString FooterText => @"Wow, another one. Sicc"; public bool Cancelled { get; private set; } @@ -147,6 +143,10 @@ namespace osu.Game.Tests.Visual.UserInterface OnCancel = () => Cancelled = true; } + protected override void OnCommit(string text) + { + } + protected override LocalisableString CommitButtonText => @"Save"; protected override LocalisableString TextBoxPlaceholder => @"Multiline textboxes soon"; } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 092a92f935..c7c66874d1 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.Sprites; using osuTK.Graphics; using osu.Game.Graphics.UserInterface; -using System; using osuTK; using osu.Framework.Bindables; using osu.Framework.Localisation; @@ -23,8 +22,6 @@ namespace osu.Game.Overlays.Comments { private const int side_padding = 8; - public Action? OnCommit; - protected abstract LocalisableString FooterText { get; } protected abstract LocalisableString CommitButtonText { get; } @@ -98,11 +95,7 @@ namespace osu.Game.Overlays.Comments Text = CommitButtonText, Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Action = () => - { - OnCommit?.Invoke(Current.Value); - Current.Value = string.Empty; - } + Action = () => OnCommit(Current.Value) } } } @@ -121,6 +114,8 @@ namespace osu.Game.Overlays.Comments Current.BindValueChanged(text => CommitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } + protected abstract void OnCommit(string text); + private partial class EditorTextBox : BasicTextBox { protected override float LeftRightPadding => side_padding; @@ -151,7 +146,7 @@ namespace osu.Game.Overlays.Comments protected override Drawable GetDrawableCharacter(char c) => new FallingDownContainer { AutoSizeAxes = Axes.Both, - Child = new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) }, + Child = new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) } }; } From 47fb467012d77ce75da83ca2c884529d4644154d Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 8 Jan 2023 19:02:48 +0100 Subject: [PATCH 057/248] Remove nullable disabling in carousel --- .../SongSelect/TestScenePlaySongSelect.cs | 6 +-- osu.Game/Screens/Select/BeatmapCarousel.cs | 8 ++-- .../Select/Carousel/CarouselBeatmap.cs | 2 - .../Select/Carousel/CarouselBeatmapSet.cs | 10 ++--- .../Screens/Select/Carousel/CarouselGroup.cs | 2 +- .../Carousel/CarouselGroupEagerSelect.cs | 10 ++--- .../Screens/Select/Carousel/CarouselHeader.cs | 6 +-- .../Screens/Select/Carousel/CarouselItem.cs | 4 +- .../Carousel/DrawableCarouselBeatmap.cs | 44 +++++++++--------- .../Carousel/DrawableCarouselBeatmapSet.cs | 45 +++++++++---------- .../Select/Carousel/DrawableCarouselItem.cs | 14 +++--- .../Carousel/FilterableDifficultyIcon.cs | 2 - .../Select/Carousel/GroupedDifficultyIcon.cs | 2 - .../Select/Carousel/SetPanelBackground.cs | 2 - .../Select/Carousel/SetPanelContent.cs | 2 - 15 files changed, 65 insertions(+), 94 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 01c5ad8358..cfee02dfb8 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -208,7 +208,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("select next and enter", () => { InputManager.MoveMouseTo(songSelect!.Carousel.ChildrenOfType() - .First(b => !((CarouselBeatmap)b.Item).BeatmapInfo.Equals(songSelect!.Carousel.SelectedBeatmapInfo))); + .First(b => !((CarouselBeatmap)b.Item!).BeatmapInfo.Equals(songSelect!.Carousel.SelectedBeatmapInfo))); InputManager.Click(MouseButton.Left); @@ -235,7 +235,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("select next and enter", () => { InputManager.MoveMouseTo(songSelect!.Carousel.ChildrenOfType() - .First(b => !((CarouselBeatmap)b.Item).BeatmapInfo.Equals(songSelect!.Carousel.SelectedBeatmapInfo))); + .First(b => !((CarouselBeatmap)b.Item!).BeatmapInfo.Equals(songSelect!.Carousel.SelectedBeatmapInfo))); InputManager.PressButton(MouseButton.Left); @@ -614,7 +614,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("selected only shows expected ruleset (plus converts)", () => { - var selectedPanel = songSelect!.Carousel.ChildrenOfType().First(s => s.Item.State.Value == CarouselItemState.Selected); + var selectedPanel = songSelect!.Carousel.ChildrenOfType().First(s => s.Item!.State.Value == CarouselItemState.Selected); // special case for converts checked here. return selectedPanel.ChildrenOfType().All(i => diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 6955b8ef56..4a6ff7417e 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -64,7 +64,7 @@ namespace osu.Game.Screens.Select /// /// A function to optionally decide on a recommended difficulty from a beatmap set. /// - public Func, BeatmapInfo>? GetRecommendedBeatmap; + public Func, BeatmapInfo?>? GetRecommendedBeatmap; private CarouselBeatmapSet? selectedBeatmapSet; @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Select { CarouselRoot newRoot = new CarouselRoot(this); - newRoot.AddItems(beatmapSets.Select(s => createCarouselSet(s.Detach())).Where(g => g != null)); + newRoot.AddItems(beatmapSets.Select(s => createCarouselSet(s.Detach())).Where(g => g != null)!); root = newRoot; @@ -739,7 +739,7 @@ namespace osu.Game.Screens.Select foreach (var panel in Scroll.Children) { - if (toDisplay.Remove(panel.Item)) + if (toDisplay.Remove(panel.Item!)) { // panel already displayed. continue; @@ -770,7 +770,7 @@ namespace osu.Game.Screens.Select { updateItem(item); - if (item.Item.Visible) + if (item.Item!.Visible) { bool isSelected = item.Item.State.Value == CarouselItemState.Selected; diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 03490ff37b..837939716b 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Game.Beatmaps; diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 9a4319c6b2..a360ddabc7 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -33,7 +31,7 @@ namespace osu.Game.Screens.Select.Carousel public BeatmapSetInfo BeatmapSet; - public Func, BeatmapInfo> GetRecommendedBeatmap; + public Func, BeatmapInfo?>? GetRecommendedBeatmap; public CarouselBeatmapSet(BeatmapSetInfo beatmapSet) { @@ -47,7 +45,7 @@ namespace osu.Game.Screens.Select.Carousel .ForEach(AddItem); } - protected override CarouselItem GetNextToSelect() + protected override CarouselItem? GetNextToSelect() { if (LastSelected == null || LastSelected.Filtered.Value) { @@ -132,8 +130,8 @@ namespace osu.Game.Screens.Select.Carousel bool filtered = Items.All(i => i.Filtered.Value); - filtered |= criteria.Sort == SortMode.DateRanked && BeatmapSet?.DateRanked == null; - filtered |= criteria.Sort == SortMode.DateSubmitted && BeatmapSet?.DateSubmitted == null; + filtered |= criteria.Sort == SortMode.DateRanked && BeatmapSet.DateRanked == null; + filtered |= criteria.Sort == SortMode.DateSubmitted && BeatmapSet.DateSubmitted == null; Filtered.Value = filtered; } diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs index 9302578038..8667dce226 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens.Select.Carousel /// public class CarouselGroup : CarouselItem { - public override DrawableCarouselItem? CreateDrawableRepresentation() => null; + public override DrawableCarouselItem CreateDrawableRepresentation() => null!; public IReadOnlyList Items => items; diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs index 6366fc8050..7f90e05744 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroupEagerSelect.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -26,7 +24,7 @@ namespace osu.Game.Screens.Select.Carousel /// /// The last selected item. /// - protected CarouselItem LastSelected { get; private set; } + protected CarouselItem? LastSelected { get; private set; } /// /// We need to keep track of the index for cases where the selection is removed but we want to select a new item based on its old location. @@ -112,7 +110,7 @@ namespace osu.Game.Screens.Select.Carousel /// Finds the item this group would select next if it attempted selection /// /// An unfiltered item nearest to the last selected one or null if all items are filtered - protected virtual CarouselItem GetNextToSelect() + protected virtual CarouselItem? GetNextToSelect() { if (Items.Count == 0) return null; @@ -141,7 +139,7 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void PerformSelection() { - CarouselItem nextToSelect = GetNextToSelect(); + CarouselItem? nextToSelect = GetNextToSelect(); if (nextToSelect != null) nextToSelect.State.Value = CarouselItemState.Selected; @@ -149,7 +147,7 @@ namespace osu.Game.Screens.Select.Carousel updateSelected(null); } - private void updateSelected(CarouselItem newSelection) + private void updateSelected(CarouselItem? newSelection) { if (newSelection != null) LastSelected = newSelection; diff --git a/osu.Game/Screens/Select/Carousel/CarouselHeader.cs b/osu.Game/Screens/Select/Carousel/CarouselHeader.cs index 1ae69bc951..e46f0da45d 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselHeader.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -95,9 +93,9 @@ namespace osu.Game.Screens.Select.Carousel public partial class HoverLayer : HoverSampleDebounceComponent { - private Sample sampleHover; + private Sample? sampleHover; - private Box box; + private Box box = null!; public HoverLayer() { diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index cbf079eb4b..5de9f2b995 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; @@ -51,7 +49,7 @@ namespace osu.Game.Screens.Select.Carousel public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ItemID.CompareTo(other.ItemID); - public int CompareTo(CarouselItem other) => CarouselYPosition.CompareTo(other.CarouselYPosition); + public int CompareTo(CarouselItem? other) => CarouselYPosition.CompareTo(other!.CarouselYPosition); } public enum CarouselItemState diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 4e10961e55..88a55198b2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -47,31 +45,31 @@ namespace osu.Game.Screens.Select.Carousel private readonly BeatmapInfo beatmapInfo; - private Sprite background; + private Sprite background = null!; - private Action startRequested; - private Action editRequested; - private Action hideRequested; + private Action? startRequested; + private Action? editRequested; + private Action? hideRequested; - private Triangles triangles; + private Triangles triangles = null!; - private StarCounter starCounter; - private DifficultyIcon difficultyIcon; - - [Resolved(CanBeNull = true)] - private BeatmapSetOverlay beatmapOverlay { get; set; } + private StarCounter starCounter = null!; + private DifficultyIcon difficultyIcon = null!; [Resolved] - private BeatmapDifficultyCache difficultyCache { get; set; } - - [Resolved(CanBeNull = true)] - private ManageCollectionsDialog manageCollectionsDialog { get; set; } + private BeatmapSetOverlay? beatmapOverlay { get; set; } [Resolved] - private RealmAccess realm { get; set; } + private BeatmapDifficultyCache difficultyCache { get; set; } = null!; - private IBindable starDifficultyBindable; - private CancellationTokenSource starDifficultyCancellationSource; + [Resolved] + private ManageCollectionsDialog? manageCollectionsDialog { get; set; } + + [Resolved] + private RealmAccess realm { get; set; } = null!; + + private IBindable starDifficultyBindable = null!; + private CancellationTokenSource? starDifficultyCancellationSource; public DrawableCarouselBeatmap(CarouselBeatmap panel) { @@ -79,8 +77,8 @@ namespace osu.Game.Screens.Select.Carousel Item = panel; } - [BackgroundDependencyLoader(true)] - private void load(BeatmapManager manager, SongSelect songSelect) + [BackgroundDependencyLoader] + private void load(BeatmapManager? manager, SongSelect? songSelect) { Header.Height = height; @@ -194,7 +192,7 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - if (Item.State.Value == CarouselItemState.Selected) + if (Item!.State.Value == CarouselItemState.Selected) startRequested?.Invoke(beatmapInfo); return base.OnClick(e); @@ -202,7 +200,7 @@ namespace osu.Game.Screens.Select.Carousel protected override void ApplyState() { - if (Item.State.Value != CarouselItemState.Collapsed && Alpha == 0) + if (Item!.State.Value != CarouselItemState.Collapsed && Alpha == 0) starCounter.ReplayAnimation(); starDifficultyCancellationSource?.Cancel(); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index a7fb25bc1b..f0bb8b15c2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -1,14 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -27,30 +24,28 @@ namespace osu.Game.Screens.Select.Carousel { public const float HEIGHT = MAX_HEIGHT; - private Action restoreHiddenRequested; - private Action viewDetails; - - [Resolved(CanBeNull = true)] - private IDialogOverlay dialogOverlay { get; set; } - - [Resolved(CanBeNull = true)] - private ManageCollectionsDialog manageCollectionsDialog { get; set; } + private Action restoreHiddenRequested = null!; + private Action? viewDetails; [Resolved] - private RealmAccess realm { get; set; } + private IDialogOverlay? dialogOverlay { get; set; } + + [Resolved] + private ManageCollectionsDialog? manageCollectionsDialog { get; set; } + + [Resolved] + private RealmAccess realm { get; set; } = null!; public IEnumerable DrawableBeatmaps => beatmapContainer?.IsLoaded != true ? Enumerable.Empty() : beatmapContainer.AliveChildren; - [CanBeNull] - private Container beatmapContainer; + private Container? beatmapContainer; - private BeatmapSetInfo beatmapSet; + private BeatmapSetInfo beatmapSet = null!; - [CanBeNull] - private Task beatmapsLoadTask; + private Task? beatmapsLoadTask; [Resolved] - private BeatmapManager manager { get; set; } + private BeatmapManager manager { get; set; } = null!; protected override void FreeAfterUse() { @@ -61,8 +56,8 @@ namespace osu.Game.Screens.Select.Carousel ClearTransforms(); } - [BackgroundDependencyLoader(true)] - private void load(BeatmapSetOverlay beatmapOverlay) + [BackgroundDependencyLoader] + private void load(BeatmapSetOverlay? beatmapOverlay) { restoreHiddenRequested = s => { @@ -80,7 +75,7 @@ namespace osu.Game.Screens.Select.Carousel // position updates should not occur if the item is filtered away. // this avoids panels flying across the screen only to be eventually off-screen or faded out. - if (!Item.Visible) + if (!Item!.Visible) return; float targetY = Item.CarouselYPosition; @@ -151,7 +146,7 @@ namespace osu.Game.Screens.Select.Carousel private void updateBeatmapDifficulties() { - var carouselBeatmapSet = (CarouselBeatmapSet)Item; + var carouselBeatmapSet = (CarouselBeatmapSet)Item!; var visibleBeatmaps = carouselBeatmapSet.Items.Where(c => c.Visible).ToArray(); @@ -196,14 +191,14 @@ namespace osu.Game.Screens.Select.Carousel float yPos = DrawableCarouselBeatmap.CAROUSEL_BEATMAP_SPACING; - bool isSelected = Item.State.Value == CarouselItemState.Selected; + bool isSelected = Item!.State.Value == CarouselItemState.Selected; foreach (var panel in beatmapContainer.Children) { if (isSelected) { panel.MoveToY(yPos, 800, Easing.OutQuint); - yPos += panel.Item.TotalHeight; + yPos += panel.Item!.TotalHeight; } else panel.MoveToY(0, 800, Easing.OutQuint); @@ -218,7 +213,7 @@ namespace osu.Game.Screens.Select.Carousel List items = new List(); - if (Item.State.Value == CarouselItemState.NotSelected) + if (Item!.State.Value == CarouselItemState.NotSelected) items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => Item.State.Value = CarouselItemState.Selected)); if (beatmapSet.OnlineID > 0 && viewDetails != null) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index 26a32c23dd..580dcb3471 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Diagnostics; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -34,9 +32,9 @@ namespace osu.Game.Screens.Select.Carousel public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Header.ReceivePositionalInputAt(screenSpacePos); - private CarouselItem item; + private CarouselItem? item; - public CarouselItem Item + public CarouselItem? Item { get => item; set @@ -105,7 +103,7 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void UpdateItem() { - if (item == null) + if (item == null || Item == null) return; Scheduler.AddOnce(ApplyState); @@ -130,9 +128,7 @@ namespace osu.Game.Screens.Select.Carousel { // Use the fact that we know the precise height of the item from the model to avoid the need for AutoSize overhead. // Additionally, AutoSize doesn't work well due to content starting off-screen and being masked away. - Height = Item.TotalHeight; - - Debug.Assert(Item != null); + Height = Item!.TotalHeight; switch (Item.State.Value) { @@ -162,7 +158,7 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - Item.State.Value = CarouselItemState.Selected; + Item!.State.Value = CarouselItemState.Selected; return true; } } diff --git a/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs b/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs index 911b8fd4da..cd8e20ad39 100644 --- a/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs +++ b/osu.Game/Screens/Select/Carousel/FilterableDifficultyIcon.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Input.Events; diff --git a/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs b/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs index 6e01c82a08..3de44fa032 100644 --- a/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs +++ b/osu.Game/Screens/Select/Carousel/GroupedDifficultyIcon.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs b/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs index a9dc59cc39..6f13a34bfc 100644 --- a/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs +++ b/osu.Game/Screens/Select/Carousel/SetPanelBackground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs index 0de507edce..7ca0e92ac8 100644 --- a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs +++ b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; From a32c4a64e74bae35fa294e4d00b1e7d150aa88fe Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 8 Jan 2023 19:18:28 +0100 Subject: [PATCH 058/248] Fix errors in test --- .../Visual/SongSelect/TestSceneBeatmapCarousel.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 2d1c5ef120..3cff853f92 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.SongSelect var visibleBeatmapPanels = carousel.Items.OfType().Where(p => p.IsPresent).ToArray(); return visibleBeatmapPanels.Length == 1 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 0) == 1; + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item)!.BeatmapInfo.Ruleset.OnlineID == 0) == 1; }); AddStep("filter to ruleset 1", () => carousel.Filter(new FilterCriteria @@ -86,8 +86,8 @@ namespace osu.Game.Tests.Visual.SongSelect var visibleBeatmapPanels = carousel.Items.OfType().Where(p => p.IsPresent).ToArray(); return visibleBeatmapPanels.Length == 2 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 0) == 1 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 1) == 1; + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item)!.BeatmapInfo.Ruleset.OnlineID == 0) == 1 + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item)!.BeatmapInfo.Ruleset.OnlineID == 1) == 1; }); AddStep("filter to ruleset 2", () => carousel.Filter(new FilterCriteria @@ -101,8 +101,8 @@ namespace osu.Game.Tests.Visual.SongSelect var visibleBeatmapPanels = carousel.Items.OfType().Where(p => p.IsPresent).ToArray(); return visibleBeatmapPanels.Length == 2 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 0) == 1 - && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item).BeatmapInfo.Ruleset.OnlineID == 2) == 1; + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item!).BeatmapInfo.Ruleset.OnlineID == 0) == 1 + && visibleBeatmapPanels.Count(p => ((CarouselBeatmap)p.Item!).BeatmapInfo.Ruleset.OnlineID == 2) == 1; }); } @@ -1069,7 +1069,7 @@ namespace osu.Game.Tests.Visual.SongSelect return Precision.AlmostEquals( carousel.ScreenSpaceDrawQuad.Centre, carousel.Items - .First(i => i.Item.State.Value == CarouselItemState.Selected) + .First(i => i.Item!.State.Value == CarouselItemState.Selected) .ScreenSpaceDrawQuad.Centre, 100); }); } @@ -1103,7 +1103,7 @@ namespace osu.Game.Tests.Visual.SongSelect if (currentlySelected == null) return true; - return currentlySelected.Item.Visible; + return currentlySelected.Item!.Visible; } private void checkInvisibleDifficultiesUnselectable() From f6b1dfc7b0f0f390e9fa9733aa528847a7fa648d Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 28 May 2022 21:41:23 -0700 Subject: [PATCH 059/248] Fix channel listing items overflowing at high ui scaling --- .../Chat/Listing/ChannelListingItem.cs | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs index 22a3bdc06f..9c85c73ee4 100644 --- a/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs +++ b/osu.Game/Overlays/Chat/Listing/ChannelListingItem.cs @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Chat.Listing private Box hoverBox = null!; private SpriteIcon checkbox = null!; private OsuSpriteText channelText = null!; - private OsuSpriteText topicText = null!; + private OsuTextFlowContainer topicText = null!; private IBindable channelJoined = null!; [Resolved] @@ -65,8 +65,8 @@ namespace osu.Game.Overlays.Chat.Listing Masking = true; CornerRadius = 5; - RelativeSizeAxes = Axes.X; - Height = 20 + (vertical_margin * 2); + RelativeSizeAxes = Content.RelativeSizeAxes = Axes.X; + AutoSizeAxes = Content.AutoSizeAxes = Axes.Y; Children = new Drawable[] { @@ -79,14 +79,19 @@ namespace osu.Game.Overlays.Chat.Listing }, new GridContainer { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, ColumnDimensions = new[] { new Dimension(GridSizeMode.Absolute, 40), new Dimension(GridSizeMode.Absolute, 200), - new Dimension(GridSizeMode.Absolute, 400), + new Dimension(maxSize: 400), new Dimension(GridSizeMode.AutoSize), - new Dimension(), + new Dimension(GridSizeMode.Absolute, 50), // enough for any 5 digit user count + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize, minSize: 20 + (vertical_margin * 2)), }, Content = new[] { @@ -108,12 +113,13 @@ namespace osu.Game.Overlays.Chat.Listing Font = OsuFont.Torus.With(size: text_size, weight: FontWeight.SemiBold), Margin = new MarginPadding { Bottom = 2 }, }, - topicText = new OsuSpriteText + topicText = new OsuTextFlowContainer(t => t.Font = OsuFont.Torus.With(size: text_size)) { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Text = Channel.Topic, - Font = OsuFont.Torus.With(size: text_size), Margin = new MarginPadding { Bottom = 2 }, }, new SpriteIcon From 13b00928c81f9e212c9618108660cfa205c55361 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 15:52:08 +0900 Subject: [PATCH 060/248] Rename loading spinner bool to reflect that it has a setter --- .../UserInterface/TestSceneCommentEditor.cs | 4 ++-- osu.Game/Overlays/Comments/CommentEditor.cs | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index aeaca5ac21..799f5c52bd 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -120,9 +120,9 @@ namespace osu.Game.Tests.Visual.UserInterface protected override void OnCommit(string value) { - CommitButton.IsLoadingSpinnerShown = true; + CommitButton.ShowLoadingSpinner = true; CommittedText = value; - Scheduler.AddDelayed(() => CommitButton.IsLoadingSpinnerShown = false, 1000); + Scheduler.AddDelayed(() => CommitButton.ShowLoadingSpinner = false, 1000); } protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index c7c66874d1..da71d0f364 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -2,19 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.Containers; +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.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Graphics.Sprites; -using osuTK.Graphics; using osu.Game.Graphics.UserInterface; -using osuTK; -using osu.Framework.Bindables; -using osu.Framework.Localisation; using osu.Game.Graphics.UserInterfaceV2; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Comments { @@ -159,17 +159,17 @@ namespace osu.Game.Overlays.Comments public readonly BindableBool IsBlocked = new BindableBool(); - private bool isLoadingSpinnerShown; + private bool showLoadingSpinner; /// /// Whether loading spinner shown. /// - public bool IsLoadingSpinnerShown + public bool ShowLoadingSpinner { - get => isLoadingSpinnerShown; + get => showLoadingSpinner; set { - isLoadingSpinnerShown = value; + showLoadingSpinner = value; Enabled.Value = !value && !IsBlocked.Value; spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); @@ -194,7 +194,7 @@ namespace osu.Game.Overlays.Comments base.LoadComplete(); IsBlocked.BindValueChanged(e => { - Enabled.Value = !IsLoadingSpinnerShown && !e.NewValue; + Enabled.Value = !ShowLoadingSpinner && !e.NewValue; }, true); } From 13c3d2c25444aae1e3c1de607fc566659781a01f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:15:30 +0900 Subject: [PATCH 061/248] Fix retry loop for channel initialisation resulting in request pile-up Closes #22060. --- osu.Game/Online/Chat/ChannelManager.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 5d55374373..9741341efc 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -335,6 +335,11 @@ namespace osu.Game.Online.Chat private void initializeChannels() { + // This request is self-retrying until it succeeds. + // To avoid requests piling up when not logged in (ie. API is unavailable) exit early. + if (api.IsLoggedIn) + return; + var req = new ListChannelsRequest(); bool joinDefaults = JoinedChannels.Count == 0; @@ -350,10 +355,11 @@ namespace osu.Game.Online.Chat joinChannel(ch); } }; + req.Failure += error => { Logger.Error(error, "Fetching channel list failed"); - initializeChannels(); + Scheduler.AddDelayed(initializeChannels, 60000); }; api.Queue(req); From 4a77105e78f15b1a72d1b10a61b6dc5e8346ddc1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:28:08 +0900 Subject: [PATCH 062/248] Rename `LockPlayfieldAspect` and add comment explaining the change --- osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs | 2 +- osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs | 4 ++-- .../UI/TaikoPlayfieldAdjustmentContainer.cs | 9 +++++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs index f7fdd447d6..3b3b3e606c 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Taiko.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset; - drawableTaikoRuleset.LockPlayfieldAspect.Value = false; + drawableTaikoRuleset.LockPlayfieldMaxAspect.Value = false; var playfield = (TaikoPlayfield)drawableRuleset.Playfield; playfield.ClassicHitTargetPosition.Value = true; diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs index 32a83d87b8..146daa8c27 100644 --- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.UI { public new BindableDouble TimeRange => base.TimeRange; - public readonly BindableBool LockPlayfieldAspect = new BindableBool(true); + public readonly BindableBool LockPlayfieldMaxAspect = new BindableBool(true); protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping; @@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Taiko.UI public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer { - LockPlayfieldAspect = { BindTarget = LockPlayfieldAspect } + LockPlayfieldMaxAspect = { BindTarget = LockPlayfieldMaxAspect } }; protected override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs index d42aaddf9e..42732d90e4 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.UI private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768; private const float default_aspect = 16f / 9f; - public readonly IBindable LockPlayfieldAspect = new BindableBool(true); + public readonly IBindable LockPlayfieldMaxAspect = new BindableBool(true); protected override void Update() { @@ -21,7 +21,12 @@ namespace osu.Game.Rulesets.Taiko.UI float height = default_relative_height; - if (LockPlayfieldAspect.Value && Parent.ChildSize.X / Parent.ChildSize.Y > default_aspect) + // Players coming from stable expect to be able to change the aspect ratio regardless of the window size. + // We originally wanted to limit this more, but there was considerable pushback from the community. + // + // As a middle-ground, the aspect ratio can still be adjusted in the downwards direction but has a maximum limit. + // This is still a bit weird, because readability changes with window size, but it is what it is. + if (LockPlayfieldMaxAspect.Value && Parent.ChildSize.X / Parent.ChildSize.Y > default_aspect) height *= Math.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect; Height = height; From 22d0b34623536c46634982a02e102907b45e22a2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 16:38:37 +0900 Subject: [PATCH 063/248] Remove flag causing intiialisation to only run once ever --- osu.Game/Online/Chat/ChannelManager.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 9741341efc..26ab9e87ba 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -71,7 +71,6 @@ namespace osu.Game.Online.Chat private UserLookupCache users { get; set; } private readonly IBindable apiState = new Bindable(); - private bool channelsInitialised; private ScheduledDelegate scheduledAck; private long? lastSilenceMessageId; @@ -95,15 +94,7 @@ namespace osu.Game.Online.Chat connector.NewMessages += msgs => Schedule(() => addMessages(msgs)); - connector.PresenceReceived += () => Schedule(() => - { - if (!channelsInitialised) - { - channelsInitialised = true; - // we want this to run after the first presence so we can see if the user is in any channels already. - initializeChannels(); - } - }); + connector.PresenceReceived += () => Schedule(initializeChannels); connector.Start(); From 15eebd1f50d6aa4e2b666bc80c810b564330f972 Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Mon, 9 Jan 2023 11:47:13 +0200 Subject: [PATCH 064/248] Only show message about Songs folder --- osu.Game/Database/LegacyImportManager.cs | 4 ++-- .../Overlays/FirstRunSetup/ScreenImportFromStable.cs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Database/LegacyImportManager.cs b/osu.Game/Database/LegacyImportManager.cs index f9136fa8b6..20738f859e 100644 --- a/osu.Game/Database/LegacyImportManager.cs +++ b/osu.Game/Database/LegacyImportManager.cs @@ -54,14 +54,14 @@ namespace osu.Game.Database public void UpdateStorage(string stablePath) => cachedStorage = new StableStorage(stablePath, gameHost as DesktopGameHost); - public bool CheckHardLinkAvailability() + public bool CheckSongsFolderHardLinkAvailability() { var stableStorage = GetCurrentStableStorage(); if (stableStorage == null || gameHost is not DesktopGameHost desktopGameHost) return false; - string testExistingPath = stableStorage.GetFullPath(string.Empty); + string testExistingPath = stableStorage.GetSongStorage().GetFullPath(string.Empty); string testDestinationPath = desktopGameHost.Storage.GetFullPath(string.Empty); return HardLinkHelper.CheckAvailability(testDestinationPath, testExistingPath); diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index 0a2274575f..ca6e736637 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -122,13 +122,13 @@ namespace osu.Game.Overlays.FirstRunSetup stableLocatorTextBox.Current.Value = storage.GetFullPath(string.Empty); importButton.Enabled.Value = true; - bool available = legacyImportManager.CheckHardLinkAvailability(); - Logger.Log($"Hard link support is {available}"); + bool available = legacyImportManager.CheckSongsFolderHardLinkAvailability(); + Logger.Log($"Hard link support for beatmaps is {available}"); if (available) { copyInformation.Text = - "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation. "; + "Beatmap migration will use \"hard links\". No extra disk space will be used, and you can delete beatmaps from either installation at any point without affecting the other. "; copyInformation.AddLink("Learn more about how \"hard links\" work", LinkAction.OpenWiki, @"Client/Release_stream/Lazer/File_storage#via-hard-links"); } @@ -137,8 +137,8 @@ namespace osu.Game.Overlays.FirstRunSetup else { copyInformation.Text = RuntimeInfo.OS == RuntimeInfo.Platform.Windows - ? "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS). " - : "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system supports hard links). "; + ? "A second copy of beatmaps will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous Songs folder (and the file system is NTFS). " + : "A second copy of beatmaps will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous Songs folder (and the file system supports hard links). "; copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => { game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); From 62ffb4fe78c30da147b82757a5c0d3acfb08a3b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 18:54:11 +0900 Subject: [PATCH 065/248] Pause imports during active gameplay --- osu.Game/Beatmaps/BeatmapManager.cs | 4 +++- osu.Game/Database/ModelManager.cs | 6 +++++ .../Database/RealmArchiveModelImporter.cs | 24 ++++++++++++++++++- osu.Game/OsuGame.cs | 4 ++++ osu.Game/Scoring/ScoreManager.cs | 2 ++ osu.Game/Skinning/SkinManager.cs | 2 ++ 6 files changed, 40 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index f0533f27be..623a657cd0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -62,6 +62,7 @@ namespace osu.Game.Beatmaps BeatmapTrackStore = audioManager.GetTrackStore(userResources); beatmapImporter = CreateBeatmapImporter(storage, realm); + beatmapImporter.PauseImports.BindTo(PauseImports); beatmapImporter.ProcessBeatmap = args => ProcessBeatmap?.Invoke(args); beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj); @@ -458,7 +459,8 @@ namespace osu.Game.Beatmaps public Task Import(ImportTask[] tasks, ImportParameters parameters = default) => beatmapImporter.Import(tasks, parameters); - public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => beatmapImporter.Import(notification, tasks, parameters); + public Task>> Import(ProgressNotification notification, ImportTask[] tasks, ImportParameters parameters = default) => + beatmapImporter.Import(notification, tasks, parameters); public Task?> Import(ImportTask task, ImportParameters parameters = default, CancellationToken cancellationToken = default) => beatmapImporter.Import(task, parameters, cancellationToken); diff --git a/osu.Game/Database/ModelManager.cs b/osu.Game/Database/ModelManager.cs index 5c106aa493..9a88bd5646 100644 --- a/osu.Game/Database/ModelManager.cs +++ b/osu.Game/Database/ModelManager.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; +using osu.Framework.Bindables; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Extensions; @@ -18,6 +19,11 @@ namespace osu.Game.Database public class ModelManager : IModelManager, IModelFileManager where TModel : RealmObject, IHasRealmFiles, IHasGuidPrimaryKey, ISoftDelete { + /// + /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. + /// + public readonly BindableBool PauseImports = new BindableBool(); + protected RealmAccess Realm { get; } private readonly RealmFileStore realmFileStore; diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 4e8b27e0b4..cd86a5a94c 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Humanizer; +using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; @@ -56,6 +57,11 @@ namespace osu.Game.Database /// private static readonly ThreadedTaskScheduler import_scheduler_batch = new ThreadedTaskScheduler(import_queue_request_concurrency, nameof(RealmArchiveModelImporter)); + /// + /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. + /// + public readonly BindableBool PauseImports = new BindableBool(); + public abstract IEnumerable HandledExtensions { get; } protected readonly RealmFileStore Files; @@ -253,7 +259,7 @@ namespace osu.Game.Database /// An optional cancellation token. public virtual Live? ImportModel(TModel item, ArchiveReader? archive = null, ImportParameters parameters = default, CancellationToken cancellationToken = default) => Realm.Run(realm => { - cancellationToken.ThrowIfCancellationRequested(); + pauseIfNecessary(cancellationToken); TModel? existing; @@ -551,6 +557,22 @@ namespace osu.Game.Database /// Whether to perform deletion. protected virtual bool ShouldDeleteArchive(string path) => false; + private void pauseIfNecessary(CancellationToken cancellationToken) + { + if (!PauseImports.Value) + return; + + Logger.Log(@"Import is being paused."); + + while (PauseImports.Value) + { + cancellationToken.ThrowIfCancellationRequested(); + Thread.Sleep(500); + } + + Logger.Log(@"Import is being resumed."); + } + private IEnumerable getIDs(IEnumerable files) { foreach (var f in files.OrderBy(f => f.Filename)) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6efa3c4172..27152743f8 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -307,6 +307,10 @@ namespace osu.Game // Transfer any runtime changes back to configuration file. SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString(); + BeatmapManager.PauseImports.BindTo(LocalUserPlaying); + SkinManager.PauseImports.BindTo(LocalUserPlaying); + ScoreManager.PauseImports.BindTo(LocalUserPlaying); + IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); Audio.AddAdjustment(AdjustableProperty.Volume, inactiveVolumeFade); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 5ec96a951b..0852ab43f4 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -38,6 +38,8 @@ namespace osu.Game.Scoring { PostNotification = obj => PostNotification?.Invoke(obj) }; + + scoreImporter.PauseImports.BindTo(PauseImports); } public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index f750bfad8a..a0e7037d6d 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -79,6 +79,8 @@ namespace osu.Game.Skinning PostNotification = obj => PostNotification?.Invoke(obj), }; + skinImporter.PauseImports.BindTo(PauseImports); + var defaultSkins = new[] { DefaultClassicSkin = new DefaultLegacySkin(this), From f5c8ba420c4b9693c33f801b9cb5b0757917bc8d Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Mon, 9 Jan 2023 14:53:16 +0200 Subject: [PATCH 066/248] Revert message change --- osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs index ca6e736637..23f3b3e1af 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenImportFromStable.cs @@ -128,7 +128,7 @@ namespace osu.Game.Overlays.FirstRunSetup if (available) { copyInformation.Text = - "Beatmap migration will use \"hard links\". No extra disk space will be used, and you can delete beatmaps from either installation at any point without affecting the other. "; + "Data migration will use \"hard links\". No extra disk space will be used, and you can delete either data folder at any point without affecting the other installation. "; copyInformation.AddLink("Learn more about how \"hard links\" work", LinkAction.OpenWiki, @"Client/Release_stream/Lazer/File_storage#via-hard-links"); } @@ -137,8 +137,8 @@ namespace osu.Game.Overlays.FirstRunSetup else { copyInformation.Text = RuntimeInfo.OS == RuntimeInfo.Platform.Windows - ? "A second copy of beatmaps will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous Songs folder (and the file system is NTFS). " - : "A second copy of beatmaps will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous Songs folder (and the file system supports hard links). "; + ? "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system is NTFS). " + : "A second copy of all files will be made during import. To avoid this, please make sure the lazer data folder is on the same drive as your previous osu! install (and the file system supports hard links). "; copyInformation.AddLink(GeneralSettingsStrings.ChangeFolderLocation, () => { game?.PerformFromScreen(menu => menu.Push(new MigrationSelectScreen())); From 811a5626084e86a5fb47d002c2dc89f1f1b98012 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 01:10:20 +0900 Subject: [PATCH 067/248] Don't use bindables to avoid potential cross-usage contamination --- osu.Game/Beatmaps/BeatmapManager.cs | 11 ++++++++++- osu.Game/Database/ModelManager.cs | 3 +-- osu.Game/Database/RealmArchiveModelImporter.cs | 7 +++---- osu.Game/OsuGame.cs | 9 ++++++--- osu.Game/Scoring/ScoreManager.cs | 12 ++++++++++-- osu.Game/Skinning/SkinManager.cs | 12 ++++++++++-- 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 623a657cd0..eafd1e96e8 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -44,6 +44,16 @@ namespace osu.Game.Beatmaps public Action<(BeatmapSetInfo beatmapSet, bool isBatch)>? ProcessBeatmap { private get; set; } + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + beatmapImporter.PauseImports = value; + } + } + public BeatmapManager(Storage storage, RealmAccess realm, IAPIProvider? api, AudioManager audioManager, IResourceStore gameResources, GameHost? host = null, WorkingBeatmap? defaultBeatmap = null, BeatmapDifficultyCache? difficultyCache = null, bool performOnlineLookups = false) : base(storage, realm) @@ -62,7 +72,6 @@ namespace osu.Game.Beatmaps BeatmapTrackStore = audioManager.GetTrackStore(userResources); beatmapImporter = CreateBeatmapImporter(storage, realm); - beatmapImporter.PauseImports.BindTo(PauseImports); beatmapImporter.ProcessBeatmap = args => ProcessBeatmap?.Invoke(args); beatmapImporter.PostNotification = obj => PostNotification?.Invoke(obj); diff --git a/osu.Game/Database/ModelManager.cs b/osu.Game/Database/ModelManager.cs index 9a88bd5646..7d1dc5239a 100644 --- a/osu.Game/Database/ModelManager.cs +++ b/osu.Game/Database/ModelManager.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; -using osu.Framework.Bindables; using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Extensions; @@ -22,7 +21,7 @@ namespace osu.Game.Database /// /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. /// - public readonly BindableBool PauseImports = new BindableBool(); + public virtual bool PauseImports { get; set; } protected RealmAccess Realm { get; } diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index cd86a5a94c..1fe1569d36 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; using Humanizer; -using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Logging; @@ -60,7 +59,7 @@ namespace osu.Game.Database /// /// Temporarily pause imports to avoid performance overheads affecting gameplay scenarios. /// - public readonly BindableBool PauseImports = new BindableBool(); + public bool PauseImports { get; set; } public abstract IEnumerable HandledExtensions { get; } @@ -559,12 +558,12 @@ namespace osu.Game.Database private void pauseIfNecessary(CancellationToken cancellationToken) { - if (!PauseImports.Value) + if (!PauseImports) return; Logger.Log(@"Import is being paused."); - while (PauseImports.Value) + while (PauseImports) { cancellationToken.ThrowIfCancellationRequested(); Thread.Sleep(500); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 27152743f8..dc4d56de11 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -307,9 +307,12 @@ namespace osu.Game // Transfer any runtime changes back to configuration file. SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString(); - BeatmapManager.PauseImports.BindTo(LocalUserPlaying); - SkinManager.PauseImports.BindTo(LocalUserPlaying); - ScoreManager.PauseImports.BindTo(LocalUserPlaying); + LocalUserPlaying.BindValueChanged(p => + { + BeatmapManager.PauseImports = p.NewValue; + SkinManager.PauseImports = p.NewValue; + ScoreManager.PauseImports = p.NewValue; + }, true); IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); diff --git a/osu.Game/Scoring/ScoreManager.cs b/osu.Game/Scoring/ScoreManager.cs index 0852ab43f4..3217c79768 100644 --- a/osu.Game/Scoring/ScoreManager.cs +++ b/osu.Game/Scoring/ScoreManager.cs @@ -28,6 +28,16 @@ namespace osu.Game.Scoring private readonly OsuConfigManager configManager; private readonly ScoreImporter scoreImporter; + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + scoreImporter.PauseImports = value; + } + } + public ScoreManager(RulesetStore rulesets, Func beatmaps, Storage storage, RealmAccess realm, IAPIProvider api, OsuConfigManager configManager = null) : base(storage, realm) @@ -38,8 +48,6 @@ namespace osu.Game.Scoring { PostNotification = obj => PostNotification?.Invoke(obj) }; - - scoreImporter.PauseImports.BindTo(PauseImports); } public Score GetScore(ScoreInfo score) => scoreImporter.GetScore(score); diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index a0e7037d6d..a4cf83b32e 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -64,6 +64,16 @@ namespace osu.Game.Skinning private Skin trianglesSkin { get; } + public override bool PauseImports + { + get => base.PauseImports; + set + { + base.PauseImports = value; + skinImporter.PauseImports = value; + } + } + public SkinManager(Storage storage, RealmAccess realm, GameHost host, IResourceStore resources, AudioManager audio, Scheduler scheduler) : base(storage, realm) { @@ -79,8 +89,6 @@ namespace osu.Game.Skinning PostNotification = obj => PostNotification?.Invoke(obj), }; - skinImporter.PauseImports.BindTo(PauseImports); - var defaultSkins = new[] { DefaultClassicSkin = new DefaultLegacySkin(this), From e35f63c001704e6914e1925955b4ddae4b0731c3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 01:37:16 +0900 Subject: [PATCH 068/248] Ensure screenshot filenames are unique by locking over file creation --- osu.Game/Graphics/ScreenshotManager.cs | 40 +++++++++++++++----------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 29e9b0276c..d799e82bc9 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.IO; using System.Threading; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -117,11 +118,11 @@ namespace osu.Game.Graphics host.GetClipboard()?.SetImage(image); - string filename = getFilename(); + (string filename, var stream) = getWritableStream(); if (filename == null) return; - using (var stream = storage.CreateFileSafely(filename)) + using (stream) { switch (screenshotFormat.Value) { @@ -142,7 +143,7 @@ namespace osu.Game.Graphics notificationOverlay.Post(new SimpleNotification { - Text = $"{filename} saved!", + Text = $"Screenshot {filename} saved!", Activated = () => { storage.PresentFileExternally(filename); @@ -152,23 +153,28 @@ namespace osu.Game.Graphics } }); - private string getFilename() + private static readonly object filename_reservation_lock = new object(); + + private (string filename, Stream stream) getWritableStream() { - var dt = DateTime.Now; - string fileExt = screenshotFormat.ToString().ToLowerInvariant(); - - string withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}"; - if (!storage.Exists(withoutIndex)) - return withoutIndex; - - for (ulong i = 1; i < ulong.MaxValue; i++) + lock (filename_reservation_lock) { - string indexedName = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}-{i}.{fileExt}"; - if (!storage.Exists(indexedName)) - return indexedName; - } + var dt = DateTime.Now; + string fileExt = screenshotFormat.ToString().ToLowerInvariant(); - return null; + string withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}"; + if (!storage.Exists(withoutIndex)) + return (withoutIndex, storage.GetStream(withoutIndex, FileAccess.Write, FileMode.Create)); + + for (ulong i = 1; i < ulong.MaxValue; i++) + { + string indexedName = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}-{i}.{fileExt}"; + if (!storage.Exists(indexedName)) + return (indexedName, storage.GetStream(indexedName, FileAccess.Write, FileMode.Create)); + } + + return (null, null); + } } } } From fdf0d4bd620208fdbcbee3fb35c7ed051b2015fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 9 Jan 2023 17:37:28 +0100 Subject: [PATCH 069/248] Rename `UserProfile{ -> Data}` --- .../Online/TestSceneHistoricalSection.cs | 4 ++-- .../Online/TestScenePlayHistorySubsection.cs | 18 +++++++++--------- .../Online/TestSceneUserProfileHeader.cs | 10 +++++----- .../Visual/Online/TestSceneUserRanks.cs | 2 +- .../Profile/Header/BottomHeaderContainer.cs | 2 +- .../Profile/Header/CentreHeaderContainer.cs | 2 +- .../Header/Components/FollowersButton.cs | 2 +- .../Profile/Header/Components/LevelBadge.cs | 2 +- .../Header/Components/LevelProgressBar.cs | 2 +- .../Components/MappingSubscribersButton.cs | 2 +- .../Header/Components/MessageUserButton.cs | 2 +- .../Components/OverlinedTotalPlayTime.cs | 4 ++-- .../Profile/Header/DetailHeaderContainer.cs | 4 ++-- .../Profile/Header/MedalHeaderContainer.cs | 2 +- .../Profile/Header/TopHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- osu.Game/Overlays/Profile/ProfileSection.cs | 2 +- .../Beatmaps/PaginatedBeatmapContainer.cs | 2 +- .../Historical/ChartProfileSubsection.cs | 4 ++-- .../PaginatedMostPlayedBeatmapContainer.cs | 2 +- .../Historical/PlayHistorySubsection.cs | 2 +- .../Sections/Historical/ReplaysSubsection.cs | 2 +- .../Profile/Sections/Kudosu/KudosuInfo.cs | 4 ++-- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 2 +- .../Sections/PaginatedProfileSubsection.cs | 4 ++-- .../Profile/Sections/ProfileSubsection.cs | 4 ++-- .../Sections/Ranks/PaginatedScoreContainer.cs | 2 +- .../Recent/PaginatedRecentActivityContainer.cs | 2 +- .../{UserProfile.cs => UserProfileData.cs} | 4 ++-- osu.Game/Overlays/UserProfileOverlay.cs | 2 +- 30 files changed, 52 insertions(+), 52 deletions(-) rename osu.Game/Overlays/Profile/{UserProfile.cs => UserProfileData.cs} (88%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 92bb41b7d5..0603fa3250 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 2 })); - AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfile(new APIUser { Id = 39828 })); + AddStep("Show peppy", () => section.UserProfile.Value = new UserProfileData(new APIUser { Id = 2 })); + AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfileData(new APIUser { Id = 39828 })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index a486d77f97..8bd4e398e4 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); - private readonly Bindable user = new Bindable(); + private readonly Bindable user = new Bindable(); private readonly PlayHistorySubsection section; public TestScenePlayHistorySubsection() @@ -44,49 +44,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_null_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_null_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_empty_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_empty_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_one_value)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_one_value)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_two_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_two_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_constant_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_constant_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_zero_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_zero_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_filled_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_filled_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => user.Value = new UserProfile(user_with_missing_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_missing_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 4caab98f63..75de033497 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -29,13 +29,13 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.UserProfile.Value = new UserProfile(TestSceneUserProfileOverlay.TEST_USER)); + AddStep("Show example user", () => header.UserProfile.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); } [Test] public void TestOnlineState() { - AddStep("Show online user", () => header.UserProfile.Value = new UserProfile(new APIUser + AddStep("Show online user", () => header.UserProfile.Value = new UserProfileData(new APIUser { Id = 1001, Username = "IAmOnline", @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Online IsOnline = true, })); - AddStep("Show offline user", () => header.UserProfile.Value = new UserProfile(new APIUser + AddStep("Show offline user", () => header.UserProfile.Value = new UserProfileData(new APIUser { Id = 1002, Username = "IAmOffline", @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestRankedState() { - AddStep("Show ranked user", () => header.UserProfile.Value = new UserProfile(new APIUser + AddStep("Show ranked user", () => header.UserProfile.Value = new UserProfileData(new APIUser { Id = 2001, Username = "RankedUser", @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online } })); - AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfile(new APIUser + AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfileData(new APIUser { Id = 2002, Username = "UnrankedUser", diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 184b969279..503719add4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfile(new APIUser { Id = 124493 })); + AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfileData(new APIUser { Id = 124493 })); } } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 64a333dff7..a13f3585a5 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private LinkFlowContainer topLinkContainer = null!; private LinkFlowContainer bottomLinkContainer = null!; diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 701c4a1464..6675b5f52a 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private OverlinedInfoContainer hiddenDetailGlobal = null!; private OverlinedInfoContainer hiddenDetailCountry = null!; diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index 48e9718a7c..959212413f 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index f68c9838a0..3e5582a1c8 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; private set; } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index e3100c5af5..69be4c7b7a 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; } diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index 29b42cb223..cae407ef91 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index f57b43c3a4..45e20957c8 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index 1de13ba7c7..687382ed90 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); public LocalisableString TooltipText { get; set; } @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Profile.Header.Components UserProfile.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent userProfile) + private void updateTime(ValueChangedEvent userProfile) { int? playTime = userProfile.NewValue?.User.Statistics?.PlayTime; TooltipText = (playTime ?? 0) / 3600 + " hours"; diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 8b9a90c9a3..b7b9fd52c7 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); private bool expanded = true; @@ -170,7 +170,7 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay(UserProfile? userProfile) + private void updateDisplay(UserProfileData? userProfile) { var user = userProfile?.User; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index b41c60ed4e..df51a82cc9 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Header { private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 69258c914f..0889c36b16 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); [Resolved] private IAPIProvider api { get; set; } = null!; @@ -173,7 +173,7 @@ namespace osu.Game.Overlays.Profile.Header UserProfile.BindValueChanged(user => updateUser(user.NewValue)); } - private void updateUser(UserProfile? userProfile) + private void updateUser(UserProfileData? userProfile) { var user = userProfile?.User; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 447e9148e8..f87ee707ff 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile { private UserCoverBackground coverContainer = null!; - public Bindable UserProfile = new Bindable(); + public Bindable UserProfile = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -99,7 +99,7 @@ namespace osu.Game.Overlays.Profile protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(UserProfile? userProfile) => coverContainer.User = userProfile?.User; + private void updateDisplay(UserProfileData? userProfile) => coverContainer.User = userProfile?.User; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 97b8f2b13f..1e85411bc6 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfile = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 3b1f26ee7d..0e74aba369 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) : base(user, headerText) { this.type = type; diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index 724733c7a9..0ba93200d9 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable userProfile, LocalisableString headerText) + protected ChartProfileSubsection(Bindable userProfile, LocalisableString headerText) : base(userProfile, headerText) { } @@ -44,7 +44,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical UserProfile.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { var values = GetValues(e.NewValue?.User); diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 5851262229..6b08b68962 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable userProfile) + public PaginatedMostPlayedBeatmapContainer(Bindable userProfile) : base(userProfile, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index 5fa58dbdab..5d83610f84 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable userProfile) + public PlayHistorySubsection(Bindable userProfile) : base(userProfile, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index 04e70afa36..0a82f79310 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -12,7 +12,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable userProfile) + public ReplaysSubsection(Bindable userProfile) : base(userProfile, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index 7fd0759fac..c2de0efb69 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -19,9 +19,9 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable userProfile = new Bindable(); + private readonly Bindable userProfile = new Bindable(); - public KudosuInfo(Bindable userProfile) + public KudosuInfo(Bindable userProfile) { this.userProfile.BindTo(userProfile); CountSection total; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index 6addd86894..0173e7ce74 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable userProfile) + public PaginatedKudosuHistoryContainer(Bindable userProfile) : base(userProfile, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index d77844fd56..df881ad2a7 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Profile.Sections private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, LocalisableString? missingText = null) + protected PaginatedProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, LocalisableString? missingText = null) : base(userProfile, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Sections UserProfile.BindValueChanged(onUserChanged, true); } - private void onUserChanged(ValueChangedEvent e) + private void onUserChanged(ValueChangedEvent e) { loadCancellation?.Cancel(); retrievalRequest?.Cancel(); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 5df8688659..e85d5f22ef 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -11,14 +11,14 @@ namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable UserProfile = new Bindable(); + protected readonly Bindable UserProfile = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index cdd1738c8e..968deecad4 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable userProfile, LocalisableString headerText) + public PaginatedScoreContainer(ScoreType type, Bindable userProfile, LocalisableString headerText) : base(userProfile, headerText) { this.type = type; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index c08ea58b5a..ad7242c339 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable userProfile) + public PaginatedRecentActivityContainer(Bindable userProfile) : base(userProfile, missingText: EventsStrings.Empty) { } diff --git a/osu.Game/Overlays/Profile/UserProfile.cs b/osu.Game/Overlays/Profile/UserProfileData.cs similarity index 88% rename from osu.Game/Overlays/Profile/UserProfile.cs rename to osu.Game/Overlays/Profile/UserProfileData.cs index 12a469ddf9..1a1cb8f7d4 100644 --- a/osu.Game/Overlays/Profile/UserProfile.cs +++ b/osu.Game/Overlays/Profile/UserProfileData.cs @@ -8,7 +8,7 @@ namespace osu.Game.Overlays.Profile /// /// Contains data about a profile presented on the . /// - public class UserProfile + public class UserProfileData { /// /// The user whose profile is being presented. @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile // TODO: add ruleset - public UserProfile(APIUser user) + public UserProfileData(APIUser user) { User = user; } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 5ec92efdbb..40933d9179 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -125,7 +125,7 @@ namespace osu.Game.Overlays { Debug.Assert(sections != null && sectionsContainer != null && tabs != null); - var userProfile = new UserProfile(user); + var userProfile = new UserProfileData(user); Header.UserProfile.Value = userProfile; if (user.ProfileOrder != null) From 4dec3cae5709309f35f7aad2337cf2fdbf4fef8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 9 Jan 2023 17:46:08 +0100 Subject: [PATCH 070/248] Rename `UserProfileData`-related symbols --- .../Online/TestSceneHistoricalSection.cs | 4 ++-- .../Online/TestScenePlayHistorySubsection.cs | 20 +++++++++---------- .../Online/TestSceneUserProfileHeader.cs | 10 +++++----- .../Visual/Online/TestSceneUserRanks.cs | 2 +- .../Profile/Header/BottomHeaderContainer.cs | 4 ++-- .../Profile/Header/CentreHeaderContainer.cs | 14 ++++++------- .../Header/Components/FollowersButton.cs | 4 ++-- .../Profile/Header/Components/LevelBadge.cs | 4 ++-- .../Header/Components/LevelProgressBar.cs | 4 ++-- .../Components/MappingSubscribersButton.cs | 4 ++-- .../Header/Components/MessageUserButton.cs | 6 +++--- .../Components/OverlinedTotalPlayTime.cs | 8 ++++---- .../Profile/Header/DetailHeaderContainer.cs | 10 +++++----- .../Profile/Header/MedalHeaderContainer.cs | 4 ++-- .../Profile/Header/TopHeaderContainer.cs | 8 ++++---- osu.Game/Overlays/Profile/ProfileHeader.cs | 16 +++++++-------- osu.Game/Overlays/Profile/ProfileSection.cs | 2 +- .../Beatmaps/PaginatedBeatmapContainer.cs | 4 ++-- .../Profile/Sections/BeatmapsSection.cs | 14 ++++++------- .../Historical/ChartProfileSubsection.cs | 4 ++-- .../PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- .../Historical/PlayHistorySubsection.cs | 4 ++-- .../Sections/Historical/ReplaysSubsection.cs | 4 ++-- .../Profile/Sections/HistoricalSection.cs | 8 ++++---- .../Profile/Sections/Kudosu/KudosuInfo.cs | 8 ++++---- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 4 ++-- .../Profile/Sections/KudosuSection.cs | 4 ++-- .../Sections/PaginatedProfileSubsection.cs | 4 ++-- .../Profile/Sections/ProfileSubsection.cs | 4 ++-- .../Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- .../Overlays/Profile/Sections/RanksSection.cs | 6 +++--- .../PaginatedRecentActivityContainer.cs | 4 ++-- .../Profile/Sections/RecentSection.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 6 +++--- 34 files changed, 106 insertions(+), 106 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 0603fa3250..78e0c6fce4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.UserProfile.Value = new UserProfileData(new APIUser { Id = 2 })); - AddStep("Show WubWoofWolf", () => section.UserProfile.Value = new UserProfileData(new APIUser { Id = 39828 })); + AddStep("Show peppy", () => section.UserProfileData.Value = new UserProfileData(new APIUser { Id = 2 })); + AddStep("Show WubWoofWolf", () => section.UserProfileData.Value = new UserProfileData(new APIUser { Id = 39828 })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index 8bd4e398e4..634b9df212 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); - private readonly Bindable user = new Bindable(); + private readonly Bindable userProfileData = new Bindable(); private readonly PlayHistorySubsection section; public TestScenePlayHistorySubsection() @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4 }, - section = new PlayHistorySubsection(user) + section = new PlayHistorySubsection(userProfileData) { Anchor = Anchor.Centre, Origin = Anchor.Centre @@ -44,49 +44,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_null_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_null_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_empty_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_empty_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_one_value)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_one_value)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_two_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_two_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_constant_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_constant_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_zero_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_zero_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_filled_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_filled_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => user.Value = new UserProfileData(user_with_missing_values)); + AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_missing_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 75de033497..9b565c1276 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -29,13 +29,13 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.UserProfile.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); + AddStep("Show example user", () => header.UserProfileData.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); } [Test] public void TestOnlineState() { - AddStep("Show online user", () => header.UserProfile.Value = new UserProfileData(new APIUser + AddStep("Show online user", () => header.UserProfileData.Value = new UserProfileData(new APIUser { Id = 1001, Username = "IAmOnline", @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Online IsOnline = true, })); - AddStep("Show offline user", () => header.UserProfile.Value = new UserProfileData(new APIUser + AddStep("Show offline user", () => header.UserProfileData.Value = new UserProfileData(new APIUser { Id = 1002, Username = "IAmOffline", @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestRankedState() { - AddStep("Show ranked user", () => header.UserProfile.Value = new UserProfileData(new APIUser + AddStep("Show ranked user", () => header.UserProfileData.Value = new UserProfileData(new APIUser { Id = 2001, Username = "RankedUser", @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online } })); - AddStep("Show unranked user", () => header.UserProfile.Value = new UserProfileData(new APIUser + AddStep("Show unranked user", () => header.UserProfileData.Value = new UserProfileData(new APIUser { Id = 2002, Username = "UnrankedUser", diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 503719add4..6ec7ea008b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.UserProfile.Value = new UserProfileData(new APIUser { Id = 124493 })); + AddStep("Show cookiezi", () => ranks.UserProfileData.Value = new UserProfileData(new APIUser { Id = 124493 })); } } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index a13f3585a5..091d04ad35 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); private LinkFlowContainer topLinkContainer = null!; private LinkFlowContainer bottomLinkContainer = null!; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header } }; - UserProfile.BindValueChanged(user => updateDisplay(user.NewValue?.User)); + UserProfileData.BindValueChanged(data => updateDisplay(data.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 6675b5f52a..8910d3dc3b 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); private OverlinedInfoContainer hiddenDetailGlobal = null!; private OverlinedInfoContainer hiddenDetailCountry = null!; @@ -53,15 +53,15 @@ namespace osu.Game.Overlays.Profile.Header { new FollowersButton { - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, new MappingSubscribersButton { - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, new MessageUserButton { - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, } }, @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Size = new Vector2(40), - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, expandedDetailContainer = new Container { @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Profile.Header Child = new LevelProgressBar { RelativeSizeAxes = Axes.Both, - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } } }, hiddenDetailContainer = new FillFlowContainer @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Profile.Header expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); }); - UserProfile.BindValueChanged(userProfile => updateDisplay(userProfile.NewValue?.User)); + UserProfileData.BindValueChanged(data => updateDisplay(data.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index 959212413f..a73b3444f6 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load() { // todo: when friending/unfriending is implemented, the APIAccess.Friends list should be updated accordingly. - UserProfile.BindValueChanged(user => SetValue(user.NewValue?.User.FollowerCount ?? 0), true); + UserProfileData.BindValueChanged(data => SetValue(data.NewValue?.User.FollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 3e5582a1c8..501c7bd41b 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public LocalisableString TooltipText { get; private set; } @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - UserProfile.BindValueChanged(user => updateLevel(user.NewValue?.User)); + UserProfileData.BindValueChanged(data => updateLevel(data.NewValue?.User)); } private void updateLevel(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index 69be4c7b7a..6a5827a867 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public LocalisableString TooltipText { get; } @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - UserProfile.BindValueChanged(user => updateProgress(user.NewValue?.User)); + UserProfileData.BindValueChanged(data => updateProgress(data.NewValue?.User)); } private void updateProgress(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index cae407ef91..7265302a88 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load() { - UserProfile.BindValueChanged(user => SetValue(user.NewValue?.User.MappingFollowerCount ?? 0), true); + UserProfileData.BindValueChanged(data => SetValue(data.NewValue?.User.MappingFollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 45e20957c8..0b9fa437c2 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; @@ -48,12 +48,12 @@ namespace osu.Game.Overlays.Profile.Header.Components { if (!Content.IsPresent) return; - channelManager?.OpenPrivateChannel(UserProfile.Value?.User); + channelManager?.OpenPrivateChannel(UserProfileData.Value?.User); userOverlay?.Hide(); chatOverlay?.Show(); }; - UserProfile.ValueChanged += e => + UserProfileData.ValueChanged += e => { var user = e.NewValue?.User; Content.Alpha = user != null && !user.PMFriendsOnly && apiProvider.LocalUser.Value.Id != user.Id ? 1 : 0; diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index 687382ed90..c2db9d8273 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); public LocalisableString TooltipText { get; set; } @@ -35,12 +35,12 @@ namespace osu.Game.Overlays.Profile.Header.Components LineColour = colourProvider.Highlight1, }; - UserProfile.BindValueChanged(updateTime, true); + UserProfileData.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent userProfile) + private void updateTime(ValueChangedEvent data) { - int? playTime = userProfile.NewValue?.User.Statistics?.PlayTime; + int? playTime = data.NewValue?.User.Statistics?.PlayTime; TooltipText = (playTime ?? 0) / 3600 + " hours"; info.Content = formatTime(playTime); } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index b7b9fd52c7..d2986c343d 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); private bool expanded = true; @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Y; - UserProfile.ValueChanged += e => updateDisplay(e.NewValue); + UserProfileData.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] { @@ -98,7 +98,7 @@ namespace osu.Game.Overlays.Profile.Header { new OverlinedTotalPlayTime { - UserProfile = { BindTarget = UserProfile } + UserProfileData = { BindTarget = UserProfileData } }, medalInfo = new OverlinedInfoContainer { @@ -170,9 +170,9 @@ namespace osu.Game.Overlays.Profile.Header }; } - private void updateDisplay(UserProfileData? userProfile) + private void updateDisplay(UserProfileData? data) { - var user = userProfile?.User; + var user = data?.User; medalInfo.Content = user?.Achievements?.Length.ToString() ?? "0"; ppInfo.Content = user?.Statistics?.PP?.ToLocalisableString("#,##0") ?? (LocalisableString)"0"; diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index df51a82cc9..2c2e2b3197 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -20,14 +20,14 @@ namespace osu.Game.Overlays.Profile.Header { private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { Alpha = 0; AutoSizeAxes = Axes.Y; - UserProfile.ValueChanged += e => updateDisplay(e.NewValue?.User); + UserProfileData.ValueChanged += e => updateDisplay(e.NewValue?.User); InternalChildren = new Drawable[] { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 0889c36b16..c8a797e478 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); [Resolved] private IAPIProvider api { get; set; } = null!; @@ -170,12 +170,12 @@ namespace osu.Game.Overlays.Profile.Header } }; - UserProfile.BindValueChanged(user => updateUser(user.NewValue)); + UserProfileData.BindValueChanged(data => updateUser(data.NewValue)); } - private void updateUser(UserProfileData? userProfile) + private void updateUser(UserProfileData? data) { - var user = userProfile?.User; + var user = data?.User; avatar.User = user; usernameText.Text = user?.Username ?? string.Empty; diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index f87ee707ff..5f58960b15 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile { private UserCoverBackground coverContainer = null!; - public Bindable UserProfile = new Bindable(); + public Bindable UserProfileData = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile { ContentSidePadding = UserProfileOverlay.CONTENT_X_MARGIN; - UserProfile.ValueChanged += e => updateDisplay(e.NewValue); + UserProfileData.ValueChanged += e => updateDisplay(e.NewValue); TabControl.AddItem(LayoutStrings.HeaderUsersShow); @@ -72,34 +72,34 @@ namespace osu.Game.Overlays.Profile new TopHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, detailHeaderContainer = new DetailHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, new MedalHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, new BottomHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfile = { BindTarget = UserProfile }, + UserProfileData = { BindTarget = UserProfileData }, }, } }; protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(UserProfileData? userProfile) => coverContainer.User = userProfile?.User; + private void updateDisplay(UserProfileData? data) => coverContainer.User = data?.User; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 1e85411bc6..009e0d1dac 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable UserProfile = new Bindable(); + public readonly Bindable UserProfileData = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 0e74aba369..9c692cbeac 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -22,8 +22,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) - : base(user, headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable userProfileData, LocalisableString headerText) + : base(userProfileData, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index 19d0da2cef..8818cae735 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -18,13 +18,13 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedBeatmapContainer(BeatmapSetType.Favourite, UserProfile, UsersStrings.ShowExtraBeatmapsFavouriteTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Ranked, UserProfile, UsersStrings.ShowExtraBeatmapsRankedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Loved, UserProfile, UsersStrings.ShowExtraBeatmapsLovedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Guest, UserProfile, UsersStrings.ShowExtraBeatmapsGuestTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Pending, UserProfile, UsersStrings.ShowExtraBeatmapsPendingTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, UserProfile, UsersStrings.ShowExtraBeatmapsGraveyardTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Nominated, UserProfile, UsersStrings.ShowExtraBeatmapsNominatedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Favourite, UserProfileData, UsersStrings.ShowExtraBeatmapsFavouriteTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Ranked, UserProfileData, UsersStrings.ShowExtraBeatmapsRankedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Loved, UserProfileData, UsersStrings.ShowExtraBeatmapsLovedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Guest, UserProfileData, UsersStrings.ShowExtraBeatmapsGuestTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Pending, UserProfileData, UsersStrings.ShowExtraBeatmapsPendingTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, UserProfileData, UsersStrings.ShowExtraBeatmapsGraveyardTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Nominated, UserProfileData, UsersStrings.ShowExtraBeatmapsNominatedTitle), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index 0ba93200d9..77e967376c 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable userProfile, LocalisableString headerText) - : base(userProfile, headerText) + protected ChartProfileSubsection(Bindable userProfileData, LocalisableString headerText) + : base(userProfileData, headerText) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 6b08b68962..7afb21e8ca 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable userProfile) - : base(userProfile, UsersStrings.ShowExtraHistoricalMostPlayedTitle) + public PaginatedMostPlayedBeatmapContainer(Bindable userProfileData) + : base(userProfileData, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index 5d83610f84..cf8708d7b2 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable userProfile) - : base(userProfile, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) + public PlayHistorySubsection(Bindable userProfileData) + : base(userProfileData, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index 0a82f79310..ab35680fd8 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable userProfile) - : base(userProfile, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) + public ReplaysSubsection(Bindable userProfileData) + : base(userProfileData, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs index eecdffad19..5590db6502 100644 --- a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs +++ b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs @@ -20,10 +20,10 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new PlayHistorySubsection(UserProfile), - new PaginatedMostPlayedBeatmapContainer(UserProfile), - new PaginatedScoreContainer(ScoreType.Recent, UserProfile, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), - new ReplaysSubsection(UserProfile) + new PlayHistorySubsection(UserProfileData), + new PaginatedMostPlayedBeatmapContainer(UserProfileData), + new PaginatedScoreContainer(ScoreType.Recent, UserProfileData, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), + new ReplaysSubsection(UserProfileData) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index c2de0efb69..d5a945b3da 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -19,11 +19,11 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable userProfile = new Bindable(); + private readonly Bindable userProfileData = new Bindable(); - public KudosuInfo(Bindable userProfile) + public KudosuInfo(Bindable userProfileData) { - this.userProfile.BindTo(userProfile); + this.userProfileData.BindTo(userProfileData); CountSection total; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu CornerRadius = 3; Child = total = new CountTotal(); - this.userProfile.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; + this.userProfileData.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; } protected override bool OnClick(ClickEvent e) => true; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index 0173e7ce74..a2ab104239 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,8 +14,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable userProfile) - : base(userProfile, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) + public PaginatedKudosuHistoryContainer(Bindable userProfileData) + : base(userProfileData, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index b884f8854a..8fbaa1214f 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs @@ -18,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new KudosuInfo(UserProfile), - new PaginatedKudosuHistoryContainer(UserProfile), + new KudosuInfo(UserProfileData), + new PaginatedKudosuHistoryContainer(UserProfileData), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index df881ad2a7..3556e9d809 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -46,8 +46,8 @@ namespace osu.Game.Overlays.Profile.Sections private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, LocalisableString? missingText = null) - : base(userProfile, headerText, CounterVisibilityState.AlwaysVisible) + protected PaginatedProfileSubsection(Bindable userProfileData, LocalisableString? headerText = null, LocalisableString? missingText = null) + : base(userProfileData, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; } diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index e85d5f22ef..20452a1274 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -18,11 +18,11 @@ namespace osu.Game.Overlays.Profile.Sections private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable userProfile, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable userProfileData, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; - UserProfile.BindTo(userProfile); + UserProfile.BindTo(userProfileData); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 968deecad4..14d57bfadc 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable userProfile, LocalisableString headerText) - : base(userProfile, headerText) + public PaginatedScoreContainer(ScoreType type, Bindable userProfileData, LocalisableString headerText) + : base(userProfileData, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index f8d1d82300..6b705a40d5 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -18,9 +18,9 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedScoreContainer(ScoreType.Pinned, UserProfile, UsersStrings.ShowExtraTopRanksPinnedTitle), - new PaginatedScoreContainer(ScoreType.Best, UserProfile, UsersStrings.ShowExtraTopRanksBestTitle), - new PaginatedScoreContainer(ScoreType.Firsts, UserProfile, UsersStrings.ShowExtraTopRanksFirstTitle) + new PaginatedScoreContainer(ScoreType.Pinned, UserProfileData, UsersStrings.ShowExtraTopRanksPinnedTitle), + new PaginatedScoreContainer(ScoreType.Best, UserProfileData, UsersStrings.ShowExtraTopRanksBestTitle), + new PaginatedScoreContainer(ScoreType.Firsts, UserProfileData, UsersStrings.ShowExtraTopRanksFirstTitle) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index ad7242c339..6f346b457a 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable userProfile) - : base(userProfile, missingText: EventsStrings.Empty) + public PaginatedRecentActivityContainer(Bindable userProfileData) + : base(userProfileData, missingText: EventsStrings.Empty) { } diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index 6a90b7d1e3..95dbe7373c 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedRecentActivityContainer(UserProfile), + new PaginatedRecentActivityContainer(UserProfileData), }; } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 40933d9179..add90a0eed 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays Show(); - if (user.OnlineID == Header?.UserProfile.Value?.User.Id) + if (user.OnlineID == Header?.UserProfileData.Value?.User.Id) return; if (sectionsContainer != null) @@ -126,7 +126,7 @@ namespace osu.Game.Overlays Debug.Assert(sections != null && sectionsContainer != null && tabs != null); var userProfile = new UserProfileData(user); - Header.UserProfile.Value = userProfile; + Header.UserProfileData.Value = userProfile; if (user.ProfileOrder != null) { @@ -136,7 +136,7 @@ namespace osu.Game.Overlays if (sec != null) { - sec.UserProfile.Value = userProfile; + sec.UserProfileData.Value = userProfile; sectionsContainer.Add(sec); tabs.AddItem(sec); From a1fbfe4b8b6da1f3f7ff8415e71306ae897b13f7 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 19:53:41 +0300 Subject: [PATCH 071/248] Specifiy importer name during pause/resume in logs --- osu.Game/Database/RealmArchiveModelImporter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 1fe1569d36..1ea97ba718 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -561,7 +561,7 @@ namespace osu.Game.Database if (!PauseImports) return; - Logger.Log(@"Import is being paused."); + Logger.Log($@"{GetType().Name} is being paused."); while (PauseImports) { @@ -569,7 +569,7 @@ namespace osu.Game.Database Thread.Sleep(500); } - Logger.Log(@"Import is being resumed."); + Logger.Log($@"{GetType().Name} is being resumed."); } private IEnumerable getIDs(IEnumerable files) From 8a052235916ff3b532b515b12c04f62457eab686 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 20:07:46 +0300 Subject: [PATCH 072/248] Check cancellation token if importer was resumed while sleeping --- osu.Game/Database/RealmArchiveModelImporter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 1ea97ba718..d107a6a605 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -569,6 +569,7 @@ namespace osu.Game.Database Thread.Sleep(500); } + cancellationToken.ThrowIfCancellationRequested(); Logger.Log($@"{GetType().Name} is being resumed."); } From 6027e7cc4e60012eae835b453f3310078f3e1b97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 9 Jan 2023 18:22:49 +0100 Subject: [PATCH 073/248] Fix one more missed related symbol --- .../Profile/Sections/Historical/ChartProfileSubsection.cs | 2 +- .../Overlays/Profile/Sections/PaginatedProfileSubsection.cs | 6 +++--- osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index 77e967376c..2162adc2b7 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override void LoadComplete() { base.LoadComplete(); - UserProfile.BindValueChanged(onUserChanged, true); + UserProfileData.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent e) diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index 3556e9d809..6ed347e929 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Profile.Sections protected override void LoadComplete() { base.LoadComplete(); - UserProfile.BindValueChanged(onUserChanged, true); + UserProfileData.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent e) @@ -109,14 +109,14 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { - if (UserProfile.Value?.User == null) + if (UserProfileData.Value?.User == null) return; loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(UserProfile.Value.User, CurrentPage.Value); + retrievalRequest = CreateRequest(UserProfileData.Value.User, CurrentPage.Value); retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 20452a1274..78e23da33a 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable UserProfile = new Bindable(); + protected readonly Bindable UserProfileData = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Sections { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; - UserProfile.BindTo(userProfileData); + UserProfileData.BindTo(userProfileData); } [BackgroundDependencyLoader] From 69260ca3c358c77c83e87ee4b9ddaf57fc39fa0a Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 18:36:55 +0100 Subject: [PATCH 074/248] remove unnecessary usages of nullable forgiveness, add asserts for debugging --- .../Visual/SongSelect/TestSceneBeatmapCarousel.cs | 2 +- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 +++- osu.Game/Screens/Select/Carousel/CarouselGroup.cs | 2 +- osu.Game/Screens/Select/Carousel/CarouselItem.cs | 10 ++++++++-- .../Select/Carousel/DrawableCarouselBeatmap.cs | 6 +++--- .../Select/Carousel/DrawableCarouselBeatmapSet.cs | 14 ++++++++------ .../Select/Carousel/DrawableCarouselItem.cs | 10 +++++++--- 7 files changed, 31 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 3cff853f92..1a466dea58 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -1069,7 +1069,7 @@ namespace osu.Game.Tests.Visual.SongSelect return Precision.AlmostEquals( carousel.ScreenSpaceDrawQuad.Centre, carousel.Items - .First(i => i.Item!.State.Value == CarouselItemState.Selected) + .First(i => i.Item?.State.Value == CarouselItemState.Selected) .ScreenSpaceDrawQuad.Centre, 100); }); } diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 4a6ff7417e..12dcdbd3dc 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -770,7 +770,9 @@ namespace osu.Game.Screens.Select { updateItem(item); - if (item.Item!.Visible) + Debug.Assert(item.Item != null); + + if (item.Item.Visible) { bool isSelected = item.Item.State.Value == CarouselItemState.Selected; diff --git a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs index 8667dce226..9302578038 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselGroup.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselGroup.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens.Select.Carousel /// public class CarouselGroup : CarouselItem { - public override DrawableCarouselItem CreateDrawableRepresentation() => null!; + public override DrawableCarouselItem? CreateDrawableRepresentation() => null; public IReadOnlyList Items => items; diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 5de9f2b995..38a1d7117f 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using osu.Framework.Bindables; namespace osu.Game.Screens.Select.Carousel @@ -41,7 +42,7 @@ namespace osu.Game.Screens.Select.Carousel /// /// Create a fresh drawable version of this item. /// - public abstract DrawableCarouselItem CreateDrawableRepresentation(); + public abstract DrawableCarouselItem? CreateDrawableRepresentation(); public virtual void Filter(FilterCriteria criteria) { @@ -49,7 +50,12 @@ namespace osu.Game.Screens.Select.Carousel public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ItemID.CompareTo(other.ItemID); - public int CompareTo(CarouselItem? other) => CarouselYPosition.CompareTo(other!.CarouselYPosition); + public int CompareTo(CarouselItem? other) + { + Debug.Assert(other != null); + + return CarouselYPosition.CompareTo(other.CarouselYPosition); + } } public enum CarouselItemState diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 88a55198b2..e05d950369 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -192,7 +192,7 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - if (Item!.State.Value == CarouselItemState.Selected) + if (Item?.State.Value == CarouselItemState.Selected) startRequested?.Invoke(beatmapInfo); return base.OnClick(e); @@ -200,13 +200,13 @@ namespace osu.Game.Screens.Select.Carousel protected override void ApplyState() { - if (Item!.State.Value != CarouselItemState.Collapsed && Alpha == 0) + if (Item?.State.Value != CarouselItemState.Collapsed && Alpha == 0) starCounter.ReplayAnimation(); starDifficultyCancellationSource?.Cancel(); // Only compute difficulty when the item is visible. - if (Item.State.Value != CarouselItemState.Collapsed) + if (Item?.State.Value != CarouselItemState.Collapsed) { // We've potentially cancelled the computation above so a new bindable is required. starDifficultyBindable = difficultyCache.GetBindableDifficulty(beatmapInfo, (starDifficultyCancellationSource = new CancellationTokenSource()).Token); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index f0bb8b15c2..8974b173fb 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -73,10 +73,10 @@ namespace osu.Game.Screens.Select.Carousel { base.Update(); + Debug.Assert(Item != null); // position updates should not occur if the item is filtered away. // this avoids panels flying across the screen only to be eventually off-screen or faded out. - if (!Item!.Visible) - return; + if (!Item.Visible) return; float targetY = Item.CarouselYPosition; @@ -146,7 +146,9 @@ namespace osu.Game.Screens.Select.Carousel private void updateBeatmapDifficulties() { - var carouselBeatmapSet = (CarouselBeatmapSet)Item!; + if (Item == null) return; + + var carouselBeatmapSet = (CarouselBeatmapSet)Item; var visibleBeatmaps = carouselBeatmapSet.Items.Where(c => c.Visible).ToArray(); @@ -166,7 +168,7 @@ namespace osu.Game.Screens.Select.Carousel { X = 100, RelativeSizeAxes = Axes.Both, - ChildrenEnumerable = visibleBeatmaps.Select(c => c.CreateDrawableRepresentation()) + ChildrenEnumerable = visibleBeatmaps.Select(c => c.CreateDrawableRepresentation()!) }; beatmapsLoadTask = LoadComponentAsync(beatmapContainer, loaded => @@ -191,7 +193,7 @@ namespace osu.Game.Screens.Select.Carousel float yPos = DrawableCarouselBeatmap.CAROUSEL_BEATMAP_SPACING; - bool isSelected = Item!.State.Value == CarouselItemState.Selected; + bool isSelected = Item?.State.Value == CarouselItemState.Selected; foreach (var panel in beatmapContainer.Children) { @@ -213,7 +215,7 @@ namespace osu.Game.Screens.Select.Carousel List items = new List(); - if (Item!.State.Value == CarouselItemState.NotSelected) + if (Item?.State.Value == CarouselItemState.NotSelected) items.Add(new OsuMenuItem("Expand", MenuItemType.Highlighted, () => Item.State.Value = CarouselItemState.Selected)); if (beatmapSet.OnlineID > 0 && viewDetails != null) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index 580dcb3471..c283cca3c8 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -103,7 +103,7 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void UpdateItem() { - if (item == null || Item == null) + if (Item == null) return; Scheduler.AddOnce(ApplyState); @@ -126,9 +126,11 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void ApplyState() { + if (Item == null) return; + // Use the fact that we know the precise height of the item from the model to avoid the need for AutoSize overhead. // Additionally, AutoSize doesn't work well due to content starting off-screen and being masked away. - Height = Item!.TotalHeight; + Height = Item.TotalHeight; switch (Item.State.Value) { @@ -158,7 +160,9 @@ namespace osu.Game.Screens.Select.Carousel protected override bool OnClick(ClickEvent e) { - Item!.State.Value = CarouselItemState.Selected; + Debug.Assert(Item != null); + + Item.State.Value = CarouselItemState.Selected; return true; } } From d6f60db234d0d4e632f911d2ef2a220d798cf70f Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 18:51:51 +0100 Subject: [PATCH 075/248] Add the ability to toggle the visibility of the main bar in BarHitErrorMeter.cs --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index eeca2be7cd..d1b79afe35 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -42,6 +42,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); + [SettingSource("Bar visibility")] + public Bindable BarVisibility { get; } = new Bindable(true); + private const int judgement_line_width = 14; private const int max_concurrent_judgements = 50; @@ -178,6 +181,11 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters CentreMarkerStyle.BindValueChanged(style => recreateCentreMarker(style.NewValue), true); LabelStyle.BindValueChanged(style => recreateLabels(style.NewValue), true); + BarVisibility.BindValueChanged(visible => + { + colourBarsEarly.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); + colourBarsLate.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); + }, true); // delay the appearance animations for only the initial appearance. using (arrowContainer.BeginDelayedSequence(450)) From dbc19777e02120b1362886deec24adf3b7c8fe9c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 21:17:40 +0300 Subject: [PATCH 076/248] Move stable import buttons under "debug" section --- .../MaintenanceSettingsStrings.cs | 20 ------ .../Settings/Sections/DebugSection.cs | 12 ++-- .../DebugSettings/BatchImportSettings.cs | 66 +++++++++++++++++++ .../Sections/Maintenance/BeatmapSettings.cs | 17 +---- .../Maintenance/CollectionsSettings.cs | 17 +---- .../Sections/Maintenance/ScoreSettings.cs | 17 +---- .../Sections/Maintenance/SkinSettings.cs | 17 +---- 7 files changed, 77 insertions(+), 89 deletions(-) create mode 100644 osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs diff --git a/osu.Game/Localisation/MaintenanceSettingsStrings.cs b/osu.Game/Localisation/MaintenanceSettingsStrings.cs index 8aa0adf7a0..469f565f1e 100644 --- a/osu.Game/Localisation/MaintenanceSettingsStrings.cs +++ b/osu.Game/Localisation/MaintenanceSettingsStrings.cs @@ -54,11 +54,6 @@ namespace osu.Game.Localisation /// public static LocalisableString RestartAndReOpenRequiredForCompletion => new TranslatableString(getKey(@"restart_and_re_open_required_for_completion"), @"To complete this operation, osu! will close. Please open it again to use the new data location."); - /// - /// "Import beatmaps from stable" - /// - public static LocalisableString ImportBeatmapsFromStable => new TranslatableString(getKey(@"import_beatmaps_from_stable"), @"Import beatmaps from stable"); - /// /// "Delete ALL beatmaps" /// @@ -69,31 +64,16 @@ namespace osu.Game.Localisation /// public static LocalisableString DeleteAllBeatmapVideos => new TranslatableString(getKey(@"delete_all_beatmap_videos"), @"Delete ALL beatmap videos"); - /// - /// "Import scores from stable" - /// - public static LocalisableString ImportScoresFromStable => new TranslatableString(getKey(@"import_scores_from_stable"), @"Import scores from stable"); - /// /// "Delete ALL scores" /// public static LocalisableString DeleteAllScores => new TranslatableString(getKey(@"delete_all_scores"), @"Delete ALL scores"); - /// - /// "Import skins from stable" - /// - public static LocalisableString ImportSkinsFromStable => new TranslatableString(getKey(@"import_skins_from_stable"), @"Import skins from stable"); - /// /// "Delete ALL skins" /// public static LocalisableString DeleteAllSkins => new TranslatableString(getKey(@"delete_all_skins"), @"Delete ALL skins"); - /// - /// "Import collections from stable" - /// - public static LocalisableString ImportCollectionsFromStable => new TranslatableString(getKey(@"import_collections_from_stable"), @"Import collections from stable"); - /// /// "Delete ALL collections" /// diff --git a/osu.Game/Overlays/Settings/Sections/DebugSection.cs b/osu.Game/Overlays/Settings/Sections/DebugSection.cs index 2594962314..509410fbb1 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSection.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSection.cs @@ -3,6 +3,7 @@ #nullable disable +using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; @@ -22,11 +23,12 @@ namespace osu.Game.Overlays.Settings.Sections public DebugSection() { - Children = new Drawable[] - { - new GeneralSettings(), - new MemorySettings(), - }; + Add(new GeneralSettings()); + + if (DebugUtils.IsDebugBuild) + Add(new BatchImportSettings()); + + Add(new MemorySettings()); } } } diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs new file mode 100644 index 0000000000..1c17356313 --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/BatchImportSettings.cs @@ -0,0 +1,66 @@ +// 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.Localisation; +using osu.Game.Database; + +namespace osu.Game.Overlays.Settings.Sections.DebugSettings +{ + public partial class BatchImportSettings : SettingsSubsection + { + protected override LocalisableString Header => @"Batch Import"; + + private SettingsButton importBeatmapsButton = null!; + private SettingsButton importCollectionsButton = null!; + private SettingsButton importScoresButton = null!; + private SettingsButton importSkinsButton = null!; + + [BackgroundDependencyLoader] + private void load(LegacyImportManager? legacyImportManager) + { + if (legacyImportManager?.SupportsImportFromStable != true) + return; + + AddRange(new[] + { + importBeatmapsButton = new SettingsButton + { + Text = @"Import beatmaps from stable", + Action = () => + { + importBeatmapsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(_ => Schedule(() => importBeatmapsButton.Enabled.Value = true)); + } + }, + importSkinsButton = new SettingsButton + { + Text = @"Import skins from stable", + Action = () => + { + importSkinsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Skins).ContinueWith(_ => Schedule(() => importSkinsButton.Enabled.Value = true)); + } + }, + importCollectionsButton = new SettingsButton + { + Text = @"Import collections from stable", + Action = () => + { + importCollectionsButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Collections).ContinueWith(_ => Schedule(() => importCollectionsButton.Enabled.Value = true)); + } + }, + importScoresButton = new SettingsButton + { + Text = @"Import scores from stable", + Action = () => + { + importScoresButton.Enabled.Value = false; + legacyImportManager.ImportFromStableAsync(StableContent.Scores).ContinueWith(_ => Schedule(() => importScoresButton.Enabled.Value = true)); + } + }, + }); + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs index 9c0b86c862..4b1836ed86 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/BeatmapSettings.cs @@ -6,7 +6,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Beatmaps; -using osu.Game.Database; using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.Maintenance @@ -15,28 +14,14 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Beatmaps; - private SettingsButton importBeatmapsButton = null!; private SettingsButton deleteBeatmapsButton = null!; private SettingsButton deleteBeatmapVideosButton = null!; private SettingsButton restoreButton = null!; private SettingsButton undeleteButton = null!; [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(BeatmapManager beatmaps, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importBeatmapsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportBeatmapsFromStable, - Action = () => - { - importBeatmapsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Beatmaps).ContinueWith(_ => Schedule(() => importBeatmapsButton.Enabled.Value = true)); - } - }); - } - Add(deleteBeatmapsButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllBeatmaps, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs index 4da5aaf492..09acc22c25 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/CollectionsSettings.cs @@ -14,8 +14,6 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Collections; - private SettingsButton importCollectionsButton = null!; - [Resolved] private RealmAccess realm { get; set; } = null!; @@ -23,21 +21,8 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance private INotificationOverlay? notificationOverlay { get; set; } [BackgroundDependencyLoader] - private void load(LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importCollectionsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportCollectionsFromStable, - Action = () => - { - importCollectionsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Collections).ContinueWith(_ => Schedule(() => importCollectionsButton.Enabled.Value = true)); - } - }); - } - Add(new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllCollections, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs index 1f09854843..c6f4f1e1a5 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/ScoreSettings.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Game.Database; using osu.Game.Localisation; using osu.Game.Scoring; @@ -14,25 +13,11 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Scores; - private SettingsButton importScoresButton = null!; private SettingsButton deleteScoresButton = null!; [BackgroundDependencyLoader] - private void load(ScoreManager scores, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(ScoreManager scores, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importScoresButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportScoresFromStable, - Action = () => - { - importScoresButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Scores).ContinueWith(_ => Schedule(() => importScoresButton.Enabled.Value = true)); - } - }); - } - Add(deleteScoresButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllScores, diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs index e4185fe6c2..c3ac49af6d 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/SkinSettings.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Localisation; -using osu.Game.Database; using osu.Game.Localisation; using osu.Game.Skinning; @@ -14,25 +13,11 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance { protected override LocalisableString Header => CommonStrings.Skins; - private SettingsButton importSkinsButton = null!; private SettingsButton deleteSkinsButton = null!; [BackgroundDependencyLoader] - private void load(SkinManager skins, LegacyImportManager? legacyImportManager, IDialogOverlay? dialogOverlay) + private void load(SkinManager skins, IDialogOverlay? dialogOverlay) { - if (legacyImportManager?.SupportsImportFromStable == true) - { - Add(importSkinsButton = new SettingsButton - { - Text = MaintenanceSettingsStrings.ImportSkinsFromStable, - Action = () => - { - importSkinsButton.Enabled.Value = false; - legacyImportManager.ImportFromStableAsync(StableContent.Skins).ContinueWith(_ => Schedule(() => importSkinsButton.Enabled.Value = true)); - } - }); - } - Add(deleteSkinsButton = new DangerousSettingsButton { Text = MaintenanceSettingsStrings.DeleteAllSkins, From 98390ea2a86b8eedadac75605a43f6ac316b4088 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 21:33:04 +0300 Subject: [PATCH 077/248] Fix condition flipped --- osu.Game/Online/Chat/ChannelManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 26ab9e87ba..1e3921bac0 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -328,7 +328,7 @@ namespace osu.Game.Online.Chat { // This request is self-retrying until it succeeds. // To avoid requests piling up when not logged in (ie. API is unavailable) exit early. - if (api.IsLoggedIn) + if (!api.IsLoggedIn) return; var req = new ListChannelsRequest(); From 6abbc7dc28472508edb9dc2341ca0461bb362cf0 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 20:59:28 +0100 Subject: [PATCH 078/248] Further fix nullability --- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 +++- osu.Game/Screens/Select/Carousel/CarouselItem.cs | 8 +------- .../Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 6 ++++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 12dcdbd3dc..03085a8638 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -739,7 +739,9 @@ namespace osu.Game.Screens.Select foreach (var panel in Scroll.Children) { - if (toDisplay.Remove(panel.Item!)) + Debug.Assert(panel.Item != null); + + if (toDisplay.Remove(panel.Item)) { // panel already displayed. continue; diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 38a1d7117f..4a5af6f6b1 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using osu.Framework.Bindables; namespace osu.Game.Screens.Select.Carousel @@ -50,12 +49,7 @@ namespace osu.Game.Screens.Select.Carousel public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ItemID.CompareTo(other.ItemID); - public int CompareTo(CarouselItem? other) - { - Debug.Assert(other != null); - - return CarouselYPosition.CompareTo(other.CarouselYPosition); - } + public int CompareTo(CarouselItem? other) => CarouselYPosition.CompareTo(other?.CarouselYPosition); } public enum CarouselItemState diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 8974b173fb..ea59c330b4 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -146,7 +146,7 @@ namespace osu.Game.Screens.Select.Carousel private void updateBeatmapDifficulties() { - if (Item == null) return; + Debug.Assert(Item != null); var carouselBeatmapSet = (CarouselBeatmapSet)Item; @@ -197,10 +197,12 @@ namespace osu.Game.Screens.Select.Carousel foreach (var panel in beatmapContainer.Children) { + Debug.Assert(panel.Item != null); + if (isSelected) { panel.MoveToY(yPos, 800, Easing.OutQuint); - yPos += panel.Item!.TotalHeight; + yPos += panel.Item.TotalHeight; } else panel.MoveToY(0, 800, Easing.OutQuint); From 602062f011e42531dc78f79b3ba099145607dd80 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Mon, 9 Jan 2023 21:04:51 +0100 Subject: [PATCH 079/248] Address unclear naming issue --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index d1b79afe35..2907695ce7 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -42,8 +42,8 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); - [SettingSource("Bar visibility")] - public Bindable BarVisibility { get; } = new Bindable(true); + [SettingSource("Show colour bars")] + public Bindable ColourBarVisibility { get; } = new Bindable(true); private const int judgement_line_width = 14; @@ -181,7 +181,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters CentreMarkerStyle.BindValueChanged(style => recreateCentreMarker(style.NewValue), true); LabelStyle.BindValueChanged(style => recreateLabels(style.NewValue), true); - BarVisibility.BindValueChanged(visible => + ColourBarVisibility.BindValueChanged(visible => { colourBarsEarly.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); colourBarsLate.FadeTo(visible.NewValue ? 1 : 0, 500, Easing.OutQuint); From f216d7264b2f10500023ec97a4348884f662af5a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 22:51:38 +0300 Subject: [PATCH 080/248] Improve missing beatmap failure logging on score import --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 13 +++++++++---- osu.Game/Scoring/ScoreImporter.cs | 10 ++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index 15ed992c3e..a507bb73c6 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -8,6 +8,7 @@ using System.Diagnostics; using System.IO; using System.Linq; using Newtonsoft.Json; +using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; @@ -46,10 +47,12 @@ namespace osu.Game.Scoring.Legacy score.ScoreInfo = scoreInfo; int version = sr.ReadInt32(); + string beatmapHash = sr.ReadString(); + + workingBeatmap = GetBeatmap(beatmapHash); - workingBeatmap = GetBeatmap(sr.ReadString()); if (workingBeatmap is DummyWorkingBeatmap) - throw new BeatmapNotFoundException(); + throw new BeatmapNotFoundException(beatmapHash); scoreInfo.User = new APIUser { Username = sr.ReadString() }; @@ -334,9 +337,11 @@ namespace osu.Game.Scoring.Legacy public class BeatmapNotFoundException : Exception { - public BeatmapNotFoundException() - : base("No corresponding beatmap for the score could be found.") + public string Hash { get; } + + public BeatmapNotFoundException(string hash) { + Hash = hash; } } } diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index a3d7fe5de0..d63741e73b 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Newtonsoft.Json; +using osu.Framework.Graphics.Sprites; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -17,6 +18,7 @@ using osu.Game.Scoring.Legacy; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using Realms; @@ -44,7 +46,9 @@ namespace osu.Game.Scoring protected override ScoreInfo? CreateModel(ArchiveReader archive) { - using (var stream = archive.GetStream(archive.Filenames.First(f => f.EndsWith(".osr", StringComparison.OrdinalIgnoreCase)))) + string name = archive.Filenames.First(f => f.EndsWith(".osr", StringComparison.OrdinalIgnoreCase)); + + using (var stream = archive.GetStream(name)) { try { @@ -52,7 +56,9 @@ namespace osu.Game.Scoring } catch (LegacyScoreDecoder.BeatmapNotFoundException e) { - Logger.Log(e.Message, LoggingTarget.Information, LogLevel.Error); + Logger.Log($@"Score '{name}' failed to import: no corresponding beatmap with the hash '{e.Hash}' could be found.", LoggingTarget.Database); + Logger.Log($@"Score '{name}' failed to import due to missing beatmap. Check database logs for more info.", LoggingTarget.Information, LogLevel.Error); + return null; } } From 20ed337ea863ce2288340f8c4fde5043e29bae82 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 23:25:52 +0300 Subject: [PATCH 081/248] Remove unused using directive --- osu.Game/Scoring/ScoreImporter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index d63741e73b..2dfd461eb9 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Linq; using System.Threading; using Newtonsoft.Json; -using osu.Framework.Graphics.Sprites; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -18,7 +17,6 @@ using osu.Game.Scoring.Legacy; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; -using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; using Realms; From 91eab7985bb2a3fd83bd1202c81c16847dacf6af Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 21:35:27 +0100 Subject: [PATCH 082/248] feat(ui): Implement a segmented graph --- .../Graphics/UserInterface/SegmentedGraph.cs | 314 ++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 osu.Game/Graphics/UserInterface/SegmentedGraph.cs diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs new file mode 100644 index 0000000000..261e535fbc --- /dev/null +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -0,0 +1,314 @@ +// 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; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Threading; +using osuTK; + +namespace osu.Game.Graphics.UserInterface +{ + public abstract partial class SegmentedGraph : Container + where T : struct, IComparable, IConvertible, IEquatable + { + private BufferedContainer? rectSegments; + private float previousDrawWidth; + private bool graphNeedsUpdate; + + private T[]? values; + private int[] tiers = Array.Empty(); + private readonly SegmentManager segments; + + private readonly int tierCount; + + protected SegmentedGraph(int tierCount) + { + this.tierCount = tierCount; + TierColours = new Colour4[tierCount]; + segments = new SegmentManager(tierCount); + } + + public T[] Values + { + get => values ?? Array.Empty(); + set + { + if (value == values) return; + + values = value; + recalculateTiers(values); + graphNeedsUpdate = true; + } + } + + public readonly Colour4[] TierColours; + + private CancellationTokenSource? cts; + private ScheduledDelegate? scheduledCreate; + + protected override void Update() + { + base.Update(); + + if (graphNeedsUpdate || (values != null && DrawWidth != previousDrawWidth)) + { + rectSegments?.FadeOut(150, Easing.OutQuint).Expire(); + + scheduledCreate?.Cancel(); + scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 150); + + previousDrawWidth = DrawWidth; + graphNeedsUpdate = false; + } + } + + protected virtual void RecreateGraph() + { + var newSegments = new BufferedContainer(cachedFrameBuffer: true) + { + RedrawOnScale = false, + RelativeSizeAxes = Axes.Both + }; + + cts?.Cancel(); + recalculateSegments(); + redrawSegments(newSegments); + + LoadComponentAsync(newSegments, s => + { + Children = new Drawable[] + { + rectSegments = s + }; + + s.FadeInFromZero(100); + }, (cts = new CancellationTokenSource()).Token); + } + + private void recalculateTiers(T[]? arr) + { + if (arr == null || arr.Length == 0) + { + tiers = Array.Empty(); + return; + } + + float[] floatValues = arr.Select(v => Convert.ToSingle(v)).ToArray(); + + // Shift values to eliminate negative ones + float min = floatValues.Min(); + + if (min < 0) + { + for (int i = 0; i < floatValues.Length; i++) + floatValues[i] += min; + } + + // Normalize values + float max = floatValues.Max(); + + for (int i = 0; i < floatValues.Length; i++) + floatValues[i] /= max; + + // Deduce tiers from values + tiers = floatValues.Select(v => (int)Math.Floor(v * tierCount)).ToArray(); + } + + private void recalculateSegments() + { + segments.Clear(); + + if (tiers.Length == 0) + { + segments.Add(0, 0, 1); + return; + } + + for (int i = 0; i < tiers.Length; i++) + { + for (int tier = 0; tier < tierCount; tier++) + { + if (tier < 0) + continue; + + // One tier covers itself and all tiers above it. + // By layering multiple transparent boxes, higher tiers will be brighter. + // If using opaque colors, higher tiers will be on front, covering lower tiers. + if (tiers[i] >= tier) + { + if (!segments.IsTierStarted(tier)) + segments.StartSegment(tier, i * 1f / tiers.Length); + } + else + { + if (segments.IsTierStarted(tier)) + segments.EndSegment(tier, i * 1f / tiers.Length); + } + } + } + + segments.EndAllPendingSegments(); + segments.Sort(); + } + + private Colour4 tierToColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); + + // Base implementation, could be drawn with draw node if preferred + private void redrawSegments(BufferedContainer container) + { + if (segments.Count == 0) + return; + + foreach (SegmentInfo segment in segments) // Lower tiers will be drawn first, putting them in the back + { + float width = segment.Length * DrawWidth; + + // If the segment width exceeds the DrawWidth, just fill the rest + if (width >= DrawWidth) + width = DrawWidth; + + container.Add(new Box + { + Name = $"Tier {segment.Tier} segment", + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Position = new Vector2(segment.Start * DrawWidth, 0), + Width = width, + Colour = tierToColour(segment.Tier) + }); + } + } + + protected struct SegmentInfo + { + /// + /// The tier this segment is at. + /// + public int Tier; + + /// + /// The progress at which this segment starts. + /// + /// + /// The value is a normalized float (from 0 to 1). + /// + public float Start; + + /// + /// The progress at which this segment ends. + /// + /// + /// The value is a normalized float (from 0 to 1). + /// + public float End; + + /// + /// The length of this segment. + /// + /// + /// The value is a normalized float (from 0 to 1). + /// + public float Length => End - Start; + } + + protected class SegmentManager : IEnumerable + { + private readonly List segments = new List(); + + private readonly SegmentInfo?[] pendingSegments; + + public SegmentManager(int tierCount) + { + pendingSegments = new SegmentInfo?[tierCount]; + } + + public void StartSegment(int tier, float start) + { + if (pendingSegments[tier] != null) + throw new InvalidOperationException($"Another {nameof(SegmentInfo)} of tier {tier.ToString()} has already been started."); + + pendingSegments[tier] = new SegmentInfo + { + Tier = tier, + Start = Math.Clamp(start, 0, 1) + }; + } + + public void EndSegment(int tier, float end) + { + SegmentInfo? pendingSegment = pendingSegments[tier]; + if (pendingSegment == null) + throw new InvalidOperationException($"Cannot end {nameof(SegmentInfo)} of tier {tier.ToString()} that has not been started."); + + SegmentInfo segment = pendingSegment.Value; + segment.End = Math.Clamp(end, 0, 1); + segments.Add(segment); + pendingSegments[tier] = null; + } + + public void EndAllPendingSegments() + { + foreach (SegmentInfo? pendingSegment in pendingSegments) + { + if (pendingSegment != null) + { + SegmentInfo finalizedSegment = pendingSegment.Value; + finalizedSegment.End = 1; + segments.Add(finalizedSegment); + } + } + } + + public void Sort() => + segments.Sort((a, b) => + a.Tier != b.Tier + ? a.Tier.CompareTo(b.Tier) + : a.Start.CompareTo(b.Start)); + + public void Add(SegmentInfo segment) => segments.Add(segment); + + public void Clear() + { + segments.Clear(); + + for (int i = 0; i < pendingSegments.Length; i++) + pendingSegments[i] = null; + } + + public int Count => segments.Count; + + public void Add(int tier, float start, float end) + { + SegmentInfo segment = new SegmentInfo + { + Tier = tier, + Start = Math.Clamp(start, 0, 1), + End = Math.Clamp(end, 0, 1) + }; + + if (segment.Start > segment.End) + throw new InvalidOperationException("Segment start cannot be after segment end."); + + Add(segment); + } + + public bool IsTierStarted(int tier) + { + if (tier < 0) + return false; + + return pendingSegments[tier].HasValue; + } + + public IEnumerator GetEnumerator() => segments.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + } +} From 23e4cfb4691a4eea687e56bd90cb8d4463adabac Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 9 Jan 2023 23:37:36 +0300 Subject: [PATCH 083/248] Show spinner next to buttons and get rid of `EditorCommitButton` --- .../UserInterface/TestSceneCommentEditor.cs | 17 ++- osu.Game/Overlays/Comments/CommentEditor.cs | 116 ++++++++---------- 2 files changed, 58 insertions(+), 75 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 799f5c52bd..e7840d4a2a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -7,7 +7,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; using osu.Framework.Testing; @@ -56,9 +55,9 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); - AddUntilStep("button is loading", () => commentEditor.ButtonLoading); + AddUntilStep("button is loading", () => commentEditor.IsSpinnerShown); AddAssert("text committed", () => commentEditor.CommittedText == "text"); - AddUntilStep("button is not loading", () => !commentEditor.ButtonLoading); + AddUntilStep("button is not loading", () => !commentEditor.IsSpinnerShown); } [Test] @@ -72,7 +71,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("press Enter", () => InputManager.Key(Key.Enter)); - AddAssert("button is not loading", () => !commentEditor.ButtonLoading); + AddAssert("button is not loading", () => !commentEditor.IsSpinnerShown); AddAssert("no text committed", () => commentEditor.CommittedText.Length == 0); } @@ -92,9 +91,9 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); - AddUntilStep("button is loading", () => commentEditor.ButtonLoading); + AddUntilStep("button is loading", () => commentEditor.IsSpinnerShown); AddAssert("text committed", () => commentEditor.CommittedText == "some other text"); - AddUntilStep("button is not loading", () => !commentEditor.ButtonLoading); + AddUntilStep("button is not loading", () => !commentEditor.IsSpinnerShown); } [Test] @@ -116,13 +115,13 @@ namespace osu.Game.Tests.Visual.UserInterface public string CommittedText { get; private set; } = string.Empty; - public bool ButtonLoading => CommitButton.ChildrenOfType().Single().IsPresent && !CommitButton.ChildrenOfType().Single().IsPresent; + public bool IsSpinnerShown => this.ChildrenOfType().Single().IsPresent; protected override void OnCommit(string value) { - CommitButton.ShowLoadingSpinner = true; + ShowLoadingSpinner = true; CommittedText = value; - Scheduler.AddDelayed(() => CommitButton.ShowLoadingSpinner = false, 1000); + Scheduler.AddDelayed(() => ShowLoadingSpinner = false, 1000); } protected override LocalisableString FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index da71d0f364..f11cef55d4 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -32,7 +32,24 @@ namespace osu.Game.Overlays.Comments protected readonly Bindable Current = new Bindable(); - protected EditorCommitButton CommitButton = null!; + private RoundedButton commitButton = null!; + private LoadingSpinner loadingSpinner = null!; + + private bool showLoadingSpinner; + + protected bool ShowLoadingSpinner + { + set + { + commitButton.Enabled.Value = !value && !string.IsNullOrEmpty(Current.Value); + showLoadingSpinner = value; + + if (value) + loadingSpinner.Show(); + else + loadingSpinner.Hide(); + } + } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -82,36 +99,57 @@ namespace osu.Game.Overlays.Comments Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), Text = FooterText }, - ButtonsContainer = new FillFlowContainer + new FillFlowContainer { - Name = @"Buttons", Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(5, 0), - Child = CommitButton = new EditorCommitButton + Children = new Drawable[] { - Text = CommitButtonText, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Action = () => OnCommit(Current.Value) + ButtonsContainer = new FillFlowContainer + { + Name = @"Buttons", + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Child = commitButton = new RoundedButton + { + Width = 100, + Height = 30, + Text = CommitButtonText, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Action = () => OnCommit(Current.Value) + } + }, + loadingSpinner = new LoadingSpinner + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Size = new Vector2(18), + }, } - } + }, } } } } }); - textBox.OnCommit += (_, _) => CommitButton.TriggerClick(); + textBox.OnCommit += (_, _) => commitButton.TriggerClick(); } protected override void LoadComplete() { base.LoadComplete(); - - Current.BindValueChanged(text => CommitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); + Current.BindValueChanged(text => + { + commitButton.Enabled.Value = !showLoadingSpinner && !string.IsNullOrEmpty(text.NewValue); + }, true); } protected abstract void OnCommit(string text); @@ -149,59 +187,5 @@ namespace osu.Game.Overlays.Comments Child = new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) } }; } - - protected sealed partial class EditorCommitButton : RoundedButton - { - private const int duration = 200; - - private readonly LoadingSpinner spinner; - private SpriteText text = null!; - - public readonly BindableBool IsBlocked = new BindableBool(); - - private bool showLoadingSpinner; - - /// - /// Whether loading spinner shown. - /// - public bool ShowLoadingSpinner - { - get => showLoadingSpinner; - set - { - showLoadingSpinner = value; - Enabled.Value = !value && !IsBlocked.Value; - spinner.FadeTo(value ? 1f : 0f, duration, Easing.OutQuint); - text.FadeTo(value ? 0f : 1f, duration, Easing.OutQuint); - } - } - - public EditorCommitButton() - { - Width = 100; - Height = 30; - Add(spinner = new LoadingSpinner - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(16), - Depth = -2, - }); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - IsBlocked.BindValueChanged(e => - { - Enabled.Value = !ShowLoadingSpinner && !e.NewValue; - }, true); - } - - protected override SpriteText CreateText() - { - return text = base.CreateText(); - } - } } } From e6479b73ded35cc109627f9bcffbbc7b8ac3c676 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 9 Jan 2023 23:43:35 +0300 Subject: [PATCH 084/248] Remove one more unused using directive --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index a507bb73c6..6f0b0c62f8 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -8,7 +8,6 @@ using System.Diagnostics; using System.IO; using System.Linq; using Newtonsoft.Json; -using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Legacy; From f971405c8c3978d6603461316f3d37ec8be105c6 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Tue, 10 Jan 2023 00:02:31 +0000 Subject: [PATCH 085/248] append time as well --- osu.Game/Database/LegacyScoreExporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/LegacyScoreExporter.cs b/osu.Game/Database/LegacyScoreExporter.cs index 7c0ba7c6ee..01f9afdc86 100644 --- a/osu.Game/Database/LegacyScoreExporter.cs +++ b/osu.Game/Database/LegacyScoreExporter.cs @@ -23,7 +23,7 @@ namespace osu.Game.Database protected override string GetFilename(ScoreInfo score) { string scoreString = score.GetDisplayString(); - string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd})"; + string filename = $"{scoreString} ({score.Date.LocalDateTime:yyyy-MM-dd_HH-mm})"; return filename; } From 93038ce496164e19c9fb26d05455bf40c401c31d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 17:49:08 +0900 Subject: [PATCH 086/248] Use `OfType` instead of forceful nullability --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 03085a8638..19eced08d9 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Select { CarouselRoot newRoot = new CarouselRoot(this); - newRoot.AddItems(beatmapSets.Select(s => createCarouselSet(s.Detach())).Where(g => g != null)!); + newRoot.AddItems(beatmapSets.Select(s => createCarouselSet(s.Detach())).OfType()); root = newRoot; From d53dafa29fc539de5c21705c433976f7d3df15e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 17:52:28 +0900 Subject: [PATCH 087/248] Revert `Debug.Assert` --- osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs index c283cca3c8..f065926eb7 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselItem.cs @@ -126,7 +126,7 @@ namespace osu.Game.Screens.Select.Carousel protected virtual void ApplyState() { - if (Item == null) return; + Debug.Assert(Item != null); // Use the fact that we know the precise height of the item from the model to avoid the need for AutoSize overhead. // Additionally, AutoSize doesn't work well due to content starting off-screen and being masked away. From b7e845201f51019529fb913dbe214de4168ff127 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:03:17 +0900 Subject: [PATCH 088/248] Fix whitespace around `Debug.Assert` --- osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index ea59c330b4..3975bb6bb6 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -74,6 +74,7 @@ namespace osu.Game.Screens.Select.Carousel base.Update(); Debug.Assert(Item != null); + // position updates should not occur if the item is filtered away. // this avoids panels flying across the screen only to be eventually off-screen or faded out. if (!Item.Visible) return; From 63ce5787e7525ac0d73c3291f283946e20296f2f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:06:45 +0900 Subject: [PATCH 089/248] Start bars invisible --- osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 2907695ce7..17d07ce16c 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -111,6 +111,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Origin = Anchor.TopCentre, Width = bar_width, RelativeSizeAxes = Axes.Y, + Alpha = 0, Height = 0.5f, Scale = new Vector2(1, -1), }, @@ -118,6 +119,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters { Anchor = Anchor.Centre, Origin = Anchor.TopCentre, + Alpha = 0, Width = bar_width, RelativeSizeAxes = Axes.Y, Height = 0.5f, From 3c93d0551cf4c13479fc41d6bfdee64825b5e30a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:07:15 +0900 Subject: [PATCH 090/248] Move setting up to be in line with other toggle --- .../Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs index 17d07ce16c..0337f66bd9 100644 --- a/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs +++ b/osu.Game/Screens/Play/HUD/HitErrorMeters/BarHitErrorMeter.cs @@ -33,6 +33,9 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters Precision = 0.1f, }; + [SettingSource("Show colour bars")] + public Bindable ColourBarVisibility { get; } = new Bindable(true); + [SettingSource("Show moving average arrow", "Whether an arrow should move beneath the bar showing the average error.")] public Bindable ShowMovingAverage { get; } = new BindableBool(true); @@ -42,9 +45,6 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters [SettingSource("Label style", "How to show early/late extremities")] public Bindable LabelStyle { get; } = new Bindable(LabelStyles.Icons); - [SettingSource("Show colour bars")] - public Bindable ColourBarVisibility { get; } = new Bindable(true); - private const int judgement_line_width = 14; private const int max_concurrent_judgements = 50; From 85f542c3a80a88ddc258b302ac5403b8d99c5e37 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:15:08 +0900 Subject: [PATCH 091/248] Make `GameplayClock` `private` --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index 8d3cab40b0..b9f5deacb0 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play.HUD private IBindable beatmap { get; set; } = null!; [Resolved] - protected IGameplayClock GameplayClock { get; private set; } = null!; + private IGameplayClock gameplayClock { get; set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colour) @@ -38,10 +38,10 @@ namespace osu.Game.Screens.Play.HUD base.Update(); //We dont want it going to 0 when we pause. so we block the updates - if (GameplayClock.IsPaused.Value) return; + if (gameplayClock.IsPaused.Value) return; // We want to check Rate every update to cover windup/down - Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(GameplayClock.CurrentTime).BPM * GameplayClock.Rate; + Current.Value = beatmap.Value.Beatmap.ControlPointInfo.TimingPointAt(gameplayClock.CurrentTime).BPM * gameplayClock.Rate; } protected override OsuSpriteText CreateSpriteText() From 37d219a8ad011814c7ad93a2a10bc5d3e1f0ea2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 18:20:39 +0900 Subject: [PATCH 092/248] Fix comments, remove fixed width on "bpm" text and adjust baseline adjust slightly --- osu.Game/Screens/Play/HUD/BPMCounter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/BPMCounter.cs b/osu.Game/Screens/Play/HUD/BPMCounter.cs index b9f5deacb0..c07b203341 100644 --- a/osu.Game/Screens/Play/HUD/BPMCounter.cs +++ b/osu.Game/Screens/Play/HUD/BPMCounter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Play.HUD { base.Update(); - //We dont want it going to 0 when we pause. so we block the updates + //We don't want it going to 0 when we pause. so we block the updates if (gameplayClock.IsPaused.Value) return; // We want to check Rate every update to cover windup/down @@ -84,9 +84,9 @@ namespace osu.Game.Screens.Play.HUD { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Font = OsuFont.Numeric.With(size: 8, fixedWidth: true), + Font = OsuFont.Numeric.With(size: 8), Text = @"BPM", - Padding = new MarginPadding { Bottom = 1.5f }, // align baseline better + Padding = new MarginPadding { Bottom = 2f }, // align baseline better } } }; From c6b6d0dcfee83d39e698f7787ccd681c15305919 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 13:31:29 +0300 Subject: [PATCH 093/248] Remove verbose log from notifications feed --- osu.Game/Scoring/ScoreImporter.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Scoring/ScoreImporter.cs b/osu.Game/Scoring/ScoreImporter.cs index 2dfd461eb9..f69c1b9385 100644 --- a/osu.Game/Scoring/ScoreImporter.cs +++ b/osu.Game/Scoring/ScoreImporter.cs @@ -55,8 +55,6 @@ namespace osu.Game.Scoring catch (LegacyScoreDecoder.BeatmapNotFoundException e) { Logger.Log($@"Score '{name}' failed to import: no corresponding beatmap with the hash '{e.Hash}' could be found.", LoggingTarget.Database); - Logger.Log($@"Score '{name}' failed to import due to missing beatmap. Check database logs for more info.", LoggingTarget.Information, LogLevel.Error); - return null; } } From 0d6b9ebc0f18aa2db7cde7b9a55bf91ced958e88 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 13:32:03 +0300 Subject: [PATCH 094/248] Display number of failing models during batch-import --- osu.Game/Database/RealmArchiveModelImporter.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index d107a6a605..20cae725ad 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -154,9 +154,12 @@ namespace osu.Game.Database } else { - notification.CompletionText = imported.Count == 1 - ? $"Imported {imported.First().GetDisplayString()}!" - : $"Imported {imported.Count} {HumanisedModelName}s!"; + if (tasks.Length > imported.Count) + notification.CompletionText = $"Imported {imported.Count} out of {tasks.Length} {HumanisedModelName}s."; + else if (imported.Count > 1) + notification.CompletionText = $"Imported {imported.Count} {HumanisedModelName}s!"; + else + notification.CompletionText = $"Imported {imported.First().GetDisplayString()}!"; if (imported.Count > 0 && PresentImport != null) { From a22b7298c6facab60b864886b460d42a8d906432 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 22:27:36 +0900 Subject: [PATCH 095/248] Adjust english slightly --- osu.Game/Database/RealmArchiveModelImporter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/RealmArchiveModelImporter.cs b/osu.Game/Database/RealmArchiveModelImporter.cs index 20cae725ad..db8861c281 100644 --- a/osu.Game/Database/RealmArchiveModelImporter.cs +++ b/osu.Game/Database/RealmArchiveModelImporter.cs @@ -155,7 +155,7 @@ namespace osu.Game.Database else { if (tasks.Length > imported.Count) - notification.CompletionText = $"Imported {imported.Count} out of {tasks.Length} {HumanisedModelName}s."; + notification.CompletionText = $"Imported {imported.Count} of {tasks.Length} {HumanisedModelName}s."; else if (imported.Count > 1) notification.CompletionText = $"Imported {imported.Count} {HumanisedModelName}s!"; else From 23a78e6fad219de63eabdbe20ae36a3e61034e15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 23:57:38 +0900 Subject: [PATCH 096/248] Combine commit button enabled handling --- osu.Game/Overlays/Comments/CommentEditor.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index f11cef55d4..8e02d015ed 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -35,19 +35,16 @@ namespace osu.Game.Overlays.Comments private RoundedButton commitButton = null!; private LoadingSpinner loadingSpinner = null!; - private bool showLoadingSpinner; - protected bool ShowLoadingSpinner { set { - commitButton.Enabled.Value = !value && !string.IsNullOrEmpty(Current.Value); - showLoadingSpinner = value; - if (value) loadingSpinner.Show(); else loadingSpinner.Hide(); + + updateCommitButtonState(); } } @@ -146,14 +143,14 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { base.LoadComplete(); - Current.BindValueChanged(text => - { - commitButton.Enabled.Value = !showLoadingSpinner && !string.IsNullOrEmpty(text.NewValue); - }, true); + Current.BindValueChanged(_ => updateCommitButtonState(), true); } protected abstract void OnCommit(string text); + private void updateCommitButtonState() => + commitButton.Enabled.Value = loadingSpinner.State.Value == Visibility.Hidden && !string.IsNullOrEmpty(Current.Value); + private partial class EditorTextBox : BasicTextBox { protected override float LeftRightPadding => side_padding; From aab84d50eb0113e1dba40752c487d6d55abfba0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 10 Jan 2023 18:29:56 +0100 Subject: [PATCH 097/248] Remove boxing overhead in `CarouselItem` comparator --- osu.Game/Screens/Select/Carousel/CarouselItem.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 4a5af6f6b1..5e425a4a1c 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -49,7 +49,12 @@ namespace osu.Game.Screens.Select.Carousel public virtual int CompareTo(FilterCriteria criteria, CarouselItem other) => ItemID.CompareTo(other.ItemID); - public int CompareTo(CarouselItem? other) => CarouselYPosition.CompareTo(other?.CarouselYPosition); + public int CompareTo(CarouselItem? other) + { + if (other == null) return 1; + + return CarouselYPosition.CompareTo(other.CarouselYPosition); + } } public enum CarouselItemState From 9633a3f58f94efee23a006a7e7ebd976057b6579 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 20:59:35 +0300 Subject: [PATCH 098/248] Add failing test coverage --- .../TestSceneOverlayContainer.cs | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneOverlayContainer.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayContainer.cs new file mode 100644 index 0000000000..d9c2774611 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayContainer.cs @@ -0,0 +1,106 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.Volume; +using osuTK; +using osuTK.Graphics; +using osuTK.Input; +using Box = osu.Framework.Graphics.Shapes.Box; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public partial class TestSceneOverlayContainer : OsuManualInputManagerTestScene + { + [SetUp] + public void SetUp() => Schedule(() => Child = new TestOverlay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.5f) + }); + + [Test] + public void TestScrollBlocked() + { + OsuScrollContainer scroll = null!; + + AddStep("add scroll container", () => + { + Add(scroll = new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue, + Child = new Box + { + RelativeSizeAxes = Axes.X, + Height = DrawHeight * 10, + Colour = ColourInfo.GradientVertical(Colour4.Black, Colour4.White), + } + }); + }); + + AddStep("perform scroll", () => + { + InputManager.MoveMouseTo(Content); + InputManager.ScrollVerticalBy(-10); + }); + + AddAssert("scroll didn't receive input", () => scroll.Current == 0); + } + + [Test] + public void TestAltScrollNotBlocked() + { + bool scrollReceived = false; + + AddStep("add volume control receptor", () => Add(new VolumeControlReceptor + { + RelativeSizeAxes = Axes.Both, + Depth = float.MaxValue, + ScrollActionRequested = (_, _, _) => scrollReceived = true, + })); + + AddStep("hold alt", () => InputManager.PressKey(Key.AltLeft)); + AddStep("perform scroll", () => + { + InputManager.MoveMouseTo(Content); + InputManager.ScrollVerticalBy(10); + }); + + AddAssert("receptor received scroll input", () => scrollReceived); + AddStep("release alt", () => InputManager.ReleaseKey(Key.AltLeft)); + } + + private partial class TestOverlay : OsuFocusedOverlayContainer + { + [BackgroundDependencyLoader] + private void load() + { + State.Value = Visibility.Visible; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = "Overlay content", + Colour = Color4.Black, + }, + }; + } + } + } +} From 11648db91077a1cf27008374b821aed32f6dc780 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 10 Jan 2023 19:30:42 +0300 Subject: [PATCH 099/248] Fix game overlays not blocking scroll properly --- .../Graphics/Containers/OsuFocusedOverlayContainer.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 740c170f8f..07b5b53e0e 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -25,8 +25,6 @@ namespace osu.Game.Graphics.Containers protected virtual string PopInSampleName => "UI/overlay-pop-in"; protected virtual string PopOutSampleName => "UI/overlay-pop-out"; - protected override bool BlockScrollInput => false; - protected override bool BlockNonPositionalInput => true; /// @@ -90,6 +88,15 @@ namespace osu.Game.Graphics.Containers base.OnMouseUp(e); } + protected override bool OnScroll(ScrollEvent e) + { + // allow for controlling volume when alt is held. + // mostly for compatibility with osu-stable. + if (e.AltPressed) return false; + + return true; + } + public virtual bool OnPressed(KeyBindingPressEvent e) { if (e.Repeat) From 62e12277d826793da660871d0b8d44dc9e847356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 10 Jan 2023 19:24:54 +0100 Subject: [PATCH 100/248] Rename things yet again --- .../Online/TestSceneHistoricalSection.cs | 4 ++-- .../Online/TestScenePlayHistorySubsection.cs | 20 +++++++++---------- .../Online/TestSceneUserProfileHeader.cs | 10 +++++----- .../Visual/Online/TestSceneUserRanks.cs | 2 +- .../Profile/Header/BottomHeaderContainer.cs | 4 ++-- .../Profile/Header/CentreHeaderContainer.cs | 14 ++++++------- .../Header/Components/FollowersButton.cs | 4 ++-- .../Profile/Header/Components/LevelBadge.cs | 4 ++-- .../Header/Components/LevelProgressBar.cs | 4 ++-- .../Components/MappingSubscribersButton.cs | 4 ++-- .../Header/Components/MessageUserButton.cs | 6 +++--- .../Components/OverlinedTotalPlayTime.cs | 8 ++++---- .../Profile/Header/DetailHeaderContainer.cs | 6 +++--- .../Profile/Header/MedalHeaderContainer.cs | 4 ++-- .../Profile/Header/TopHeaderContainer.cs | 4 ++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 16 +++++++-------- osu.Game/Overlays/Profile/ProfileSection.cs | 2 +- .../Beatmaps/PaginatedBeatmapContainer.cs | 4 ++-- .../Profile/Sections/BeatmapsSection.cs | 14 ++++++------- .../Historical/ChartProfileSubsection.cs | 6 +++--- .../PaginatedMostPlayedBeatmapContainer.cs | 4 ++-- .../Historical/PlayHistorySubsection.cs | 4 ++-- .../Sections/Historical/ReplaysSubsection.cs | 4 ++-- .../Profile/Sections/HistoricalSection.cs | 8 ++++---- .../Profile/Sections/Kudosu/KudosuInfo.cs | 8 ++++---- .../Kudosu/PaginatedKudosuHistoryContainer.cs | 4 ++-- .../Profile/Sections/KudosuSection.cs | 4 ++-- .../Sections/PaginatedProfileSubsection.cs | 10 +++++----- .../Profile/Sections/ProfileSubsection.cs | 6 +++--- .../Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- .../Overlays/Profile/Sections/RanksSection.cs | 6 +++--- .../PaginatedRecentActivityContainer.cs | 4 ++-- .../Profile/Sections/RecentSection.cs | 2 +- osu.Game/Overlays/UserProfileOverlay.cs | 6 +++--- 34 files changed, 107 insertions(+), 107 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index 78e0c6fce4..dd37dced93 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Visual.Online Child = section = new HistoricalSection(), }); - AddStep("Show peppy", () => section.UserProfileData.Value = new UserProfileData(new APIUser { Id = 2 })); - AddStep("Show WubWoofWolf", () => section.UserProfileData.Value = new UserProfileData(new APIUser { Id = 39828 })); + AddStep("Show peppy", () => section.User.Value = new UserProfileData(new APIUser { Id = 2 })); + AddStep("Show WubWoofWolf", () => section.User.Value = new UserProfileData(new APIUser { Id = 39828 })); } } } diff --git a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs index 634b9df212..8bd4e398e4 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePlayHistorySubsection.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); - private readonly Bindable userProfileData = new Bindable(); + private readonly Bindable user = new Bindable(); private readonly PlayHistorySubsection section; public TestScenePlayHistorySubsection() @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4 }, - section = new PlayHistorySubsection(userProfileData) + section = new PlayHistorySubsection(user) { Anchor = Anchor.Centre, Origin = Anchor.Centre @@ -44,49 +44,49 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestNullValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_null_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_null_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestEmptyValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_empty_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_empty_values)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestOneValue() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_one_value)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_one_value)); AddAssert("Section is hidden", () => section.Alpha == 0); } [Test] public void TestTwoValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_two_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_two_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_constant_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_constant_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestConstantZeroValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_zero_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_zero_values)); AddAssert("Section is visible", () => section.Alpha == 1); } [Test] public void TestFilledValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_filled_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_filled_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is the same", () => user_with_filled_values.MonthlyPlayCounts.Length == getChartValuesLength()); } @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestMissingValues() { - AddStep("Load user", () => userProfileData.Value = new UserProfileData(user_with_missing_values)); + AddStep("Load user", () => user.Value = new UserProfileData(user_with_missing_values)); AddAssert("Section is visible", () => section.Alpha == 1); AddAssert("Array length is 7", () => getChartValuesLength() == 7); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 9b565c1276..7f5cfb6179 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -29,13 +29,13 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestBasic() { - AddStep("Show example user", () => header.UserProfileData.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); + AddStep("Show example user", () => header.User.Value = new UserProfileData(TestSceneUserProfileOverlay.TEST_USER)); } [Test] public void TestOnlineState() { - AddStep("Show online user", () => header.UserProfileData.Value = new UserProfileData(new APIUser + AddStep("Show online user", () => header.User.Value = new UserProfileData(new APIUser { Id = 1001, Username = "IAmOnline", @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual.Online IsOnline = true, })); - AddStep("Show offline user", () => header.UserProfileData.Value = new UserProfileData(new APIUser + AddStep("Show offline user", () => header.User.Value = new UserProfileData(new APIUser { Id = 1002, Username = "IAmOffline", @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestRankedState() { - AddStep("Show ranked user", () => header.UserProfileData.Value = new UserProfileData(new APIUser + AddStep("Show ranked user", () => header.User.Value = new UserProfileData(new APIUser { Id = 2001, Username = "RankedUser", @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online } })); - AddStep("Show unranked user", () => header.UserProfileData.Value = new UserProfileData(new APIUser + AddStep("Show unranked user", () => header.User.Value = new UserProfileData(new APIUser { Id = 2002, Username = "UnrankedUser", diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 6ec7ea008b..bab48806d4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("Show cookiezi", () => ranks.UserProfileData.Value = new UserProfileData(new APIUser { Id = 124493 })); + AddStep("Show cookiezi", () => ranks.User.Value = new UserProfileData(new APIUser { Id = 124493 })); } } } diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 091d04ad35..1e80257a57 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header { public partial class BottomHeaderContainer : CompositeDrawable { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); private LinkFlowContainer topLinkContainer = null!; private LinkFlowContainer bottomLinkContainer = null!; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header } }; - UserProfileData.BindValueChanged(data => updateDisplay(data.NewValue?.User)); + User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 8910d3dc3b..ecf78e7b92 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header public partial class CentreHeaderContainer : CompositeDrawable { public readonly BindableBool DetailsVisible = new BindableBool(true); - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); private OverlinedInfoContainer hiddenDetailGlobal = null!; private OverlinedInfoContainer hiddenDetailCountry = null!; @@ -53,15 +53,15 @@ namespace osu.Game.Overlays.Profile.Header { new FollowersButton { - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, new MappingSubscribersButton { - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, new MessageUserButton { - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, } }, @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Size = new Vector2(40), - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, expandedDetailContainer = new Container { @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Profile.Header Child = new LevelProgressBar { RelativeSizeAxes = Axes.Both, - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } } }, hiddenDetailContainer = new FillFlowContainer @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Profile.Header expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); }); - UserProfileData.BindValueChanged(data => updateDisplay(data.NewValue?.User)); + User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs index a73b3444f6..844efa5cf0 100644 --- a/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/FollowersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class FollowersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => FriendsStrings.ButtonsDisabled; @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private void load() { // todo: when friending/unfriending is implemented, the APIAccess.Friends list should be updated accordingly. - UserProfileData.BindValueChanged(data => SetValue(data.NewValue?.User.FollowerCount ?? 0), true); + User.BindValueChanged(user => SetValue(user.NewValue?.User.FollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 501c7bd41b..78c5231736 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; private set; } @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - UserProfileData.BindValueChanged(data => updateLevel(data.NewValue?.User)); + User.BindValueChanged(user => updateLevel(user.NewValue?.User)); } private void updateLevel(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index 6a5827a867..919ccb0dd4 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelProgressBar : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; } @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - UserProfileData.BindValueChanged(data => updateProgress(data.NewValue?.User)); + User.BindValueChanged(user => updateProgress(user.NewValue?.User)); } private void updateProgress(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs index 7265302a88..d509ec0f81 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MappingSubscribersButton.cs @@ -11,7 +11,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MappingSubscribersButton : ProfileHeaderStatisticsButton { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => FollowsStrings.MappingFollowers; @@ -20,7 +20,7 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load() { - UserProfileData.BindValueChanged(data => SetValue(data.NewValue?.User.MappingFollowerCount ?? 0), true); + User.BindValueChanged(user => SetValue(user.NewValue?.User.MappingFollowerCount ?? 0), true); } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs index 0b9fa437c2..5f934e3916 100644 --- a/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/MessageUserButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class MessageUserButton : ProfileHeaderButton { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public override LocalisableString TooltipText => UsersStrings.CardSendMessage; @@ -48,12 +48,12 @@ namespace osu.Game.Overlays.Profile.Header.Components { if (!Content.IsPresent) return; - channelManager?.OpenPrivateChannel(UserProfileData.Value?.User); + channelManager?.OpenPrivateChannel(User.Value?.User); userOverlay?.Hide(); chatOverlay?.Show(); }; - UserProfileData.ValueChanged += e => + User.ValueChanged += e => { var user = e.NewValue?.User; Content.Alpha = user != null && !user.PMFriendsOnly && apiProvider.LocalUser.Value.Id != user.Id ? 1 : 0; diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index c2db9d8273..0396f42336 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip { - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; set; } @@ -35,12 +35,12 @@ namespace osu.Game.Overlays.Profile.Header.Components LineColour = colourProvider.Highlight1, }; - UserProfileData.BindValueChanged(updateTime, true); + User.BindValueChanged(updateTime, true); } - private void updateTime(ValueChangedEvent data) + private void updateTime(ValueChangedEvent user) { - int? playTime = data.NewValue?.User.Statistics?.PlayTime; + int? playTime = user.NewValue?.User.Statistics?.PlayTime; TooltipText = (playTime ?? 0) / 3600 + " hours"; info.Content = formatTime(playTime); } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index d2986c343d..3bab798caf 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); private bool expanded = true; @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Y; - UserProfileData.ValueChanged += e => updateDisplay(e.NewValue); + User.ValueChanged += e => updateDisplay(e.NewValue); InternalChildren = new Drawable[] { @@ -98,7 +98,7 @@ namespace osu.Game.Overlays.Profile.Header { new OverlinedTotalPlayTime { - UserProfileData = { BindTarget = UserProfileData } + User = { BindTarget = User } }, medalInfo = new OverlinedInfoContainer { diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 2c2e2b3197..edb695a00e 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -20,14 +20,14 @@ namespace osu.Game.Overlays.Profile.Header { private FillFlowContainer badgeFlowContainer = null!; - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { Alpha = 0; AutoSizeAxes = Axes.Y; - UserProfileData.ValueChanged += e => updateDisplay(e.NewValue?.User); + User.ValueChanged += e => updateDisplay(e.NewValue?.User); InternalChildren = new Drawable[] { diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index c8a797e478..43ba8e64e4 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Profile.Header { private const float avatar_size = 110; - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); [Resolved] private IAPIProvider api { get; set; } = null!; @@ -170,7 +170,7 @@ namespace osu.Game.Overlays.Profile.Header } }; - UserProfileData.BindValueChanged(data => updateUser(data.NewValue)); + User.BindValueChanged(user => updateUser(user.NewValue)); } private void updateUser(UserProfileData? data) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 5f58960b15..5f5740a0aa 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile { private UserCoverBackground coverContainer = null!; - public Bindable UserProfileData = new Bindable(); + public Bindable User = new Bindable(); private CentreHeaderContainer centreHeaderContainer; private DetailHeaderContainer detailHeaderContainer; @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile { ContentSidePadding = UserProfileOverlay.CONTENT_X_MARGIN; - UserProfileData.ValueChanged += e => updateDisplay(e.NewValue); + User.ValueChanged += e => updateDisplay(e.NewValue); TabControl.AddItem(LayoutStrings.HeaderUsersShow); @@ -72,34 +72,34 @@ namespace osu.Game.Overlays.Profile new TopHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, detailHeaderContainer = new DetailHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, new MedalHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, new BottomHeaderContainer { RelativeSizeAxes = Axes.X, - UserProfileData = { BindTarget = UserProfileData }, + User = { BindTarget = User }, }, } }; protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); - private void updateDisplay(UserProfileData? data) => coverContainer.User = data?.User; + private void updateDisplay(UserProfileData? user) => coverContainer.User = user?.User; private partial class ProfileHeaderTitle : OverlayTitle { diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index 009e0d1dac..edb3ec1733 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile protected override Container Content => content; - public readonly Bindable UserProfileData = new Bindable(); + public readonly Bindable User = new Bindable(); protected ProfileSection() { diff --git a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs index 9c692cbeac..0e74aba369 100644 --- a/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Beatmaps/PaginatedBeatmapContainer.cs @@ -22,8 +22,8 @@ namespace osu.Game.Overlays.Profile.Sections.Beatmaps protected override int InitialItemsCount => type == BeatmapSetType.Graveyard ? 2 : 6; - public PaginatedBeatmapContainer(BeatmapSetType type, Bindable userProfileData, LocalisableString headerText) - : base(userProfileData, headerText) + public PaginatedBeatmapContainer(BeatmapSetType type, Bindable user, LocalisableString headerText) + : base(user, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs index 8818cae735..3b304a79ef 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapsSection.cs @@ -18,13 +18,13 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedBeatmapContainer(BeatmapSetType.Favourite, UserProfileData, UsersStrings.ShowExtraBeatmapsFavouriteTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Ranked, UserProfileData, UsersStrings.ShowExtraBeatmapsRankedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Loved, UserProfileData, UsersStrings.ShowExtraBeatmapsLovedTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Guest, UserProfileData, UsersStrings.ShowExtraBeatmapsGuestTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Pending, UserProfileData, UsersStrings.ShowExtraBeatmapsPendingTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, UserProfileData, UsersStrings.ShowExtraBeatmapsGraveyardTitle), - new PaginatedBeatmapContainer(BeatmapSetType.Nominated, UserProfileData, UsersStrings.ShowExtraBeatmapsNominatedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Favourite, User, UsersStrings.ShowExtraBeatmapsFavouriteTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Ranked, User, UsersStrings.ShowExtraBeatmapsRankedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Loved, User, UsersStrings.ShowExtraBeatmapsLovedTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Guest, User, UsersStrings.ShowExtraBeatmapsGuestTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Pending, User, UsersStrings.ShowExtraBeatmapsPendingTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Graveyard, User, UsersStrings.ShowExtraBeatmapsGraveyardTitle), + new PaginatedBeatmapContainer(BeatmapSetType.Nominated, User, UsersStrings.ShowExtraBeatmapsNominatedTitle), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs index 2162adc2b7..583006031c 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ChartProfileSubsection.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical /// protected abstract LocalisableString GraphCounterName { get; } - protected ChartProfileSubsection(Bindable userProfileData, LocalisableString headerText) - : base(userProfileData, headerText) + protected ChartProfileSubsection(Bindable user, LocalisableString headerText) + : base(user, headerText) { } @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical protected override void LoadComplete() { base.LoadComplete(); - UserProfileData.BindValueChanged(onUserChanged, true); + User.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent e) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs index 7afb21e8ca..5d9cfb7a1d 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PaginatedMostPlayedBeatmapContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { public partial class PaginatedMostPlayedBeatmapContainer : PaginatedProfileSubsection { - public PaginatedMostPlayedBeatmapContainer(Bindable userProfileData) - : base(userProfileData, UsersStrings.ShowExtraHistoricalMostPlayedTitle) + public PaginatedMostPlayedBeatmapContainer(Bindable user) + : base(user, UsersStrings.ShowExtraHistoricalMostPlayedTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs index cf8708d7b2..f472ded182 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/PlayHistorySubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalMonthlyPlaycountsCountLabel; - public PlayHistorySubsection(Bindable userProfileData) - : base(userProfileData, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) + public PlayHistorySubsection(Bindable user) + : base(user, UsersStrings.ShowExtraHistoricalMonthlyPlaycountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs index ab35680fd8..225eaa8c7e 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/ReplaysSubsection.cs @@ -12,8 +12,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical { protected override LocalisableString GraphCounterName => UsersStrings.ShowExtraHistoricalReplaysWatchedCountsCountLabel; - public ReplaysSubsection(Bindable userProfileData) - : base(userProfileData, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) + public ReplaysSubsection(Bindable user) + : base(user, UsersStrings.ShowExtraHistoricalReplaysWatchedCountsTitle) { } diff --git a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs index 5590db6502..19f7a32d4d 100644 --- a/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs +++ b/osu.Game/Overlays/Profile/Sections/HistoricalSection.cs @@ -20,10 +20,10 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new PlayHistorySubsection(UserProfileData), - new PaginatedMostPlayedBeatmapContainer(UserProfileData), - new PaginatedScoreContainer(ScoreType.Recent, UserProfileData, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), - new ReplaysSubsection(UserProfileData) + new PlayHistorySubsection(User), + new PaginatedMostPlayedBeatmapContainer(User), + new PaginatedScoreContainer(ScoreType.Recent, User, UsersStrings.ShowExtraHistoricalRecentPlaysTitle), + new ReplaysSubsection(User) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index d5a945b3da..5e0227de5b 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -19,11 +19,11 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class KudosuInfo : Container { - private readonly Bindable userProfileData = new Bindable(); + private readonly Bindable user = new Bindable(); - public KudosuInfo(Bindable userProfileData) + public KudosuInfo(Bindable user) { - this.userProfileData.BindTo(userProfileData); + this.user.BindTo(user); CountSection total; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu CornerRadius = 3; Child = total = new CountTotal(); - this.userProfileData.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; + this.user.ValueChanged += u => total.Count = u.NewValue?.User.Kudosu.Total ?? 0; } protected override bool OnClick(ClickEvent e) => true; diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs index a2ab104239..fad0095248 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/PaginatedKudosuHistoryContainer.cs @@ -14,8 +14,8 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { public partial class PaginatedKudosuHistoryContainer : PaginatedProfileSubsection { - public PaginatedKudosuHistoryContainer(Bindable userProfileData) - : base(userProfileData, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) + public PaginatedKudosuHistoryContainer(Bindable user) + : base(user, missingText: UsersStrings.ShowExtraKudosuEntryEmpty) { } diff --git a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs index 8fbaa1214f..482a853c44 100644 --- a/osu.Game/Overlays/Profile/Sections/KudosuSection.cs +++ b/osu.Game/Overlays/Profile/Sections/KudosuSection.cs @@ -18,8 +18,8 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new Drawable[] { - new KudosuInfo(UserProfileData), - new PaginatedKudosuHistoryContainer(UserProfileData), + new KudosuInfo(User), + new PaginatedKudosuHistoryContainer(User), }; } } diff --git a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs index 6ed347e929..ddaa710d68 100644 --- a/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/PaginatedProfileSubsection.cs @@ -46,8 +46,8 @@ namespace osu.Game.Overlays.Profile.Sections private OsuSpriteText missing = null!; private readonly LocalisableString? missingText; - protected PaginatedProfileSubsection(Bindable userProfileData, LocalisableString? headerText = null, LocalisableString? missingText = null) - : base(userProfileData, headerText, CounterVisibilityState.AlwaysVisible) + protected PaginatedProfileSubsection(Bindable user, LocalisableString? headerText = null, LocalisableString? missingText = null) + : base(user, headerText, CounterVisibilityState.AlwaysVisible) { this.missingText = missingText; } @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Profile.Sections protected override void LoadComplete() { base.LoadComplete(); - UserProfileData.BindValueChanged(onUserChanged, true); + User.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent e) @@ -109,14 +109,14 @@ namespace osu.Game.Overlays.Profile.Sections private void showMore() { - if (UserProfileData.Value?.User == null) + if (User.Value?.User == null) return; loadCancellation = new CancellationTokenSource(); CurrentPage = CurrentPage?.TakeNext(ItemsPerPage) ?? new PaginationParameters(InitialItemsCount); - retrievalRequest = CreateRequest(UserProfileData.Value.User, CurrentPage.Value); + retrievalRequest = CreateRequest(User.Value.User, CurrentPage.Value); retrievalRequest.Success += items => UpdateItems(items, loadCancellation); api.Queue(retrievalRequest); diff --git a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs index 78e23da33a..35d3ac1579 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileSubsection.cs @@ -11,18 +11,18 @@ namespace osu.Game.Overlays.Profile.Sections { public abstract partial class ProfileSubsection : FillFlowContainer { - protected readonly Bindable UserProfileData = new Bindable(); + protected readonly Bindable User = new Bindable(); private readonly LocalisableString headerText; private readonly CounterVisibilityState counterVisibilityState; private ProfileSubsectionHeader header = null!; - protected ProfileSubsection(Bindable userProfileData, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) + protected ProfileSubsection(Bindable user, LocalisableString? headerText = null, CounterVisibilityState counterVisibilityState = CounterVisibilityState.AlwaysHidden) { this.headerText = headerText ?? string.Empty; this.counterVisibilityState = counterVisibilityState; - UserProfileData.BindTo(userProfileData); + User.BindTo(user); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 14d57bfadc..735f5021fe 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable userProfileData, LocalisableString headerText) - : base(userProfileData, headerText) + public PaginatedScoreContainer(ScoreType type, Bindable user, LocalisableString headerText) + : base(user, headerText) { this.type = type; } diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index 6b705a40d5..ce831b30a8 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -18,9 +18,9 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedScoreContainer(ScoreType.Pinned, UserProfileData, UsersStrings.ShowExtraTopRanksPinnedTitle), - new PaginatedScoreContainer(ScoreType.Best, UserProfileData, UsersStrings.ShowExtraTopRanksBestTitle), - new PaginatedScoreContainer(ScoreType.Firsts, UserProfileData, UsersStrings.ShowExtraTopRanksFirstTitle) + new PaginatedScoreContainer(ScoreType.Pinned, User, UsersStrings.ShowExtraTopRanksPinnedTitle), + new PaginatedScoreContainer(ScoreType.Best, User, UsersStrings.ShowExtraTopRanksBestTitle), + new PaginatedScoreContainer(ScoreType.Firsts, User, UsersStrings.ShowExtraTopRanksFirstTitle) }; } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 6f346b457a..9e8279cfc0 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -16,8 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public partial class PaginatedRecentActivityContainer : PaginatedProfileSubsection { - public PaginatedRecentActivityContainer(Bindable userProfileData) - : base(userProfileData, missingText: EventsStrings.Empty) + public PaginatedRecentActivityContainer(Bindable user) + : base(user, missingText: EventsStrings.Empty) { } diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index 95dbe7373c..e29dc7f635 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedRecentActivityContainer(UserProfileData), + new PaginatedRecentActivityContainer(User), }; } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index add90a0eed..a48d183047 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays Show(); - if (user.OnlineID == Header?.UserProfileData.Value?.User.Id) + if (user.OnlineID == Header?.User.Value?.User.Id) return; if (sectionsContainer != null) @@ -126,7 +126,7 @@ namespace osu.Game.Overlays Debug.Assert(sections != null && sectionsContainer != null && tabs != null); var userProfile = new UserProfileData(user); - Header.UserProfileData.Value = userProfile; + Header.User.Value = userProfile; if (user.ProfileOrder != null) { @@ -136,7 +136,7 @@ namespace osu.Game.Overlays if (sec != null) { - sec.UserProfileData.Value = userProfile; + sec.User.Value = userProfile; sectionsContainer.Add(sec); tabs.AddItem(sec); From 21073f36012ede15d245f2813520ba5b4267c406 Mon Sep 17 00:00:00 2001 From: tsrk Date: Tue, 10 Jan 2023 22:49:35 +0100 Subject: [PATCH 101/248] reafactor: use DrawNode to draw SegmenteddGraph --- .../Graphics/UserInterface/SegmentedGraph.cs | 138 +++++++++--------- 1 file changed, 72 insertions(+), 66 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 261e535fbc..65c2146889 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -5,20 +5,19 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; -using System.Threading; +using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Threading; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Rendering; +using osu.Framework.Graphics.Shaders; +using osu.Framework.Graphics.Textures; using osuTK; namespace osu.Game.Graphics.UserInterface { - public abstract partial class SegmentedGraph : Container + public abstract partial class SegmentedGraph : Drawable where T : struct, IComparable, IConvertible, IEquatable { - private BufferedContainer? rectSegments; - private float previousDrawWidth; private bool graphNeedsUpdate; private T[]? values; @@ -44,53 +43,33 @@ namespace osu.Game.Graphics.UserInterface values = value; recalculateTiers(values); graphNeedsUpdate = true; + Invalidate(Invalidation.DrawNode); } } public readonly Colour4[] TierColours; - private CancellationTokenSource? cts; - private ScheduledDelegate? scheduledCreate; + private Texture texture = null!; + private IShader shader = null!; + + [BackgroundDependencyLoader] + private void load(IRenderer renderer, ShaderManager shaders) + { + texture = renderer.WhitePixel; + shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE); + } protected override void Update() { base.Update(); - if (graphNeedsUpdate || (values != null && DrawWidth != previousDrawWidth)) + if (graphNeedsUpdate) { - rectSegments?.FadeOut(150, Easing.OutQuint).Expire(); - - scheduledCreate?.Cancel(); - scheduledCreate = Scheduler.AddDelayed(RecreateGraph, 150); - - previousDrawWidth = DrawWidth; - graphNeedsUpdate = false; + recalculateSegments(); + Invalidate(Invalidation.DrawNode); } } - protected virtual void RecreateGraph() - { - var newSegments = new BufferedContainer(cachedFrameBuffer: true) - { - RedrawOnScale = false, - RelativeSizeAxes = Axes.Both - }; - - cts?.Cancel(); - recalculateSegments(); - redrawSegments(newSegments); - - LoadComponentAsync(newSegments, s => - { - Children = new Drawable[] - { - rectSegments = s - }; - - s.FadeInFromZero(100); - }, (cts = new CancellationTokenSource()).Token); - } - private void recalculateTiers(T[]? arr) { if (arr == null || arr.Length == 0) @@ -159,32 +138,7 @@ namespace osu.Game.Graphics.UserInterface private Colour4 tierToColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); - // Base implementation, could be drawn with draw node if preferred - private void redrawSegments(BufferedContainer container) - { - if (segments.Count == 0) - return; - - foreach (SegmentInfo segment in segments) // Lower tiers will be drawn first, putting them in the back - { - float width = segment.Length * DrawWidth; - - // If the segment width exceeds the DrawWidth, just fill the rest - if (width >= DrawWidth) - width = DrawWidth; - - container.Add(new Box - { - Name = $"Tier {segment.Tier} segment", - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Y, - Position = new Vector2(segment.Start * DrawWidth, 0), - Width = width, - Colour = tierToColour(segment.Tier) - }); - } - } + protected override DrawNode CreateDrawNode() => new SegmentedGraphDrawNode(this); protected struct SegmentInfo { @@ -218,6 +172,58 @@ namespace osu.Game.Graphics.UserInterface public float Length => End - Start; } + private class SegmentedGraphDrawNode : DrawNode + { + public new SegmentedGraph Source => (SegmentedGraph)base.Source; + + private Texture texture = null!; + private IShader shader = null!; + private readonly List segments = new List(); + private Vector2 drawSize; + + public SegmentedGraphDrawNode(SegmentedGraph source) + : base(source) + { + } + + public override void ApplyState() + { + base.ApplyState(); + + texture = Source.texture; + shader = Source.shader; + drawSize = Source.DrawSize; + segments.Clear(); + segments.AddRange(Source.segments); + } + + public override void Draw(IRenderer renderer) + { + base.Draw(renderer); + + shader.Bind(); + + foreach (SegmentInfo segment in segments) + { + Vector2 topLeft = new Vector2(segment.Start * drawSize.X, 0); + Vector2 topRight = new Vector2(segment.End * drawSize.X, 0); + Vector2 bottomLeft = new Vector2(segment.Start * drawSize.X, drawSize.Y); + Vector2 bottomRight = new Vector2(segment.End * drawSize.X, drawSize.Y); + + renderer.DrawQuad( + texture, + new Quad( + Vector2Extensions.Transform(topLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(topRight, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), + Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix)), + Source.tierToColour(segment.Tier)); + } + + shader.Unbind(); + } + } + protected class SegmentManager : IEnumerable { private readonly List segments = new List(); From b38cf8c56c4323f074e3acd90001258ae650b99c Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 11 Jan 2023 02:26:25 +0300 Subject: [PATCH 102/248] Use empty string as default --- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 8e02d015ed..906ff0c4a2 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Comments protected FillFlowContainer ButtonsContainer { get; private set; } = null!; - protected readonly Bindable Current = new Bindable(); + protected readonly Bindable Current = new Bindable(string.Empty); private RoundedButton commitButton = null!; private LoadingSpinner loadingSpinner = null!; From 44de24f15397faf8b0c49401e65c543326f215cc Mon Sep 17 00:00:00 2001 From: Stedoss <29103029+Stedoss@users.noreply.github.com> Date: Tue, 10 Jan 2023 23:30:09 +0000 Subject: [PATCH 103/248] `BeatmapSetOverlay` fetch on login state change --- osu.Game/Overlays/BeatmapSetOverlay.cs | 79 ++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index fd831ad4ae..e905308066 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet; @@ -30,6 +31,14 @@ namespace osu.Game.Overlays private readonly Bindable beatmapSet = new Bindable(); + [Resolved] + private IAPIProvider api { get; set; } + + private IBindable apiUser; + + private int? lastRequestedBeatmapId; + private BeatmapSetLookupType? lastBeatmapSetLookupType; + /// /// Isolates the beatmap set overlay from the game-wide selected mods bindable /// to avoid affecting the beatmap details section (i.e. ). @@ -72,6 +81,17 @@ namespace osu.Game.Overlays }; } + [BackgroundDependencyLoader] + private void load() + { + apiUser = api.LocalUser.GetBoundCopy(); + apiUser.BindValueChanged(_ => Schedule(() => + { + if (api.IsLoggedIn) + fetchAndSetLastRequestedBeatmap(); + })); + } + protected override BeatmapSetHeader CreateHeader() => new BeatmapSetHeader(); protected override Color4 BackgroundColour => ColourProvider.Background6; @@ -84,26 +104,24 @@ namespace osu.Game.Overlays public void FetchAndShowBeatmap(int beatmapId) { + lastRequestedBeatmapId = beatmapId; + lastBeatmapSetLookupType = BeatmapSetLookupType.BeatmapId; + beatmapSet.Value = null; - var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId); - req.Success += res => - { - beatmapSet.Value = res; - Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineID == beatmapId); - }; - API.Queue(req); + fetchAndSetBeatmap(beatmapId); Show(); } public void FetchAndShowBeatmapSet(int beatmapSetId) { + lastRequestedBeatmapId = beatmapSetId; + lastBeatmapSetLookupType = BeatmapSetLookupType.SetId; + beatmapSet.Value = null; - var req = new GetBeatmapSetRequest(beatmapSetId); - req.Success += res => beatmapSet.Value = res; - API.Queue(req); + fetchAndSetBeatmapSet(beatmapSetId); Show(); } @@ -118,6 +136,47 @@ namespace osu.Game.Overlays Show(); } + private void fetchAndSetBeatmap(int beatmapId) + { + if (!api.IsLoggedIn) + return; + + var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId); + req.Success += res => + { + beatmapSet.Value = res; + Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineID == beatmapId); + }; + API.Queue(req); + } + + private void fetchAndSetBeatmapSet(int beatmapSetId) + { + if (!api.IsLoggedIn) + return; + + var req = new GetBeatmapSetRequest(beatmapSetId); + req.Success += res => beatmapSet.Value = res; + API.Queue(req); + } + + private void fetchAndSetLastRequestedBeatmap() + { + if (lastRequestedBeatmapId == null) + return; + + switch (lastBeatmapSetLookupType) + { + case BeatmapSetLookupType.SetId: + fetchAndSetBeatmapSet(lastRequestedBeatmapId.Value); + break; + + case BeatmapSetLookupType.BeatmapId: + fetchAndSetBeatmap(lastRequestedBeatmapId.Value); + break; + } + } + private partial class CommentsSection : BeatmapSetLayoutSection { public readonly Bindable BeatmapSet = new Bindable(); From 43d9c289784d3b8367c794b638bea37aa66f4fc9 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 11 Jan 2023 11:31:05 +0900 Subject: [PATCH 104/248] Add triage action --- .github/workflows/triage.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/triage.yml diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml new file mode 100644 index 0000000000..8ba653bafc --- /dev/null +++ b/.github/workflows/triage.yml @@ -0,0 +1,14 @@ +name: Triage +on: + issues: + types: [opened] + +jobs: + build: + name: Triage + runs-on: ubuntu-latest + steps: + - uses: Logerfo/triage-action@0.0.2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + label: needs-triage From 5d3218418074027aec8f0865c135df0d9bcb78c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 12:31:25 +0900 Subject: [PATCH 105/248] Revert "Add triage action" This reverts commit 43d9c289784d3b8367c794b638bea37aa66f4fc9. Not working for us --- .github/workflows/triage.yml | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 .github/workflows/triage.yml diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml deleted file mode 100644 index 8ba653bafc..0000000000 --- a/.github/workflows/triage.yml +++ /dev/null @@ -1,14 +0,0 @@ -name: Triage -on: - issues: - types: [opened] - -jobs: - build: - name: Triage - runs-on: ubuntu-latest - steps: - - uses: Logerfo/triage-action@0.0.2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - label: needs-triage From d9a6e4b8621af6909d5aeafc7137b1dd53b96452 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 11 Jan 2023 13:01:11 +0900 Subject: [PATCH 106/248] Ensure drain lenience of 1.0 completly removes drain --- osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs b/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs index d94c6dd2e0..592dcbfeb8 100644 --- a/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs +++ b/osu.Game/Rulesets/Scoring/DrainingHealthProcessor.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Scoring public DrainingHealthProcessor(double drainStartTime, double drainLenience = 0) { this.drainStartTime = drainStartTime; - this.drainLenience = drainLenience; + this.drainLenience = Math.Clamp(drainLenience, 0, 1); } protected override void Update() @@ -79,7 +79,8 @@ namespace osu.Game.Rulesets.Scoring double lastGameplayTime = Math.Clamp(Time.Current - Time.Elapsed, drainStartTime, gameplayEndTime); double currentGameplayTime = Math.Clamp(Time.Current, drainStartTime, gameplayEndTime); - Health.Value -= drainRate * (currentGameplayTime - lastGameplayTime); + if (drainLenience < 1) + Health.Value -= drainRate * (currentGameplayTime - lastGameplayTime); } public override void ApplyBeatmap(IBeatmap beatmap) From f03677f39479d2dfb58e17ae75a631367885f457 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 11 Jan 2023 13:01:18 +0900 Subject: [PATCH 107/248] Remove HP drain from mania --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 6162184c9a..0cec0ee075 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Mania public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(); - public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new ManiaHealthProcessor(drainStartTime, 0.5); + public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new ManiaHealthProcessor(drainStartTime); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this); diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs index 5c6682ed73..16f7af0d0a 100644 --- a/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs +++ b/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs @@ -11,8 +11,8 @@ namespace osu.Game.Rulesets.Mania.Scoring public partial class ManiaHealthProcessor : DrainingHealthProcessor { /// - public ManiaHealthProcessor(double drainStartTime, double drainLenience = 0) - : base(drainStartTime, drainLenience) + public ManiaHealthProcessor(double drainStartTime) + : base(drainStartTime, 1.0) { } From 5441c02a1a8fa01d1a33fb6b633ac2de5b157740 Mon Sep 17 00:00:00 2001 From: StanR Date: Wed, 11 Jan 2023 07:11:38 +0300 Subject: [PATCH 108/248] Implement user group badges --- .../Online/TestSceneUserProfileHeader.cs | 1 + .../Online/TestSceneUserProfileOverlay.cs | 5 + .../Online/API/Requests/Responses/APIUser.cs | 3 + .../API/Requests/Responses/APIUserGroup.cs | 37 ++++++ .../Header/Components/GroupInfoContainer.cs | 106 ++++++++++++++++++ .../Profile/Header/TopHeaderContainer.cs | 9 +- 6 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APIUserGroup.cs create mode 100644 osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index bfd6372e6f..3c0ea4f590 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -59,6 +59,7 @@ namespace osu.Game.Tests.Visual.Online { Id = 2001, Username = "RankedUser", + Groups = new[] { new APIUserGroup() { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" } }, Statistics = new UserStatistics { IsRanked = true, diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index 35c7e7bf28..cab883c0da 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -27,6 +27,11 @@ namespace osu.Game.Tests.Visual.Online JoinDate = DateTimeOffset.Now.AddDays(-1), LastVisit = DateTimeOffset.Now, ProfileOrder = new[] { "me" }, + Groups = new[] + { + new APIUserGroup { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" }, + new APIUserGroup { Colour = "#A347EB", ShortName = "BN", Name = "Beatmap Nominators", Playmodes = new[] { "osu", "taiko" } } + }, Statistics = new UserStatistics { IsRanked = true, diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs index 9cb0c0704d..0e62b03f1a 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUser.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs @@ -255,6 +255,9 @@ namespace osu.Game.Online.API.Requests.Responses [CanBeNull] public Dictionary RulesetsStatistics { get; set; } + [JsonProperty("groups")] + public APIUserGroup[] Groups; + public override string ToString() => Username; /// diff --git a/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs b/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs new file mode 100644 index 0000000000..5f943e583e --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIUserGroup + { + [JsonProperty(@"colour")] + public string Colour { get; set; } = null!; + + [JsonProperty(@"has_listing")] + public bool HasListings { get; set; } + + [JsonProperty(@"has_playmodes")] + public bool HasPlaymodes { get; set; } + + [JsonProperty(@"id")] + public int Id { get; set; } + + [JsonProperty(@"identifier")] + public string Identifier { get; set; } = null!; + + [JsonProperty(@"is_probationary")] + public bool IsProbationary { get; set; } + + [JsonProperty(@"name")] + public string Name { get; set; } = null!; + + [JsonProperty(@"short_name")] + public string ShortName { get; set; } = null!; + + [JsonProperty(@"playmodes")] + public string[]? Playmodes { get; set; } + } +} diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs new file mode 100644 index 0000000000..363a74b5c1 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs @@ -0,0 +1,106 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Rulesets; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public partial class GroupBadge : Container, IHasTooltip + { + public LocalisableString TooltipText { get; } + + public int TextSize { get; set; } = 12; + + private readonly APIUserGroup group; + + public GroupBadge(APIUserGroup group) + { + this.group = group; + + AutoSizeAxes = Axes.Both; + Masking = true; + CornerRadius = 8; + + TooltipText = group.Name; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider? colourProvider, RulesetStore rulesets) + { + FillFlowContainer innerContainer; + + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider?.Background6 ?? Colour4.Black + }, + innerContainer = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Padding = new MarginPadding { Vertical = 2, Horizontal = 10 }, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), + Children = new[] + { + new OsuSpriteText + { + Text = group.ShortName, + Colour = Color4Extensions.FromHex(group.Colour), + Shadow = false, + Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true) + } + } + } + }); + + if (group.Playmodes?.Length > 0) + { + innerContainer.AddRange(group.Playmodes.Select(p => + (rulesets.GetRuleset(p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => + { + icon.Size = new Vector2(TextSize - 1); + })).ToList() + ); + } + } + } + + public partial class GroupInfoContainer : FillFlowContainer + { + public readonly Bindable User = new Bindable(); + + public GroupInfoContainer() + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(2); + + User.BindValueChanged(val => + { + if (val.NewValue?.Groups?.Length > 0) + { + Clear(true); + Children = val.NewValue?.Groups.Select(g => new GroupBadge(g)).ToList(); + } + }); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index a6501f567f..c26efaf271 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -40,6 +40,7 @@ namespace osu.Game.Overlays.Profile.Header private UpdateableFlag userFlag = null!; private OsuSpriteText userCountryText = null!; private FillFlowContainer userStats = null!; + private GroupInfoContainer groupInfoContainer = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -90,6 +91,7 @@ namespace osu.Game.Overlays.Profile.Header { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, + Spacing = new Vector2(5), Children = new Drawable[] { usernameText = new OsuSpriteText @@ -98,10 +100,14 @@ namespace osu.Game.Overlays.Profile.Header }, openUserExternally = new ExternalLinkButton { - Margin = new MarginPadding { Left = 5 }, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, + groupInfoContainer = new GroupInfoContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + } } }, titleText = new OsuSpriteText @@ -184,6 +190,7 @@ namespace osu.Game.Overlays.Profile.Header supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); + groupInfoContainer.User.Value = user; userStats.Clear(); From b710f86d7559d6b469797f39d3267f3f2139bcef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 16:15:28 +0900 Subject: [PATCH 109/248] Refactor to use tuples and de-duplicate request code --- osu.Game/Overlays/BeatmapSetOverlay.cs | 55 ++++++-------------------- 1 file changed, 13 insertions(+), 42 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index e905308066..7b9b43f368 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -36,8 +36,7 @@ namespace osu.Game.Overlays private IBindable apiUser; - private int? lastRequestedBeatmapId; - private BeatmapSetLookupType? lastBeatmapSetLookupType; + private (BeatmapSetLookupType type, int id)? lastLookup; /// /// Isolates the beatmap set overlay from the game-wide selected mods bindable @@ -88,7 +87,7 @@ namespace osu.Game.Overlays apiUser.BindValueChanged(_ => Schedule(() => { if (api.IsLoggedIn) - fetchAndSetLastRequestedBeatmap(); + performFetch(); })); } @@ -104,25 +103,20 @@ namespace osu.Game.Overlays public void FetchAndShowBeatmap(int beatmapId) { - lastRequestedBeatmapId = beatmapId; - lastBeatmapSetLookupType = BeatmapSetLookupType.BeatmapId; - + lastLookup = (BeatmapSetLookupType.BeatmapId, beatmapId); beatmapSet.Value = null; - fetchAndSetBeatmap(beatmapId); - + performFetch(); Show(); } public void FetchAndShowBeatmapSet(int beatmapSetId) { - lastRequestedBeatmapId = beatmapSetId; - lastBeatmapSetLookupType = BeatmapSetLookupType.SetId; + lastLookup = (BeatmapSetLookupType.SetId, beatmapSetId); beatmapSet.Value = null; - fetchAndSetBeatmapSet(beatmapSetId); - + performFetch(); Show(); } @@ -136,47 +130,24 @@ namespace osu.Game.Overlays Show(); } - private void fetchAndSetBeatmap(int beatmapId) + private void performFetch() { if (!api.IsLoggedIn) return; - var req = new GetBeatmapSetRequest(beatmapId, BeatmapSetLookupType.BeatmapId); + if (lastLookup == null) + return; + + var req = new GetBeatmapSetRequest(lastLookup.Value.id, BeatmapSetLookupType.BeatmapId); req.Success += res => { beatmapSet.Value = res; - Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineID == beatmapId); + if (lastLookup.Value.type == BeatmapSetLookupType.BeatmapId) + Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineID == lastLookup.Value.id); }; API.Queue(req); } - private void fetchAndSetBeatmapSet(int beatmapSetId) - { - if (!api.IsLoggedIn) - return; - - var req = new GetBeatmapSetRequest(beatmapSetId); - req.Success += res => beatmapSet.Value = res; - API.Queue(req); - } - - private void fetchAndSetLastRequestedBeatmap() - { - if (lastRequestedBeatmapId == null) - return; - - switch (lastBeatmapSetLookupType) - { - case BeatmapSetLookupType.SetId: - fetchAndSetBeatmapSet(lastRequestedBeatmapId.Value); - break; - - case BeatmapSetLookupType.BeatmapId: - fetchAndSetBeatmap(lastRequestedBeatmapId.Value); - break; - } - } - private partial class CommentsSection : BeatmapSetLayoutSection { public readonly Bindable BeatmapSet = new Bindable(); From e0d58d51b61296e3a1b5b0783d8d3bce9838b234 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 16:47:29 +0900 Subject: [PATCH 110/248] Split out classes into own files and rename `GroupInfoContainer` to a flow --- .../{GroupInfoContainer.cs => GroupBadge.cs} | 26 ++------------- .../Header/Components/GroupBadgeFlow.cs | 33 +++++++++++++++++++ .../Profile/Header/TopHeaderContainer.cs | 6 ++-- 3 files changed, 38 insertions(+), 27 deletions(-) rename osu.Game/Overlays/Profile/Header/Components/{GroupInfoContainer.cs => GroupBadge.cs} (74%) create mode 100644 osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs similarity index 74% rename from osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs index 363a74b5c1..b469fbbcd1 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs @@ -1,9 +1,8 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -74,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header.Components if (group.Playmodes?.Length > 0) { innerContainer.AddRange(group.Playmodes.Select(p => - (rulesets.GetRuleset(p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => + (rulesets.GetRuleset((string)p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => { icon.Size = new Vector2(TextSize - 1); })).ToList() @@ -82,25 +81,4 @@ namespace osu.Game.Overlays.Profile.Header.Components } } } - - public partial class GroupInfoContainer : FillFlowContainer - { - public readonly Bindable User = new Bindable(); - - public GroupInfoContainer() - { - AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - Spacing = new Vector2(2); - - User.BindValueChanged(val => - { - if (val.NewValue?.Groups?.Length > 0) - { - Clear(true); - Children = val.NewValue?.Groups.Select(g => new GroupBadge(g)).ToList(); - } - }); - } - } } diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs new file mode 100644 index 0000000000..062cba2581 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.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 System.Linq; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; +using osuTK; + +namespace osu.Game.Overlays.Profile.Header.Components +{ + public partial class GroupBadgeFlow : FillFlowContainer + { + public readonly Bindable User = new Bindable(); + + public GroupBadgeFlow() + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + Spacing = new Vector2(2); + + User.BindValueChanged(val => + { + if (val.NewValue?.Groups?.Length > 0) + { + Clear(true); + Children = val.NewValue?.Groups.Select(g => new GroupBadge(g)).ToList(); + } + }); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index c26efaf271..d6f2faf5e5 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Profile.Header private UpdateableFlag userFlag = null!; private OsuSpriteText userCountryText = null!; private FillFlowContainer userStats = null!; - private GroupInfoContainer groupInfoContainer = null!; + private GroupBadgeFlow groupBadgeFlow = null!; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -103,7 +103,7 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, }, - groupInfoContainer = new GroupInfoContainer + groupBadgeFlow = new GroupBadgeFlow { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, @@ -190,7 +190,7 @@ namespace osu.Game.Overlays.Profile.Header supporterTag.SupportLevel = user?.SupportLevel ?? 0; titleText.Text = user?.Title ?? string.Empty; titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff"); - groupInfoContainer.User.Value = user; + groupBadgeFlow.User.Value = user; userStats.Clear(); From 318867f486db0895ade53249401de2b697351e08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 16:48:47 +0900 Subject: [PATCH 111/248] Fix previous badges potentially not being cleared if new user has no badges --- .../Profile/Header/Components/GroupBadgeFlow.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs index 062cba2581..8a2c8b4874 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs @@ -20,13 +20,12 @@ namespace osu.Game.Overlays.Profile.Header.Components Direction = FillDirection.Horizontal; Spacing = new Vector2(2); - User.BindValueChanged(val => + User.BindValueChanged(user => { - if (val.NewValue?.Groups?.Length > 0) - { - Clear(true); - Children = val.NewValue?.Groups.Select(g => new GroupBadge(g)).ToList(); - } + Clear(true); + + if (user.NewValue != null) + AddRange(user.NewValue.Groups.Select(g => new GroupBadge(g))); }); } } From b1a13286a34054e7fee38956413b5135a3d73543 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 16:50:37 +0900 Subject: [PATCH 112/248] Remove some redundancies --- osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs | 2 +- osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs index 3c0ea4f590..15c5afe1db 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileHeader.cs @@ -59,7 +59,7 @@ namespace osu.Game.Tests.Visual.Online { Id = 2001, Username = "RankedUser", - Groups = new[] { new APIUserGroup() { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" } }, + Groups = new[] { new APIUserGroup { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" } }, Statistics = new UserStatistics { IsRanked = true, diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs index b469fbbcd1..ce56768a72 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Profile.Header.Components if (group.Playmodes?.Length > 0) { innerContainer.AddRange(group.Playmodes.Select(p => - (rulesets.GetRuleset((string)p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => + (rulesets.GetRuleset(p)?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }).With(icon => { icon.Size = new Vector2(TextSize - 1); })).ToList() From df544100755827e7a3888756ed3b1a0b780b3833 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 17:31:26 +0900 Subject: [PATCH 113/248] Fix skin fail sound not correctly playing Closes #21719. Tested using skin in issue thread. --- osu.Game/Screens/Play/FailAnimation.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 24171c25a8..3f21f811c1 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -15,11 +15,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Utils; +using osu.Game.Audio; using osu.Game.Audio.Effects; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -48,7 +50,7 @@ namespace osu.Game.Screens.Play private const float duration = 2500; - private Sample? failSample; + private ISample? failSample; [Resolved] private OsuConfigManager config { get; set; } = null!; @@ -73,10 +75,10 @@ namespace osu.Game.Screens.Play } [BackgroundDependencyLoader] - private void load(AudioManager audio, IBindable beatmap) + private void load(AudioManager audio, ISkinSource skin, IBindable beatmap) { track = beatmap.Value.Track; - failSample = audio.Samples.Get(@"Gameplay/failsound"); + failSample = skin.GetSample(new SampleInfo(@"Gameplay/failsound")); AddRangeInternal(new Drawable[] { From 2dcc61caf59f9980387aacec456923c2b9d94f72 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 17:38:08 +0900 Subject: [PATCH 114/248] Add extra level of nullabiliy checking because NRT is not present --- osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs index 8a2c8b4874..33b3de94db 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadgeFlow.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { Clear(true); - if (user.NewValue != null) + if (user.NewValue?.Groups != null) AddRange(user.NewValue.Groups.Select(g => new GroupBadge(g))); }); } From 578d16f2bce9f21fa4b5c01ba5ea78e76d31f3cb Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 11:11:31 +0100 Subject: [PATCH 115/248] perf: Do not draw sectoins that are less than 1px --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 65c2146889..9a8fd1c4c5 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -194,7 +194,7 @@ namespace osu.Game.Graphics.UserInterface shader = Source.shader; drawSize = Source.DrawSize; segments.Clear(); - segments.AddRange(Source.segments); + segments.AddRange(Source.segments.Where(s => s.Length * drawSize.X > 1)); } public override void Draw(IRenderer renderer) From 42ff8c75fa9bb211f6e1478a49447a3d1f74f558 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 11:22:18 +0100 Subject: [PATCH 116/248] refactor: make class not abstract --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 9a8fd1c4c5..977594d9b0 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -15,7 +15,7 @@ using osuTK; namespace osu.Game.Graphics.UserInterface { - public abstract partial class SegmentedGraph : Drawable + public partial class SegmentedGraph : Drawable where T : struct, IComparable, IConvertible, IEquatable { private bool graphNeedsUpdate; From a87debab0fae30685a9f22b97867b89e6ba1c2a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 20:15:20 +0900 Subject: [PATCH 117/248] Fix kiai flash opacity on legacy skins being too intense --- osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs index fd9434e02a..427a0ede4d 100644 --- a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs +++ b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs @@ -13,7 +13,7 @@ namespace osu.Game.Skinning { private readonly Drawable flashingDrawable; - private const float flash_opacity = 0.55f; + private const float flash_opacity = 0.3f; public LegacyKiaiFlashingDrawable(Func creationFunc) { From 0d1046ed833c54a245970a88a8c951981368a3d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 21:25:53 +0900 Subject: [PATCH 118/248] Add full colour application to kiai sprites --- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index 6547b058c2..989f5a8a7c 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ObjectExtensions; @@ -66,17 +67,28 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy // the conditional above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist. // expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png. + Color4 objectColour = drawableOsuObject!.AccentColour.Value; + int add = Math.Max(25, 300 - (int)(objectColour.R * 255) - (int)(objectColour.G * 255) - (int)(objectColour.B * 255)); + + Color4 finalColour = new Color4( + (byte)Math.Min((byte)(objectColour.R * 255) + add, 255), + (byte)Math.Min((byte)(objectColour.G * 255) + add, 255), + (byte)Math.Min((byte)(objectColour.B * 255) + add, 255), + 255); + InternalChildren = new[] { CircleSprite = new LegacyKiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(circleName) }) { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Colour = finalColour, }, OverlayLayer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, + Colour = finalColour, Child = OverlaySprite = new LegacyKiaiFlashingDrawable(() => skin.GetAnimation(@$"{circleName}overlay", true, true, frameLength: 1000 / 2d)) { Anchor = Anchor.Centre, From e9571be4abac6f16569fb034ef8b64bae9e2381b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 18:25:24 +0900 Subject: [PATCH 119/248] Fix incorrect application layer causing completely discoloured circles --- .../Skinning/Legacy/LegacyMainCirclePiece.cs | 32 ++++++++++--------- .../Skinning/LegacyKiaiFlashingDrawable.cs | 7 ++++ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs index 989f5a8a7c..cadac4d319 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs @@ -30,8 +30,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private readonly bool hasNumber; - protected Drawable CircleSprite = null!; - protected Drawable OverlaySprite = null!; + protected LegacyKiaiFlashingDrawable CircleSprite = null!; + protected LegacyKiaiFlashingDrawable OverlaySprite = null!; protected Container OverlayLayer { get; private set; } = null!; @@ -66,29 +66,17 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy // at this point, any further texture fetches should be correctly using the priority source if the base texture was retrieved using it. // the conditional above handles the case where a sliderendcircle.png is retrieved from the skin, but sliderendcircleoverlay.png doesn't exist. // expected behaviour in this scenario is not showing the overlay, rather than using hitcircleoverlay.png. - - Color4 objectColour = drawableOsuObject!.AccentColour.Value; - int add = Math.Max(25, 300 - (int)(objectColour.R * 255) - (int)(objectColour.G * 255) - (int)(objectColour.B * 255)); - - Color4 finalColour = new Color4( - (byte)Math.Min((byte)(objectColour.R * 255) + add, 255), - (byte)Math.Min((byte)(objectColour.G * 255) + add, 255), - (byte)Math.Min((byte)(objectColour.B * 255) + add, 255), - 255); - InternalChildren = new[] { CircleSprite = new LegacyKiaiFlashingDrawable(() => new Sprite { Texture = skin.GetTexture(circleName) }) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Colour = finalColour, }, OverlayLayer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Colour = finalColour, Child = OverlaySprite = new LegacyKiaiFlashingDrawable(() => skin.GetAnimation(@$"{circleName}overlay", true, true, frameLength: 1000 / 2d)) { Anchor = Anchor.Centre, @@ -126,7 +114,21 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy { base.LoadComplete(); - accentColour.BindValueChanged(colour => CircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true); + accentColour.BindValueChanged(colour => + { + Color4 objectColour = colour.NewValue; + int add = Math.Max(25, 300 - (int)(objectColour.R * 255) - (int)(objectColour.G * 255) - (int)(objectColour.B * 255)); + + var kiaiTintColour = new Color4( + (byte)Math.Min((byte)(objectColour.R * 255) + add, 255), + (byte)Math.Min((byte)(objectColour.G * 255) + add, 255), + (byte)Math.Min((byte)(objectColour.B * 255) + add, 255), + 255); + + CircleSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue); + OverlaySprite.KiaiGlowColour = CircleSprite.KiaiGlowColour = LegacyColourCompatibility.DisallowZeroAlpha(kiaiTintColour); + }, true); + if (hasNumber) indexInCurrentCombo.BindValueChanged(index => hitCircleText.Text = (index.NewValue + 1).ToString(), true); diff --git a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs index 427a0ede4d..2f79512ed8 100644 --- a/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs +++ b/osu.Game/Skinning/LegacyKiaiFlashingDrawable.cs @@ -6,11 +6,18 @@ using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; +using osuTK.Graphics; namespace osu.Game.Skinning { public partial class LegacyKiaiFlashingDrawable : BeatSyncedContainer { + public Color4 KiaiGlowColour + { + get => flashingDrawable.Colour; + set => flashingDrawable.Colour = value; + } + private readonly Drawable flashingDrawable; private const float flash_opacity = 0.3f; From e128b9ee5cb75e9522493d09866d92bb653632dc Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 14:02:18 +0100 Subject: [PATCH 120/248] fix(SegmentedGraph): make ctor public --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 977594d9b0..2a63d53870 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -26,7 +26,7 @@ namespace osu.Game.Graphics.UserInterface private readonly int tierCount; - protected SegmentedGraph(int tierCount) + public SegmentedGraph(int tierCount) { this.tierCount = tierCount; TierColours = new Colour4[tierCount]; From 6249322a32bf6b3314a2d69add184eb131269fed Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 14:03:36 +0100 Subject: [PATCH 121/248] fix(SegmentedGraph): solve issue for negatives values --- osu.Game/Graphics/UserInterface/SegmentedGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 2a63d53870..f8c5c08bbf 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -86,7 +86,7 @@ namespace osu.Game.Graphics.UserInterface if (min < 0) { for (int i = 0; i < floatValues.Length; i++) - floatValues[i] += min; + floatValues[i] += Math.Abs(min); } // Normalize values From 845cdb3097ce2781c2575f0c8277900852fcccf5 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 14:03:49 +0100 Subject: [PATCH 122/248] test: add visual tests for SegmentedGraph class --- .../UserInterface/TestSceneSegmentedGraph.cs | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs new file mode 100644 index 0000000000..ab7078d1b7 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -0,0 +1,96 @@ +// 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.Graphics; +using osu.Game.Graphics.UserInterface; +using osuTK; +using Vector4 = System.Numerics.Vector4; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public partial class TestSceneSegmentedGraph : OsuTestScene + { + private readonly SegmentedGraph graph; + + public TestSceneSegmentedGraph() + { + Children = new Drawable[] + { + graph = new SegmentedGraph(10) + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(1, 0.5f), + }, + }; + + for (int i = 0; i < graph.TierColours.Length; i++) + { + graph.TierColours[i] = + new Colour4(Vector4.Lerp(Colour4.Blue.Vector, Colour4.White.Vector, i * 1f / (graph.TierColours.Length - 1))); + } + + AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1, 10).ToArray()); + AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).ToArray()); + AddStep("values from 1-500", () => graph.Values = Enumerable.Range(1, 500).ToArray()); + AddStep("sin() function of size 100", () => sinFunction()); + AddStep("sin() function of size 500", () => sinFunction(500)); + AddStep("bumps of size 100", () => bumps()); + AddStep("bumps of size 500", () => bumps(500)); + AddStep("100 random values", () => randomValues()); + AddStep("500 random values", () => randomValues(500)); + AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().ToArray()); + } + + private void sinFunction(int size = 100) + { + const int max_value = 255; + int[] values = new int[size]; + + float step = 2 * MathF.PI / size; + float x = 0; + + for (int i = 0; i < size; i++) + { + values[i] = (int)(max_value * MathF.Sin(x)); + x += step; + } + + graph.Values = values; + } + + private void bumps(int size = 100) + { + const int max_value = 255; + int[] values = new int[size]; + + float step = 2 * MathF.PI / size; + float x = 0; + + for (int i = 0; i < size; i++) + { + values[i] = (int)(max_value * Math.Abs(MathF.Sin(x))); + x += step; + } + + graph.Values = values; + } + + private void randomValues(int size = 100) + { + Random rng = new Random(); + + int[] values = new int[size]; + + for (int i = 0; i < size; i++) + { + values[i] = rng.Next(255); + } + + graph.Values = values; + } + } +} From 442b2238b8cdf0f04d0054cb12c73571b51cba59 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 14:37:57 +0100 Subject: [PATCH 123/248] test(SegmentedGraph): add concrete application test with beatmap density --- .../UserInterface/TestSceneSegmentedGraph.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index ab7078d1b7..f8df0528d6 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -2,9 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu; using osuTK; using Vector4 = System.Numerics.Vector4; @@ -42,6 +46,8 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("bumps of size 500", () => bumps(500)); AddStep("100 random values", () => randomValues()); AddStep("500 random values", () => randomValues(500)); + AddStep("beatmap density with granularity of 200", () => beatmapDensity()); + AddStep("beatmap density with granularity of 300", () => beatmapDensity(300)); AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().ToArray()); } @@ -92,5 +98,40 @@ namespace osu.Game.Tests.Visual.UserInterface graph.Values = values; } + + private void beatmapDensity(int granularity = 200) + { + var ruleset = new OsuRuleset(); + var beatmap = CreateBeatmap(ruleset.RulesetInfo); + IEnumerable objects = beatmap.HitObjects; + + // Taken from SongProgressGraph + int[] values = new int[granularity]; + + if (!objects.Any()) + return; + + double firstHit = objects.First().StartTime; + double lastHit = objects.Max(o => o.GetEndTime()); + + if (lastHit == 0) + lastHit = objects.Last().StartTime; + + double interval = (lastHit - firstHit + 1) / granularity; + + foreach (var h in objects) + { + double endTime = h.GetEndTime(); + + Debug.Assert(endTime >= h.StartTime); + + int startRange = (int)((h.StartTime - firstHit) / interval); + int endRange = (int)((endTime - firstHit) / interval); + for (int i = startRange; i <= endRange; i++) + values[i]++; + } + + graph.Values = values; + } } } From 1f129d4e163132c6355eb0c397c64d5bfacd8052 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Wed, 11 Jan 2023 21:20:56 +0300 Subject: [PATCH 124/248] Add failing test --- .../TestScenePlacementBeforeTrackStart.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 osu.Game.Rulesets.Mania.Tests/Editor/TestScenePlacementBeforeTrackStart.cs diff --git a/osu.Game.Rulesets.Mania.Tests/Editor/TestScenePlacementBeforeTrackStart.cs b/osu.Game.Rulesets.Mania.Tests/Editor/TestScenePlacementBeforeTrackStart.cs new file mode 100644 index 0000000000..00dd75ceee --- /dev/null +++ b/osu.Game.Rulesets.Mania.Tests/Editor/TestScenePlacementBeforeTrackStart.cs @@ -0,0 +1,30 @@ +// 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.Containers; +using osu.Framework.Testing; +using osu.Game.Tests.Visual; +using osuTK.Input; + +namespace osu.Game.Rulesets.Mania.Tests.Editor +{ + public partial class TestScenePlacementBeforeTrackStart : EditorTestScene + { + protected override Ruleset CreateEditorRuleset() => new ManiaRuleset(); + + [Test] + public void TestPlacement() + { + AddStep("Seek to 0", () => EditorClock.Seek(0)); + AddStep("Select note", () => InputManager.Key(Key.Number2)); + AddStep("Hover negative span", () => + { + InputManager.MoveMouseTo(this.ChildrenOfType().First(x => x.Name == "Icons").Children[0]); + }); + AddStep("Click", () => InputManager.Click(MouseButton.Left)); + AddAssert("No notes placed", () => EditorBeatmap.HitObjects.All(x => x.StartTime >= 0)); + } + } +} From 6c52b8339b5cacbb960f43bc74b0cc187104109f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 11 Jan 2023 22:02:06 +0300 Subject: [PATCH 125/248] Fix game-level components finishing load after content --- osu.Game/OsuGame.cs | 4 +-- osu.Game/OsuGameBase.cs | 54 +++++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index dc4d56de11..4113c9be8f 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -933,9 +933,9 @@ namespace osu.Game loadComponentSingleFile(dashboard = new DashboardOverlay(), overlayContent.Add, true); loadComponentSingleFile(news = new NewsOverlay(), overlayContent.Add, true); var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); - loadComponentSingleFile(channelManager = new ChannelManager(API), AddInternal, true); + loadComponentSingleFile(channelManager = new ChannelManager(API), Add, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); - loadComponentSingleFile(new MessageNotifier(), AddInternal, true); + loadComponentSingleFile(new MessageNotifier(), Add, true); loadComponentSingleFile(Settings = new SettingsOverlay(), leftFloatingOverlayContent.Add, true); loadComponentSingleFile(changelogOverlay = new ChangelogOverlay(), overlayContent.Add, true); loadComponentSingleFile(userProfile = new UserProfileOverlay(), overlayContent.Add, true); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 36e248c1f2..c78a527514 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -206,7 +206,7 @@ namespace osu.Game /// private readonly FramedBeatmapClock beatmapClock = new FramedBeatmapClock(true); - protected override Container Content => content; + protected override Container Content => content ?? base.Content; private Container content; @@ -296,7 +296,7 @@ namespace osu.Game dependencies.Cache(ScoreDownloader = new ScoreModelDownloader(ScoreManager, API)); // Add after all the above cache operations as it depends on them. - AddInternal(difficultyCache); + Add(difficultyCache); // TODO: OsuGame or OsuGameBase? dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage)); @@ -305,19 +305,19 @@ namespace osu.Game dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints)); dependencies.CacheAs(soloStatisticsWatcher = new SoloStatisticsWatcher()); - AddInternal(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); + Add(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); BeatmapManager.ProcessBeatmap = args => beatmapUpdater.Process(args.beatmapSet, !args.isBatch); dependencies.Cache(userCache = new UserLookupCache()); - AddInternal(userCache); + Add(userCache); dependencies.Cache(beatmapCache = new BeatmapLookupCache()); - AddInternal(beatmapCache); + Add(beatmapCache); var scorePerformanceManager = new ScorePerformanceCache(); dependencies.Cache(scorePerformanceManager); - AddInternal(scorePerformanceManager); + Add(scorePerformanceManager); dependencies.CacheAs(rulesetConfigCache = new RulesetConfigCache(realm, RulesetStore)); @@ -344,27 +344,34 @@ namespace osu.Game // add api components to hierarchy. if (API is APIAccess apiAccess) - AddInternal(apiAccess); + Add(apiAccess); - AddInternal(spectatorClient); - AddInternal(MultiplayerClient); - AddInternal(metadataClient); - AddInternal(soloStatisticsWatcher); + Add(spectatorClient); + Add(MultiplayerClient); + Add(metadataClient); + Add(soloStatisticsWatcher); - AddInternal(rulesetConfigCache); + Add(rulesetConfigCache); + + PreviewTrackManager previewTrackManager; + dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore)); + Add(previewTrackManager); + + Add(MusicController = new MusicController()); + dependencies.CacheAs(MusicController); + + MusicController.TrackChanged += onTrackChanged; + Add(beatmapClock); GlobalActionContainer globalBindings; - base.Content.Add(SafeAreaContainer = new SafeAreaContainer + Add(SafeAreaContainer = new SafeAreaContainer { SafeAreaOverrideEdges = SafeAreaOverrideEdges, RelativeSizeAxes = Axes.Both, Child = CreateScalingContainer().WithChildren(new Drawable[] { (GlobalCursorDisplay = new GlobalCursorDisplay - { - RelativeSizeAxes = Axes.Both - }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { RelativeSizeAxes = Axes.Both }), @@ -373,21 +380,16 @@ namespace osu.Game }) }); + GlobalCursorDisplay.Child = content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) + { + RelativeSizeAxes = Axes.Both + }; + KeyBindingStore = new RealmKeyBindingStore(realm, keyCombinationProvider); KeyBindingStore.Register(globalBindings, RulesetStore.AvailableRulesets); dependencies.Cache(globalBindings); - PreviewTrackManager previewTrackManager; - dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore)); - Add(previewTrackManager); - - AddInternal(MusicController = new MusicController()); - dependencies.CacheAs(MusicController); - - MusicController.TrackChanged += onTrackChanged; - AddInternal(beatmapClock); - Ruleset.BindValueChanged(onRulesetChanged); Beatmap.BindValueChanged(onBeatmapChanged); } From 624e90b213f4e328add5723206555fd1b56e0374 Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 21:32:12 +0100 Subject: [PATCH 126/248] style: nitpicks --- .../Graphics/UserInterface/SegmentedGraph.cs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index f8c5c08bbf..d0356e6327 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -136,7 +136,7 @@ namespace osu.Game.Graphics.UserInterface segments.Sort(); } - private Colour4 tierToColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); + private Colour4 getTierColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); protected override DrawNode CreateDrawNode() => new SegmentedGraphDrawNode(this); @@ -217,7 +217,7 @@ namespace osu.Game.Graphics.UserInterface Vector2Extensions.Transform(topRight, DrawInfo.Matrix), Vector2Extensions.Transform(bottomLeft, DrawInfo.Matrix), Vector2Extensions.Transform(bottomRight, DrawInfo.Matrix)), - Source.tierToColour(segment.Tier)); + Source.getTierColour(segment.Tier)); } shader.Unbind(); @@ -263,12 +263,12 @@ namespace osu.Game.Graphics.UserInterface { foreach (SegmentInfo? pendingSegment in pendingSegments) { - if (pendingSegment != null) - { - SegmentInfo finalizedSegment = pendingSegment.Value; - finalizedSegment.End = 1; - segments.Add(finalizedSegment); - } + if (pendingSegment == null) + continue; + + SegmentInfo finalizedSegment = pendingSegment.Value; + finalizedSegment.End = 1; + segments.Add(finalizedSegment); } } @@ -305,13 +305,7 @@ namespace osu.Game.Graphics.UserInterface Add(segment); } - public bool IsTierStarted(int tier) - { - if (tier < 0) - return false; - - return pendingSegments[tier].HasValue; - } + public bool IsTierStarted(int tier) => tier >= 0 && pendingSegments[tier].HasValue; public IEnumerator GetEnumerator() => segments.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); From f80112187ec81ad83410ee419ee75ac4ce6b4e11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 11 Jan 2023 23:27:20 +0100 Subject: [PATCH 127/248] Rewrite contributing guidelines - Includes changes to process discussed in development meeting today. - Describes issue vs discussion axis which wasn't present at the time the document was originally created. - Reduces amount of unnecessary text in hopes that the document will actually be read in full. --- CONTRIBUTING.md | 156 ++++++++++++++++-------------------------------- 1 file changed, 53 insertions(+), 103 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c72a3b442e..9f7d88f5c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,137 +2,87 @@ Thank you for showing interest in the development of osu!. We aim to provide a good collaborating environment for everyone involved, and as such have decided to list some of the most important things to keep in mind in the process. The guidelines below have been chosen based on past experience. -These are not "official rules" *per se*, but following them will help everyone deal with things in the most efficient manner. - ## Table of contents -1. [I would like to submit an issue!](#i-would-like-to-submit-an-issue) -2. [I would like to submit a pull request!](#i-would-like-to-submit-a-pull-request) +1. [Reporting bugs](#reporting-bugs) +2. [Providing general feedback](#providing-general-feedback) +3. [Issue or discussion?](#issue-or-discussion) +4. [Submitting pull requests](#submitting-pull-requests) +5. [Resources](#resources) -## I would like to submit an issue! +## Reporting bugs -Issues, bug reports and feature suggestions are welcomed, though please keep in mind that at any point in time, hundreds of issues are open, which vary in severity and the amount of time needed to address them. As such it's not uncommon for issues to remain unresolved for a long time or even closed outright if they are deemed not important enough to fix in the foreseeable future. Issues that are required to "go live" or otherwise achieve parity with stable are prioritised the most. +A **bug** is a situation in which there is something clearly *and objectively* wrong with the game. Examples of applicable bug reports are: -* **Before submitting an issue, try searching existing issues first.** +- The game crashes to desktop when I start a beatmap +- Friends appear twice in the friend listing +- The game slows down a lot when I play this specific map +- A piece of text is overlapping another piece of text on the screen - For housekeeping purposes, we close issues that overlap with or duplicate other pre-existing issues - you can help us not to have to do that by searching existing issues yourself first. The issue search box, as well as the issue tag system, are tools you can use to check if an issue has been reported before. +To track bug reports, we primarily use GitHub **issues**. When opening an issue, please keep in mind the following: -* **When submitting a bug report, please try to include as much detail as possible.** +- Before opening the issue, please search for any similar existing issues using the text search bar and the issue labels. This includes both open and closed issues (we may have already fixed something, but the fix hasn't yet been released). +- When opening the issue, please fill out as much of the issue template as you can. In particular, please make sure to include logs and screenshots as much as possible. The instructions on how to find the log files are included in the issue template. +- We may ask you for follow-up information to reproduce or debug the problem. Please look out for this and provide follow-up info if we request it. - Bugs are not equal - some of them will be reproducible every time on pretty much all hardware, while others will be hard to track down due to being specific to particular hardware or even somewhat random in nature. As such, providing as much detail as possible when reporting a bug is hugely appreciated. A good starting set of information consists of: +If we cannot reproduce the issue, it is deemed low priority, or it is deemed to be specific to your setup in some way, the issue may be downgraded to a discussion. This will be done by a maintainer for you. - * the in-game logs, which are located at: - * `%AppData%/osu/logs` (on Windows), - * `~/.local/share/osu/logs` (on Linux), - * `~/Library/Application Support/osu/logs` (on macOS), - * `Android/data/sh.ppy.osulazer/files/logs` (on Android), - * on iOS they can be obtained by connecting your device to your desktop and [copying the `logs` directory from the app's own document storage using iTunes](https://support.apple.com/en-us/HT201301#copy-to-computer), - * your system specifications (including the operating system and platform you are playing on), - * a reproduction scenario (list of steps you have performed leading up to the occurrence of the bug), - * a video or picture of the bug, if at all possible. +## Providing general feedback -* **Provide more information when asked to do so.** +If you wish to: - Sometimes when a bug is more elusive or complicated, none of the information listed above will pinpoint a concrete cause of the problem. In this case we will most likely ask you for additional info, such as a Windows Event Log dump or a copy of your local osu! database (`client.db`). Providing that information is beneficial to both parties - we can track down the problem better, and hopefully fix it for you at some point once we know where it is! +- provide *subjective* feedback on the game (about how the UI looks, about how the default skin works, about game mechanics, about how the PP and scoring systems work, etc.), +- suggest a new feature to be added to the game, +- report a non-specific problem with the game that you think may be connected to your hardware or operating system specifically, -* **When submitting a feature proposal, please describe it in the most understandable way you can.** +then it is generally best to start with a **discussion** first. Discussions are a good avenue to group subjective feedback on a single topic, or gauge interest in a particular feature request. - Communicating your idea for a feature can often be hard, and we would like to avoid any misunderstandings. As such, please try to explain your idea in a short, but understandable manner - it's best to avoid jargon or terms and references that could be considered obscure. A mock-up picture (doesn't have to be good!) of the feature can also go a long way in explaining. +When opening a discussion, please keep in mind the following: -* **Refrain from posting "+1" comments.** +- Use the search function to see if your idea has been proposed before, or if there is already a thread about a particular issue you wish to raise. +- If proposing a feature, please try to explain the feature in as much detail as possible. +- If you're reporting a non-specific problem, please provide applicable logs, screenshots, or video that illustrate the issue. - If an issue has already been created, saying that you also experience it without providing any additional details doesn't really help us in any way. To express support for a proposal or indicate that you are also affected by a particular bug, you can use comment reactions instead. +If a discussion gathers enough traction, then it may be converted into an issue. This will be done by a maintainer for you. -* **Refrain from asking if an issue has been resolved yet.** +## Issue or discussion? - As mentioned above, the issue tracker has hundreds of issues open at any given time. Currently the game is being worked on by two members of the core team, and a handful of outside contributors who offer their free time to help out. As such, it can happen that an issue gets placed on the backburner due to being less important; generally posting a comment demanding its resolution some months or years after it is reported is not very likely to increase its priority. +We realise that the line between an issue and a discussion may be fuzzy, so while we ask you to use your best judgement based on the description above, please don't think about it too hard either. Feedback in a slightly wrong place is better than no feedback at all. -* **Avoid long discussions about non-development topics.** +When in doubt, it's probably best to start with a discussion first. We will escalate to issues as needed. - GitHub is mostly a developer space, and as such isn't really fit for lengthened discussions about gameplay mechanics (which might not even be in any way confirmed for the final release) and similar non-technical matters. Such matters are probably best addressed at the osu! forums. +## Submitting pull requests -## I would like to submit a pull request! +While pull requests from unaffiliated contributors are welcome, please note that due to significant community interest and limited review throughput, the core team's primary focus is on the issues which are currently [on the roadmap](https://github.com/orgs/ppy/projects/7/views/6). Reviewing PRs that fall outside of the scope of the roadmap is done on a best-effort basis, so please be aware that it may take a while before a core maintainer gets around to review your change. -We also welcome pull requests from unaffiliated contributors. The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues that you can work on; we also mark issues that we think would be good for newcomers with the [`good-first-issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue) label. +The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. We also have a [`good-first-issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue) label, although from experience it is not used very often, as it is relatively rare that we can spot an issue that will definitively be a good first issue for a new contributor regardless of their programming experience. -However, do keep in mind that the core team is committed to bringing osu!(lazer) up to par with osu!(stable) first and foremost, so depending on what your contribution concerns, it might not be merged and released right away. Our approach to managing issues and their priorities is described [in the wiki](https://github.com/ppy/osu/wiki/Project-management). +In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive. -Here are some key things to note before jumping in: +If you'd like to propose a subjective change to one of the visual aspects of the game, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort. This in particular applies if you want to work on [one of the available designs from the osu! public Figma library](https://www.figma.com/file/6m10GiGEncVFWmgOoSyakH/osu!-Figma-Library). -* **Make sure you are comfortable with C\# and your development environment.** +Aside from the above, below is a brief checklist of things to watch out when you're preparing your code changes: - While we are accepting of all kinds of contributions, we also have a certain quality standard we'd like to uphold and limited time to review your code. Therefore, we would like to avoid providing entry-level advice, and as such if you're not very familiar with C\# as a programming language, we'd recommend that you start off with a few personal projects to get acquainted with the language's syntax, toolchain and principles of object-oriented programming first. +- Make sure you're comfortable with the principles of object-oriented programming, the syntax of C\# and your development environment. +- Make sure you are familiar with [git](https://git-scm.com/) and [the pull request workflow](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests). +- Please do not make code changes via the GitHub web interface. +- Please add tests for your changes. We expect most new features and bugfixes to have test coverage, unless the effort of adding them is prohibitive. The visual testing methodology we use is described in more detail [here](https://github.com/ppy/osu-framework/wiki/Development-and-Testing). +- Please run tests and code style analysis (via `InspectCode.{ps1,sh}` scripts in the root of this repository) before opening the PR. This is particularly important if you're a first-time contributor, as CI will not run for your PR until we allow it to do so. - In addition, please take the time to take a look at and get acquainted with the [development and testing](https://github.com/ppy/osu-framework/wiki/Development-and-Testing) procedure we have set up. +After you're done with your changes and you wish to open the PR, please observe the following recommendations: -* **Make sure you are familiar with git and the pull request workflow.** +- Please submit the pull request from a [topic branch](https://git-scm.com/book/en/v2/Git-Branching-Branching-Workflows#_topic_branch) (not `master`), and keep the *Allow edits from maintainers* check box selected, so that we can push fixes to your PR if necessary. +- Please avoid pushing untested or incomplete code. +- Please do not force-push or rebase unless we ask you to. +- Please do not merge `master` continually if there are no conflicts to resolve. We will do this for you when the change is ready for merge. - [git](https://git-scm.com/) is a distributed version control system that might not be very intuitive at the beginning if you're not familiar with version control. In particular, projects using git have a particular workflow for submitting code changes, which is called the pull request workflow. +We are highly committed to quality when it comes to the osu! project. This means that contributions from less experienced community members can take multiple rounds of review to get to a mergeable state. We try our utmost best to never conflate a person with the code they authored, and to keep the discussion focused on the code at all times. Please consider our comments and requests a learning experience. - To make things run more smoothly, we recommend that you look up some online resources to familiarise yourself with the git vocabulary and commands, and practice working with forks and submitting pull requests at your own pace. A high-level overview of the process can be found in [this article by GitHub](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests). +If you're uncertain about some part of the codebase or some inner workings of the game and framework, please reach out either by leaving a comment in the relevant issue, discussion, or PR thread, or by posting a message in the [development Discord server](https://discord.gg/ppy). We will try to help you as much as we can. -* **Double-check designs before starting work on new functionality.** +## Resources - When implementing new features, keep in mind that we already have a lot of the UI designed. If you wish to work on something with the intention of having it included in the official distribution, please open an issue for discussion and we will give you what you need from a design perspective to proceed. If you want to make *changes* to the design, we recommend you open an issue with your intentions before spending too much time to ensure no effort is wasted. - -* **Make sure to submit pull requests off of a topic branch.** - - As described in the article linked in the previous point, topic branches help you parallelise your work and separate it from the main `master` branch, and additionally are easier for maintainers to work with. Working with multiple `master` branches across many remotes is difficult to keep track of, and it's easy to make a mistake and push to the wrong `master` branch by accident. - -* **Refrain from making changes through the GitHub web interface.** - - Even though GitHub provides an option to edit code or replace files in the repository using the web interface, we strongly discourage using it in most scenarios. Editing files this way is inefficient and likely to introduce whitespace or file encoding changes that make it more difficult to review the code. - - Code written through the web interface will also very likely be questioned outright by the reviewers, as it is likely that it has not been properly tested or that it will fail continuous integration checks. We strongly encourage using an IDE like [Visual Studio](https://visualstudio.microsoft.com/), [Visual Studio Code](https://code.visualstudio.com/) or [JetBrains Rider](https://www.jetbrains.com/rider/) instead. - -* **Add tests for your code whenever possible.** - - Automated tests are an essential part of a quality and reliable codebase. They help to make the code more maintainable by ensuring it is safe to reorganise (or refactor) the code in various ways, and also prevent regressions - bugs that resurface after having been fixed at some point in the past. If it is viable, please put in the time to add tests, so that the changes you make can last for a (hopefully) very long time. - -* **Run tests before opening a pull request.** - - Tying into the previous point, sometimes changes in one part of the codebase can result in unpredictable changes in behaviour in other pieces of the code. This is why it is best to always try to run tests before opening a PR. - - Continuous integration will always run the tests for you (and us), too, but it is best not to rely on it, as there might be many builds queued at any time. Running tests on your own will help you be more certain that at the point of clicking the "Create pull request" button, your changes are as ready as can be. - -* **Run code style analysis before opening a pull request.** - - As part of continuous integration, we also run code style analysis, which is supposed to make sure that your code is formatted the same way as all the pre-existing code in the repository. The reason we enforce a particular code style everywhere is to make sure the codebase is consistent in that regard - having one whitespace convention in one place and another one elsewhere causes disorganisation. - -* **Make sure that the pull request is complete before opening it.** - - Whether it's fixing a bug or implementing new functionality, it's best that you make sure that the change you want to submit as a pull request is as complete as it can be before clicking the *Create pull request* button. Having to track if a pull request is ready for review or not places additional burden on reviewers. - - Draft pull requests are an option, but use them sparingly and within reason. They are best suited to discuss code changes that cannot be easily described in natural language or have a potential large impact on the future direction of the project. When in doubt, don't open drafts unless a maintainer asks you to do so. - -* **Only push code when it's ready.** - - As an extension of the above, when making changes to an already-open PR, please try to only push changes you are reasonably certain of. Pushing after every commit causes the continuous integration build queue to grow in size, slowing down work and taking up time that could be spent verifying other changes. - -* **Make sure to keep the *Allow edits from maintainers* check box checked.** - - To speed up the merging process, collaborators and team members will sometimes want to push changes to your branch themselves, to make minor code style adjustments or to otherwise refactor the code without having to describe how they'd like the code to look like in painstaking detail. Having the *Allow edits from maintainers* check box checked lets them do that; without it they are forced to report issues back to you and wait for you to address them. - -* **Refrain from continually merging the master branch back to the PR.** - - Unless there are merge conflicts that need resolution, there is no need to keep merging `master` back to a branch over and over again. One of the maintainers will merge `master` themselves before merging the PR itself anyway, and continual merge commits can cause CI to get overwhelmed due to queueing up too many builds. - -* **Refrain from force-pushing to the PR branch.** - - Force-pushing should be avoided, as it can lead to accidentally overwriting a maintainer's changes or CI building wrong commits. We value all history in the project, so there is no need to squash or amend commits in most cases. - - The cases in which force-pushing is warranted are very rare (such as accidentally leaking sensitive info in one of the files committed, adding unrelated files, or mis-merging a dependent PR). - -* **Be patient when waiting for the code to be reviewed and merged.** - - As much as we'd like to review all contributions as fast as possible, our time is limited, as team members have to work on their own tasks in addition to reviewing code. As such, work needs to be prioritised, and it can unfortunately take weeks or months for your PR to be merged, depending on how important it is deemed to be. - -* **Don't mistake criticism of code for criticism of your person.** - - As mentioned before, we are highly committed to quality when it comes to the osu! project. This means that contributions from less experienced community members can take multiple rounds of review to get to a mergeable state. We try our utmost best to never conflate a person with the code they authored, and to keep the discussion focused on the code at all times. Please consider our comments and requests a learning experience, and don't treat it as a personal attack. - -* **Feel free to reach out for help.** - - If you're uncertain about some part of the codebase or some inner workings of the game and framework, please reach out either by leaving a comment in the relevant issue or PR thread, or by posting a message in the [development Discord server](https://discord.gg/ppy). We will try to help you as much as we can. - - When it comes to which form of communication is best, GitHub generally lends better to longer-form discussions, while Discord is better for snappy call-and-response answers. Use your best discretion when deciding, and try to keep a single discussion in one place instead of moving back and forth. +- [Development roadmap](https://github.com/orgs/ppy/projects/7/views/6): What the core team is currently working on +- [`ppy/osu-framework` wiki](https://github.com/ppy/osu-framework/wiki): Contains introductory information about osu!framework, the bespoke 2D game framework we use for the game +- [`ppy/osu` wiki](https://github.com/ppy/osu/wiki): Contains articles about various technical aspects of the game +- [Public Figma library](https://www.figma.com/file/6m10GiGEncVFWmgOoSyakH/osu!-Figma-Library): Contains finished and draft designs for osu! From 03ac2fd7d74b446f62328648c83e857d7aef1cd9 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 03:33:20 +0300 Subject: [PATCH 128/248] More tests --- .../Editing/TestSceneSnappingNearZero.cs | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 osu.Game.Tests/Editing/TestSceneSnappingNearZero.cs diff --git a/osu.Game.Tests/Editing/TestSceneSnappingNearZero.cs b/osu.Game.Tests/Editing/TestSceneSnappingNearZero.cs new file mode 100644 index 0000000000..59081215ba --- /dev/null +++ b/osu.Game.Tests/Editing/TestSceneSnappingNearZero.cs @@ -0,0 +1,79 @@ +// 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.ControlPoints; + +namespace osu.Game.Tests.Editing +{ + [TestFixture] + public class TestSceneSnappingNearZero + { + private readonly ControlPointInfo cpi = new ControlPointInfo(); + + [Test] + public void TestOnZero() + { + test(0, 500, 0, 0); + test(0, 500, 100, 0); + test(0, 500, 250, 500); + test(0, 500, 600, 500); + + test(0, 500, -600, 0); + } + + [Test] + public void TestAlmostOnZero() + { + test(50, 500, 0, 50); + test(50, 500, 50, 50); + test(50, 500, 100, 50); + test(50, 500, 299, 50); + test(50, 500, 300, 550); + + test(50, 500, -500, 50); + } + + [Test] + public void TestAlmostOnOne() + { + test(499, 500, -1, 499); + test(499, 500, 0, 499); + test(499, 500, 1, 499); + test(499, 500, 499, 499); + test(499, 500, 600, 499); + test(499, 500, 800, 999); + } + + [Test] + public void TestOnOne() + { + test(500, 500, -500, 0); + test(500, 500, 0, 0); + test(500, 500, 200, 0); + test(500, 500, 400, 500); + test(500, 500, 500, 500); + test(500, 500, 600, 500); + test(500, 500, 900, 1000); + } + + [Test] + public void TestNegative() + { + test(-600, 500, -600, 400); + test(-600, 500, -100, 400); + test(-600, 500, 0, 400); + test(-600, 500, 200, 400); + test(-600, 500, 400, 400); + test(-600, 500, 600, 400); + test(-600, 500, 1000, 900); + } + + private void test(double pointTime, double beatLength, double from, double expected) + { + cpi.Clear(); + cpi.Add(pointTime, new TimingControlPoint { BeatLength = beatLength }); + Assert.That(cpi.GetClosestSnappedTime(from, 1), Is.EqualTo(expected), $"From: {from}"); + } + } +} From 51e21ee6f00962c396a1987ab248c236e1865f96 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 03:38:57 +0300 Subject: [PATCH 129/248] Make snapped time always positive --- osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs index 29b7191ecf..1a15db98e4 100644 --- a/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs +++ b/osu.Game/Beatmaps/ControlPoints/ControlPointInfo.cs @@ -183,9 +183,15 @@ namespace osu.Game.Beatmaps.ControlPoints private static double getClosestSnappedTime(TimingControlPoint timingPoint, double time, int beatDivisor) { double beatLength = timingPoint.BeatLength / beatDivisor; - int beatLengths = (int)Math.Round((time - timingPoint.Time) / beatLength, MidpointRounding.AwayFromZero); + double beats = (Math.Max(time, 0) - timingPoint.Time) / beatLength; - return timingPoint.Time + beatLengths * beatLength; + int roundedBeats = (int)Math.Round(beats, MidpointRounding.AwayFromZero); + double snappedTime = timingPoint.Time + roundedBeats * beatLength; + + if (snappedTime >= 0) + return snappedTime; + + return snappedTime + beatLength; } /// From e8029e63908fff723cdabe43152ca534a1ed3f5e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 03:39:27 +0300 Subject: [PATCH 130/248] Fix unrelated tests --- osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs | 8 ++++---- osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs b/osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs index 6f3fe875e3..8ebf34b1ca 100644 --- a/osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs +++ b/osu.Game.Tests/NonVisual/ClosestBeatDivisorTest.cs @@ -17,7 +17,7 @@ namespace osu.Game.Tests.NonVisual public void TestExactDivisors() { var cpi = new ControlPointInfo(); - cpi.Add(-1000, new TimingControlPoint { BeatLength = 1000 }); + cpi.Add(0, new TimingControlPoint { BeatLength = 1000 }); double[] divisors = { 3, 1, 16, 12, 8, 6, 4, 3, 2, 1 }; @@ -47,7 +47,7 @@ namespace osu.Game.Tests.NonVisual public void TestExactDivisorsHighBPMStream() { var cpi = new ControlPointInfo(); - cpi.Add(-50, new TimingControlPoint { BeatLength = 50 }); // 1200 BPM 1/4 (limit testing) + cpi.Add(0, new TimingControlPoint { BeatLength = 50 }); // 1200 BPM 1/4 (limit testing) // A 1/4 stream should land on 1/1, 1/2 and 1/4 divisors. double[] divisors = { 4, 4, 4, 4, 4, 4, 4, 4 }; @@ -60,7 +60,7 @@ namespace osu.Game.Tests.NonVisual public void TestApproximateDivisors() { var cpi = new ControlPointInfo(); - cpi.Add(-1000, new TimingControlPoint { BeatLength = 1000 }); + cpi.Add(0, new TimingControlPoint { BeatLength = 1000 }); double[] divisors = { 3.03d, 0.97d, 14, 13, 7.94d, 6.08d, 3.93d, 2.96d, 2.02d, 64 }; double[] closestDivisors = { 3, 1, 16, 12, 8, 6, 4, 3, 2, 1 }; @@ -68,7 +68,7 @@ namespace osu.Game.Tests.NonVisual assertClosestDivisors(divisors, closestDivisors, cpi); } - private void assertClosestDivisors(IReadOnlyList divisors, IReadOnlyList closestDivisors, ControlPointInfo cpi, double step = 1) + private static void assertClosestDivisors(IReadOnlyList divisors, IReadOnlyList closestDivisors, ControlPointInfo cpi, double step = 1) { List hitobjects = new List(); double offset = cpi.TimingPoints[0].Time; diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs index 70118e0b67..b396b382ff 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs @@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual.Editing double lastStarRating = 0; double lastLength = 0; - AddStep("Add timing point", () => EditorBeatmap.ControlPointInfo.Add(500, new TimingControlPoint())); + AddStep("Add timing point", () => EditorBeatmap.ControlPointInfo.Add(200, new TimingControlPoint { BeatLength = 600 })); AddStep("Change to placement mode", () => InputManager.Key(Key.Number2)); AddStep("Move to playfield", () => InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre)); AddStep("Place single hitcircle", () => InputManager.Click(MouseButton.Left)); From 5694487a7bfbdee738a464daa4b5ae6a9b380577 Mon Sep 17 00:00:00 2001 From: tsrk Date: Thu, 12 Jan 2023 02:36:35 +0100 Subject: [PATCH 131/248] fix(SegmentedGraph): update `graphNeedsUpdate` variable during `Update()` loop --- .../UserInterface/TestSceneSegmentedGraph.cs | 24 +++++++------------ .../Graphics/UserInterface/SegmentedGraph.cs | 9 +++++-- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index f8df0528d6..a3426b36b4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -54,49 +54,43 @@ namespace osu.Game.Tests.Visual.UserInterface private void sinFunction(int size = 100) { const int max_value = 255; - int[] values = new int[size]; + graph.Values = new int[size]; float step = 2 * MathF.PI / size; float x = 0; for (int i = 0; i < size; i++) { - values[i] = (int)(max_value * MathF.Sin(x)); + graph.Values[i] = (int)(max_value * MathF.Sin(x)); x += step; } - - graph.Values = values; } private void bumps(int size = 100) { const int max_value = 255; - int[] values = new int[size]; + graph.Values = new int[size]; float step = 2 * MathF.PI / size; float x = 0; for (int i = 0; i < size; i++) { - values[i] = (int)(max_value * Math.Abs(MathF.Sin(x))); + graph.Values[i] = (int)(max_value * Math.Abs(MathF.Sin(x))); x += step; } - - graph.Values = values; } private void randomValues(int size = 100) { Random rng = new Random(); - int[] values = new int[size]; + graph.Values = new int[size]; for (int i = 0; i < size; i++) { - values[i] = rng.Next(255); + graph.Values[i] = rng.Next(255); } - - graph.Values = values; } private void beatmapDensity(int granularity = 200) @@ -106,7 +100,7 @@ namespace osu.Game.Tests.Visual.UserInterface IEnumerable objects = beatmap.HitObjects; // Taken from SongProgressGraph - int[] values = new int[granularity]; + graph.Values = new int[granularity]; if (!objects.Any()) return; @@ -128,10 +122,8 @@ namespace osu.Game.Tests.Visual.UserInterface int startRange = (int)((h.StartTime - firstHit) / interval); int endRange = (int)((endTime - firstHit) / interval); for (int i = startRange; i <= endRange; i++) - values[i]++; + graph.Values[i]++; } - - graph.Values = values; } } } diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index d0356e6327..af457edc11 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -41,9 +41,7 @@ namespace osu.Game.Graphics.UserInterface if (value == values) return; values = value; - recalculateTiers(values); graphNeedsUpdate = true; - Invalidate(Invalidation.DrawNode); } } @@ -65,8 +63,10 @@ namespace osu.Game.Graphics.UserInterface if (graphNeedsUpdate) { + recalculateTiers(values); recalculateSegments(); Invalidate(Invalidation.DrawNode); + graphNeedsUpdate = false; } } @@ -170,6 +170,11 @@ namespace osu.Game.Graphics.UserInterface /// The value is a normalized float (from 0 to 1). /// public float Length => End - Start; + + public override string ToString() + { + return $"({Tier}, {Start * 100}%, {End * 100}%)"; + } } private class SegmentedGraphDrawNode : DrawNode From f8fade79677657b8cb75886170a311fe87ccf624 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 11 Jan 2023 19:04:55 -0800 Subject: [PATCH 132/248] Add failing beatmap set lookup type test --- .../Online/TestSceneBeatmapSetOverlay.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index 7d978b9726..5d13421195 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -14,6 +14,8 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Testing; using osu.Game.Beatmaps.Drawables; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Resources.Localisation.Web; @@ -241,6 +243,44 @@ namespace osu.Game.Tests.Visual.Online AddStep(@"show without reload", overlay.Show); } + [TestCase(BeatmapSetLookupType.BeatmapId)] + [TestCase(BeatmapSetLookupType.SetId)] + public void TestFetchLookupType(BeatmapSetLookupType lookupType) + { + string type = string.Empty; + + AddStep("register request handling", () => + { + ((DummyAPIAccess)API).HandleRequest = req => + { + switch (req) + { + case GetBeatmapSetRequest getBeatmapSet: + type = getBeatmapSet.Type.ToString(); + return true; + } + + return false; + }; + }); + + AddStep(@"fetch", () => + { + switch (lookupType) + { + case BeatmapSetLookupType.BeatmapId: + overlay.FetchAndShowBeatmap(55); + break; + + case BeatmapSetLookupType.SetId: + overlay.FetchAndShowBeatmapSet(55); + break; + } + }); + + AddAssert(@"type is correct", () => type == lookupType.ToString()); + } + private APIBeatmapSet createManyDifficultiesBeatmapSet() { var set = getBeatmapSet(); From 2076f9fd087463da325eebeb39de9d84c0a5bfbf Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Wed, 11 Jan 2023 19:06:51 -0800 Subject: [PATCH 133/248] Fix lookup type being incorrect when fetching beatmap set --- osu.Game/Overlays/BeatmapSetOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 7b9b43f368..237ce22767 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -138,7 +138,7 @@ namespace osu.Game.Overlays if (lastLookup == null) return; - var req = new GetBeatmapSetRequest(lastLookup.Value.id, BeatmapSetLookupType.BeatmapId); + var req = new GetBeatmapSetRequest(lastLookup.Value.id, lastLookup.Value.type); req.Success += res => { beatmapSet.Value = res; From 425d1350e266aee4221898ab52a7e272d6840a8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jan 2023 12:31:25 +0900 Subject: [PATCH 134/248] Update README slightly to work better with new document --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 0de82eba75..f3f025fa10 100644 --- a/README.md +++ b/README.md @@ -101,9 +101,7 @@ JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it ## Contributing -When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Based on past experiences, we have prepared a [list of contributing guidelines](CONTRIBUTING.md) that should hopefully ease you into our collaboration process and answer the most frequently-asked questions. - -Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured, with any libraries we are using, or with any processes involved with contributing, *please* bring it up. We welcome all feedback so we can make contributing to this project as painless as possible. +When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Please refer to the [contributing guidelines](CONTRIBUTING.md) to understand how to help in the most effective way possible. If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web). From bbec42c00ee377535a4879f0ccbf28c2983f0b65 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 12 Jan 2023 14:18:21 +0900 Subject: [PATCH 135/248] Fix incorrect max combo after watching imported legacy replays --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 13276a8748..ff0d91c0dd 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -423,6 +423,8 @@ namespace osu.Game.Rulesets.Scoring score.Accuracy = Accuracy.Value; score.Rank = Rank.Value; score.HitEvents = hitEvents; + score.Statistics.Clear(); + score.MaximumStatistics.Clear(); foreach (var result in HitResultExtensions.ALL_TYPES) score.Statistics[result] = scoreResultCounts.GetValueOrDefault(result); From 0548ca2aa8edbcdf2eddd62bda7fe153b4899f1d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Jan 2023 09:48:38 +0300 Subject: [PATCH 136/248] Avoid changing target content midway through code --- osu.Game/OsuGameBase.cs | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index c78a527514..33d33fe181 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -206,7 +206,7 @@ namespace osu.Game /// private readonly FramedBeatmapClock beatmapClock = new FramedBeatmapClock(true); - protected override Container Content => content ?? base.Content; + protected override Container Content => content; private Container content; @@ -296,7 +296,7 @@ namespace osu.Game dependencies.Cache(ScoreDownloader = new ScoreModelDownloader(ScoreManager, API)); // Add after all the above cache operations as it depends on them. - Add(difficultyCache); + base.Content.Add(difficultyCache); // TODO: OsuGame or OsuGameBase? dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage)); @@ -305,19 +305,19 @@ namespace osu.Game dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints)); dependencies.CacheAs(soloStatisticsWatcher = new SoloStatisticsWatcher()); - Add(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); + base.Content.Add(new BeatmapOnlineChangeIngest(beatmapUpdater, realm, metadataClient)); BeatmapManager.ProcessBeatmap = args => beatmapUpdater.Process(args.beatmapSet, !args.isBatch); dependencies.Cache(userCache = new UserLookupCache()); - Add(userCache); + base.Content.Add(userCache); dependencies.Cache(beatmapCache = new BeatmapLookupCache()); - Add(beatmapCache); + base.Content.Add(beatmapCache); var scorePerformanceManager = new ScorePerformanceCache(); dependencies.Cache(scorePerformanceManager); - Add(scorePerformanceManager); + base.Content.Add(scorePerformanceManager); dependencies.CacheAs(rulesetConfigCache = new RulesetConfigCache(realm, RulesetStore)); @@ -344,34 +344,37 @@ namespace osu.Game // add api components to hierarchy. if (API is APIAccess apiAccess) - Add(apiAccess); + base.Content.Add(apiAccess); - Add(spectatorClient); - Add(MultiplayerClient); - Add(metadataClient); - Add(soloStatisticsWatcher); + base.Content.Add(spectatorClient); + base.Content.Add(MultiplayerClient); + base.Content.Add(metadataClient); + base.Content.Add(soloStatisticsWatcher); - Add(rulesetConfigCache); + base.Content.Add(rulesetConfigCache); PreviewTrackManager previewTrackManager; dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore)); - Add(previewTrackManager); + base.Content.Add(previewTrackManager); - Add(MusicController = new MusicController()); + base.Content.Add(MusicController = new MusicController()); dependencies.CacheAs(MusicController); MusicController.TrackChanged += onTrackChanged; - Add(beatmapClock); + base.Content.Add(beatmapClock); GlobalActionContainer globalBindings; - Add(SafeAreaContainer = new SafeAreaContainer + base.Content.Add(SafeAreaContainer = new SafeAreaContainer { SafeAreaOverrideEdges = SafeAreaOverrideEdges, RelativeSizeAxes = Axes.Both, Child = CreateScalingContainer().WithChildren(new Drawable[] { (GlobalCursorDisplay = new GlobalCursorDisplay + { + RelativeSizeAxes = Axes.Both + }).WithChild(content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) { RelativeSizeAxes = Axes.Both }), @@ -380,11 +383,6 @@ namespace osu.Game }) }); - GlobalCursorDisplay.Child = content = new OsuTooltipContainer(GlobalCursorDisplay.MenuCursor) - { - RelativeSizeAxes = Axes.Both - }; - KeyBindingStore = new RealmKeyBindingStore(realm, keyCombinationProvider); KeyBindingStore.Register(globalBindings, RulesetStore.AvailableRulesets); From 7cbc03dce6703b863d2c0349fe7454c247f36e5c Mon Sep 17 00:00:00 2001 From: tsrk Date: Thu, 12 Jan 2023 10:13:16 +0100 Subject: [PATCH 137/248] refactor(SegmentedGraph): use (get/set)ters to expose TierColour --- .../UserInterface/TestSceneSegmentedGraph.cs | 15 +++++--- .../Graphics/UserInterface/SegmentedGraph.cs | 38 +++++++++++++++++-- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index a3426b36b4..5c0b3e0a20 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -10,7 +10,6 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu; using osuTK; -using Vector4 = System.Numerics.Vector4; namespace osu.Game.Tests.Visual.UserInterface { @@ -22,7 +21,7 @@ namespace osu.Game.Tests.Visual.UserInterface { Children = new Drawable[] { - graph = new SegmentedGraph(10) + graph = new SegmentedGraph(6) { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, @@ -31,11 +30,15 @@ namespace osu.Game.Tests.Visual.UserInterface }, }; - for (int i = 0; i < graph.TierColours.Length; i++) + graph.TierColours = new[] { - graph.TierColours[i] = - new Colour4(Vector4.Lerp(Colour4.Blue.Vector, Colour4.White.Vector, i * 1f / (graph.TierColours.Length - 1))); - } + Colour4.Red, + Colour4.OrangeRed, + Colour4.Orange, + Colour4.Yellow, + Colour4.YellowGreen, + Colour4.Green + }; AddStep("values from 1-10", () => graph.Values = Enumerable.Range(1, 10).ToArray()); AddStep("values from 1-100", () => graph.Values = Enumerable.Range(1, 100).ToArray()); diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index af457edc11..456274e559 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -29,7 +29,7 @@ namespace osu.Game.Graphics.UserInterface public SegmentedGraph(int tierCount) { this.tierCount = tierCount; - TierColours = new Colour4[tierCount]; + tierColours = new Colour4[tierCount]; segments = new SegmentManager(tierCount); } @@ -45,7 +45,39 @@ namespace osu.Game.Graphics.UserInterface } } - public readonly Colour4[] TierColours; + private Colour4[] tierColours; + + public Colour4[] TierColours + { + get => tierColours; + set + { + if (value.Length == 0 || value == tierColours) + return; + + if (value.Length == tierCount) + { + tierColours = value; + } + else if (value.Length < tierCount) + { + var colourList = new List(value); + + for (int i = value.Length; i < tierCount; i++) + { + colourList.Add(value.Last()); + } + + tierColours = colourList.ToArray(); + } + else + { + tierColours = value[..tierCount]; + } + + graphNeedsUpdate = true; + } + } private Texture texture = null!; private IShader shader = null!; @@ -136,7 +168,7 @@ namespace osu.Game.Graphics.UserInterface segments.Sort(); } - private Colour4 getTierColour(int tier) => tier >= 0 ? TierColours[tier] : new Colour4(0, 0, 0, 0); + private Colour4 getTierColour(int tier) => tier >= 0 ? tierColours[tier] : new Colour4(0, 0, 0, 0); protected override DrawNode CreateDrawNode() => new SegmentedGraphDrawNode(this); From bb2ece5c71bed3c8ebc0f68d24e4f30ef02023c6 Mon Sep 17 00:00:00 2001 From: tsrk Date: Thu, 12 Jan 2023 10:57:12 +0100 Subject: [PATCH 138/248] refactor(SegmentedGraph): adjust tierCount based on passed Colours --- .../UserInterface/TestSceneSegmentedGraph.cs | 22 ++++++++++++++ .../Graphics/UserInterface/SegmentedGraph.cs | 30 +++++-------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs index 5c0b3e0a20..80941569af 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneSegmentedGraph.cs @@ -52,6 +52,28 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("beatmap density with granularity of 200", () => beatmapDensity()); AddStep("beatmap density with granularity of 300", () => beatmapDensity(300)); AddStep("reversed values from 1-10", () => graph.Values = Enumerable.Range(1, 10).Reverse().ToArray()); + AddStep("change colour", () => + { + graph.TierColours = new[] + { + Colour4.White, + Colour4.LightBlue, + Colour4.Aqua, + Colour4.Blue + }; + }); + AddStep("reset colour", () => + { + graph.TierColours = new[] + { + Colour4.Red, + Colour4.OrangeRed, + Colour4.Orange, + Colour4.Yellow, + Colour4.YellowGreen, + Colour4.Green + }; + }); } private void sinFunction(int size = 100) diff --git a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs index 456274e559..8ccba710b8 100644 --- a/osu.Game/Graphics/UserInterface/SegmentedGraph.cs +++ b/osu.Game/Graphics/UserInterface/SegmentedGraph.cs @@ -24,12 +24,15 @@ namespace osu.Game.Graphics.UserInterface private int[] tiers = Array.Empty(); private readonly SegmentManager segments; - private readonly int tierCount; + private int tierCount; - public SegmentedGraph(int tierCount) + public SegmentedGraph(int tierCount = 1) { this.tierCount = tierCount; - tierColours = new Colour4[tierCount]; + tierColours = new[] + { + new Colour4(0, 0, 0, 0) + }; segments = new SegmentManager(tierCount); } @@ -55,25 +58,8 @@ namespace osu.Game.Graphics.UserInterface if (value.Length == 0 || value == tierColours) return; - if (value.Length == tierCount) - { - tierColours = value; - } - else if (value.Length < tierCount) - { - var colourList = new List(value); - - for (int i = value.Length; i < tierCount; i++) - { - colourList.Add(value.Last()); - } - - tierColours = colourList.ToArray(); - } - else - { - tierColours = value[..tierCount]; - } + tierCount = value.Length; + tierColours = value; graphNeedsUpdate = true; } From b0385123795ea37dffb2b42fe7135cc37ee6ebb4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jan 2023 22:14:41 +0900 Subject: [PATCH 139/248] Remove `CFBundleVersion` from iOS plist file This allows using `-p:ApplicationVersion:1234.5.6` to specify a version at build / publish time. Without removing it the plist file's value always takes precedence. --- osu.iOS/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index c4b08ab78e..8bddce4ad2 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -10,8 +10,6 @@ osu! CFBundleShortVersionString 0.1 - CFBundleVersion - 0.1.0 LSRequiresIPhoneOS MinimumOSVersion From f77db12c1e1ee34c307aafa4c834485d779075c6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 12 Jan 2023 23:09:43 +0900 Subject: [PATCH 140/248] Also remove `CFBundleShortVersionString` --- osu.iOS/Info.plist | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist index 8bddce4ad2..0ce1d952d0 100644 --- a/osu.iOS/Info.plist +++ b/osu.iOS/Info.plist @@ -8,8 +8,6 @@ osu! CFBundleDisplayName osu! - CFBundleShortVersionString - 0.1 LSRequiresIPhoneOS MinimumOSVersion From 2365b065a4994f38fe67bab7d193e5a09bee538c Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 18:07:54 +0300 Subject: [PATCH 141/248] Enable nullability for editor components --- osu.Game/Screens/Edit/Components/BottomBarContainer.cs | 2 -- osu.Game/Screens/Edit/Components/EditorSidebar.cs | 2 -- .../Screens/Edit/Components/EditorSidebarSection.cs | 2 -- .../Components/Menus/EditorScreenSwitcherControl.cs | 4 +--- osu.Game/Screens/Edit/Components/PlaybackControl.cs | 8 +++----- .../Edit/Components/RadioButtons/EditorRadioButton.cs | 10 ++++------ .../RadioButtons/EditorRadioButtonCollection.cs | 7 +++---- .../Edit/Components/RadioButtons/RadioButton.cs | 8 +++----- .../Components/TernaryButtons/DrawableTernaryButton.cs | 4 +--- .../Edit/Components/TernaryButtons/TernaryButton.cs | 6 ++---- osu.Game/Screens/Edit/Components/TimeInfoContainer.cs | 10 ++++------ .../Components/Timelines/Summary/Parts/BookmarkPart.cs | 2 -- .../Components/Timelines/Summary/Parts/BreakPart.cs | 2 -- .../Timelines/Summary/Parts/ControlPointPart.cs | 2 -- .../Summary/Parts/ControlPointVisualisation.cs | 2 -- .../Timelines/Summary/Parts/GroupVisualisation.cs | 2 -- .../Summary/Parts/IControlPointVisualisation.cs | 2 -- .../Components/Timelines/Summary/Parts/MarkerPart.cs | 8 +++----- .../Components/Timelines/Summary/Parts/TimelinePart.cs | 6 ++---- .../Components/Timelines/Summary/SummaryTimeline.cs | 2 -- .../Components/Timelines/Summary/TestGameplayButton.cs | 2 -- .../Summary/Visualisations/DurationVisualisation.cs | 2 -- .../Summary/Visualisations/PointVisualisation.cs | 2 -- .../Components/Timeline/TimelineHitObjectBlueprint.cs | 2 +- 24 files changed, 27 insertions(+), 72 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 32ec3b6833..0ba1ab9258 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; diff --git a/osu.Game/Screens/Edit/Components/EditorSidebar.cs b/osu.Game/Screens/Edit/Components/EditorSidebar.cs index cfcfcd75e6..9a8c5115dd 100644 --- a/osu.Game/Screens/Edit/Components/EditorSidebar.cs +++ b/osu.Game/Screens/Edit/Components/EditorSidebar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs b/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs index 4e8c55efa1..279793c0a1 100644 --- a/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs +++ b/osu.Game/Screens/Edit/Components/EditorSidebarSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs index e88138def4..3d51874082 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; @@ -38,7 +36,7 @@ namespace osu.Game.Screens.Edit.Components.Menus }); } - protected override Dropdown CreateDropdown() => null; + protected override Dropdown CreateDropdown() => null!; protected override TabItem CreateTabItem(EditorScreenMode value) => new TabItem(value); diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index f403551a62..87cbcb8aff 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osuTK; using osuTK.Graphics; @@ -25,10 +23,10 @@ namespace osu.Game.Screens.Edit.Components { public partial class PlaybackControl : BottomBarContainer { - private IconButton playButton; + private IconButton playButton = null!; [Resolved] - private EditorClock editorClock { get; set; } + private EditorClock editorClock { get; set; } = null!; private readonly BindableNumber freqAdjust = new BindableDouble(1); @@ -108,7 +106,7 @@ namespace osu.Game.Screens.Edit.Components protected override TabItem CreateTabItem(double value) => new PlaybackTabItem(value); - protected override Dropdown CreateDropdown() => null; + protected override Dropdown CreateDropdown() => null!; public PlaybackTabControl() { diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs index bfcc0084bd..65f3e41c13 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -24,7 +22,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons /// /// Invoked when this has been selected. /// - public Action Selected; + public Action? Selected; public readonly RadioButton Button; @@ -33,10 +31,10 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons private Color4 selectedBackgroundColour; private Color4 selectedIconColour; - private Drawable icon; + private Drawable icon = null!; - [Resolved(canBeNull: true)] - private EditorBeatmap editorBeatmap { get; set; } + [Resolved] + private EditorBeatmap? editorBeatmap { get; set; } public EditorRadioButton(RadioButton button) { diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs index 92dd47dc81..4391729adc 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/EditorRadioButtonCollection.cs @@ -1,8 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using System; using System.Collections.Generic; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; @@ -13,7 +12,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons { public partial class EditorRadioButtonCollection : CompositeDrawable { - private IReadOnlyList items; + private IReadOnlyList items = Array.Empty(); public IReadOnlyList Items { @@ -45,7 +44,7 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons }; } - private RadioButton currentlySelected; + private RadioButton? currentlySelected; private void addButton(RadioButton button) { diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs index 03745ce19d..9dcd29bf83 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -24,11 +22,11 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons /// /// A function which creates a drawable icon to represent this item. If null, a sane default should be used. /// - public readonly Func CreateIcon; + public readonly Func? CreateIcon; - private readonly Action action; + private readonly Action? action; - public RadioButton(string label, Action action, Func createIcon = null) + public RadioButton(string label, Action? action, Func? createIcon = null) { Label = label; CreateIcon = createIcon; diff --git a/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs b/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs index 45b7cd1b7c..873551db77 100644 --- a/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs +++ b/osu.Game/Screens/Edit/Components/TernaryButtons/DrawableTernaryButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -23,7 +21,7 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons private Color4 selectedBackgroundColour; private Color4 selectedIconColour; - private Drawable icon; + private Drawable icon = null!; public readonly TernaryButton Button; diff --git a/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs b/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs index 8eb781c947..0ff2aa83b5 100644 --- a/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs +++ b/osu.Game/Screens/Edit/Components/TernaryButtons/TernaryButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -19,9 +17,9 @@ namespace osu.Game.Screens.Edit.Components.TernaryButtons /// /// A function which creates a drawable icon to represent this item. If null, a sane default should be used. /// - public readonly Func CreateIcon; + public readonly Func? CreateIcon; - public TernaryButton(Bindable bindable, string description, Func createIcon = null) + public TernaryButton(Bindable bindable, string description, Func? createIcon = null) { Bindable = bindable; Description = description; diff --git a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs index 1c16671ce4..9c51258f17 100644 --- a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs +++ b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Graphics.Sprites; using osu.Framework.Allocation; @@ -15,14 +13,14 @@ namespace osu.Game.Screens.Edit.Components { public partial class TimeInfoContainer : BottomBarContainer { - private OsuSpriteText trackTimer; - private OsuSpriteText bpm; + private OsuSpriteText trackTimer = null!; + private OsuSpriteText bpm = null!; [Resolved] - private EditorBeatmap editorBeatmap { get; set; } + private EditorBeatmap editorBeatmap { get; set; } = null!; [Resolved] - private EditorClock editorClock { get; set; } + private EditorClock editorClock { get; set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colours, OverlayColourProvider colourProvider) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs index f1023ade8c..3102bf7c06 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BookmarkPart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs index de5d074c51..e502dd951b 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/BreakPart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Beatmaps.Timing; using osu.Game.Graphics; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs index 111ba0b732..6f53f710ba 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointPart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Specialized; using System.Diagnostics; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs index aa494271f8..12620963e1 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/ControlPointVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs index 64c0745596..b39365277f 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/GroupVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/IControlPointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/IControlPointVisualisation.cs index b9e2a969a5..c81f1828f7 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/IControlPointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/IControlPointVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index 5be6db55a4..d42c02e03d 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; @@ -20,10 +18,10 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// public partial class MarkerPart : TimelinePart { - private Drawable marker; + private Drawable marker = null!; [Resolved] - private EditorClock editorClock { get; set; } + private EditorClock editorClock { get; set; } = null!; [BackgroundDependencyLoader] private void load() @@ -44,7 +42,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return true; } - private ScheduledDelegate scheduledSeek; + private ScheduledDelegate? scheduledSeek; /// /// Seeks the to the time closest to a position on the screen relative to the . diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index e380a2063b..ee7e759ebc 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Audio.Track; @@ -26,7 +24,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts private readonly IBindable beatmap = new Bindable(); [Resolved] - protected EditorBeatmap EditorBeatmap { get; private set; } + protected EditorBeatmap EditorBeatmap { get; private set; } = null!; protected readonly IBindable Track = new Bindable(); @@ -34,7 +32,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts protected override Container Content => content; - public TimelinePart(Container content = null) + public TimelinePart(Container? content = null) { AddInternal(this.content = content ?? new Container { RelativeSizeAxes = Axes.Both }); diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index 075d47d82e..6199cefb57 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs index a3a003947c..9b45464e81 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs index 6fc994b8b1..bfb50a05ea 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/DurationVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs index 75dacdf3e7..3f0c125ada 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 03e67306df..4e5087c004 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -291,7 +291,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private Timeline timeline { get; set; } = null!; - [Resolved(CanBeNull = true)] + [Resolved] private IEditorChangeHandler? changeHandler { get; set; } private ScheduledDelegate? dragOperation; From 0bd1c46c7481fbac28933810195f5a9a8a2a2d0d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Thu, 12 Jan 2023 19:48:11 +0300 Subject: [PATCH 142/248] Undo sizing changes --- .../Comments/CancellableCommentEditor.cs | 8 +----- osu.Game/Overlays/Comments/CommentEditor.cs | 28 ++++++++++++++----- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index 7418ba344b..02abc5b6cf 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -3,8 +3,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Graphics.UserInterfaceV2; using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Comments @@ -16,14 +14,10 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load() { - ButtonsContainer.Add(new RoundedButton + ButtonsContainer.Add(new EditorButton { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, Action = () => OnCancel?.Invoke(), Text = CommonStrings.ButtonsCancel, - Width = 100, - Height = 30, }); } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 906ff0c4a2..769263b3fc 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.Comments { Name = @"Footer", RelativeSizeAxes = Axes.X, - Height = 40, + Height = 35, Padding = new MarginPadding { Horizontal = side_padding }, Children = new Drawable[] { @@ -93,7 +93,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold), + Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), Text = FooterText }, new FillFlowContainer @@ -113,13 +113,9 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(5, 0), - Child = commitButton = new RoundedButton + Child = commitButton = new EditorButton { - Width = 100, - Height = 30, Text = CommitButtonText, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, Action = () => OnCommit(Current.Value) } }, @@ -184,5 +180,23 @@ namespace osu.Game.Overlays.Comments Child = new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) } }; } + + protected partial class EditorButton : RoundedButton + { + public EditorButton() + { + Width = 80; + Height = 25; + Anchor = Anchor.CentreRight; + Origin = Anchor.CentreRight; + } + + protected override SpriteText CreateText() + { + var t = base.CreateText(); + t.Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 12); + return t; + } + } } } From a9915d6a6419405f304da760cd2d05b6a6877815 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Jan 2023 22:44:41 +0300 Subject: [PATCH 143/248] Make OverlayRulesetSelector display only legacy rulesets --- osu.Game/Overlays/OverlayRulesetSelector.cs | 1 + osu.Game/Rulesets/RulesetSelector.cs | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index bcce2ce433..daef2edc4a 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -14,6 +14,7 @@ namespace osu.Game.Overlays public partial class OverlayRulesetSelector : RulesetSelector { public OverlayRulesetSelector() + : base(true) { AutoSizeAxes = Axes.Both; } diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index 062f8d6450..91fc89b164 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -16,11 +16,23 @@ namespace osu.Game.Rulesets protected override Dropdown CreateDropdown() => null; + private readonly bool legacyOnly; + + public RulesetSelector(bool legacyOnly = false) + { + this.legacyOnly = legacyOnly; + } + [BackgroundDependencyLoader] private void load() { foreach (var ruleset in Rulesets.AvailableRulesets) { + int id = ruleset.OnlineID; + + if ((id < 0 || id > 3) && legacyOnly) + continue; + try { AddItem(ruleset); From 1dae1149cb458f4e0aac468f0f1f76dbc20c3ec1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Jan 2023 22:52:45 +0300 Subject: [PATCH 144/248] Don't display non-legacy rulesets in beatmap listing --- .../BeatmapListing/BeatmapSearchRulesetFilterRow.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs index fa37810f37..88a62701fc 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs @@ -28,7 +28,14 @@ namespace osu.Game.Overlays.BeatmapListing AddTabItem(new RulesetFilterTabItemAny()); foreach (var r in rulesets.AvailableRulesets) + { + // Don't display non-legacy rulesets + int id = r.OnlineID; + if (id < 0 || id > 3) + continue; + AddItem(r); + } } } From 115cb0d2973ab96a5ccb62fd11981b15ef1db6b5 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Jan 2023 23:14:21 +0300 Subject: [PATCH 145/248] Fix channel manager test scene not waiting for notifications client connection --- osu.Game.Tests/Chat/TestSceneChannelManager.cs | 2 ++ osu.Game/Online/Chat/ChannelManager.cs | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/osu.Game.Tests/Chat/TestSceneChannelManager.cs b/osu.Game.Tests/Chat/TestSceneChannelManager.cs index cdd192cfe1..3a4c55c65c 100644 --- a/osu.Game.Tests/Chat/TestSceneChannelManager.cs +++ b/osu.Game.Tests/Chat/TestSceneChannelManager.cs @@ -75,6 +75,8 @@ namespace osu.Game.Tests.Chat return false; }; }); + + AddUntilStep("wait for notifications client", () => channelManager.NotificationsConnected); } [Test] diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 1e3921bac0..7ab678775f 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -64,6 +64,11 @@ namespace osu.Game.Online.Chat /// public IBindableList AvailableChannels => availableChannels; + /// + /// Whether the client responsible for channel notifications is connected. + /// + public bool NotificationsConnected => connector.IsConnected.Value; + private readonly IAPIProvider api; private readonly NotificationsClientConnector connector; From a7ac31fa3435a90be9f7483ed93d081c32bf9e6e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Jan 2023 23:21:33 +0300 Subject: [PATCH 146/248] Use IsLegacyRuleset extension method --- .../Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs | 4 ++-- osu.Game/Rulesets/RulesetSelector.cs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs index 88a62701fc..96626d0ac6 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; +using osu.Game.Extensions; using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets; @@ -30,8 +31,7 @@ namespace osu.Game.Overlays.BeatmapListing foreach (var r in rulesets.AvailableRulesets) { // Don't display non-legacy rulesets - int id = r.OnlineID; - if (id < 0 || id > 3) + if (!r.IsLegacyRuleset()) continue; AddItem(r); diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index 91fc89b164..1451f0d55d 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Framework.Allocation; using osu.Framework.Logging; +using osu.Game.Extensions; namespace osu.Game.Rulesets { @@ -28,9 +29,7 @@ namespace osu.Game.Rulesets { foreach (var ruleset in Rulesets.AvailableRulesets) { - int id = ruleset.OnlineID; - - if ((id < 0 || id > 3) && legacyOnly) + if (!ruleset.IsLegacyRuleset() && legacyOnly) continue; try From d74a5ef9e6e76da206e3f68fcb15eeec09418b3d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 12 Jan 2023 23:26:29 +0300 Subject: [PATCH 147/248] Use property instead of ctor parameter --- osu.Game/Overlays/OverlayRulesetSelector.cs | 4 +++- osu.Game/Rulesets/RulesetSelector.cs | 9 ++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index daef2edc4a..b9274231b0 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -13,8 +13,10 @@ namespace osu.Game.Overlays { public partial class OverlayRulesetSelector : RulesetSelector { + // Since this component is used in online overlays and currently web-side doesn't support non-legacy rulesets - let's disable them for now. + protected override bool LegacyOnly => true; + public OverlayRulesetSelector() - : base(true) { AutoSizeAxes = Axes.Both; } diff --git a/osu.Game/Rulesets/RulesetSelector.cs b/osu.Game/Rulesets/RulesetSelector.cs index 1451f0d55d..ba10033a98 100644 --- a/osu.Game/Rulesets/RulesetSelector.cs +++ b/osu.Game/Rulesets/RulesetSelector.cs @@ -17,19 +17,14 @@ namespace osu.Game.Rulesets protected override Dropdown CreateDropdown() => null; - private readonly bool legacyOnly; - - public RulesetSelector(bool legacyOnly = false) - { - this.legacyOnly = legacyOnly; - } + protected virtual bool LegacyOnly => false; [BackgroundDependencyLoader] private void load() { foreach (var ruleset in Rulesets.AvailableRulesets) { - if (!ruleset.IsLegacyRuleset() && legacyOnly) + if (!ruleset.IsLegacyRuleset() && LegacyOnly) continue; try From a16050534d3a72c7225d5ecff22ea82e7be59c60 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 12 Jan 2023 14:20:16 -0800 Subject: [PATCH 148/248] Fix mute button not blocking outside overlay closing presses --- osu.Game/Overlays/Volume/MuteButton.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 9cc346a38b..5acbbd2803 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -88,5 +88,11 @@ namespace osu.Game.Overlays.Volume { Content.TransformTo, ColourInfo>("BorderColour", unhoveredColour, 500, Easing.OutQuint); } + + protected override bool OnMouseDown(MouseDownEvent e) + { + base.OnMouseDown(e); + return true; + } } } From c554a34eaf8ebeedf306a2192f980d2f3774c77b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 13 Jan 2023 02:11:05 +0300 Subject: [PATCH 149/248] Add "fps" keyword to frame limiter dropdown --- .../Overlays/Settings/Sections/Graphics/RendererSettings.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs index 775606caf0..a5fdfdc105 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs @@ -27,7 +27,8 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics new SettingsEnumDropdown { LabelText = GraphicsSettingsStrings.FrameLimiter, - Current = config.GetBindable(FrameworkSetting.FrameSync) + Current = config.GetBindable(FrameworkSetting.FrameSync), + Keywords = new[] { @"fps" }, }, new SettingsEnumDropdown { From 403ca05e5e61aeecb19ce9afeb59ca91bf2a49db Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 13 Jan 2023 00:52:14 +0100 Subject: [PATCH 150/248] Enable nullability for song select --- .../Multiplayer/MultiplayerMatchSongSelect.cs | 2 + .../OnlinePlay/OnlinePlaySongSelect.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 155 ++++++++++-------- 3 files changed, 87 insertions(+), 72 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index 873a1b0d50..6a4ce7aff5 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -105,6 +106,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Schedule(() => { + Debug.Assert(Carousel != null); Carousel.AllowSelection = true; }); }); diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs index b9d8912170..e0ae437d49 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs @@ -173,7 +173,7 @@ namespace osu.Game.Screens.OnlinePlay IsValidMod = IsValidMod }; - protected override IEnumerable<(FooterButton, OverlayContainer)> CreateFooterButtons() + protected override IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() { var buttons = base.CreateFooterButtons().ToList(); buttons.Insert(buttons.FindIndex(b => b.Item1 is FooterButtonMods) + 1, (new FooterButtonFreeMods { Current = FreeMods }, freeModSelectOverlay)); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f4804c6a6c..6826dffd5f 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -36,7 +34,6 @@ using osu.Framework.Input.Bindings; using osu.Game.Collections; using osu.Game.Graphics.UserInterface; using System.Diagnostics; -using JetBrains.Annotations; using osu.Game.Screens.Play; using osu.Game.Skinning; @@ -49,7 +46,7 @@ namespace osu.Game.Screens.Select protected const float BACKGROUND_BLUR = 20; private const float left_area_padding = 20; - public FilterControl FilterControl { get; private set; } + public FilterControl FilterControl { get; private set; } = null!; /// /// Whether this song select instance should take control of the global track, @@ -64,18 +61,18 @@ namespace osu.Game.Screens.Select /// /// Can be null if is false. /// - protected BeatmapOptionsOverlay BeatmapOptions { get; private set; } + protected BeatmapOptionsOverlay BeatmapOptions { get; private set; } = null!; /// /// Can be null if is false. /// - protected Footer Footer { get; private set; } + protected Footer? Footer { get; private set; } /// /// Contains any panel which is triggered by a footer button. /// Helps keep them located beneath the footer itself. /// - protected Container FooterPanels { get; private set; } + protected Container FooterPanels { get; private set; } = null!; /// /// Whether entering editor mode should be allowed. @@ -85,50 +82,49 @@ namespace osu.Game.Screens.Select public bool BeatmapSetsLoaded => IsLoaded && Carousel?.BeatmapSetsLoaded == true; [Resolved] - private Bindable> selectedMods { get; set; } + private Bindable> selectedMods { get; set; } = null!; - protected BeatmapCarousel Carousel { get; private set; } + protected BeatmapCarousel? Carousel { get; private set; } - private ParallaxContainer wedgeBackground; + private ParallaxContainer wedgeBackground = null!; - protected Container LeftArea { get; private set; } + protected Container LeftArea { get; private set; } = null!; - private BeatmapInfoWedge beatmapInfoWedge; - - [Resolved(canBeNull: true)] - private IDialogOverlay dialogOverlay { get; set; } + private BeatmapInfoWedge beatmapInfoWedge = null!; [Resolved] - private BeatmapManager beatmaps { get; set; } + private IDialogOverlay? dialogOverlay { get; set; } - protected ModSelectOverlay ModSelect { get; private set; } + [Resolved] + private BeatmapManager beatmaps { get; set; } = null!; - protected Sample SampleConfirm { get; private set; } + protected ModSelectOverlay ModSelect { get; private set; } = null!; - private Sample sampleChangeDifficulty; - private Sample sampleChangeBeatmap; + protected Sample? SampleConfirm { get; private set; } - private Container carouselContainer; + private Sample sampleChangeDifficulty = null!; + private Sample sampleChangeBeatmap = null!; - protected BeatmapDetailArea BeatmapDetails { get; private set; } + private Container carouselContainer = null!; - private FooterButtonOptions beatmapOptionsButton; + protected BeatmapDetailArea BeatmapDetails { get; private set; } = null!; + + private FooterButtonOptions beatmapOptionsButton = null!; private readonly Bindable decoupledRuleset = new Bindable(); private double audioFeedbackLastPlaybackTime; - [CanBeNull] - private IDisposable modSelectOverlayRegistration; + private IDisposable? modSelectOverlayRegistration; [Resolved] - private MusicController music { get; set; } + private MusicController? music { get; set; } - [Resolved(CanBeNull = true)] - internal IOverlayManager OverlayManager { get; private set; } + [Resolved] + internal IOverlayManager? OverlayManager { get; private set; } [BackgroundDependencyLoader(true)] - private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog manageCollectionsDialog, DifficultyRecommender recommender) + private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog? manageCollectionsDialog, DifficultyRecommender? recommender) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). transferRulesetValue(); @@ -273,7 +269,7 @@ namespace osu.Game.Screens.Select BeatmapOptions = new BeatmapOptionsOverlay(), } }, - Footer = new Footer(), + Footer = new Footer() }); } @@ -318,16 +314,20 @@ namespace osu.Game.Screens.Select /// Creates the buttons to be displayed in the footer. /// /// A set of and an optional which the button opens when pressed. - protected virtual IEnumerable<(FooterButton, OverlayContainer)> CreateFooterButtons() => new (FooterButton, OverlayContainer)[] + protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() { - (new FooterButtonMods { Current = Mods }, ModSelect), - (new FooterButtonRandom + Debug.Assert(Carousel != null); + return new (FooterButton, OverlayContainer?)[] { - NextRandom = () => Carousel.SelectNextRandom(), - PreviousRandom = Carousel.SelectPreviousRandom - }, null), - (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) - }; + (new FooterButtonMods { Current = Mods }, ModSelect), + (new FooterButtonRandom + { + NextRandom = () => Carousel.SelectNextRandom(), + PreviousRandom = Carousel.SelectPreviousRandom + }, null), + (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) + }; + } protected virtual ModSelectOverlay CreateModSelectOverlay() => new SoloModSelectOverlay(); @@ -336,10 +336,11 @@ namespace osu.Game.Screens.Select // if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter). bool shouldDebounce = this.IsCurrentScreen(); + Debug.Assert(Carousel != null); Carousel.Filter(criteria, shouldDebounce); } - private DependencyContainer dependencies; + private DependencyContainer dependencies = null!; protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { @@ -357,7 +358,7 @@ namespace osu.Game.Screens.Select /// protected abstract BeatmapDetailArea CreateBeatmapDetailArea(); - public void Edit(BeatmapInfo beatmapInfo = null) + public void Edit(BeatmapInfo? beatmapInfo = null) { if (!AllowEditing) throw new InvalidOperationException($"Attempted to edit when {nameof(AllowEditing)} is disabled"); @@ -372,8 +373,10 @@ namespace osu.Game.Screens.Select /// An optional beatmap to override the current carousel selection. /// An optional ruleset to override the current carousel selection. /// An optional custom action to perform instead of . - public void FinaliseSelection(BeatmapInfo beatmapInfo = null, RulesetInfo ruleset = null, Action customStartAction = null) + public void FinaliseSelection(BeatmapInfo? beatmapInfo = null, RulesetInfo? ruleset = null, Action? customStartAction = null) { + Debug.Assert(Carousel != null); + // This is very important as we have not yet bound to screen-level bindables before the carousel load is completed. if (!Carousel.BeatmapSetsLoaded) { @@ -419,43 +422,44 @@ namespace osu.Game.Screens.Select /// If a resultant action occurred that takes the user away from SongSelect. protected abstract bool OnStart(); - private ScheduledDelegate selectionChangedDebounce; + private ScheduledDelegate? selectionChangedDebounce; - private void updateCarouselSelection(ValueChangedEvent e = null) + private void updateCarouselSelection(ValueChangedEvent? e = null) { var beatmap = e?.NewValue ?? Beatmap.Value; if (beatmap is DummyWorkingBeatmap || !this.IsCurrentScreen()) return; Logger.Log($"Song select working beatmap updated to {beatmap}"); - if (!Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) + Debug.Assert(Carousel != null); + + if (Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) return; + + // A selection may not have been possible with filters applied. + + // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. + if (!beatmap.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) { - // A selection may not have been possible with filters applied. - - // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. - if (!beatmap.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) - { - Ruleset.Value = beatmap.BeatmapInfo.Ruleset; - transferRulesetValue(); - } - - // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), - // we still want to temporarily show the new beatmap, bypassing filters. - // This will be undone the next time the user changes the filter. - var criteria = FilterControl.CreateCriteria(); - criteria.SelectedBeatmapSet = beatmap.BeatmapInfo.BeatmapSet; - Carousel.Filter(criteria); - - Carousel.SelectBeatmap(beatmap.BeatmapInfo); + Ruleset.Value = beatmap.BeatmapInfo.Ruleset; + transferRulesetValue(); } + + // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), + // we still want to temporarily show the new beatmap, bypassing filters. + // This will be undone the next time the user changes the filter. + var criteria = FilterControl.CreateCriteria(); + criteria.SelectedBeatmapSet = beatmap.BeatmapInfo.BeatmapSet; + Carousel.Filter(criteria); + + Carousel.SelectBeatmap(beatmap.BeatmapInfo); } // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. - private BeatmapInfo beatmapInfoPrevious; - private BeatmapInfo beatmapInfoNoDebounce; - private RulesetInfo rulesetNoDebounce; + private BeatmapInfo? beatmapInfoPrevious; + private BeatmapInfo? beatmapInfoNoDebounce; + private RulesetInfo? rulesetNoDebounce; - private void updateSelectedBeatmap(BeatmapInfo beatmapInfo) + private void updateSelectedBeatmap(BeatmapInfo? beatmapInfo) { if (beatmapInfo == null && beatmapInfoNoDebounce == null) return; @@ -467,7 +471,7 @@ namespace osu.Game.Screens.Select performUpdateSelected(); } - private void updateSelectedRuleset(RulesetInfo ruleset) + private void updateSelectedRuleset(RulesetInfo? ruleset) { if (ruleset == null && rulesetNoDebounce == null) return; @@ -485,7 +489,7 @@ namespace osu.Game.Screens.Select private void performUpdateSelected() { var beatmap = beatmapInfoNoDebounce; - var ruleset = rulesetNoDebounce; + RulesetInfo? ruleset = rulesetNoDebounce; selectionChangedDebounce?.Cancel(); @@ -518,6 +522,7 @@ namespace osu.Game.Screens.Select if (transferRulesetValue()) { + Debug.Assert(Carousel != null); // transferRulesetValue() may trigger a re-filter. If the current selection does not match the new ruleset, we want to switch away from it. // The default logic on WorkingBeatmap change is to switch to a matching ruleset (see workingBeatmapChanged()), but we don't want that here. // We perform an early selection attempt and clear out the beatmap selection to avoid a second ruleset change (revert). @@ -604,6 +609,7 @@ namespace osu.Game.Screens.Select ModSelect.SelectedMods.Disabled = false; ModSelect.SelectedMods.BindTo(selectedMods); + Debug.Assert(Carousel != null); Carousel.AllowSelection = true; BeatmapDetails.Refresh(); @@ -620,6 +626,7 @@ namespace osu.Game.Screens.Select { // restart playback on returning to song select, regardless. // not sure this should be a permanent thing (we may want to leave a user pause paused even on returning) + Debug.Assert(music != null); music.ResetTrackAdjustments(); music.Play(requestedByUser: true); } @@ -665,6 +672,7 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); + Debug.Assert(Carousel != null); Carousel.AllowSelection = false; endLooping(); @@ -694,6 +702,8 @@ namespace osu.Game.Screens.Select isHandlingLooping = true; ensureTrackLooping(Beatmap.Value, TrackChangeDirection.None); + + Debug.Assert(music != null); music.TrackChanged += ensureTrackLooping; } @@ -703,6 +713,7 @@ namespace osu.Game.Screens.Select if (!isHandlingLooping) return; + Debug.Assert(music != null); music.CurrentTrack.Looping = isHandlingLooping = false; music.TrackChanged -= ensureTrackLooping; @@ -763,7 +774,7 @@ namespace osu.Game.Screens.Select } } - private readonly WeakReference lastTrack = new WeakReference(null); + private readonly WeakReference lastTrack = new WeakReference(null); /// /// Ensures some music is playing for the current track. @@ -774,6 +785,7 @@ namespace osu.Game.Screens.Select if (!ControlGlobalMusic) return; + Debug.Assert(music != null); ITrack track = music.CurrentTrack; bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; @@ -791,6 +803,7 @@ namespace osu.Game.Screens.Select { bindBindables(); + Debug.Assert(Carousel != null); Carousel.AllowSelection = true; // If a selection was already obtained, do not attempt to update the selected beatmap. @@ -868,14 +881,14 @@ namespace osu.Game.Screens.Select return true; } - private void delete(BeatmapSetInfo beatmap) + private void delete(BeatmapSetInfo? beatmap) { if (beatmap == null) return; dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap)); } - private void clearScores(BeatmapInfo beatmapInfo) + private void clearScores(BeatmapInfo? beatmapInfo) { if (beatmapInfo == null) return; @@ -950,7 +963,7 @@ namespace osu.Game.Screens.Select private partial class ResetScrollContainer : Container { - private readonly Action onHoverAction; + private readonly Action? onHoverAction; public ResetScrollContainer(Action onHoverAction) { From 464c5eaa2f430dd293df5f5fb016a0dbce064082 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 12:16:35 +0900 Subject: [PATCH 151/248] Fix grammar --- osu.Game/Overlays/OverlayRulesetSelector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index b9274231b0..9205a14d9f 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays { public partial class OverlayRulesetSelector : RulesetSelector { - // Since this component is used in online overlays and currently web-side doesn't support non-legacy rulesets - let's disable them for now. + // Since this component is used in online overlays and currently web-side doesn't support non-legacy rulesets, let's disable them for now. protected override bool LegacyOnly => true; public OverlayRulesetSelector() From d8e0e67c458d2955b4f1dfc0d5165a2a2102bf10 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 12:26:45 +0900 Subject: [PATCH 152/248] Add default version specifications to iOS csproj file Matches implementation for android. --- osu.iOS/osu.iOS.csproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index def538af1a..fa4c61372f 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -4,6 +4,9 @@ 13.4 Exe true + 0.0.0 + 1 + $(Version) From 5a38abe67923ab550a3b60936b864d544d09893b Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Thu, 12 Jan 2023 19:32:53 -0800 Subject: [PATCH 153/248] Add comment highlighting reason for blocking mouse down --- osu.Game/Overlays/Volume/MuteButton.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 5acbbd2803..c83ad4ac0d 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -92,6 +92,8 @@ namespace osu.Game.Overlays.Volume protected override bool OnMouseDown(MouseDownEvent e) { base.OnMouseDown(e); + + // Block mouse down to avoid dismissing overlays sitting behind the mute button return true; } } From bdf901e490ca972a7142bd947a48a68a090e935e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:27:56 +0900 Subject: [PATCH 154/248] Use more correct default version to avoid startup crash on attempting to parse --- osu.iOS/osu.iOS.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index fa4c61372f..9a31525517 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -4,8 +4,8 @@ 13.4 Exe true - 0.0.0 - 1 + 1.0.0 + $(Version) $(Version) From 5658c3a12325035c3a751fcaf4fcc092ee5c4faa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:20:18 +0900 Subject: [PATCH 155/248] Enable NRT on account creation classes --- osu.Game/Online/API/RegistrationRequest.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game/Online/API/RegistrationRequest.cs b/osu.Game/Online/API/RegistrationRequest.cs index 6dc867481a..dfedaa30e0 100644 --- a/osu.Game/Online/API/RegistrationRequest.cs +++ b/osu.Game/Online/API/RegistrationRequest.cs @@ -1,17 +1,16 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using System; using Newtonsoft.Json; namespace osu.Game.Online.API { public class RegistrationRequest : OsuWebRequest { - internal string Username; - internal string Email; - internal string Password; + internal string Username = string.Empty; + internal string Email = string.Empty; + internal string Password = string.Empty; protected override void PrePerform() { @@ -24,18 +23,18 @@ namespace osu.Game.Online.API public class RegistrationRequestErrors { - public UserErrors User; + public UserErrors? User; public class UserErrors { [JsonProperty("username")] - public string[] Username; + public string[] Username = Array.Empty(); [JsonProperty("user_email")] - public string[] Email; + public string[] Email = Array.Empty(); [JsonProperty("password")] - public string[] Password; + public string[] Password = Array.Empty(); } } } From a7327b02a2b3ecb2df7713ed86dc3a0e12ac83e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:32:53 +0900 Subject: [PATCH 156/248] Add API level support for error message and redirect during registration flow --- osu.Game/Online/API/APIAccess.cs | 29 +++++++++++++++++++--- osu.Game/Online/API/RegistrationRequest.cs | 10 ++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 757f6598e7..94bb77d6ec 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -329,12 +329,35 @@ namespace osu.Game.Online.API { try { - return JObject.Parse(req.GetResponseString().AsNonNull()).SelectToken("form_error", true).AsNonNull().ToObject(); + return JObject.Parse(req.GetResponseString().AsNonNull()).SelectToken(@"form_error", true).AsNonNull().ToObject(); } catch { - // if we couldn't deserialize the error message let's throw the original exception outwards. - e.Rethrow(); + try + { + // attempt to parse a non-form error message + var response = JObject.Parse(req.GetResponseString().AsNonNull()); + + string redirect = (string)response.SelectToken(@"url", true); + string message = (string)response.SelectToken(@"error", false); + + if (!string.IsNullOrEmpty(redirect)) + { + return new RegistrationRequest.RegistrationRequestErrors + { + Redirect = redirect, + Message = message, + }; + } + + // if we couldn't deserialize the error message let's throw the original exception outwards. + e.Rethrow(); + } + catch + { + // if we couldn't deserialize the error message let's throw the original exception outwards. + e.Rethrow(); + } } } diff --git a/osu.Game/Online/API/RegistrationRequest.cs b/osu.Game/Online/API/RegistrationRequest.cs index dfedaa30e0..78633f70b7 100644 --- a/osu.Game/Online/API/RegistrationRequest.cs +++ b/osu.Game/Online/API/RegistrationRequest.cs @@ -23,6 +23,16 @@ namespace osu.Game.Online.API public class RegistrationRequestErrors { + /// + /// An optional error message. + /// + public string? Message; + + /// + /// An optional URL which the user should be directed towards to complete registration. + /// + public string? Redirect; + public UserErrors? User; public class UserErrors From 4d58e6d8d2ab35b3addd1c70a5e1d46de1b8d836 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:36:45 +0900 Subject: [PATCH 157/248] Add UI support for redirecting the user to web registration --- .../Overlays/AccountCreation/ScreenEntry.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index ea1ee2c9a9..fe53ca0309 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -47,6 +47,9 @@ namespace osu.Game.Overlays.AccountCreation [Resolved] private GameHost host { get; set; } + [Resolved] + private OsuGame game { get; set; } + [BackgroundDependencyLoader] private void load() { @@ -194,9 +197,20 @@ namespace osu.Game.Overlays.AccountCreation { if (errors != null) { - usernameDescription.AddErrors(errors.User.Username); - emailAddressDescription.AddErrors(errors.User.Email); - passwordDescription.AddErrors(errors.User.Password); + if (errors.User != null) + { + usernameDescription.AddErrors(errors.User.Username); + emailAddressDescription.AddErrors(errors.User.Email); + passwordDescription.AddErrors(errors.User.Password); + } + + if (!string.IsNullOrEmpty(errors.Redirect)) + { + if (!string.IsNullOrEmpty(errors.Message)) + passwordDescription.AddErrors(new[] { errors.Message }); + + game.OpenUrlExternally(errors.Redirect); + } } else { From 11f630d49d9491b8f44a23abafce13ac1f4d9b80 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 15:42:34 +0900 Subject: [PATCH 158/248] Prefill username and email --- osu.Game/Overlays/AccountCreation/ScreenEntry.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index fe53ca0309..2e20f83e9e 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -209,7 +209,7 @@ namespace osu.Game.Overlays.AccountCreation if (!string.IsNullOrEmpty(errors.Message)) passwordDescription.AddErrors(new[] { errors.Message }); - game.OpenUrlExternally(errors.Redirect); + game.OpenUrlExternally($"{errors.Redirect}?username={usernameTextBox.Text}&email={emailTextBox.Text}"); } } else From 911cc78094b82b41a9909bc79d7e3b8db21eeb67 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jan 2023 16:21:13 +0900 Subject: [PATCH 159/248] Fix debug build thinking it's deployed due to major version >= 1 --- osu.iOS/osu.iOS.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj index 9a31525517..2d61b73125 100644 --- a/osu.iOS/osu.iOS.csproj +++ b/osu.iOS/osu.iOS.csproj @@ -4,7 +4,7 @@ 13.4 Exe true - 1.0.0 + 0.1.0 $(Version) $(Version) From 653376f5f2814476a3a29da545896d8c23badec7 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 13 Jan 2023 09:32:36 +0100 Subject: [PATCH 160/248] Fix test failures --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index cfee02dfb8..97ffd896c6 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1151,7 +1151,7 @@ namespace osu.Game.Tests.Visual.SongSelect public WorkingBeatmap CurrentBeatmap => Beatmap.Value; public IWorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap; - public new BeatmapCarousel Carousel => base.Carousel; + public new BeatmapCarousel Carousel => base.Carousel!; public new ModSelectOverlay ModSelect => base.ModSelect; public new void PresentScore(ScoreInfo score) => base.PresentScore(score); From a6b6fb864eaa673e9f5cd325a1965624fb482973 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Fri, 13 Jan 2023 13:10:29 +0100 Subject: [PATCH 161/248] Make carousel non nullable and ensure pre load usages of methods that reference it are protected against failure --- .../SongSelect/TestScenePlaySongSelect.cs | 2 +- .../Multiplayer/MultiplayerMatchSongSelect.cs | 2 -- osu.Game/Screens/Select/SongSelect.cs | 29 +++++++------------ 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 97ffd896c6..cfee02dfb8 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1151,7 +1151,7 @@ namespace osu.Game.Tests.Visual.SongSelect public WorkingBeatmap CurrentBeatmap => Beatmap.Value; public IWorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap; - public new BeatmapCarousel Carousel => base.Carousel!; + public new BeatmapCarousel Carousel => base.Carousel; public new ModSelectOverlay ModSelect => base.ModSelect; public new void PresentScore(ScoreInfo score) => base.PresentScore(score); diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs index 6a4ce7aff5..873a1b0d50 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSongSelect.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -106,7 +105,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer Schedule(() => { - Debug.Assert(Carousel != null); Carousel.AllowSelection = true; }); }); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 6826dffd5f..ef5827fad7 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -79,12 +79,12 @@ namespace osu.Game.Screens.Select /// public virtual bool AllowEditing => true; - public bool BeatmapSetsLoaded => IsLoaded && Carousel?.BeatmapSetsLoaded == true; + public bool BeatmapSetsLoaded => IsLoaded && Carousel.BeatmapSetsLoaded; [Resolved] private Bindable> selectedMods { get; set; } = null!; - protected BeatmapCarousel? Carousel { get; private set; } + protected BeatmapCarousel Carousel { get; private set; } = null!; private ParallaxContainer wedgeBackground = null!; @@ -127,7 +127,7 @@ namespace osu.Game.Screens.Select private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog? manageCollectionsDialog, DifficultyRecommender? recommender) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). - transferRulesetValue(); + transferRulesetValue(false); LoadComponentAsync(Carousel = new BeatmapCarousel { @@ -314,10 +314,8 @@ namespace osu.Game.Screens.Select /// Creates the buttons to be displayed in the footer. /// /// A set of and an optional which the button opens when pressed. - protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() - { - Debug.Assert(Carousel != null); - return new (FooterButton, OverlayContainer?)[] + protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() => + new (FooterButton, OverlayContainer?)[] { (new FooterButtonMods { Current = Mods }, ModSelect), (new FooterButtonRandom @@ -327,7 +325,6 @@ namespace osu.Game.Screens.Select }, null), (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) }; - } protected virtual ModSelectOverlay CreateModSelectOverlay() => new SoloModSelectOverlay(); @@ -336,7 +333,6 @@ namespace osu.Game.Screens.Select // if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter). bool shouldDebounce = this.IsCurrentScreen(); - Debug.Assert(Carousel != null); Carousel.Filter(criteria, shouldDebounce); } @@ -375,8 +371,6 @@ namespace osu.Game.Screens.Select /// An optional custom action to perform instead of . public void FinaliseSelection(BeatmapInfo? beatmapInfo = null, RulesetInfo? ruleset = null, Action? customStartAction = null) { - Debug.Assert(Carousel != null); - // This is very important as we have not yet bound to screen-level bindables before the carousel load is completed. if (!Carousel.BeatmapSetsLoaded) { @@ -431,8 +425,6 @@ namespace osu.Game.Screens.Select Logger.Log($"Song select working beatmap updated to {beatmap}"); - Debug.Assert(Carousel != null); - if (Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) return; // A selection may not have been possible with filters applied. @@ -522,7 +514,6 @@ namespace osu.Game.Screens.Select if (transferRulesetValue()) { - Debug.Assert(Carousel != null); // transferRulesetValue() may trigger a re-filter. If the current selection does not match the new ruleset, we want to switch away from it. // The default logic on WorkingBeatmap change is to switch to a matching ruleset (see workingBeatmapChanged()), but we don't want that here. // We perform an early selection attempt and clear out the beatmap selection to avoid a second ruleset change (revert). @@ -609,7 +600,6 @@ namespace osu.Game.Screens.Select ModSelect.SelectedMods.Disabled = false; ModSelect.SelectedMods.BindTo(selectedMods); - Debug.Assert(Carousel != null); Carousel.AllowSelection = true; BeatmapDetails.Refresh(); @@ -672,7 +662,6 @@ namespace osu.Game.Screens.Select BeatmapOptions.Hide(); - Debug.Assert(Carousel != null); Carousel.AllowSelection = false; endLooping(); @@ -803,7 +792,6 @@ namespace osu.Game.Screens.Select { bindBindables(); - Debug.Assert(Carousel != null); Carousel.AllowSelection = true; // If a selection was already obtained, do not attempt to update the selected beatmap. @@ -867,7 +855,7 @@ namespace osu.Game.Screens.Select /// Will immediately run filter operations if required. /// /// Whether a transfer occurred. - private bool transferRulesetValue() + private bool transferRulesetValue(bool carouselLoaded = true) { if (decoupledRuleset.Value?.Equals(Ruleset.Value) == true) return false; @@ -875,9 +863,12 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; + // We don't want to declare the carousel as nullable, so this check allows us to avoid running the carousel flush during the loading process + if (!carouselLoaded) return true; + // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). - Carousel?.FlushPendingFilterOperations(); + Carousel.FlushPendingFilterOperations(); return true; } From e38075c4ef06b0db3b436ddf374193d6ccefd609 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Fri, 13 Jan 2023 09:37:23 -0500 Subject: [PATCH 162/248] Use PlacementState to check juice stream placement --- osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs | 2 +- .../Edit/Compose/Components/ComposeBlueprintContainer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index fbe897b484..0b9d1ad41d 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -188,7 +188,7 @@ namespace osu.Game.Rulesets.Catch.Edit if (EditorBeatmap.PlacementObject.Value is JuiceStream) { // Juice stream path is not subject to snapping. - if (((JuiceStream)EditorBeatmap.PlacementObject.Value).Distance != 0) + if (BlueprintContainer.currentPlacement.PlacementActive is PlacementBlueprint.PlacementState.Active) return null; } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index f955ae9cd6..b1fcd57c51 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected new EditorSelectionHandler SelectionHandler => (EditorSelectionHandler)base.SelectionHandler; - private PlacementBlueprint currentPlacement; + public PlacementBlueprint currentPlacement { get; private set; } /// /// Positional input must be received outside the container's bounds, From 6028abff3926f4e8b021e2e273e7b2927a0a0f52 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Fri, 13 Jan 2023 10:16:52 -0500 Subject: [PATCH 163/248] Code Quality --- .../Edit/CatchHitObjectComposer.cs | 2 +- .../Components/ComposeBlueprintContainer.cs | 30 +++++++++---------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index 0b9d1ad41d..cdf0ccfae9 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -188,7 +188,7 @@ namespace osu.Game.Rulesets.Catch.Edit if (EditorBeatmap.PlacementObject.Value is JuiceStream) { // Juice stream path is not subject to snapping. - if (BlueprintContainer.currentPlacement.PlacementActive is PlacementBlueprint.PlacementState.Active) + if (BlueprintContainer.CurrentPlacement.PlacementActive is PlacementBlueprint.PlacementState.Active) return null; } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 8ec1cb9198..836fceea22 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected new EditorSelectionHandler SelectionHandler => (EditorSelectionHandler)base.SelectionHandler; - public PlacementBlueprint currentPlacement { get; private set; } + public PlacementBlueprint CurrentPlacement { get; private set; } /// /// Positional input must be received outside the container's bounds, @@ -137,13 +137,13 @@ namespace osu.Game.Screens.Edit.Compose.Components private void updatePlacementNewCombo() { - if (currentPlacement?.HitObject is IHasComboInformation c) + if (CurrentPlacement?.HitObject is IHasComboInformation c) c.NewCombo = NewCombo.Value == TernaryState.True; } private void updatePlacementSamples() { - if (currentPlacement == null) return; + if (CurrentPlacement == null) return; foreach (var kvp in SelectionHandler.SelectionSampleStates) sampleChanged(kvp.Key, kvp.Value.Value); @@ -151,9 +151,9 @@ namespace osu.Game.Screens.Edit.Compose.Components private void sampleChanged(string sampleName, TernaryState state) { - if (currentPlacement == null) return; + if (CurrentPlacement == null) return; - var samples = currentPlacement.HitObject.Samples; + var samples = CurrentPlacement.HitObject.Samples; var existingSample = samples.FirstOrDefault(s => s.Name == sampleName); @@ -225,7 +225,7 @@ namespace osu.Game.Screens.Edit.Compose.Components // if no time was found from positional snapping, we should still quantize to the beat. snapResult.Time ??= Beatmap.SnapTime(EditorClock.CurrentTime, null); - currentPlacement.UpdateTimeAndPosition(snapResult); + CurrentPlacement.UpdateTimeAndPosition(snapResult); } #endregion @@ -234,9 +234,9 @@ namespace osu.Game.Screens.Edit.Compose.Components { base.Update(); - if (currentPlacement != null) + if (CurrentPlacement != null) { - switch (currentPlacement.PlacementActive) + switch (CurrentPlacement.PlacementActive) { case PlacementBlueprint.PlacementState.Waiting: if (!Composer.CursorInPlacementArea) @@ -252,7 +252,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (Composer.CursorInPlacementArea) ensurePlacementCreated(); - if (currentPlacement != null) + if (CurrentPlacement != null) updatePlacementPosition(); } @@ -281,13 +281,13 @@ namespace osu.Game.Screens.Edit.Compose.Components private void ensurePlacementCreated() { - if (currentPlacement != null) return; + if (CurrentPlacement != null) return; var blueprint = CurrentTool?.CreatePlacementBlueprint(); if (blueprint != null) { - placementBlueprintContainer.Child = currentPlacement = blueprint; + placementBlueprintContainer.Child = CurrentPlacement = blueprint; // Fixes a 1-frame position discrepancy due to the first mouse move event happening in the next frame updatePlacementPosition(); @@ -300,11 +300,11 @@ namespace osu.Game.Screens.Edit.Compose.Components private void removePlacement() { - if (currentPlacement == null) return; + if (CurrentPlacement == null) return; - currentPlacement.EndPlacement(false); - currentPlacement.Expire(); - currentPlacement = null; + CurrentPlacement.EndPlacement(false); + CurrentPlacement.Expire(); + CurrentPlacement = null; } private HitObjectCompositionTool currentTool; From 112cf403ecb08b19e43e1d00c96415d32dca096e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Jan 2023 18:32:56 +0300 Subject: [PATCH 164/248] Fix intermittent failure in certain beatmap carousel tests --- osu.Game/Screens/Select/Carousel/SetPanelContent.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs index 7ca0e92ac8..8d6fbbf256 100644 --- a/osu.Game/Screens/Select/Carousel/SetPanelContent.cs +++ b/osu.Game/Screens/Select/Carousel/SetPanelContent.cs @@ -21,6 +21,8 @@ namespace osu.Game.Screens.Select.Carousel private readonly CarouselBeatmapSet carouselSet; + private FillFlowContainer iconFlow = null!; + public SetPanelContent(CarouselBeatmapSet carouselSet) { this.carouselSet = carouselSet; @@ -82,13 +84,12 @@ namespace osu.Game.Screens.Select.Carousel TextPadding = new MarginPadding { Horizontal = 8, Vertical = 2 }, Status = beatmapSet.Status }, - new FillFlowContainer + iconFlow = new FillFlowContainer { AutoSizeAxes = Axes.Both, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, Spacing = new Vector2(3), - ChildrenEnumerable = getDifficultyIcons(), }, } } @@ -96,6 +97,12 @@ namespace osu.Game.Screens.Select.Carousel }; } + protected override void LoadComplete() + { + base.LoadComplete(); + iconFlow.ChildrenEnumerable = getDifficultyIcons(); + } + private const int maximum_difficulty_icons = 18; private IEnumerable getDifficultyIcons() From 777c3f447cfb4acedd8a017504e0dc7ad4fc2d4b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Jan 2023 19:29:13 +0300 Subject: [PATCH 165/248] Add leading zeros to test beatmaps for correct title sorting --- osu.Game.Tests/Resources/TestResources.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Resources/TestResources.cs b/osu.Game.Tests/Resources/TestResources.cs index 9c85f61330..adf28afc8e 100644 --- a/osu.Game.Tests/Resources/TestResources.cs +++ b/osu.Game.Tests/Resources/TestResources.cs @@ -12,6 +12,7 @@ using System.Threading; using NUnit.Framework; using osu.Framework.Extensions; using osu.Framework.IO.Stores; +using osu.Framework.Logging; using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; @@ -93,10 +94,12 @@ namespace osu.Game.Tests.Resources { // Create random metadata, then we can check if sorting works based on these Artist = "Some Artist " + RNG.Next(0, 9), - Title = $"Some Song (set id {setId}) {Guid.NewGuid()}", + Title = $"Some Song (set id {setId:000}) {Guid.NewGuid()}", Author = { Username = "Some Guy " + RNG.Next(0, 9) }, }; + Logger.Log($"🛠️ Generating beatmap set \"{metadata}\" for test consumption."); + var beatmapSet = new BeatmapSetInfo { OnlineID = setId, From e6ff262521119fbfd9ebfb4c5400de1836ecbcbf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Jan 2023 19:31:49 +0300 Subject: [PATCH 166/248] Fix potential nullref in certain beatmap carousel tests --- .../SongSelect/TestSceneBeatmapCarousel.cs | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs index 1a466dea58..ea9508ecff 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs @@ -16,7 +16,9 @@ using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; using osu.Game.Screens.Select; using osu.Game.Screens.Select.Carousel; using osu.Game.Screens.Select.Filter; @@ -926,10 +928,7 @@ namespace osu.Game.Tests.Visual.SongSelect // 10 sets that go osu! -> taiko -> catch -> osu! -> ... for (int i = 0; i < 10; i++) - { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); - sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); - } + sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { getRuleset(i) })); // Sort mode is important to keep the ruleset order loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); @@ -937,13 +936,29 @@ namespace osu.Game.Tests.Visual.SongSelect for (int i = 1; i < 10; i++) { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 3); + var rulesetInfo = getRuleset(i % 3); + AddStep($"Set ruleset to {rulesetInfo.ShortName}", () => { carousel.Filter(new FilterCriteria { Ruleset = rulesetInfo, Sort = SortMode.Title }, false); }); waitForSelection(i + 1, 1); } + + static RulesetInfo getRuleset(int index) + { + switch (index % 3) + { + default: + return new OsuRuleset().RulesetInfo; + + case 1: + return new TaikoRuleset().RulesetInfo; + + case 2: + return new CatchRuleset().RulesetInfo; + } + } } [Test] @@ -953,10 +968,7 @@ namespace osu.Game.Tests.Visual.SongSelect // 10 sets that go taiko, osu!, osu!, osu!, taiko, osu!, osu!, osu!, ... for (int i = 0; i < 10; i++) - { - var rulesetInfo = rulesets.AvailableRulesets.ElementAt(i % 4 == 0 ? 1 : 0); - sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { rulesetInfo })); - } + sets.Add(TestResources.CreateTestBeatmapSetInfo(5, new[] { getRuleset(i) })); // Sort mode is important to keep the ruleset order loadBeatmaps(sets, () => new FilterCriteria { Sort = SortMode.Title }); @@ -974,6 +986,18 @@ namespace osu.Game.Tests.Visual.SongSelect carousel.Filter(new FilterCriteria { Sort = SortMode.Title }, false); }); } + + static RulesetInfo getRuleset(int index) + { + switch (index % 4) + { + case 0: + return new TaikoRuleset().RulesetInfo; + + default: + return new OsuRuleset().RulesetInfo; + } + } } private void loadBeatmaps(List beatmapSets = null, Func initialCriteria = null, Action carouselAdjust = null, int? count = null, From c62d416680e3b1a4a019fd7d7b1d09f3fba9cc4f Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 13 Jan 2023 22:54:38 +0300 Subject: [PATCH 167/248] Add localisation for notification overlay --- osu.Game/Localisation/NotificationsStrings.cs | 17 ++++++++++++++++- osu.Game/Overlays/NotificationOverlay.cs | 4 ++-- .../Notifications/NotificationSection.cs | 6 +++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index 382e0d81f4..c7df185543 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -19,6 +19,21 @@ namespace osu.Game.Localisation /// public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"waiting for 'ya"); - private static string getKey(string key) => $"{prefix}:{key}"; + /// + /// "Running Tasks" + /// + public static LocalisableString RunningTasks => new TranslatableString(getKey(@"running_tasks"), @"Running Tasks"); + + /// + /// "Clear All" + /// + public static LocalisableString ClearAll => new TranslatableString(getKey(@"clear_all"), @"Clear All"); + + /// + /// "Cancel All" + /// + public static LocalisableString CancelAll => new TranslatableString(getKey(@"cancel_all"), @"Cancel All"); + + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 3f3c6551c6..71a4c58afd 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -92,8 +92,8 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Children = new[] { - new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, "Clear All"), - new NotificationSection(@"Running Tasks", new[] { typeof(ProgressNotification) }, @"Cancel All"), + new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, NotificationsStrings.ClearAll), + new NotificationSection(NotificationsStrings.RunningTasks, new[] { typeof(ProgressNotification) }, NotificationsStrings.CancelAll), } } } diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index d55a2abd2a..de4c72e473 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -33,15 +33,15 @@ namespace osu.Game.Overlays.Notifications public IEnumerable AcceptedNotificationTypes { get; } - private readonly string clearButtonText; + private readonly LocalisableString clearButtonText; private readonly LocalisableString titleText; - public NotificationSection(LocalisableString title, IEnumerable acceptedNotificationTypes, string clearButtonText) + public NotificationSection(LocalisableString title, IEnumerable acceptedNotificationTypes, LocalisableString clearButtonText) { AcceptedNotificationTypes = acceptedNotificationTypes.ToArray(); - this.clearButtonText = clearButtonText.ToUpperInvariant(); + this.clearButtonText = clearButtonText.ToUpper(); titleText = title; } From b681a0d47fd796bab5c8ec3c04b08f76f86af0a6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 13 Jan 2023 22:50:59 +0300 Subject: [PATCH 168/248] Fix intermittent failure in score submission tests --- .../Visual/Gameplay/TestScenePlayerScoreSubmission.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs index d5031bc606..1a7ea20cc0 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerScoreSubmission.cs @@ -181,7 +181,8 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("wait for fail", () => Player.GameplayState.HasFailed); AddStep("exit", () => Player.Exit()); - AddAssert("ensure failing submission", () => Player.SubmittedScore?.ScoreInfo.Passed == false); + AddUntilStep("wait for submission", () => Player.SubmittedScore != null); + AddAssert("ensure failing submission", () => Player.SubmittedScore.ScoreInfo.Passed == false); } [Test] @@ -209,7 +210,9 @@ namespace osu.Game.Tests.Visual.Gameplay addFakeHit(); AddStep("exit", () => Player.Exit()); - AddAssert("ensure failing submission", () => Player.SubmittedScore?.ScoreInfo.Passed == false); + + AddUntilStep("wait for submission", () => Player.SubmittedScore != null); + AddAssert("ensure failing submission", () => Player.SubmittedScore.ScoreInfo.Passed == false); } [Test] From a41a031909090e2d952990c2cf0818b78d652568 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 13 Jan 2023 23:11:25 +0300 Subject: [PATCH 169/248] Localise some notifications --- osu.Game/Localisation/NotificationsStrings.cs | 27 ++++++++++++++++++- osu.Game/Screens/Menu/IntroScreen.cs | 3 ++- osu.Game/Screens/Play/HUDOverlay.cs | 3 ++- osu.Game/Screens/Play/PlayerLoader.cs | 5 ++-- osu.Game/Screens/Select/PlaySongSelect.cs | 3 ++- 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index c7df185543..737a4b4391 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -15,7 +15,7 @@ namespace osu.Game.Localisation public static LocalisableString HeaderTitle => new TranslatableString(getKey(@"header_title"), @"notifications"); /// - /// "waiting for 'ya" + /// "waiting for 'ya" /// public static LocalisableString HeaderDescription => new TranslatableString(getKey(@"header_description"), @"waiting for 'ya"); @@ -34,6 +34,31 @@ namespace osu.Game.Localisation /// public static LocalisableString CancelAll => new TranslatableString(getKey(@"cancel_all"), @"Cancel All"); + /// + /// "Your battery level is low! Charge your device to prevent interruptions during gameplay." + /// + public static LocalisableString LowBatteryWarning => new TranslatableString(getKey(@"low_battery_warning"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); + + /// + /// "Your game volume is too low to hear anything! Click here to restore it." + /// + public static LocalisableString GameVolumeTooLow => new TranslatableString(getKey(@"game_volume_too_low"), @"Your game volume is too low to hear anything! Click here to restore it."); + + /// + /// "The current ruleset doesn't have an autoplay mod available!" + /// + public static LocalisableString NoAutoplayMod => new TranslatableString(getKey(@"no_autoplay_mod"), @"The current ruleset doesn't have an autoplay mod available!"); + + /// + /// "osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting." + /// + public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), @"osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting."); + + /// + /// "The score overlay is currently disabled. You can toggle this by pressing {0}." + /// + public static LocalisableString TheScoreOverlayIsDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"the_score_overlay_is_disabled"), @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs index f632d9ee73..de7732dd5e 100644 --- a/osu.Game/Screens/Menu/IntroScreen.cs +++ b/osu.Game/Screens/Menu/IntroScreen.cs @@ -20,6 +20,7 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Database; +using osu.Game.Localisation; using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -201,7 +202,7 @@ namespace osu.Game.Screens.Menu { notifications.Post(new SimpleErrorNotification { - Text = "osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting." + Text = NotificationsStrings.AudioPlaybackIssue }); } }, 5000); diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 4c2483a0e6..ee198d0209 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -24,6 +24,7 @@ using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD.ClicksPerSecond; using osu.Game.Skinning; using osuTK; +using osu.Game.Localisation; namespace osu.Game.Screens.Play { @@ -172,7 +173,7 @@ namespace osu.Game.Screens.Play notificationOverlay?.Post(new SimpleNotification { - Text = $"The score overlay is currently disabled. You can toggle this by pressing {config.LookupKeyBindings(GlobalAction.ToggleInGameInterface)}." + Text = NotificationsStrings.TheScoreOverlayIsDisabled(config.LookupKeyBindings(GlobalAction.ToggleInGameInterface)) }); } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 5cedd4f793..324dd1ddaf 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -20,6 +20,7 @@ using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Input; +using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Screens.Menu; @@ -550,7 +551,7 @@ namespace osu.Game.Screens.Play public MutedNotification() { - Text = "Your game volume is too low to hear anything! Click here to restore it."; + Text = NotificationsStrings.GameVolumeTooLow; } [BackgroundDependencyLoader] @@ -605,7 +606,7 @@ namespace osu.Game.Screens.Play public BatteryWarningNotification() { - Text = "Your battery level is low! Charge your device to prevent interruptions during gameplay."; + Text = NotificationsStrings.LowBatteryWarning; } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index f73cfe8d55..00a45d5d5a 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Events; using osu.Framework.Screens; using osu.Game.Graphics; +using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Rulesets.Mods; @@ -89,7 +90,7 @@ namespace osu.Game.Screens.Select { notifications?.Post(new SimpleNotification { - Text = "The current ruleset doesn't have an autoplay mod avalaible!" + Text = NotificationsStrings.NoAutoplayMod }); return false; } From 515ada6815eee1dbf9f1166a42c6f4f4ecb0bdd8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Fri, 13 Jan 2023 23:11:50 +0300 Subject: [PATCH 170/248] Remove `CanBeNull` where it's no longer requered --- osu.Game/Screens/Play/PlayerLoader.cs | 6 +++--- osu.Game/Screens/Select/PlaySongSelect.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 324dd1ddaf..de67642104 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -131,16 +131,16 @@ namespace osu.Game.Screens.Play private bool quickRestart; - [Resolved(CanBeNull = true)] + [Resolved] private INotificationOverlay? notificationOverlay { get; set; } - [Resolved(CanBeNull = true)] + [Resolved] private VolumeOverlay? volumeOverlay { get; set; } [Resolved] private AudioManager audioManager { get; set; } = null!; - [Resolved(CanBeNull = true)] + [Resolved] private BatteryInfo? batteryInfo { get; set; } public PlayerLoader(Func createPlayer) diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 00a45d5d5a..9edca1d0c0 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -25,7 +25,7 @@ namespace osu.Game.Screens.Select { private OsuScreen? playerLoader; - [Resolved(CanBeNull = true)] + [Resolved] private INotificationOverlay? notifications { get; set; } public override bool AllowExternalScreenChange => true; From 2e28f5ed335b588bb5bff9cf2a660f6c836c4dff Mon Sep 17 00:00:00 2001 From: StanR Date: Fri, 13 Jan 2023 23:18:24 +0300 Subject: [PATCH 171/248] Add `StatusIcon` --- osu.Game/Users/Drawables/StatusIcon.cs | 26 ++++++++++++++++++++++++++ osu.Game/Users/ExtendedUserPanel.cs | 9 ++------- 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 osu.Game/Users/Drawables/StatusIcon.cs diff --git a/osu.Game/Users/Drawables/StatusIcon.cs b/osu.Game/Users/Drawables/StatusIcon.cs new file mode 100644 index 0000000000..108d81ed57 --- /dev/null +++ b/osu.Game/Users/Drawables/StatusIcon.cs @@ -0,0 +1,26 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osuTK; + +namespace osu.Game.Users.Drawables +{ + public partial class StatusIcon : CircularContainer + { + public StatusIcon() + { + Size = new Vector2(25); + BorderThickness = 4; + BorderColour = Colour; + Masking = true; + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Colour4.White.Opacity(0) + }; + } + } +} diff --git a/osu.Game/Users/ExtendedUserPanel.cs b/osu.Game/Users/ExtendedUserPanel.cs index 85b71a5bc7..4ea3c036c1 100644 --- a/osu.Game/Users/ExtendedUserPanel.cs +++ b/osu.Game/Users/ExtendedUserPanel.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Framework.Graphics.Sprites; using osu.Game.Users.Drawables; using osu.Framework.Input.Events; using osu.Game.Online.API.Requests.Responses; @@ -25,7 +24,7 @@ namespace osu.Game.Users protected TextFlowContainer LastVisitMessage { get; private set; } - private SpriteIcon statusIcon; + private StatusIcon statusIcon; private OsuSpriteText statusMessage; protected ExtendedUserPanel(APIUser user) @@ -59,11 +58,7 @@ namespace osu.Game.Users Action = Action, }; - protected SpriteIcon CreateStatusIcon() => statusIcon = new SpriteIcon - { - Icon = FontAwesome.Regular.Circle, - Size = new Vector2(25) - }; + protected Container CreateStatusIcon() => statusIcon = new StatusIcon(); protected FillFlowContainer CreateStatusMessage(bool rightAlignedChildren) { From 5750d82c0a6979fc02aca02f5624af02592b4b27 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 13 Jan 2023 12:50:12 -0800 Subject: [PATCH 172/248] Move overlay ruleset selectors to tab control --- .../UserInterface/TestSceneOverlayHeader.cs | 2 +- .../Overlays/BeatmapSet/BeatmapSetHeader.cs | 11 ++++++++-- osu.Game/Overlays/OverlayHeader.cs | 22 ++++--------------- osu.Game/Overlays/Profile/ProfileHeader.cs | 12 +++++----- .../Rankings/RankingsOverlayHeader.cs | 2 +- osu.Game/Overlays/TabControlOverlayHeader.cs | 20 ++++++++++++++--- 6 files changed, 37 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs index 8f10065d17..e90041774e 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs @@ -108,7 +108,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override OverlayTitle CreateTitle() => new TestTitle(); - protected override Drawable CreateTitleContent() => new OverlayRulesetSelector(); + protected override Drawable CreateTabControlContent() => new OverlayRulesetSelector(); public TestStringTabControlHeader() { diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index fa9c9b5018..858742648c 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; +using osu.Framework.Localisation; using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets; @@ -16,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { - public partial class BeatmapSetHeader : OverlayHeader + public partial class BeatmapSetHeader : TabControlOverlayHeader { public readonly Bindable BeatmapSet = new Bindable(); @@ -46,7 +47,7 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet = { BindTarget = BeatmapSet } }; - protected override Drawable CreateTitleContent() => RulesetSelector = new BeatmapRulesetSelector + protected override Drawable CreateTabControlContent() => RulesetSelector = new BeatmapRulesetSelector { Current = ruleset }; @@ -62,4 +63,10 @@ namespace osu.Game.Overlays.BeatmapSet } } } + + public enum BeatmapSetTabs + { + [LocalisableDescription(typeof(LayoutStrings), nameof(LayoutStrings.HeaderBeatmapsetsShow))] + Info, + } } diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index f8935f7f0a..f28d40c429 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -75,19 +75,11 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Children = new[] + Child = Title = CreateTitle().With(title => { - Title = CreateTitle().With(title => - { - title.Anchor = Anchor.CentreLeft; - title.Origin = Anchor.CentreLeft; - }), - CreateTitleContent().With(content => - { - content.Anchor = Anchor.CentreRight; - content.Origin = Anchor.CentreRight; - }) - } + title.Anchor = Anchor.CentreLeft; + title.Origin = Anchor.CentreLeft; + }), } } }, @@ -112,12 +104,6 @@ namespace osu.Game.Overlays [NotNull] protected virtual Drawable CreateBackground() => Empty(); - /// - /// Creates a on the opposite side of the . Used mostly to create . - /// - [NotNull] - protected virtual Drawable CreateTitleContent() => Empty(); - protected abstract OverlayTitle CreateTitle(); } } diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 4620cc7318..bd12837343 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -36,13 +36,6 @@ namespace osu.Game.Overlays.Profile // todo: pending implementation. // TabControl.AddItem(LayoutStrings.HeaderUsersModding); - TabControlContainer.Add(new ProfileRulesetSelector - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - User = { BindTarget = User } - }); - // Haphazardly guaranteed by OverlayHeader constructor (see CreateBackground / CreateContent). Debug.Assert(centreHeaderContainer != null); Debug.Assert(detailHeaderContainer != null); @@ -107,6 +100,11 @@ namespace osu.Game.Overlays.Profile protected override OverlayTitle CreateTitle() => new ProfileHeaderTitle(); + protected override Drawable CreateTabControlContent() => new ProfileRulesetSelector + { + User = { BindTarget = User } + }; + private void updateDisplay(UserProfileData? user) => coverContainer.User = user?.User; private partial class ProfileHeaderTitle : OverlayTitle diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 3e0f780eeb..44f278a237 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Rankings protected override OverlayTitle CreateTitle() => new RankingsTitle(); - protected override Drawable CreateTitleContent() => rulesetSelector = new OverlayRulesetSelector(); + protected override Drawable CreateTabControlContent() => rulesetSelector = new OverlayRulesetSelector(); protected override Drawable CreateContent() => countryFilter = new CountryFilter(); diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index 8613bac40c..2b87535708 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -62,10 +62,18 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Padding = new MarginPadding { Horizontal = ContentSidePadding }, - Child = TabControl = CreateTabControl().With(control => + Children = new[] { - control.Current = Current; - }) + TabControl = CreateTabControl().With(control => + { + control.Current = Current; + }), + CreateTabControlContent().With(content => + { + content.Anchor = Anchor.CentreRight; + content.Origin = Anchor.CentreRight; + }), + } } } }); @@ -80,6 +88,12 @@ namespace osu.Game.Overlays [NotNull] protected virtual OsuTabControl CreateTabControl() => new OverlayHeaderTabControl(); + /// + /// Creates a on the opposite side of the . Used mostly to create . + /// + [NotNull] + protected virtual Drawable CreateTabControlContent() => Empty(); + public partial class OverlayHeaderTabControl : OverlayTabControl { private const float bar_height = 1; From f950b624ae4f0659f12f43148b2782aff60b98df Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 00:26:35 +0300 Subject: [PATCH 173/248] Use existing string --- osu.Game/Localisation/NotificationsStrings.cs | 5 ----- osu.Game/Overlays/NotificationOverlay.cs | 4 +++- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index 737a4b4391..101e18d777 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -24,11 +24,6 @@ namespace osu.Game.Localisation /// public static LocalisableString RunningTasks => new TranslatableString(getKey(@"running_tasks"), @"Running Tasks"); - /// - /// "Clear All" - /// - public static LocalisableString ClearAll => new TranslatableString(getKey(@"clear_all"), @"Clear All"); - /// /// "Cancel All" /// diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 71a4c58afd..ed2a67cd6b 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -17,6 +17,7 @@ using osu.Game.Overlays.Notifications; using osu.Game.Resources.Localisation.Web; using osuTK; using NotificationsStrings = osu.Game.Localisation.NotificationsStrings; +using WebNotificationsStrings = osu.Game.Resources.Localisation.Web.NotificationsStrings; namespace osu.Game.Overlays { @@ -92,7 +93,8 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Children = new[] { - new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, NotificationsStrings.ClearAll), + new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, + WebNotificationsStrings.MarkRead(WebNotificationsStrings.FiltersDefault)), new NotificationSection(NotificationsStrings.RunningTasks, new[] { typeof(ProgressNotification) }, NotificationsStrings.CancelAll), } } From d67184bd80e6410658140e0664525cf647c455da Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 00:26:44 +0300 Subject: [PATCH 174/248] Autoformat code --- osu.Game/Localisation/NotificationsStrings.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index 101e18d777..f5c3589c60 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -32,7 +32,8 @@ namespace osu.Game.Localisation /// /// "Your battery level is low! Charge your device to prevent interruptions during gameplay." /// - public static LocalisableString LowBatteryWarning => new TranslatableString(getKey(@"low_battery_warning"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); + public static LocalisableString LowBatteryWarning => + new TranslatableString(getKey(@"low_battery_warning"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); /// /// "Your game volume is too low to hear anything! Click here to restore it." @@ -47,12 +48,14 @@ namespace osu.Game.Localisation /// /// "osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting." /// - public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), @"osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting."); + public static LocalisableString AudioPlaybackIssue => new TranslatableString(getKey(@"audio_playback_issue"), + @"osu! doesn't seem to be able to play audio correctly.\n\nPlease try changing your audio device to a working setting."); /// /// "The score overlay is currently disabled. You can toggle this by pressing {0}." /// - public static LocalisableString TheScoreOverlayIsDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"the_score_overlay_is_disabled"), @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); + public static LocalisableString TheScoreOverlayIsDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"the_score_overlay_is_disabled"), + @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); private static string getKey(string key) => $@"{prefix}:{key}"; } From 85b2154f3a7ff6ca61934ad0710fcfba38b7cf83 Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 01:12:17 +0300 Subject: [PATCH 175/248] Set border colour to white --- osu.Game/Users/Drawables/StatusIcon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Users/Drawables/StatusIcon.cs b/osu.Game/Users/Drawables/StatusIcon.cs index 108d81ed57..18d06a48f8 100644 --- a/osu.Game/Users/Drawables/StatusIcon.cs +++ b/osu.Game/Users/Drawables/StatusIcon.cs @@ -14,7 +14,7 @@ namespace osu.Game.Users.Drawables { Size = new Vector2(25); BorderThickness = 4; - BorderColour = Colour; + BorderColour = Colour4.White; // the colour is being applied through Colour - since it's multiplicative it applies to the border as well Masking = true; Child = new Box { From 0b5c89d01fde788848440d474b3d50de8e30383e Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Fri, 13 Jan 2023 23:07:21 +0000 Subject: [PATCH 176/248] revert additions to `SessionStatics` --- osu.Game.Tests/NonVisual/SessionStaticsTest.cs | 6 ------ osu.Game/Configuration/SessionStatics.cs | 4 ---- .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 15 --------------- 3 files changed, 25 deletions(-) diff --git a/osu.Game.Tests/NonVisual/SessionStaticsTest.cs b/osu.Game.Tests/NonVisual/SessionStaticsTest.cs index 499c0e5d34..5c8254b947 100644 --- a/osu.Game.Tests/NonVisual/SessionStaticsTest.cs +++ b/osu.Game.Tests/NonVisual/SessionStaticsTest.cs @@ -24,16 +24,12 @@ namespace osu.Game.Tests.NonVisual sessionStatics.SetValue(Static.MutedAudioNotificationShownOnce, true); sessionStatics.SetValue(Static.LowBatteryNotificationShownOnce, true); sessionStatics.SetValue(Static.LastHoverSoundPlaybackTime, (double?)1d); - sessionStatics.SetValue(Static.ReplayPlaybackSettingExpanded, false); - sessionStatics.SetValue(Static.ReplayVisualSettingsExpanded, true); sessionStatics.SetValue(Static.SeasonalBackgrounds, new APISeasonalBackgrounds { EndDate = new DateTimeOffset(2022, 1, 1, 0, 0, 0, TimeSpan.Zero) }); Assert.IsFalse(sessionStatics.GetBindable(Static.LoginOverlayDisplayed).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.LastHoverSoundPlaybackTime).IsDefault); - Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayPlaybackSettingExpanded).IsDefault); - Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayVisualSettingsExpanded).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.SeasonalBackgrounds).IsDefault); sessionStatics.ResetAfterInactivity(); @@ -43,8 +39,6 @@ namespace osu.Game.Tests.NonVisual Assert.IsTrue(sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce).IsDefault); // some statics should not reset despite inactivity. Assert.IsFalse(sessionStatics.GetBindable(Static.LastHoverSoundPlaybackTime).IsDefault); - Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayPlaybackSettingExpanded).IsDefault); - Assert.IsFalse(sessionStatics.GetBindable(Static.ReplayVisualSettingsExpanded).IsDefault); Assert.IsFalse(sessionStatics.GetBindable(Static.SeasonalBackgrounds).IsDefault); } } diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index f08658f182..12a30a0c84 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -20,8 +20,6 @@ namespace osu.Game.Configuration SetDefault(Static.MutedAudioNotificationShownOnce, false); SetDefault(Static.LowBatteryNotificationShownOnce, false); SetDefault(Static.LastHoverSoundPlaybackTime, (double?)null); - SetDefault(Static.ReplayPlaybackSettingExpanded, true); - SetDefault(Static.ReplayVisualSettingsExpanded, false); SetDefault(Static.SeasonalBackgrounds, null); } @@ -44,8 +42,6 @@ namespace osu.Game.Configuration LoginOverlayDisplayed, MutedAudioNotificationShownOnce, LowBatteryNotificationShownOnce, - ReplayPlaybackSettingExpanded, - ReplayVisualSettingsExpanded, /// /// Info about seasonal backgrounds available fetched from API - see . diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index c4f07f77cd..1edb227a75 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -3,15 +3,12 @@ #nullable disable -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; using osuTK; using osu.Game.Screens.Play.PlayerSettings; using osuTK.Input; -using osu.Game.Configuration; -using osu.Framework.Allocation; namespace osu.Game.Screens.Play.HUD { @@ -19,9 +16,6 @@ namespace osu.Game.Screens.Play.HUD { private const int fade_duration = 200; - private Bindable playbackMenuExpanded; - - private Bindable visualMenuExpanded; public bool ReplayLoaded; @@ -54,15 +48,6 @@ namespace osu.Game.Screens.Play.HUD }; } - [BackgroundDependencyLoader] - private void load(SessionStatics statics) - { - playbackMenuExpanded = statics.GetBindable(Static.ReplayPlaybackSettingExpanded); - visualMenuExpanded = statics.GetBindable(Static.ReplayVisualSettingsExpanded); - - PlaybackSettings.Expanded.BindTo(playbackMenuExpanded); - VisualSettings.Expanded.BindTo(visualMenuExpanded); - } protected override void PopIn() => this.FadeIn(fade_duration); protected override void PopOut() => this.FadeOut(fade_duration); From c3c1d77e8e8d0ccab211e461c84b73062c7aeece Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Fri, 13 Jan 2023 23:07:59 +0000 Subject: [PATCH 177/248] make `PlayerSettingsGroup` expand on hover --- .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 6 ++--- .../PlayerSettings/PlayerSettingsGroup.cs | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index 1edb227a75..019ba53a5e 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -16,7 +16,6 @@ namespace osu.Game.Screens.Play.HUD { private const int fade_duration = 200; - public bool ReplayLoaded; public readonly PlaybackSettings PlaybackSettings; @@ -42,13 +41,12 @@ namespace osu.Game.Screens.Play.HUD { //CollectionSettings = new CollectionSettings(), //DiscussionSettings = new DiscussionSettings(), - PlaybackSettings = new PlaybackSettings(), - VisualSettings = new VisualSettings() + PlaybackSettings = new PlaybackSettings { Expanded = { Value = false } }, + VisualSettings = new VisualSettings { Expanded = { Value = false } } } }; } - protected override void PopIn() => this.FadeIn(fade_duration); protected override void PopOut() => this.FadeOut(fade_duration); diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 6c6f62a8ac..63e081b2ea 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -4,6 +4,7 @@ #nullable disable using osu.Framework.Input.Events; +using osu.Framework.Threading; using osu.Game.Overlays; namespace osu.Game.Screens.Play.PlayerSettings @@ -15,12 +16,35 @@ namespace osu.Game.Screens.Play.PlayerSettings { } + private ScheduledDelegate hoverExpandEvent; + protected override bool OnHover(HoverEvent e) { + updateHoverExpansion(); base.OnHover(e); // Importantly, return true to correctly take focus away from PlayerLoader. return true; } + + protected override void OnHoverLost(HoverLostEvent e) + { + if (hoverExpandEvent == null) return; + + hoverExpandEvent?.Cancel(); + hoverExpandEvent = null; + + Expanded.Value = false; + + base.OnHoverLost(e); + } + + private void updateHoverExpansion() + { + hoverExpandEvent?.Cancel(); + + if (IsHovered && !Expanded.Value) + hoverExpandEvent = Scheduler.AddDelayed(() => Expanded.Value = true, 0); + } } } From 660bf748d59d2033f788de97cd3b23571d3be315 Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 02:23:08 +0300 Subject: [PATCH 178/248] Fix `GroupBadge` crashing on `null` group colour --- osu.Game/Online/API/Requests/Responses/APIUserGroup.cs | 2 +- osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs b/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs index 5f943e583e..89631d3d7a 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserGroup.cs @@ -8,7 +8,7 @@ namespace osu.Game.Online.API.Requests.Responses public class APIUserGroup { [JsonProperty(@"colour")] - public string Colour { get; set; } = null!; + public string? Colour { get; set; } [JsonProperty(@"has_listing")] public bool HasListings { get; set; } diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs index ce56768a72..5a5c58dc93 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; @@ -62,7 +63,7 @@ namespace osu.Game.Overlays.Profile.Header.Components new OsuSpriteText { Text = group.ShortName, - Colour = Color4Extensions.FromHex(group.Colour), + Colour = Color4Extensions.FromHex(group.Colour ?? Colour4.White.ToHex()), Shadow = false, Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true) } From 78adaa9b03d5f73db721ebdd53bc477beb5b0d26 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:23:21 +0300 Subject: [PATCH 179/248] Enable nullability for timing screen --- .../Edit/Timing/ControlPointSettings.cs | 2 -- osu.Game/Screens/Edit/Timing/EffectSection.cs | 10 +++---- osu.Game/Screens/Edit/Timing/GroupSection.cs | 16 +++++------ .../IndeterminateSliderWithTextBoxInput.cs | 2 -- .../Edit/Timing/LabelledTimeSignature.cs | 4 +-- .../Screens/Edit/Timing/MetronomeDisplay.cs | 28 ++++++++----------- .../Edit/Timing/RepeatingButtonBehaviour.cs | 10 +++---- osu.Game/Screens/Edit/Timing/RowAttribute.cs | 6 ++-- .../RowAttributes/AttributeProgressBar.cs | 2 -- .../Timing/RowAttributes/AttributeText.cs | 2 -- .../RowAttributes/DifficultyRowAttribute.cs | 4 +-- .../RowAttributes/EffectRowAttribute.cs | 8 ++---- .../RowAttributes/SampleRowAttribute.cs | 6 ++-- .../RowAttributes/TimingRowAttribute.cs | 4 +-- osu.Game/Screens/Edit/Timing/Section.cs | 20 ++++++------- .../Edit/Timing/SliderWithTextBoxInput.cs | 2 -- osu.Game/Screens/Edit/Timing/TapButton.cs | 4 +-- .../Screens/Edit/Timing/TimingAdjustButton.cs | 16 +++++------ osu.Game/Screens/Edit/Timing/TimingSection.cs | 8 ++---- 19 files changed, 58 insertions(+), 96 deletions(-) diff --git a/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs b/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs index 97bd84b1b6..b76723378f 100644 --- a/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs +++ b/osu.Game/Screens/Edit/Timing/ControlPointSettings.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Edit/Timing/EffectSection.cs b/osu.Game/Screens/Edit/Timing/EffectSection.cs index 1f5400c03b..051ac97366 100644 --- a/osu.Game/Screens/Edit/Timing/EffectSection.cs +++ b/osu.Game/Screens/Edit/Timing/EffectSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,10 +13,10 @@ namespace osu.Game.Screens.Edit.Timing { internal partial class EffectSection : Section { - private LabelledSwitchButton kiai; - private LabelledSwitchButton omitBarLine; + private LabelledSwitchButton kiai = null!; + private LabelledSwitchButton omitBarLine = null!; - private SliderWithTextBoxInput scrollSpeedSlider; + private SliderWithTextBoxInput scrollSpeedSlider = null!; [BackgroundDependencyLoader] private void load() @@ -55,7 +53,7 @@ namespace osu.Game.Screens.Edit.Timing private bool isRebinding; - protected override void OnControlPointChanged(ValueChangedEvent point) + protected override void OnControlPointChanged(ValueChangedEvent point) { if (point.NewValue != null) { diff --git a/osu.Game/Screens/Edit/Timing/GroupSection.cs b/osu.Game/Screens/Edit/Timing/GroupSection.cs index f36989cf32..487a871881 100644 --- a/osu.Game/Screens/Edit/Timing/GroupSection.cs +++ b/osu.Game/Screens/Edit/Timing/GroupSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -17,21 +15,21 @@ namespace osu.Game.Screens.Edit.Timing { internal partial class GroupSection : CompositeDrawable { - private LabelledTextBox textBox; + private LabelledTextBox textBox = null!; - private OsuButton button; + private OsuButton button = null!; [Resolved] - protected Bindable SelectedGroup { get; private set; } + protected Bindable SelectedGroup { get; private set; } = null!; [Resolved] - protected EditorBeatmap Beatmap { get; private set; } + protected EditorBeatmap Beatmap { get; private set; } = null!; [Resolved] - private EditorClock clock { get; set; } + private EditorClock clock { get; set; } = null!; - [Resolved(canBeNull: true)] - private IEditorChangeHandler changeHandler { get; set; } + [Resolved] + private IEditorChangeHandler? changeHandler { get; set; } [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs index 64713c7714..eabe9b9f64 100644 --- a/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/IndeterminateSliderWithTextBoxInput.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using osu.Framework.Bindables; diff --git a/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs b/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs index 217aa46c3f..d0e1737f78 100644 --- a/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs +++ b/osu.Game/Screens/Edit/Timing/LabelledTimeSignature.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -35,7 +33,7 @@ namespace osu.Game.Screens.Edit.Timing set => current.Current = value; } - private OsuNumberBox numeratorBox; + private OsuNumberBox numeratorBox = null!; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs b/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs index dfe2ec1f17..f4a39405a1 100644 --- a/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/MetronomeDisplay.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -28,24 +25,23 @@ namespace osu.Game.Screens.Edit.Timing { public partial class MetronomeDisplay : BeatSyncedContainer { - private Container swing; + private Container swing = null!; - private OsuSpriteText bpmText; + private OsuSpriteText bpmText = null!; - private Drawable weight; - private Drawable stick; + private Drawable weight = null!; + private Drawable stick = null!; - private IAdjustableClock metronomeClock; + private IAdjustableClock metronomeClock = null!; - private Sample sampleTick; - private Sample sampleTickDownbeat; - private Sample sampleLatch; + private Sample? sampleTick; + private Sample? sampleTickDownbeat; + private Sample? sampleLatch; - [CanBeNull] - private ScheduledDelegate tickPlaybackDelegate; + private ScheduledDelegate? tickPlaybackDelegate; [Resolved] - private OverlayColourProvider overlayColourProvider { get; set; } + private OverlayColourProvider overlayColourProvider { get; set; } = null!; public bool EnableClicking { get; set; } = true; @@ -225,13 +221,13 @@ namespace osu.Game.Screens.Edit.Timing private double beatLength; - private TimingControlPoint timingPoint; + private TimingControlPoint timingPoint = null!; private bool isSwinging; private readonly BindableInt interpolatedBpm = new BindableInt(); - private ScheduledDelegate latchDelegate; + private ScheduledDelegate? latchDelegate; protected override void LoadComplete() { diff --git a/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs b/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs index 0b442fe5da..0437118f81 100644 --- a/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs +++ b/osu.Game/Screens/Edit/Timing/RepeatingButtonBehaviour.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -23,10 +21,10 @@ namespace osu.Game.Screens.Edit.Timing private readonly Drawable button; - private Sample sample; + private Sample? sample; - public Action RepeatBegan; - public Action RepeatEnded; + public Action? RepeatBegan; + public Action? RepeatEnded; /// /// An additive modifier for the frequency of the sample played on next actuation. @@ -61,7 +59,7 @@ namespace osu.Game.Screens.Edit.Timing base.OnMouseUp(e); } - private ScheduledDelegate adjustDelegate; + private ScheduledDelegate? adjustDelegate; private double adjustDelay = initial_delay; private void beginRepeat() diff --git a/osu.Game/Screens/Edit/Timing/RowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttribute.cs index 6f0553c771..71407701db 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -21,9 +19,9 @@ namespace osu.Game.Screens.Edit.Timing private readonly string label; - protected Drawable Background { get; private set; } + protected Drawable Background { get; private set; } = null!; - protected FillFlowContainer Content { get; private set; } + protected FillFlowContainer Content { get; private set; } = null!; public RowAttribute(ControlPoint point, string label) { diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs index 49791bd99a..4cae774078 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeProgressBar.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs index c9d7aab5d8..d735c93523 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/AttributeText.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps.ControlPoints; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs index 4d3704d44a..43f3739503 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/DifficultyRowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,7 +13,7 @@ namespace osu.Game.Screens.Edit.Timing.RowAttributes { private readonly BindableNumber speedMultiplier; - private OsuSpriteText text; + private OsuSpriteText text = null!; public DifficultyRowAttribute(DifficultyControlPoint difficulty) : base(difficulty, "difficulty") diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs index 88943e5578..3b068699ca 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/EffectRowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -16,9 +14,9 @@ namespace osu.Game.Screens.Edit.Timing.RowAttributes private readonly Bindable omitBarLine; private readonly BindableNumber scrollSpeed; - private AttributeText kiaiModeBubble; - private AttributeText omitBarLineBubble; - private AttributeText text; + private AttributeText kiaiModeBubble = null!; + private AttributeText omitBarLineBubble = null!; + private AttributeText text = null!; public EffectRowAttribute(EffectControlPoint effect) : base(effect, "effect") diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs index 915cf63baa..e86a991521 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/SampleRowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -13,8 +11,8 @@ namespace osu.Game.Screens.Edit.Timing.RowAttributes { public partial class SampleRowAttribute : RowAttribute { - private AttributeText sampleText; - private OsuSpriteText volumeText; + private AttributeText sampleText = null!; + private OsuSpriteText volumeText = null!; private readonly Bindable sampleBank; private readonly BindableNumber volume; diff --git a/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs b/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs index 3887282c6a..a6d3816bd4 100644 --- a/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs +++ b/osu.Game/Screens/Edit/Timing/RowAttributes/TimingRowAttribute.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions; @@ -17,7 +15,7 @@ namespace osu.Game.Screens.Edit.Timing.RowAttributes { private readonly BindableNumber beatLength; private readonly Bindable timeSignature; - private OsuSpriteText text; + private OsuSpriteText text = null!; public TimingRowAttribute(TimingControlPoint timing) : base(timing, "timing") diff --git a/osu.Game/Screens/Edit/Timing/Section.cs b/osu.Game/Screens/Edit/Timing/Section.cs index ebba481099..ba3874dcee 100644 --- a/osu.Game/Screens/Edit/Timing/Section.cs +++ b/osu.Game/Screens/Edit/Timing/Section.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -19,23 +17,23 @@ namespace osu.Game.Screens.Edit.Timing internal abstract partial class Section : CompositeDrawable where T : ControlPoint { - private OsuCheckbox checkbox; - private Container content; + private OsuCheckbox checkbox = null!; + private Container content = null!; - protected FillFlowContainer Flow { get; private set; } + protected FillFlowContainer Flow { get; private set; } = null!; - protected Bindable ControlPoint { get; } = new Bindable(); + protected Bindable ControlPoint { get; } = new Bindable(); private const float header_height = 50; [Resolved] - protected EditorBeatmap Beatmap { get; private set; } + protected EditorBeatmap Beatmap { get; private set; } = null!; [Resolved] - protected Bindable SelectedGroup { get; private set; } + protected Bindable SelectedGroup { get; private set; } = null!; - [Resolved(canBeNull: true)] - protected IEditorChangeHandler ChangeHandler { get; private set; } + [Resolved] + protected IEditorChangeHandler? ChangeHandler { get; private set; } [BackgroundDependencyLoader] private void load(OverlayColourProvider colours) @@ -128,7 +126,7 @@ namespace osu.Game.Screens.Edit.Timing ControlPoint.BindValueChanged(OnControlPointChanged, true); } - protected abstract void OnControlPointChanged(ValueChangedEvent point); + protected abstract void OnControlPointChanged(ValueChangedEvent point); protected abstract T CreatePoint(); } diff --git a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs index 65c5128438..1bf0e5299d 100644 --- a/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs +++ b/osu.Game/Screens/Edit/Timing/SliderWithTextBoxInput.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using osu.Framework.Bindables; diff --git a/osu.Game/Screens/Edit/Timing/TapButton.cs b/osu.Game/Screens/Edit/Timing/TapButton.cs index af5e6aa180..f28c6ccf0a 100644 --- a/osu.Game/Screens/Edit/Timing/TapButton.cs +++ b/osu.Game/Screens/Edit/Timing/TapButton.cs @@ -37,10 +37,10 @@ namespace osu.Game.Screens.Edit.Timing [Resolved] private OverlayColourProvider colourProvider { get; set; } = null!; - [Resolved(canBeNull: true)] + [Resolved] private Bindable? selectedGroup { get; set; } - [Resolved(canBeNull: true)] + [Resolved] private IBeatSyncProvider? beatSyncSource { get; set; } private Circle hoverLayer = null!; diff --git a/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs b/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs index 4018eff5d6..fac168c70c 100644 --- a/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs +++ b/osu.Game/Screens/Edit/Timing/TimingAdjustButton.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework.Allocation; @@ -22,7 +20,7 @@ namespace osu.Game.Screens.Edit.Timing /// public partial class TimingAdjustButton : CompositeDrawable { - public Action Action; + public Action? Action; private readonly double adjustAmount; @@ -44,10 +42,10 @@ namespace osu.Game.Screens.Edit.Timing private readonly RepeatingButtonBehaviour repeatBehaviour; [Resolved] - private OverlayColourProvider colourProvider { get; set; } + private OverlayColourProvider colourProvider { get; set; } = null!; [Resolved] - private EditorBeatmap editorBeatmap { get; set; } + private EditorBeatmap editorBeatmap { get; set; } = null!; public TimingAdjustButton(double adjustAmount) { @@ -104,7 +102,7 @@ namespace osu.Game.Screens.Edit.Timing if (hoveredBox == null) return false; - Action(adjustAmount * hoveredBox.Multiplier); + Action?.Invoke(adjustAmount * hoveredBox.Multiplier); hoveredBox.Flash(); @@ -119,6 +117,9 @@ namespace osu.Game.Screens.Edit.Timing private readonly Box box; private readonly OsuSpriteText text; + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + public IncrementBox(int index, double amount) { Multiplier = Math.Sign(index) * convertMultiplier(index); @@ -156,9 +157,6 @@ namespace osu.Game.Screens.Edit.Timing }; } - [Resolved] - private OverlayColourProvider colourProvider { get; set; } - protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Screens/Edit/Timing/TimingSection.cs b/osu.Game/Screens/Edit/Timing/TimingSection.cs index 81abb266d4..d2d524ccbe 100644 --- a/osu.Game/Screens/Edit/Timing/TimingSection.cs +++ b/osu.Game/Screens/Edit/Timing/TimingSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -13,8 +11,8 @@ namespace osu.Game.Screens.Edit.Timing { internal partial class TimingSection : Section { - private LabelledTimeSignature timeSignature; - private BPMTextBox bpmTextEntry; + private LabelledTimeSignature timeSignature = null!; + private BPMTextBox bpmTextEntry = null!; [BackgroundDependencyLoader] private void load() @@ -45,7 +43,7 @@ namespace osu.Game.Screens.Edit.Timing private bool isRebinding; - protected override void OnControlPointChanged(ValueChangedEvent point) + protected override void OnControlPointChanged(ValueChangedEvent point) { if (point.NewValue != null) { From 4b42240fbabf6d542594b1691a4e2746947fecab Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:24:28 +0300 Subject: [PATCH 180/248] Enable nullability for setup screen --- osu.Game/Screens/Edit/Setup/ColoursSection.cs | 4 +--- osu.Game/Screens/Edit/Setup/DesignSection.cs | 18 ++++++++---------- .../Screens/Edit/Setup/DifficultySection.cs | 10 ++++------ .../Edit/Setup/LabelledRomanisedTextBox.cs | 2 -- .../Edit/Setup/LabelledTextBoxWithPopover.cs | 4 +--- osu.Game/Screens/Edit/Setup/MetadataSection.cs | 18 ++++++++---------- .../Screens/Edit/Setup/RulesetSetupSection.cs | 2 -- osu.Game/Screens/Edit/Setup/SetupScreen.cs | 2 -- .../Screens/Edit/Setup/SetupScreenHeader.cs | 8 +++----- .../Edit/Setup/SetupScreenHeaderBackground.cs | 6 ++---- osu.Game/Screens/Edit/Setup/SetupSection.cs | 8 +++----- 11 files changed, 30 insertions(+), 52 deletions(-) diff --git a/osu.Game/Screens/Edit/Setup/ColoursSection.cs b/osu.Game/Screens/Edit/Setup/ColoursSection.cs index 10ab272a87..8cd5c0f779 100644 --- a/osu.Game/Screens/Edit/Setup/ColoursSection.cs +++ b/osu.Game/Screens/Edit/Setup/ColoursSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; @@ -15,7 +13,7 @@ namespace osu.Game.Screens.Edit.Setup { public override LocalisableString Title => EditorSetupStrings.ColoursHeader; - private LabelledColourPalette comboColours; + private LabelledColourPalette comboColours = null!; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index fd70b0c142..b05a073146 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Globalization; using System.Linq; @@ -19,16 +17,16 @@ namespace osu.Game.Screens.Edit.Setup { internal partial class DesignSection : SetupSection { - protected LabelledSwitchButton EnableCountdown; + protected LabelledSwitchButton EnableCountdown = null!; - protected FillFlowContainer CountdownSettings; - protected LabelledEnumDropdown CountdownSpeed; - protected LabelledNumberBox CountdownOffset; + protected FillFlowContainer CountdownSettings = null!; + protected LabelledEnumDropdown CountdownSpeed = null!; + protected LabelledNumberBox CountdownOffset = null!; - private LabelledSwitchButton widescreenSupport; - private LabelledSwitchButton epilepsyWarning; - private LabelledSwitchButton letterboxDuringBreaks; - private LabelledSwitchButton samplesMatchPlaybackRate; + private LabelledSwitchButton widescreenSupport = null!; + private LabelledSwitchButton epilepsyWarning = null!; + private LabelledSwitchButton letterboxDuringBreaks = null!; + private LabelledSwitchButton samplesMatchPlaybackRate = null!; public override LocalisableString Title => EditorSetupStrings.DesignHeader; diff --git a/osu.Game/Screens/Edit/Setup/DifficultySection.cs b/osu.Game/Screens/Edit/Setup/DifficultySection.cs index afe6b36cba..7026bde681 100644 --- a/osu.Game/Screens/Edit/Setup/DifficultySection.cs +++ b/osu.Game/Screens/Edit/Setup/DifficultySection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -17,10 +15,10 @@ namespace osu.Game.Screens.Edit.Setup { internal partial class DifficultySection : SetupSection { - private LabelledSliderBar circleSizeSlider; - private LabelledSliderBar healthDrainSlider; - private LabelledSliderBar approachRateSlider; - private LabelledSliderBar overallDifficultySlider; + private LabelledSliderBar circleSizeSlider = null!; + private LabelledSliderBar healthDrainSlider = null!; + private LabelledSliderBar approachRateSlider = null!; + private LabelledSliderBar overallDifficultySlider = null!; public override LocalisableString Title => EditorSetupStrings.DifficultyHeader; diff --git a/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs b/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs index 43c20b5e40..85c697bf14 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledRomanisedTextBox.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterfaceV2; diff --git a/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs b/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs index 05c8f88444..79288e2977 100644 --- a/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs +++ b/osu.Game/Screens/Edit/Setup/LabelledTextBoxWithPopover.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Extensions; using osu.Framework.Graphics; @@ -30,7 +28,7 @@ namespace osu.Game.Screens.Edit.Setup internal partial class PopoverTextBox : OsuTextBox { - public Action OnFocused; + public Action? OnFocused; protected override bool OnDragStart(DragStartEvent e) { diff --git a/osu.Game/Screens/Edit/Setup/MetadataSection.cs b/osu.Game/Screens/Edit/Setup/MetadataSection.cs index c2c853f7b2..752f590308 100644 --- a/osu.Game/Screens/Edit/Setup/MetadataSection.cs +++ b/osu.Game/Screens/Edit/Setup/MetadataSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics.UserInterface; @@ -16,16 +14,16 @@ namespace osu.Game.Screens.Edit.Setup { public partial class MetadataSection : SetupSection { - protected LabelledTextBox ArtistTextBox; - protected LabelledTextBox RomanisedArtistTextBox; + protected LabelledTextBox ArtistTextBox = null!; + protected LabelledTextBox RomanisedArtistTextBox = null!; - protected LabelledTextBox TitleTextBox; - protected LabelledTextBox RomanisedTitleTextBox; + protected LabelledTextBox TitleTextBox = null!; + protected LabelledTextBox RomanisedTitleTextBox = null!; - private LabelledTextBox creatorTextBox; - private LabelledTextBox difficultyTextBox; - private LabelledTextBox sourceTextBox; - private LabelledTextBox tagsTextBox; + private LabelledTextBox creatorTextBox = null!; + private LabelledTextBox difficultyTextBox = null!; + private LabelledTextBox sourceTextBox = null!; + private LabelledTextBox tagsTextBox = null!; public override LocalisableString Title => EditorSetupStrings.MetadataHeader; diff --git a/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs b/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs index 0914bd47bc..af59868f29 100644 --- a/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs +++ b/osu.Game/Screens/Edit/Setup/RulesetSetupSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Localisation; using osu.Game.Rulesets; using osu.Game.Localisation; diff --git a/osu.Game/Screens/Edit/Setup/SetupScreen.cs b/osu.Game/Screens/Edit/Setup/SetupScreen.cs index cc705547de..ab4299a2f0 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreen.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs index 0a6643efeb..1d66830adf 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeader.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; @@ -18,12 +16,12 @@ namespace osu.Game.Screens.Edit.Setup { internal partial class SetupScreenHeader : OverlayHeader { - public SetupScreenHeaderBackground Background { get; private set; } + public SetupScreenHeaderBackground Background { get; private set; } = null!; [Resolved] - private SectionsContainer sections { get; set; } + private SectionsContainer sections { get; set; } = null!; - private SetupScreenTabControl tabControl; + private SetupScreenTabControl tabControl = null!; protected override OverlayTitle CreateTitle() => new SetupScreenTitle(); diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs index 50743476bf..47a7512adf 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -18,10 +16,10 @@ namespace osu.Game.Screens.Edit.Setup public partial class SetupScreenHeaderBackground : CompositeDrawable { [Resolved] - private OsuColour colours { get; set; } + private OsuColour colours { get; set; } = null!; [Resolved] - private IBindable working { get; set; } + private IBindable working { get; set; } = null!; private readonly Container content; diff --git a/osu.Game/Screens/Edit/Setup/SetupSection.cs b/osu.Game/Screens/Edit/Setup/SetupSection.cs index c7690623ad..5f676798f1 100644 --- a/osu.Game/Screens/Edit/Setup/SetupSection.cs +++ b/osu.Game/Screens/Edit/Setup/SetupSection.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -16,7 +14,7 @@ namespace osu.Game.Screens.Edit.Setup { public abstract partial class SetupSection : Container { - private FillFlowContainer flow; + private FillFlowContainer flow = null!; /// /// Used to align some of the child s together to achieve a grid-like look. @@ -24,10 +22,10 @@ namespace osu.Game.Screens.Edit.Setup protected const float LABEL_WIDTH = 160; [Resolved] - protected OsuColour Colours { get; private set; } + protected OsuColour Colours { get; private set; } = null!; [Resolved] - protected EditorBeatmap Beatmap { get; private set; } + protected EditorBeatmap Beatmap { get; private set; } = null!; protected override Container Content => flow; From f70dedfd17768df2b2677fa293510fb767cd2ceb Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:24:48 +0300 Subject: [PATCH 181/248] Enable nullability for design screen --- osu.Game/Screens/Edit/Design/DesignScreen.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Design/DesignScreen.cs b/osu.Game/Screens/Edit/Design/DesignScreen.cs index 10b351ded1..c36afcdb6d 100644 --- a/osu.Game/Screens/Edit/Design/DesignScreen.cs +++ b/osu.Game/Screens/Edit/Design/DesignScreen.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Screens.Edit.Design { public partial class DesignScreen : EditorScreen From e2d6e31314253bb3dcfd1089ca082c2f0f80ad6b Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 02:26:26 +0300 Subject: [PATCH 182/248] Using --- osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs index 5a5c58dc93..e62f1cebf0 100644 --- a/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/GroupBadge.cs @@ -1,7 +1,6 @@ // 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.Allocation; using osu.Framework.Extensions.Color4Extensions; From 77e8315ee28bbbdedb3d0182022ad3b3e6ec6bef Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:30:10 +0300 Subject: [PATCH 183/248] Adjust naming --- osu.Game/Localisation/NotificationsStrings.cs | 5 ++--- osu.Game/Screens/Play/HUDOverlay.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index f5c3589c60..a1c974c777 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -32,8 +32,7 @@ namespace osu.Game.Localisation /// /// "Your battery level is low! Charge your device to prevent interruptions during gameplay." /// - public static LocalisableString LowBatteryWarning => - new TranslatableString(getKey(@"low_battery_warning"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); + public static LocalisableString BatteryLow => new TranslatableString(getKey(@"battery_low"), @"Your battery level is low! Charge your device to prevent interruptions during gameplay."); /// /// "Your game volume is too low to hear anything! Click here to restore it." @@ -54,7 +53,7 @@ namespace osu.Game.Localisation /// /// "The score overlay is currently disabled. You can toggle this by pressing {0}." /// - public static LocalisableString TheScoreOverlayIsDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"the_score_overlay_is_disabled"), + public static LocalisableString ScoreOverlayDisabled(LocalisableString arg0) => new TranslatableString(getKey(@"score_overlay_disabled"), @"The score overlay is currently disabled. You can toggle this by pressing {0}.", arg0); private static string getKey(string key) => $@"{prefix}:{key}"; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index ee198d0209..076d43c077 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -173,7 +173,7 @@ namespace osu.Game.Screens.Play notificationOverlay?.Post(new SimpleNotification { - Text = NotificationsStrings.TheScoreOverlayIsDisabled(config.LookupKeyBindings(GlobalAction.ToggleInGameInterface)) + Text = NotificationsStrings.ScoreOverlayDisabled(config.LookupKeyBindings(GlobalAction.ToggleInGameInterface)) }); } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index de67642104..d9062da8aa 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -606,7 +606,7 @@ namespace osu.Game.Screens.Play public BatteryWarningNotification() { - Text = NotificationsStrings.LowBatteryWarning; + Text = NotificationsStrings.BatteryLow; } [BackgroundDependencyLoader] From cb4f32e7bd7fb2912e98ca0d70e1308cb646113d Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 02:31:27 +0300 Subject: [PATCH 184/248] Use `StatusIcon` in `UserDropdown` --- osu.Game/Overlays/Login/UserDropdown.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Login/UserDropdown.cs b/osu.Game/Overlays/Login/UserDropdown.cs index dfc9d12977..f856f57c46 100644 --- a/osu.Game/Overlays/Login/UserDropdown.cs +++ b/osu.Game/Overlays/Login/UserDropdown.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Users.Drawables; using osuTK; using osuTK.Graphics; @@ -78,7 +79,7 @@ namespace osu.Game.Overlays.Login { public const float LABEL_LEFT_MARGIN = 20; - private readonly SpriteIcon statusIcon; + private readonly StatusIcon statusIcon; public Color4 StatusColour { @@ -101,11 +102,10 @@ namespace osu.Game.Overlays.Login Icon.Size = new Vector2(14); Icon.Margin = new MarginPadding(0); - Foreground.Add(statusIcon = new SpriteIcon + Foreground.Add(statusIcon = new StatusIcon { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Icon = FontAwesome.Regular.Circle, Size = new Vector2(14), }); From c95d8645f3afbd56ea71fc2be2093e9eab848b9a Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sat, 14 Jan 2023 02:42:04 +0300 Subject: [PATCH 185/248] Revert "Use existing string" This reverts commit f950b624ae4f0659f12f43148b2782aff60b98df. --- osu.Game/Localisation/NotificationsStrings.cs | 5 +++++ osu.Game/Overlays/NotificationOverlay.cs | 4 +--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Localisation/NotificationsStrings.cs b/osu.Game/Localisation/NotificationsStrings.cs index a1c974c777..6a9793b20c 100644 --- a/osu.Game/Localisation/NotificationsStrings.cs +++ b/osu.Game/Localisation/NotificationsStrings.cs @@ -24,6 +24,11 @@ namespace osu.Game.Localisation /// public static LocalisableString RunningTasks => new TranslatableString(getKey(@"running_tasks"), @"Running Tasks"); + /// + /// "Clear All" + /// + public static LocalisableString ClearAll => new TranslatableString(getKey(@"clear_all"), @"Clear All"); + /// /// "Cancel All" /// diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index ed2a67cd6b..71a4c58afd 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -17,7 +17,6 @@ using osu.Game.Overlays.Notifications; using osu.Game.Resources.Localisation.Web; using osuTK; using NotificationsStrings = osu.Game.Localisation.NotificationsStrings; -using WebNotificationsStrings = osu.Game.Resources.Localisation.Web.NotificationsStrings; namespace osu.Game.Overlays { @@ -93,8 +92,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Children = new[] { - new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, - WebNotificationsStrings.MarkRead(WebNotificationsStrings.FiltersDefault)), + new NotificationSection(AccountsStrings.NotificationsTitle, new[] { typeof(SimpleNotification) }, NotificationsStrings.ClearAll), new NotificationSection(NotificationsStrings.RunningTasks, new[] { typeof(ProgressNotification) }, NotificationsStrings.CancelAll), } } From e07c0c7c1fc215b24c16f82c4d015235ea2714f6 Mon Sep 17 00:00:00 2001 From: StanR Date: Sat, 14 Jan 2023 02:58:18 +0300 Subject: [PATCH 186/248] Using --- osu.Game/Overlays/Login/UserDropdown.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Login/UserDropdown.cs b/osu.Game/Overlays/Login/UserDropdown.cs index f856f57c46..0bdfa82517 100644 --- a/osu.Game/Overlays/Login/UserDropdown.cs +++ b/osu.Game/Overlays/Login/UserDropdown.cs @@ -7,7 +7,6 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; -using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; From befb27551201a49cc11f6739dd0160afe718d7df Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 14 Jan 2023 14:34:22 +0300 Subject: [PATCH 187/248] Fix intermittent failure in GCC seeking test --- .../TestSceneMasterGameplayClockContainer.cs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs b/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs index 3c6ec28da2..393217f371 100644 --- a/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs +++ b/osu.Game.Tests/Gameplay/TestSceneMasterGameplayClockContainer.cs @@ -73,16 +73,6 @@ namespace osu.Game.Tests.Gameplay } [Test] - [FlakyTest] - /* - * Fail rate around 0.15% - * - * TearDown : osu.Framework.Testing.Drawables.Steps.AssertButton+TracedException : gameplay clock time = 2500 - * --TearDown - * at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal() - * at osu.Framework.Threading.Scheduler.Update() - * at osu.Framework.Graphics.Drawable.UpdateSubTree() - */ public void TestSeekPerformsInGameplayTime( [Values(1.0, 0.5, 2.0)] double clockRate, [Values(0.0, 200.0, -200.0)] double userOffset, @@ -92,6 +82,9 @@ namespace osu.Game.Tests.Gameplay ClockBackedTestWorkingBeatmap working = null; GameplayClockContainer gameplayClockContainer = null; + // ReSharper disable once NotAccessedVariable + BindableDouble trackAdjustment = null; // keeping a reference for track adjustment + if (setAudioOffsetBeforeConstruction) AddStep($"preset audio offset to {userOffset}", () => localConfig.SetValue(OsuSetting.AudioOffset, userOffset)); @@ -103,16 +96,16 @@ namespace osu.Game.Tests.Gameplay gameplayClockContainer.Reset(startClock: !whileStopped); }); - AddStep($"set clock rate to {clockRate}", () => working.Track.AddAdjustment(AdjustableProperty.Frequency, new BindableDouble(clockRate))); + AddStep($"set clock rate to {clockRate}", () => working.Track.AddAdjustment(AdjustableProperty.Frequency, trackAdjustment = new BindableDouble(clockRate))); if (!setAudioOffsetBeforeConstruction) AddStep($"set audio offset to {userOffset}", () => localConfig.SetValue(OsuSetting.AudioOffset, userOffset)); AddStep("seek to 2500", () => gameplayClockContainer.Seek(2500)); - AddStep("gameplay clock time = 2500", () => Assert.AreEqual(gameplayClockContainer.CurrentTime, 2500, 10f)); + AddAssert("gameplay clock time = 2500", () => gameplayClockContainer.CurrentTime, () => Is.EqualTo(2500).Within(10f)); AddStep("seek to 10000", () => gameplayClockContainer.Seek(10000)); - AddStep("gameplay clock time = 10000", () => Assert.AreEqual(gameplayClockContainer.CurrentTime, 10000, 10f)); + AddAssert("gameplay clock time = 10000", () => gameplayClockContainer.CurrentTime, () => Is.EqualTo(10000).Within(10f)); } protected override void Dispose(bool isDisposing) From 2831db53f74088e1fb08e39cf51ded52cd5d76e9 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sat, 14 Jan 2023 14:19:02 +0000 Subject: [PATCH 188/248] fix wrong control flow on hover lost --- .../Play/PlayerSettings/PlayerSettingsGroup.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 63e081b2ea..f4769cd417 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -29,12 +29,13 @@ namespace osu.Game.Screens.Play.PlayerSettings protected override void OnHoverLost(HoverLostEvent e) { - if (hoverExpandEvent == null) return; + if (hoverExpandEvent != null) + { + hoverExpandEvent?.Cancel(); + hoverExpandEvent = null; - hoverExpandEvent?.Cancel(); - hoverExpandEvent = null; - - Expanded.Value = false; + Expanded.Value = false; + } base.OnHoverLost(e); } From 3fa81a52b4a6b1e99190c712f45adfd128b6ea2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 16:53:03 +0100 Subject: [PATCH 189/248] Add other profile sections to test scene --- .../Online/TestSceneUserProfileOverlay.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs index f209e8a8bb..f7e88e4437 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs @@ -86,12 +86,21 @@ namespace osu.Game.Tests.Visual.Online CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", JoinDate = DateTimeOffset.Now.AddDays(-1), LastVisit = DateTimeOffset.Now, - ProfileOrder = new[] { "me" }, Groups = new[] { new APIUserGroup { Colour = "#EB47D0", ShortName = "DEV", Name = "Developers" }, new APIUserGroup { Colour = "#A347EB", ShortName = "BN", Name = "Beatmap Nominators", Playmodes = new[] { "osu", "taiko" } } }, + ProfileOrder = new[] + { + @"me", + @"recent_activity", + @"beatmaps", + @"historical", + @"kudosu", + @"top_ranks", + @"medals" + }, Statistics = new UserStatistics { IsRanked = true, @@ -128,7 +137,12 @@ namespace osu.Game.Tests.Visual.Online Title = "osu!volunteer", Colour = "ff0000", Achievements = Array.Empty(), - PlayMode = "osu" + PlayMode = "osu", + Kudosu = new APIUser.KudosuCount + { + Available = 10, + Total = 50 + } }; } } From 49e08c06a626844eb32d880dcbf4a182325bc590 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 16:58:25 +0100 Subject: [PATCH 190/248] Adjust general appearance of user profile overlay --- .../Overlays/Profile/Header/MedalHeaderContainer.cs | 12 ++---------- osu.Game/Overlays/UserProfileOverlay.cs | 4 ++-- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index edb695a00e..2652550fb5 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -4,7 +4,6 @@ using System.Threading; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -12,7 +11,6 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header.Components; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header { @@ -43,14 +41,8 @@ namespace osu.Game.Overlays.Profile.Header Child = new Box { RelativeSizeAxes = Axes.Both, - Colour = new ColourInfo - { - TopLeft = Color4.Black.Opacity(0.2f), - TopRight = Color4.Black.Opacity(0.2f), - BottomLeft = Color4.Black.Opacity(0), - BottomRight = Color4.Black.Opacity(0) - } - }, + Colour = ColourInfo.GradientVertical(Colour4.Black.Opacity(0.2f), Colour4.Black.Opacity(0)) + } }, badgeFlowContainer = new FillFlowContainer { diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index cf7bb56cb8..b6ff78b09b 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays [Resolved] private RulesetStore rulesets { get; set; } = null!; - public const float CONTENT_X_MARGIN = 70; + public const float CONTENT_X_MARGIN = 50; public UserProfileOverlay() : base(OverlayColourScheme.Pink) @@ -59,7 +59,7 @@ namespace osu.Game.Overlays protected override ProfileHeader CreateHeader() => new ProfileHeader(); - protected override Color4 BackgroundColour => ColourProvider.Background6; + protected override Color4 BackgroundColour => ColourProvider.Background5; public void ShowUser(IUser user, IRulesetInfo? ruleset = null) { From 3f81f173fb0b34ac5c2691be799f34b022b98840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 17:17:35 +0100 Subject: [PATCH 191/248] Adjust appearance of section navigation --- osu.Game/Overlays/UserProfileOverlay.cs | 80 +++++++++++++++++-------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index b6ff78b09b..f9c6662ee3 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -12,7 +12,9 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Game.Extensions; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.API.Requests; @@ -171,46 +173,72 @@ namespace osu.Game.Overlays loadingLayer.Hide(); } - private partial class ProfileSectionTabControl : OverlayTabControl + private partial class ProfileSectionTabControl : OsuTabControl { - private const float bar_height = 2; - public ProfileSectionTabControl() { - TabContainer.RelativeSizeAxes &= ~Axes.X; - TabContainer.AutoSizeAxes |= Axes.X; - TabContainer.Anchor |= Anchor.x1; - TabContainer.Origin |= Anchor.x1; - - Height = 36 + bar_height; - BarHeight = bar_height; + Height = 40; + Padding = new MarginPadding { Horizontal = CONTENT_X_MARGIN }; + TabContainer.Spacing = new Vector2(20); } - protected override TabItem CreateTabItem(ProfileSection value) => new ProfileSectionTabItem(value) - { - AccentColour = AccentColour, - }; - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - AccentColour = colourProvider.Highlight1; - } + protected override TabItem CreateTabItem(ProfileSection value) => new ProfileSectionTabItem(value); protected override bool OnClick(ClickEvent e) => true; protected override bool OnHover(HoverEvent e) => true; - private partial class ProfileSectionTabItem : OverlayTabItem + private partial class ProfileSectionTabItem : TabItem { + private OsuSpriteText text = null!; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } = null!; + public ProfileSectionTabItem(ProfileSection value) : base(value) { - Text.Text = value.Title; - Text.Font = Text.Font.With(size: 16); - Text.Margin = new MarginPadding { Bottom = 10 + bar_height }; - Bar.ExpandedSize = 10; - Bar.Margin = new MarginPadding { Bottom = bar_height }; + } + + [BackgroundDependencyLoader] + private void load() + { + AutoSizeAxes = Axes.Both; + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + + InternalChild = text = new OsuSpriteText + { + Text = Value.Title + }; + + updateState(); + } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); + + protected override bool OnHover(HoverEvent e) + { + updateState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) => updateState(); + + private void updateState() + { + text.Font = OsuFont.Default.With(size: 14, weight: Active.Value ? FontWeight.SemiBold : FontWeight.Regular); + + Colour4 textColour; + + if (IsHovered) + textColour = colourProvider.Light1; + else + textColour = Active.Value ? colourProvider.Content1 : colourProvider.Light2; + + text.FadeColour(textColour, 300, Easing.OutQuint); } } } From 5b1111c6b1a0ba56aff0e7e4acf39558cd8362d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 17:32:20 +0100 Subject: [PATCH 192/248] Adjust appearance of user profile sections --- osu.Game/Overlays/Profile/ProfileSection.cs | 67 ++++++--------------- osu.Game/Overlays/UserProfileOverlay.cs | 4 +- 2 files changed, 22 insertions(+), 49 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index edb3ec1733..03917b75a4 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -3,16 +3,15 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osuTK; namespace osu.Game.Overlays.Profile { @@ -30,22 +29,29 @@ namespace osu.Game.Overlays.Profile public readonly Bindable User = new Bindable(); + private const float outer_gutter_width = 10; + protected ProfileSection() { AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; + Masking = true; + CornerRadius = 10; + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0, 1), + Radius = 3, + Colour = Colour4.Black.Opacity(0.25f) + }; + InternalChildren = new Drawable[] { background = new Box { RelativeSizeAxes = Axes.Both, }, - new SectionTriangles - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - }, new FillFlowContainer { Direction = FillDirection.Vertical, @@ -58,8 +64,8 @@ namespace osu.Game.Overlays.Profile AutoSizeAxes = Axes.Both, Margin = new MarginPadding { - Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, - Top = 15, + Horizontal = UserProfileOverlay.CONTENT_X_MARGIN - outer_gutter_width, + Top = 20, Bottom = 20, }, Children = new Drawable[] @@ -67,7 +73,7 @@ namespace osu.Game.Overlays.Profile new OsuSpriteText { Text = Title, - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold), + Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold), }, underscore = new Box { @@ -88,7 +94,7 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, Padding = new MarginPadding { - Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, + Horizontal = UserProfileOverlay.CONTENT_X_MARGIN - outer_gutter_width, Bottom = 20 } }, @@ -100,43 +106,8 @@ namespace osu.Game.Overlays.Profile [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - background.Colour = colourProvider.Background5; + background.Colour = colourProvider.Background4; underscore.Colour = colourProvider.Highlight1; } - - private partial class SectionTriangles : Container - { - private readonly Triangles triangles; - private readonly Box foreground; - - public SectionTriangles() - { - RelativeSizeAxes = Axes.X; - Height = 100; - Masking = true; - Children = new Drawable[] - { - triangles = new Triangles - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.Both, - TriangleScale = 3, - }, - foreground = new Box - { - RelativeSizeAxes = Axes.Both, - } - }; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - triangles.ColourLight = colourProvider.Background4; - triangles.ColourDark = colourProvider.Background5.Darken(0.2f); - foreground.Colour = ColourInfo.GradientVertical(colourProvider.Background5, colourProvider.Background5.Opacity(0)); - } - } } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index f9c6662ee3..8849c674dc 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -259,7 +259,9 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Spacing = new Vector2(0, 20), + Spacing = new Vector2(0, 10), + Padding = new MarginPadding { Horizontal = 10 }, + Margin = new MarginPadding { Bottom = 10 }, }; } } From e39eb089ce617ac0109d11858e56f2b030dacbde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 20:51:29 +0100 Subject: [PATCH 193/248] Update colouring of some profile section elements --- .../Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs | 4 ++-- osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs | 4 ++-- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs index 53447a971b..8a05341783 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs @@ -112,8 +112,8 @@ namespace osu.Game.Overlays.Profile.Sections.Historical [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - IdleColour = colourProvider.Background4; - HoverColour = colourProvider.Background3; + IdleColour = colourProvider.Background3; + HoverColour = colourProvider.Background2; } } diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index b30faee380..5e1b650bd3 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs @@ -65,8 +65,8 @@ namespace osu.Game.Overlays.Profile.Sections [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - IdleColour = colourProvider.Background3; - HoverColour = colourProvider.Background2; + IdleColour = colourProvider.Background2; + HoverColour = colourProvider.Background1; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 0f3e0bc6b2..529e78a7cf 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -160,7 +160,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Both, Height = 0.5f, - Colour = colourProvider.Background4, + Colour = colourProvider.Background3, Shear = new Vector2(-performance_background_shear, 0), EdgeSmoothness = new Vector2(2, 0), }, @@ -172,7 +172,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks RelativePositionAxes = Axes.Y, Height = -0.5f, Position = new Vector2(0, 1), - Colour = colourProvider.Background4, + Colour = colourProvider.Background3, Shear = new Vector2(performance_background_shear, 0), EdgeSmoothness = new Vector2(2, 0), }, From f80dddbb5e1f45f366617208159fd21206b060c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 17:41:57 +0100 Subject: [PATCH 194/248] Rearrange and adjust header components where simple --- .../Profile/Header/CentreHeaderContainer.cs | 67 +------------------ .../Profile/Header/DetailHeaderContainer.cs | 29 +------- osu.Game/Overlays/Profile/ProfileHeader.cs | 6 +- 3 files changed, 6 insertions(+), 96 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index ecf78e7b92..7721342ba8 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -3,26 +3,18 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Localisation; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header.Components; -using osu.Game.Resources.Localisation.Web; using osuTK; namespace osu.Game.Overlays.Profile.Header { public partial class CentreHeaderContainer : CompositeDrawable { - public readonly BindableBool DetailsVisible = new BindableBool(true); public readonly Bindable User = new Bindable(); - private OverlinedInfoContainer hiddenDetailGlobal = null!; - private OverlinedInfoContainer hiddenDetailCountry = null!; - public CentreHeaderContainer() { Height = 60; @@ -31,15 +23,12 @@ namespace osu.Game.Overlays.Profile.Header [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - Container hiddenDetailContainer; - Container expandedDetailContainer; - InternalChildren = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4 + Colour = colourProvider.Background3 }, new FillFlowContainer { @@ -66,20 +55,6 @@ namespace osu.Game.Overlays.Profile.Header } }, new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Y, - Padding = new MarginPadding { Vertical = 10 }, - Width = UserProfileOverlay.CONTENT_X_MARGIN, - Child = new ExpandDetailsButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - DetailsVisible = { BindTarget = DetailsVisible } - }, - }, - new Container { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -94,7 +69,7 @@ namespace osu.Game.Overlays.Profile.Header Size = new Vector2(40), User = { BindTarget = User } }, - expandedDetailContainer = new Container + new Container { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -107,47 +82,9 @@ namespace osu.Game.Overlays.Profile.Header User = { BindTarget = User } } }, - hiddenDetailContainer = new FillFlowContainer - { - Direction = FillDirection.Horizontal, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Width = 200, - AutoSizeAxes = Axes.Y, - Alpha = 0, - Spacing = new Vector2(10, 0), - Margin = new MarginPadding { Right = 50 }, - Children = new[] - { - hiddenDetailGlobal = new OverlinedInfoContainer - { - Title = UsersStrings.ShowRankGlobalSimple, - LineColour = colourProvider.Highlight1 - }, - hiddenDetailCountry = new OverlinedInfoContainer - { - Title = UsersStrings.ShowRankCountrySimple, - LineColour = colourProvider.Highlight1 - }, - } - } } } }; - - DetailsVisible.BindValueChanged(visible => - { - hiddenDetailContainer.FadeTo(visible.NewValue ? 0 : 1, 200, Easing.OutQuint); - expandedDetailContainer.FadeTo(visible.NewValue ? 1 : 0, 200, Easing.OutQuint); - }); - - User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); - } - - private void updateDisplay(APIUser? user) - { - hiddenDetailGlobal.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; - hiddenDetailCountry.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-"; } } } diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 3bab798caf..63473e007d 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -26,35 +26,10 @@ namespace osu.Game.Overlays.Profile.Header private OverlinedInfoContainer ppInfo = null!; private OverlinedInfoContainer detailGlobalRank = null!; private OverlinedInfoContainer detailCountryRank = null!; - private FillFlowContainer? fillFlow; private RankGraph rankGraph = null!; public readonly Bindable User = new Bindable(); - private bool expanded = true; - - public bool Expanded - { - set - { - if (expanded == value) return; - - expanded = value; - - if (fillFlow == null) return; - - fillFlow.ClearTransforms(); - - if (expanded) - fillFlow.AutoSizeAxes = Axes.Y; - else - { - fillFlow.AutoSizeAxes = Axes.None; - fillFlow.ResizeHeightTo(0, 200, Easing.OutQuint); - } - } - } - [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider, OsuColour colours) { @@ -69,10 +44,10 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background5, }, - fillFlow = new FillFlowContainer + new FillFlowContainer { RelativeSizeAxes = Axes.X, - AutoSizeAxes = expanded ? Axes.Y : Axes.None, + AutoSizeAxes = Axes.Y, AutoSizeDuration = 200, AutoSizeEasing = Easing.OutQuint, Masking = true, diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index bd12837343..c559a1c102 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -39,8 +39,6 @@ namespace osu.Game.Overlays.Profile // Haphazardly guaranteed by OverlayHeader constructor (see CreateBackground / CreateContent). Debug.Assert(centreHeaderContainer != null); Debug.Assert(detailHeaderContainer != null); - - centreHeaderContainer.DetailsVisible.BindValueChanged(visible => detailHeaderContainer.Expanded = visible.NewValue, true); } protected override Drawable CreateBackground() => @@ -75,7 +73,7 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, User = { BindTarget = User }, }, - centreHeaderContainer = new CentreHeaderContainer + new MedalHeaderContainer { RelativeSizeAxes = Axes.X, User = { BindTarget = User }, @@ -85,7 +83,7 @@ namespace osu.Game.Overlays.Profile RelativeSizeAxes = Axes.X, User = { BindTarget = User }, }, - new MedalHeaderContainer + centreHeaderContainer = new CentreHeaderContainer { RelativeSizeAxes = Axes.X, User = { BindTarget = User }, From de077403e9b2a6259c74e6d8ba80221da249b3ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 17:51:58 +0100 Subject: [PATCH 195/248] Adjust visual appearance of profile value displays --- ...nfoContainer.cs => ProfileValueDisplay.cs} | 30 ++++++++----------- ...linedTotalPlayTime.cs => TotalPlayTime.cs} | 11 ++++--- .../Profile/Header/DetailHeaderContainer.cs | 30 ++++++++----------- 3 files changed, 30 insertions(+), 41 deletions(-) rename osu.Game/Overlays/Profile/Header/Components/{OverlinedInfoContainer.cs => ProfileValueDisplay.cs} (64%) rename osu.Game/Overlays/Profile/Header/Components/{OverlinedTotalPlayTime.cs => TotalPlayTime.cs} (83%) diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs similarity index 64% rename from osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs index 42b67865a0..4b1a0409a3 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs @@ -1,19 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public partial class OverlinedInfoContainer : CompositeDrawable + public partial class ProfileValueDisplay : CompositeDrawable { - private readonly Circle line; private readonly OsuSpriteText title; private readonly OsuSpriteText content; @@ -27,12 +25,7 @@ namespace osu.Game.Overlays.Profile.Header.Components set => content.Text = value; } - public Color4 LineColour - { - set => line.Colour = value; - } - - public OverlinedInfoContainer(bool big = false, int minimumWidth = 60) + public ProfileValueDisplay(bool big = false, int minimumWidth = 60) { AutoSizeAxes = Axes.Both; InternalChild = new FillFlowContainer @@ -41,19 +34,13 @@ namespace osu.Game.Overlays.Profile.Header.Components AutoSizeAxes = Axes.Both, Children = new Drawable[] { - line = new Circle - { - RelativeSizeAxes = Axes.X, - Height = 2, - Margin = new MarginPadding { Bottom = 2 } - }, title = new OsuSpriteText { - Font = OsuFont.GetFont(size: big ? 14 : 12, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: 12) }, content = new OsuSpriteText { - Font = OsuFont.GetFont(size: big ? 40 : 18, weight: FontWeight.Light) + Font = OsuFont.GetFont(size: big ? 30 : 20, weight: FontWeight.Light) }, new Container // Add a minimum size to the FillFlowContainer { @@ -62,5 +49,12 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + title.Colour = colourProvider.Content1; + content.Colour = colourProvider.Content2; + } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs similarity index 83% rename from osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs rename to osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs index 0396f42336..08ca59d89b 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs @@ -11,15 +11,15 @@ using osu.Game.Resources.Localisation.Web; namespace osu.Game.Overlays.Profile.Header.Components { - public partial class OverlinedTotalPlayTime : CompositeDrawable, IHasTooltip + public partial class TotalPlayTime : CompositeDrawable, IHasTooltip { public readonly Bindable User = new Bindable(); public LocalisableString TooltipText { get; set; } - private OverlinedInfoContainer info = null!; + private ProfileValueDisplay info = null!; - public OverlinedTotalPlayTime() + public TotalPlayTime() { AutoSizeAxes = Axes.Both; @@ -27,12 +27,11 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load() { - InternalChild = info = new OverlinedInfoContainer + InternalChild = info = new ProfileValueDisplay(minimumWidth: 140) { Title = UsersStrings.ShowStatsPlayTime, - LineColour = colourProvider.Highlight1, }; User.BindValueChanged(updateTime, true); diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 63473e007d..5e55521f21 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -22,16 +22,16 @@ namespace osu.Game.Overlays.Profile.Header public partial class DetailHeaderContainer : CompositeDrawable { private readonly Dictionary scoreRankInfos = new Dictionary(); - private OverlinedInfoContainer medalInfo = null!; - private OverlinedInfoContainer ppInfo = null!; - private OverlinedInfoContainer detailGlobalRank = null!; - private OverlinedInfoContainer detailCountryRank = null!; + private ProfileValueDisplay medalInfo = null!; + private ProfileValueDisplay ppInfo = null!; + private ProfileValueDisplay detailGlobalRank = null!; + private ProfileValueDisplay detailCountryRank = null!; private RankGraph rankGraph = null!; public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider, OsuColour colours) + private void load(OverlayColourProvider colourProvider) { AutoSizeAxes = Axes.Y; @@ -71,19 +71,17 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(10, 0), Children = new Drawable[] { - new OverlinedTotalPlayTime - { - User = { BindTarget = User } - }, - medalInfo = new OverlinedInfoContainer + medalInfo = new ProfileValueDisplay { Title = UsersStrings.ShowStatsMedals, - LineColour = colours.GreenLight, }, - ppInfo = new OverlinedInfoContainer + ppInfo = new ProfileValueDisplay { Title = "pp", - LineColour = colours.Red, + }, + new TotalPlayTime + { + User = { BindTarget = User } }, } }, @@ -126,15 +124,13 @@ namespace osu.Game.Overlays.Profile.Header Spacing = new Vector2(0, 20), Children = new Drawable[] { - detailGlobalRank = new OverlinedInfoContainer(true, 110) + detailGlobalRank = new ProfileValueDisplay(true, 110) { Title = UsersStrings.ShowRankGlobalSimple, - LineColour = colourProvider.Highlight1, }, - detailCountryRank = new OverlinedInfoContainer(false, 110) + detailCountryRank = new ProfileValueDisplay(false, 110) { Title = UsersStrings.ShowRankCountrySimple, - LineColour = colourProvider.Highlight1, }, } } From 6a9d8426605333f260a702b75ead339f03213285 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 18:02:05 +0100 Subject: [PATCH 196/248] Adjust user profile header detail appearance --- .../Profile/Header/DetailHeaderContainer.cs | 69 +++++++++---------- .../Profile/Header/MedalHeaderContainer.cs | 3 +- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 5e55521f21..890e6c4e04 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -53,9 +53,39 @@ namespace osu.Game.Overlays.Profile.Header Masking = true, Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), + Spacing = new Vector2(0, 15), Children = new Drawable[] { + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(20), + Children = new Drawable[] + { + detailGlobalRank = new ProfileValueDisplay(true) + { + Title = UsersStrings.ShowRankGlobalSimple, + }, + detailCountryRank = new ProfileValueDisplay(true) + { + Title = UsersStrings.ShowRankCountrySimple, + }, + } + }, + new Container + { + RelativeSizeAxes = Axes.X, + Height = 60, + Children = new Drawable[] + { + rankGraph = new RankGraph + { + RelativeSizeAxes = Axes.Both, + }, + } + }, new Container { RelativeSizeAxes = Axes.X, @@ -103,39 +133,6 @@ namespace osu.Game.Overlays.Profile.Header } } }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Right = 130 }, - Children = new Drawable[] - { - rankGraph = new RankGraph - { - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - Width = 130, - Anchor = Anchor.TopRight, - Direction = FillDirection.Vertical, - Padding = new MarginPadding { Horizontal = 10 }, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - detailGlobalRank = new ProfileValueDisplay(true, 110) - { - Title = UsersStrings.ShowRankGlobalSimple, - }, - detailCountryRank = new ProfileValueDisplay(false, 110) - { - Title = UsersStrings.ShowRankCountrySimple, - }, - } - } - } - }, } }, }; @@ -172,14 +169,14 @@ namespace osu.Game.Overlays.Profile.Header InternalChild = new FillFlowContainer { AutoSizeAxes = Axes.Y, - Width = 56, + Width = 44, Direction = FillDirection.Vertical, Children = new Drawable[] { new DrawableRank(rank) { RelativeSizeAxes = Axes.X, - Height = 30, + Height = 22, }, rankCount = new OsuSpriteText { diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 2652550fb5..be160a6948 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -49,9 +49,8 @@ namespace osu.Game.Overlays.Profile.Header Direction = FillDirection.Full, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 5 }, Spacing = new Vector2(10, 10), - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Top = 10 }, } }; } From bfca75395be49e7257e10d24347e13cd577d8d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 18:24:45 +0100 Subject: [PATCH 197/248] Adjust colour of top header container --- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 33e24593e0..e04a8ad9ad 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -51,7 +51,7 @@ namespace osu.Game.Overlays.Profile.Header new Box { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background5, + Colour = colourProvider.Background4, }, new FillFlowContainer { From 67a3ea2c5992527db7def7414566931c22747daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 31 Dec 2022 21:10:48 +0100 Subject: [PATCH 198/248] Fix wrong date colour of kudosu history items --- osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs | 9 ++++++--- .../Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs | 7 ++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs index 84497245db..25a56196eb 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneKudosuHistory.cs @@ -5,12 +5,12 @@ using osu.Game.Overlays.Profile.Sections.Kudosu; using System.Collections.Generic; using System; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics; using osu.Game.Online.API.Requests.Responses; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { @@ -18,6 +18,9 @@ namespace osu.Game.Tests.Visual.Online { private readonly Box background; + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); + public TestSceneKudosuHistory() { FillFlowContainer content; @@ -42,9 +45,9 @@ namespace osu.Game.Tests.Visual.Online } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - background.Colour = colours.GreySeaFoam; + background.Colour = colourProvider.Background4; } private readonly IEnumerable items = new[] diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs index e7991acb89..161d5b6f64 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/DrawableKudosuHistoryItem.cs @@ -17,9 +17,6 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { private const int height = 25; - [Resolved] - private OsuColour colours { get; set; } = null!; - private readonly APIKudosuHistory historyItem; private readonly LinkFlowContainer linkFlowContainer; private readonly DrawableDate date; @@ -48,9 +45,9 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu } [BackgroundDependencyLoader] - private void load() + private void load(OverlayColourProvider colourProvider) { - date.Colour = colours.GreySeaFoamLighter; + date.Colour = colourProvider.Foreground1; var formattedSource = MessageFormatter.FormatText(getString(historyItem)); linkFlowContainer.AddLinks(formattedSource.Text, formattedSource.Links); } From 3102044d00a85caaaafd059f77a08022dfd2d7aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 14 Jan 2023 18:46:14 +0100 Subject: [PATCH 199/248] Add failing test for new difficulty creation --- .../Editing/TestSceneEditorBeatmapCreation.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs index a40c7814e1..3f89bf9e9c 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs @@ -20,6 +20,8 @@ using osu.Game.Rulesets.Catch; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.Taiko; +using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Setup; using osu.Game.Storyboards; @@ -395,5 +397,52 @@ namespace osu.Game.Tests.Visual.Editing return set != null && set.PerformRead(s => s.Beatmaps.Count == 2 && s.Files.Count == 2); }); } + + [Test] + public void TestCreateNewDifficultyForInconvertibleRuleset() + { + Guid setId = Guid.Empty; + + AddStep("retrieve set ID", () => setId = EditorBeatmap.BeatmapInfo.BeatmapSet!.ID); + AddStep("save beatmap", () => Editor.Save()); + AddStep("try to create new taiko difficulty", () => Editor.CreateNewDifficulty(new TaikoRuleset().RulesetInfo)); + + AddUntilStep("wait for created", () => + { + string? difficultyName = Editor.ChildrenOfType().SingleOrDefault()?.BeatmapInfo.DifficultyName; + return difficultyName != null && difficultyName == "New Difficulty"; + }); + AddAssert("new difficulty persisted", () => + { + var set = beatmapManager.QueryBeatmapSet(s => s.ID == setId); + return set != null && set.PerformRead(s => s.Beatmaps.Count == 2 && s.Files.Count == 2); + }); + + AddStep("add timing point", () => EditorBeatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 1000 })); + AddStep("add hitobjects", () => EditorBeatmap.AddRange(new[] + { + new Hit + { + StartTime = 0 + }, + new Hit + { + StartTime = 1000 + } + })); + AddStep("save beatmap", () => Editor.Save()); + AddStep("try to create new catch difficulty", () => Editor.CreateNewDifficulty(new CatchRuleset().RulesetInfo)); + + AddUntilStep("wait for created", () => + { + string? difficultyName = Editor.ChildrenOfType().SingleOrDefault()?.BeatmapInfo.DifficultyName; + return difficultyName != null && difficultyName == "New Difficulty (1)"; + }); + AddAssert("new difficulty persisted", () => + { + var set = beatmapManager.QueryBeatmapSet(s => s.ID == setId); + return set != null && set.PerformRead(s => s.Beatmaps.Count == 3 && s.Files.Count == 3); + }); + } } } From e7ab54379933937e8affbb008b0e3dacd3e3c92a Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Fri, 13 Jan 2023 16:08:34 -0800 Subject: [PATCH 200/248] Add ability to view converted beatmaps on beatmap set overlay --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 4 ++++ osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 3 +++ osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 3 +++ osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 5 +++-- osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs | 3 ++- 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 1665ec52fa..41db2399ac 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -13,6 +13,7 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -116,6 +117,9 @@ namespace osu.Game.Beatmaps.Drawables private Drawable getRulesetIcon() { + if ((beatmap as APIBeatmap)?.Convert == true) + return rulesets.GetRuleset(0)!.CreateInstance().CreateIcon(); + int? onlineID = ruleset.OnlineID; if (onlineID >= 0 && rulesets.GetRuleset(onlineID.Value)?.CreateInstance() is Ruleset rulesetInstance) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 27ad2a746c..7d6740ee46 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -63,6 +63,9 @@ namespace osu.Game.Online.API.Requests.Responses set => Length = TimeSpan.FromSeconds(value).TotalMilliseconds; } + [JsonProperty(@"convert")] + public bool Convert { get; set; } + [JsonProperty(@"count_circles")] public int CircleCount { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index aeae3edde2..d39ed1e1ed 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -125,6 +125,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"beatmaps")] public APIBeatmap[] Beatmaps { get; set; } = Array.Empty(); + [JsonProperty(@"converts")] + public APIBeatmap[] Converts { get; set; } = Array.Empty(); + private BeatmapMetadata metadata => new BeatmapMetadata { Title = Title, diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 84d12f2611..51b6b14579 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -168,9 +168,10 @@ namespace osu.Game.Overlays.BeatmapSet if (BeatmapSet != null) { - Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps + Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.Concat(BeatmapSet.Converts) .Where(b => b.Ruleset.MatchesOnlineID(ruleset.Value)) - .OrderBy(b => b.StarRating) + .OrderBy(b => !b.Convert) + .ThenBy(b => b.StarRating) .Select(b => new DifficultySelectorButton(b) { State = DifficultySelectorState.NotSelected, diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs index f802807c3c..76e2f256b0 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs @@ -68,11 +68,12 @@ namespace osu.Game.Overlays.BeatmapSet BeatmapSet.BindValueChanged(setInfo => { int beatmapsCount = setInfo.NewValue?.Beatmaps.Count(b => b.Ruleset.MatchesOnlineID(Value)) ?? 0; + int osuBeatmaps = setInfo.NewValue?.Beatmaps.Count(b => b.Ruleset.OnlineID == 0) ?? 0; count.Text = beatmapsCount.ToString(); countContainer.FadeTo(beatmapsCount > 0 ? 1 : 0); - Enabled.Value = beatmapsCount > 0; + Enabled.Value = beatmapsCount > 0 || osuBeatmaps > 0; }, true); } } From a9facc076f37fc6663bae5e0b64c5e124bf9e3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 14 Jan 2023 19:39:30 +0100 Subject: [PATCH 201/248] Fix difficulty creation flow failing for some ruleset combinations In current `master`, the difficulty creation flow would retrieve a "reference beatmap" to copy metadata and timing points from using `GetPlayableBeatmap()`. But, importantly, it was calling that method using *the ruleset of the new difficulty* rather than the ruleset of the existing one. This would make the difficulty creation flow fail if the beatmap couldn't be converted between rulesets (like taiko to catch). Fixing to use the reference beatmap's actual ruleset would be trivial, but there's no real reason to do all of that work anyway when a `WorkingBeatmap` is available. Because getting a playable beatmap is not required to copy across metadata and timing points, remove the `GetPlayableBeatmap()` step entirely to fix the bug. Closes #22145. --- osu.Game/Beatmaps/BeatmapManager.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index eafd1e96e8..34637501fa 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -136,14 +136,12 @@ namespace osu.Game.Beatmaps /// The ruleset with which the new difficulty should be created. public virtual WorkingBeatmap CreateNewDifficulty(BeatmapSetInfo targetBeatmapSet, WorkingBeatmap referenceWorkingBeatmap, RulesetInfo rulesetInfo) { - var playableBeatmap = referenceWorkingBeatmap.GetPlayableBeatmap(rulesetInfo); - - var newBeatmapInfo = new BeatmapInfo(rulesetInfo, new BeatmapDifficulty(), playableBeatmap.Metadata.DeepClone()) + var newBeatmapInfo = new BeatmapInfo(rulesetInfo, new BeatmapDifficulty(), referenceWorkingBeatmap.Metadata.DeepClone()) { DifficultyName = NamingUtils.GetNextBestName(targetBeatmapSet.Beatmaps.Select(b => b.DifficultyName), "New Difficulty") }; var newBeatmap = new Beatmap { BeatmapInfo = newBeatmapInfo }; - foreach (var timingPoint in playableBeatmap.ControlPointInfo.TimingPoints) + foreach (var timingPoint in referenceWorkingBeatmap.Beatmap.ControlPointInfo.TimingPoints) newBeatmap.ControlPointInfo.Add(timingPoint.Time, timingPoint.DeepClone()); return addDifficultyToSet(targetBeatmapSet, newBeatmap, referenceWorkingBeatmap.Skin); From a68d4fe5d18da32ede6420f50520769e20739106 Mon Sep 17 00:00:00 2001 From: integer <7279624+integerrr@users.noreply.github.com> Date: Sat, 14 Jan 2023 21:18:51 +0000 Subject: [PATCH 202/248] make expansion to not use scheduler --- .../PlayerSettings/PlayerSettingsGroup.cs | 25 ++++++------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index f4769cd417..55cf69b0f2 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -4,7 +4,6 @@ #nullable disable using osu.Framework.Input.Events; -using osu.Framework.Threading; using osu.Game.Overlays; namespace osu.Game.Screens.Play.PlayerSettings @@ -16,11 +15,16 @@ namespace osu.Game.Screens.Play.PlayerSettings { } - private ScheduledDelegate hoverExpandEvent; + private bool expandedByDefault = true; protected override bool OnHover(HoverEvent e) { - updateHoverExpansion(); + if (IsHovered && !Expanded.Value) + { + Expanded.Value = true; + expandedByDefault = false; + } + base.OnHover(e); // Importantly, return true to correctly take focus away from PlayerLoader. @@ -29,23 +33,10 @@ namespace osu.Game.Screens.Play.PlayerSettings protected override void OnHoverLost(HoverLostEvent e) { - if (hoverExpandEvent != null) - { - hoverExpandEvent?.Cancel(); - hoverExpandEvent = null; - + if (!expandedByDefault) Expanded.Value = false; - } base.OnHoverLost(e); } - - private void updateHoverExpansion() - { - hoverExpandEvent?.Cancel(); - - if (IsHovered && !Expanded.Value) - hoverExpandEvent = Scheduler.AddDelayed(() => Expanded.Value = true, 0); - } } } From 76eefc7573a5267ddf3016517d77e0eea1adf272 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 01:46:11 +0300 Subject: [PATCH 203/248] Add support for localisation where it was missing --- osu.Game/Graphics/UserInterface/OsuMenuItem.cs | 6 ++---- osu.Game/Graphics/UserInterface/StatefulMenuItem.cs | 11 +++++------ osu.Game/Graphics/UserInterface/ToggleMenuItem.cs | 7 +++---- .../Screens/Edit/Components/Menus/EditorMenuItem.cs | 9 +++++---- .../Components/Menus/EditorScreenSwitcherControl.cs | 5 ----- 5 files changed, 15 insertions(+), 23 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuMenuItem.cs b/osu.Game/Graphics/UserInterface/OsuMenuItem.cs index 9d65d6b8b9..20461de08f 100644 --- a/osu.Game/Graphics/UserInterface/OsuMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/OsuMenuItem.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.UserInterface; using osu.Framework.Localisation; @@ -13,12 +11,12 @@ namespace osu.Game.Graphics.UserInterface { public readonly MenuItemType Type; - public OsuMenuItem(string text, MenuItemType type = MenuItemType.Standard) + public OsuMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard) : this(text, type, null) { } - public OsuMenuItem(LocalisableString text, MenuItemType type, Action action) + public OsuMenuItem(LocalisableString text, MenuItemType type, Action? action) : base(text, action) { Type = type; diff --git a/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs b/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs index 17266e876c..85efd75a60 100644 --- a/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/StatefulMenuItem.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Bindables; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; namespace osu.Game.Graphics.UserInterface { @@ -25,7 +24,7 @@ namespace osu.Game.Graphics.UserInterface /// The text to display. /// A function that mutates a state to another state after this is pressed. /// The type of action which this performs. - protected StatefulMenuItem(string text, Func changeStateFunc, MenuItemType type = MenuItemType.Standard) + protected StatefulMenuItem(LocalisableString text, Func changeStateFunc, MenuItemType type = MenuItemType.Standard) : this(text, changeStateFunc, type, null) { } @@ -37,7 +36,7 @@ namespace osu.Game.Graphics.UserInterface /// A function that mutates a state to another state after this is pressed. /// The type of action which this performs. /// A delegate to be invoked when this is pressed. - protected StatefulMenuItem(string text, Func changeStateFunc, MenuItemType type, Action action) + protected StatefulMenuItem(LocalisableString text, Func? changeStateFunc, MenuItemType type, Action? action) : base(text, type) { Action.Value = () => @@ -69,7 +68,7 @@ namespace osu.Game.Graphics.UserInterface /// The text to display. /// A function that mutates a state to another state after this is pressed. /// The type of action which this performs. - protected StatefulMenuItem(string text, Func changeStateFunc, MenuItemType type = MenuItemType.Standard) + protected StatefulMenuItem(LocalisableString text, Func? changeStateFunc, MenuItemType type = MenuItemType.Standard) : this(text, changeStateFunc, type, null) { } @@ -81,7 +80,7 @@ namespace osu.Game.Graphics.UserInterface /// A function that mutates a state to another state after this is pressed. /// The type of action which this performs. /// A delegate to be invoked when this is pressed. - protected StatefulMenuItem(string text, Func changeStateFunc, MenuItemType type, Action action) + protected StatefulMenuItem(LocalisableString text, Func? changeStateFunc, MenuItemType type, Action? action) : base(text, o => changeStateFunc?.Invoke((T)o) ?? o, type, o => action?.Invoke((T)o)) { base.State.BindValueChanged(state => diff --git a/osu.Game/Graphics/UserInterface/ToggleMenuItem.cs b/osu.Game/Graphics/UserInterface/ToggleMenuItem.cs index 6787e17113..51e1248bc1 100644 --- a/osu.Game/Graphics/UserInterface/ToggleMenuItem.cs +++ b/osu.Game/Graphics/UserInterface/ToggleMenuItem.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; namespace osu.Game.Graphics.UserInterface { @@ -18,7 +17,7 @@ namespace osu.Game.Graphics.UserInterface /// /// The text to display. /// The type of action which this performs. - public ToggleMenuItem(string text, MenuItemType type = MenuItemType.Standard) + public ToggleMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard) : this(text, type, null) { } @@ -29,7 +28,7 @@ namespace osu.Game.Graphics.UserInterface /// The text to display. /// The type of action which this performs. /// A delegate to be invoked when this is pressed. - public ToggleMenuItem(string text, MenuItemType type, Action action) + public ToggleMenuItem(LocalisableString text, MenuItemType type, Action? action) : base(text, value => !value, type, action) { } diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs index 0a2c073dcd..1bd8979347 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Edit.Components.Menus @@ -10,13 +11,13 @@ namespace osu.Game.Screens.Edit.Components.Menus { private const int min_text_length = 40; - public EditorMenuItem(string text, MenuItemType type = MenuItemType.Standard) - : base(text.PadRight(min_text_length), type) + public EditorMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard) + : base(LocalisableString.Interpolate($"{text,-min_text_length}"), type) { } - public EditorMenuItem(string text, MenuItemType type, Action action) - : base(text.PadRight(min_text_length), type, action) + public EditorMenuItem(LocalisableString text, MenuItemType type, Action action) + : base(LocalisableString.Interpolate($"{text,-min_text_length}"), type, action) { } } diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs index 3d51874082..1f6d61d0ad 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorScreenSwitcherControl.cs @@ -56,11 +56,6 @@ namespace osu.Game.Screens.Edit.Components.Menus Bar.Expire(); } - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - } - protected override void OnActivated() { base.OnActivated(); From 24df23f42038d890ad645bc7430351baf3314afc Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 01:49:19 +0300 Subject: [PATCH 204/248] Localise background header --- osu.Game/Localisation/EditorSetupStrings.cs | 26 ++++++++++++++----- .../Edit/Setup/SetupScreenHeaderBackground.cs | 3 ++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/osu.Game/Localisation/EditorSetupStrings.cs b/osu.Game/Localisation/EditorSetupStrings.cs index 0431b9cf76..4ddacf2c5b 100644 --- a/osu.Game/Localisation/EditorSetupStrings.cs +++ b/osu.Game/Localisation/EditorSetupStrings.cs @@ -42,7 +42,8 @@ namespace osu.Game.Localisation /// /// "If enabled, an "Are you ready? 3, 2, 1, GO!" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so." /// - public static LocalisableString CountdownDescription => new TranslatableString(getKey(@"countdown_description"), @"If enabled, an ""Are you ready? 3, 2, 1, GO!"" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so."); + public static LocalisableString CountdownDescription => new TranslatableString(getKey(@"countdown_description"), + @"If enabled, an ""Are you ready? 3, 2, 1, GO!"" countdown will be inserted at the beginning of the beatmap, assuming there is enough time to do so."); /// /// "Countdown speed" @@ -52,7 +53,8 @@ namespace osu.Game.Localisation /// /// "If the countdown sounds off-time, use this to make it appear one or more beats early." /// - public static LocalisableString CountdownOffsetDescription => new TranslatableString(getKey(@"countdown_offset_description"), @"If the countdown sounds off-time, use this to make it appear one or more beats early."); + public static LocalisableString CountdownOffsetDescription => + new TranslatableString(getKey(@"countdown_offset_description"), @"If the countdown sounds off-time, use this to make it appear one or more beats early."); /// /// "Countdown offset" @@ -67,7 +69,8 @@ namespace osu.Game.Localisation /// /// "Allows storyboards to use the full screen space, rather than be confined to a 4:3 area." /// - public static LocalisableString WidescreenSupportDescription => new TranslatableString(getKey(@"widescreen_support_description"), @"Allows storyboards to use the full screen space, rather than be confined to a 4:3 area."); + public static LocalisableString WidescreenSupportDescription => + new TranslatableString(getKey(@"widescreen_support_description"), @"Allows storyboards to use the full screen space, rather than be confined to a 4:3 area."); /// /// "Epilepsy warning" @@ -77,7 +80,8 @@ namespace osu.Game.Localisation /// /// "Recommended if the storyboard or video contain scenes with rapidly flashing colours." /// - public static LocalisableString EpilepsyWarningDescription => new TranslatableString(getKey(@"epilepsy_warning_description"), @"Recommended if the storyboard or video contain scenes with rapidly flashing colours."); + public static LocalisableString EpilepsyWarningDescription => + new TranslatableString(getKey(@"epilepsy_warning_description"), @"Recommended if the storyboard or video contain scenes with rapidly flashing colours."); /// /// "Letterbox during breaks" @@ -87,7 +91,8 @@ namespace osu.Game.Localisation /// /// "Adds horizontal letterboxing to give a cinematic look during breaks." /// - public static LocalisableString LetterboxDuringBreaksDescription => new TranslatableString(getKey(@"letterbox_during_breaks_description"), @"Adds horizontal letterboxing to give a cinematic look during breaks."); + public static LocalisableString LetterboxDuringBreaksDescription => + new TranslatableString(getKey(@"letterbox_during_breaks_description"), @"Adds horizontal letterboxing to give a cinematic look during breaks."); /// /// "Samples match playback rate" @@ -97,7 +102,8 @@ namespace osu.Game.Localisation /// /// "When enabled, all samples will speed up or slow down when rate-changing mods are enabled." /// - public static LocalisableString SamplesMatchPlaybackRateDescription => new TranslatableString(getKey(@"samples_match_playback_rate_description"), @"When enabled, all samples will speed up or slow down when rate-changing mods are enabled."); + public static LocalisableString SamplesMatchPlaybackRateDescription => new TranslatableString(getKey(@"samples_match_playback_rate_description"), + @"When enabled, all samples will speed up or slow down when rate-changing mods are enabled."); /// /// "The size of all hit objects" @@ -117,7 +123,8 @@ namespace osu.Game.Localisation /// /// "The harshness of hit windows and difficulty of special objects (ie. spinners)" /// - public static LocalisableString OverallDifficultyDescription => new TranslatableString(getKey(@"overall_difficulty_description"), @"The harshness of hit windows and difficulty of special objects (ie. spinners)"); + public static LocalisableString OverallDifficultyDescription => + new TranslatableString(getKey(@"overall_difficulty_description"), @"The harshness of hit windows and difficulty of special objects (ie. spinners)"); /// /// "Metadata" @@ -199,6 +206,11 @@ namespace osu.Game.Localisation /// public static LocalisableString DifficultyHeader => new TranslatableString(getKey(@"difficulty_header"), @"Difficulty"); + /// + /// "Drag image here to set beatmap background!" + /// + public static LocalisableString DragToSetBackground => new TranslatableString(getKey(@"drag_to_set_background"), @"Drag image here to set beatmap background!"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs index 47a7512adf..033e5361bb 100644 --- a/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs +++ b/osu.Game/Screens/Edit/Setup/SetupScreenHeaderBackground.cs @@ -10,6 +10,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit.Setup { @@ -61,7 +62,7 @@ namespace osu.Game.Screens.Edit.Setup }, new OsuTextFlowContainer(t => t.Font = OsuFont.Default.With(size: 24)) { - Text = "Drag image here to set beatmap background!", + Text = EditorSetupStrings.DragToSetBackground, Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Both From 78e562903df18bf7c24d31bc640636b4fe029d78 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 01:50:41 +0300 Subject: [PATCH 205/248] Localise part of editor --- osu.Game/Localisation/EditorStrings.cs | 164 ++++++++++++++++++ .../Screens/Edit/BackgroundDimMenuItem.cs | 13 +- .../Edit/Components/PlaybackControl.cs | 3 +- .../Timelines/Summary/TestGameplayButton.cs | 3 +- .../Components/Timeline/TimelineArea.cs | 7 +- osu.Game/Screens/Edit/Editor.cs | 39 ++--- osu.Game/Screens/Edit/EditorScreenMode.cs | 15 +- .../Screens/Edit/WaveformOpacityMenuItem.cs | 3 +- 8 files changed, 207 insertions(+), 40 deletions(-) create mode 100644 osu.Game/Localisation/EditorStrings.cs diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs new file mode 100644 index 0000000000..32078468c9 --- /dev/null +++ b/osu.Game/Localisation/EditorStrings.cs @@ -0,0 +1,164 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class EditorStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.Editor"; + + /// + /// "File" + /// + public static LocalisableString File => new TranslatableString(getKey(@"file"), @"File"); + + /// + /// "Edit" + /// + public static LocalisableString Edit => new TranslatableString(getKey(@"edit"), @"Edit"); + + /// + /// "Undo" + /// + public static LocalisableString Undo => new TranslatableString(getKey(@"undo"), @"Undo"); + + /// + /// "Redo" + /// + public static LocalisableString Redo => new TranslatableString(getKey(@"redo"), @"Redo"); + + /// + /// "Cut" + /// + public static LocalisableString Cut => new TranslatableString(getKey(@"cut"), @"Cut"); + + /// + /// "Copy" + /// + public static LocalisableString Copy => new TranslatableString(getKey(@"copy"), @"Copy"); + + /// + /// "Paste" + /// + public static LocalisableString Paste => new TranslatableString(getKey(@"paste"), @"Paste"); + + /// + /// "Clone" + /// + public static LocalisableString Clone => new TranslatableString(getKey(@"clone"), @"Clone"); + + /// + /// "View" + /// + public static LocalisableString View => new TranslatableString(getKey(@"view"), @"View"); + + /// + /// "Background dim" + /// + public static LocalisableString BackgroundDim => new TranslatableString(getKey(@"background_dim"), @"Background dim"); + + /// + /// "Waveform opacity" + /// + public static LocalisableString WaveformOpacity => new TranslatableString(getKey(@"waveform_opacity"), @"Waveform opacity"); + + /// + /// "Show hit markers" + /// + public static LocalisableString ShowHitMarkers => new TranslatableString(getKey(@"show_hit_markers"), @"Show hit markers"); + + /// + /// "Timing" + /// + public static LocalisableString Timing => new TranslatableString(getKey(@"timing"), @"Timing"); + + /// + /// "Set preview point to current time" + /// + public static LocalisableString SetPreviewPointToCurrent => new TranslatableString(getKey(@"set_preview_point_to_current"), @"Set preview point to current time"); + + /// + /// "Save" + /// + public static LocalisableString Save => new TranslatableString(getKey(@"save"), @"Save"); + + /// + /// "Export package" + /// + public static LocalisableString ExportPackage => new TranslatableString(getKey(@"export_package"), @"Export package"); + + /// + /// "Create new difficulty" + /// + public static LocalisableString CreateNewDifficulty => new TranslatableString(getKey(@"create_new_difficulty"), @"Create new difficulty"); + + /// + /// "Change difficulty" + /// + public static LocalisableString ChangeDifficulty => new TranslatableString(getKey(@"change_difficulty"), @"Change difficulty"); + + /// + /// "Delete difficulty" + /// + public static LocalisableString DeleteDifficulty => new TranslatableString(getKey(@"delete_difficulty"), @"Delete difficulty"); + + /// + /// "Exit" + /// + public static LocalisableString Exit => new TranslatableString(getKey(@"exit"), @"Exit"); + + /// + /// "setup" + /// + public static LocalisableString SetupScreen => new TranslatableString(getKey(@"setup_screen"), @"setup"); + + /// + /// "compose" + /// + public static LocalisableString ComposeScreen => new TranslatableString(getKey(@"compose_screen"), @"compose"); + + /// + /// "design" + /// + public static LocalisableString DesignScreen => new TranslatableString(getKey(@"design_screen"), @"design"); + + /// + /// "timing" + /// + public static LocalisableString TimingScreen => new TranslatableString(getKey(@"timing_screen"), @"timing"); + + /// + /// "verify" + /// + public static LocalisableString VerifyScreen => new TranslatableString(getKey(@"verify_screen"), @"verify"); + + /// + /// "Playback speed" + /// + public static LocalisableString PlaybackSpeed => new TranslatableString(getKey(@"playback_speed"), @"Playback speed"); + + /// + /// "Test!" + /// + public static LocalisableString TestBeatmap => new TranslatableString(getKey(@"test_beatmap"), @"Test!"); + + /// + /// "Waveform" + /// + public static LocalisableString TimelineWaveform => new TranslatableString(getKey(@"timeline_waveform"), @"Waveform"); + + /// + /// "Ticks" + /// + public static LocalisableString TimelineTicks => new TranslatableString(getKey(@"timeline_ticks"), @"Ticks"); + + /// + /// "BPM" + /// + public static LocalisableString TimelineBpm => new TranslatableString(getKey(@"timeline_bpm"), @"BPM"); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs index b5a33f06e7..bff01385bb 100644 --- a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs +++ b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs @@ -5,17 +5,18 @@ using System.Collections.Generic; using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { internal class BackgroundDimMenuItem : MenuItem { - private readonly Bindable backgroudDim; + private readonly Bindable backgroundDim; private readonly Dictionary menuItemLookup = new Dictionary(); - public BackgroundDimMenuItem(Bindable backgroudDim) - : base("Background dim") + public BackgroundDimMenuItem(Bindable backgroundDim) + : base(EditorStrings.BackgroundDim) { Items = new[] { @@ -25,8 +26,8 @@ namespace osu.Game.Screens.Edit createMenuItem(0.75f), }; - this.backgroudDim = backgroudDim; - backgroudDim.BindValueChanged(dim => + this.backgroundDim = backgroundDim; + backgroundDim.BindValueChanged(dim => { foreach (var kvp in menuItemLookup) kvp.Value.State.Value = kvp.Key == dim.NewValue ? TernaryState.True : TernaryState.False; @@ -40,6 +41,6 @@ namespace osu.Game.Screens.Edit return item; } - private void updateOpacity(float dim) => backgroudDim.Value = dim; + private void updateOpacity(float dim) => backgroundDim.Value = dim; } } diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 87cbcb8aff..72c299f443 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -16,6 +16,7 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; using osuTK.Input; @@ -47,7 +48,7 @@ namespace osu.Game.Screens.Edit.Components new OsuSpriteText { Origin = Anchor.BottomLeft, - Text = "Playback speed", + Text = EditorStrings.PlaybackSpeed, RelativePositionAxes = Axes.Y, Y = 0.5f, Padding = new MarginPadding { Left = 45 } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs index 9b45464e81..169e72fe3f 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/TestGameplayButton.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; namespace osu.Game.Screens.Edit.Components.Timelines.Summary @@ -30,7 +31,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary Content.CornerRadius = 0; - Text = "Test!"; + Text = EditorStrings.TestBeatmap; } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs index 615925ff91..f11c7b1d00 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; using osuTK; @@ -75,17 +76,17 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { waveformCheckbox = new OsuCheckbox { - LabelText = "Waveform", + LabelText = EditorStrings.TimelineWaveform, Current = { Value = true }, }, ticksCheckbox = new OsuCheckbox { - LabelText = "Ticks", + LabelText = EditorStrings.TimelineTicks, Current = { Value = true }, }, controlPointsCheckbox = new OsuCheckbox { - LabelText = "BPM", + LabelText = EditorStrings.TimelineBpm, Current = { Value = true }, }, } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index be4e2f9628..c440cc8285 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -51,7 +51,6 @@ using osu.Game.Screens.Edit.Verify; using osu.Game.Screens.Play; using osu.Game.Users; using osuTK.Input; -using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; namespace osu.Game.Screens.Edit { @@ -294,40 +293,40 @@ namespace osu.Game.Screens.Edit RelativeSizeAxes = Axes.Both, Items = new[] { - new MenuItem("File") + new MenuItem(EditorStrings.File) { Items = createFileMenuItems() }, - new MenuItem(CommonStrings.ButtonsEdit) + new MenuItem(EditorStrings.Edit) { Items = new[] { - undoMenuItem = new EditorMenuItem("Undo", MenuItemType.Standard, Undo), - redoMenuItem = new EditorMenuItem("Redo", MenuItemType.Standard, Redo), + undoMenuItem = new EditorMenuItem(EditorStrings.Undo, MenuItemType.Standard, Undo), + redoMenuItem = new EditorMenuItem(EditorStrings.Redo, MenuItemType.Standard, Redo), new EditorMenuItemSpacer(), - cutMenuItem = new EditorMenuItem("Cut", MenuItemType.Standard, Cut), - copyMenuItem = new EditorMenuItem("Copy", MenuItemType.Standard, Copy), - pasteMenuItem = new EditorMenuItem("Paste", MenuItemType.Standard, Paste), - cloneMenuItem = new EditorMenuItem("Clone", MenuItemType.Standard, Clone), + cutMenuItem = new EditorMenuItem(EditorStrings.Cut, MenuItemType.Standard, Cut), + copyMenuItem = new EditorMenuItem(EditorStrings.Copy, MenuItemType.Standard, Copy), + pasteMenuItem = new EditorMenuItem(EditorStrings.Paste, MenuItemType.Standard, Paste), + cloneMenuItem = new EditorMenuItem(EditorStrings.Clone, MenuItemType.Standard, Clone), } }, - new MenuItem("View") + new MenuItem(EditorStrings.View) { Items = new MenuItem[] { new WaveformOpacityMenuItem(config.GetBindable(OsuSetting.EditorWaveformOpacity)), new BackgroundDimMenuItem(editorBackgroundDim), - new ToggleMenuItem("Show hit markers") + new ToggleMenuItem(EditorStrings.ShowHitMarkers) { State = { BindTarget = editorHitMarkers }, } } }, - new MenuItem("Timing") + new MenuItem(EditorStrings.Timing) { Items = new MenuItem[] { - new EditorMenuItem("Set preview point to current time", MenuItemType.Standard, SetPreviewPointToCurrentTime) + new EditorMenuItem(EditorStrings.SetPreviewPointToCurrent, MenuItemType.Standard, SetPreviewPointToCurrentTime) } } } @@ -716,7 +715,7 @@ namespace osu.Game.Screens.Edit if (!(refetchedBeatmap is DummyWorkingBeatmap)) { - Logger.Log("Editor providing re-fetched beatmap post edit session"); + Logger.Log(@"Editor providing re-fetched beatmap post edit session"); Beatmap.Value = refetchedBeatmap; } } @@ -952,15 +951,15 @@ namespace osu.Game.Screens.Edit private List createFileMenuItems() => new List { - new EditorMenuItem("Save", MenuItemType.Standard, () => Save()), - new EditorMenuItem("Export package", MenuItemType.Standard, exportBeatmap) { Action = { Disabled = !RuntimeInfo.IsDesktop } }, + new EditorMenuItem(EditorStrings.Save, MenuItemType.Standard, () => Save()), + new EditorMenuItem(EditorStrings.ExportPackage, MenuItemType.Standard, exportBeatmap) { Action = { Disabled = !RuntimeInfo.IsDesktop } }, new EditorMenuItemSpacer(), createDifficultyCreationMenu(), createDifficultySwitchMenu(), new EditorMenuItemSpacer(), - new EditorMenuItem("Delete difficulty", MenuItemType.Standard, deleteDifficulty) { Action = { Disabled = Beatmap.Value.BeatmapSetInfo.Beatmaps.Count < 2 } }, + new EditorMenuItem(EditorStrings.DeleteDifficulty, MenuItemType.Standard, deleteDifficulty) { Action = { Disabled = Beatmap.Value.BeatmapSetInfo.Beatmaps.Count < 2 } }, new EditorMenuItemSpacer(), - new EditorMenuItem("Exit", MenuItemType.Standard, this.Exit) + new EditorMenuItem(EditorStrings.Exit, MenuItemType.Standard, this.Exit) }; private void exportBeatmap() @@ -1009,7 +1008,7 @@ namespace osu.Game.Screens.Edit foreach (var ruleset in rulesets.AvailableRulesets) rulesetItems.Add(new EditorMenuItem(ruleset.Name, MenuItemType.Standard, () => CreateNewDifficulty(ruleset))); - return new EditorMenuItem("Create new difficulty") { Items = rulesetItems }; + return new EditorMenuItem(EditorStrings.CreateNewDifficulty) { Items = rulesetItems }; } protected void CreateNewDifficulty(RulesetInfo rulesetInfo) @@ -1045,7 +1044,7 @@ namespace osu.Game.Screens.Edit } } - return new EditorMenuItem("Change difficulty") { Items = difficultyItems }; + return new EditorMenuItem(EditorStrings.ChangeDifficulty) { Items = difficultyItems }; } protected void SwitchToDifficulty(BeatmapInfo nextBeatmap) => loader?.ScheduleSwitchToExistingDifficulty(nextBeatmap, GetState(nextBeatmap.Ruleset)); diff --git a/osu.Game/Screens/Edit/EditorScreenMode.cs b/osu.Game/Screens/Edit/EditorScreenMode.cs index 81fcf23cdf..f787fee1e0 100644 --- a/osu.Game/Screens/Edit/EditorScreenMode.cs +++ b/osu.Game/Screens/Edit/EditorScreenMode.cs @@ -1,27 +1,26 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using System.ComponentModel; +using osu.Framework.Localisation; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { public enum EditorScreenMode { - [Description("setup")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.SetupScreen))] SongSetup, - [Description("compose")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.ComposeScreen))] Compose, - [Description("design")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.DesignScreen))] Design, - [Description("timing")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.TimingScreen))] Timing, - [Description("verify")] + [LocalisableDescription(typeof(EditorStrings), nameof(EditorStrings.VerifyScreen))] Verify, } } diff --git a/osu.Game/Screens/Edit/WaveformOpacityMenuItem.cs b/osu.Game/Screens/Edit/WaveformOpacityMenuItem.cs index 3d3f67e70e..5b1d7142e4 100644 --- a/osu.Game/Screens/Edit/WaveformOpacityMenuItem.cs +++ b/osu.Game/Screens/Edit/WaveformOpacityMenuItem.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { @@ -17,7 +18,7 @@ namespace osu.Game.Screens.Edit private readonly Dictionary menuItemLookup = new Dictionary(); public WaveformOpacityMenuItem(Bindable waveformOpacity) - : base("Waveform opacity") + : base(EditorStrings.WaveformOpacity) { Items = new[] { From 87650044bbecc58bcdd74ee4920b3a21603a6f9d Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 01:49:54 +0300 Subject: [PATCH 206/248] Localise create/save dialog --- osu.Game/Localisation/EditorDialogsStrings.cs | 54 +++++++++++++++++++ .../Screens/Edit/CreateNewDifficultyDialog.cs | 11 ++-- osu.Game/Screens/Edit/PromptForSaveDialog.cs | 11 ++-- 3 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 osu.Game/Localisation/EditorDialogsStrings.cs diff --git a/osu.Game/Localisation/EditorDialogsStrings.cs b/osu.Game/Localisation/EditorDialogsStrings.cs new file mode 100644 index 0000000000..fc4c2b7f2a --- /dev/null +++ b/osu.Game/Localisation/EditorDialogsStrings.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 osu.Framework.Localisation; + +namespace osu.Game.Localisation +{ + public static class EditorDialogsStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.EditorDialogs"; + + /// + /// "Would you like to create a blank difficulty?" + /// + public static LocalisableString NewDifficultyDialogHeader => new TranslatableString(getKey(@"new_difficulty_dialog_header"), @"Would you like to create a blank difficulty?"); + + /// + /// "Yeah, let's start from scratch!" + /// + public static LocalisableString CreateNew => new TranslatableString(getKey(@"create_new"), @"Yeah, let's start from scratch!"); + + /// + /// "No, create an exact copy of this difficulty" + /// + public static LocalisableString CreateCopy => new TranslatableString(getKey(@"create_copy"), @"No, create an exact copy of this difficulty"); + + /// + /// "I changed my mind, I want to keep editing this difficulty" + /// + public static LocalisableString KeepEditing => new TranslatableString(getKey(@"keep_editing"), @"I changed my mind, I want to keep editing this difficulty"); + + /// + /// "Did you want to save your changes?" + /// + public static LocalisableString SaveDialogHeader => new TranslatableString(getKey(@"save_dialog_header"), @"Did you want to save your changes?"); + + /// + /// "Save my masterpiece!" + /// + public static LocalisableString Save => new TranslatableString(getKey(@"save"), @"Save my masterpiece!"); + + /// + /// "Forget all changes" + /// + public static LocalisableString ForgetAllChanges => new TranslatableString(getKey(@"forget_all_changes"), @"Forget all changes"); + + /// + /// "Oops, continue editing" + /// + public static LocalisableString ContinueEditing => new TranslatableString(getKey(@"continue_editing"), @"Oops, continue editing"); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs b/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs index 85466c5056..811da5236e 100644 --- a/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs +++ b/osu.Game/Screens/Edit/CreateNewDifficultyDialog.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Sprites; using osu.Game.Overlays.Dialog; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { @@ -20,7 +19,7 @@ namespace osu.Game.Screens.Edit public CreateNewDifficultyDialog(CreateNewDifficulty createNewDifficulty) { - HeaderText = "Would you like to create a blank difficulty?"; + HeaderText = EditorDialogsStrings.NewDifficultyDialogHeader; Icon = FontAwesome.Regular.Clone; @@ -28,17 +27,17 @@ namespace osu.Game.Screens.Edit { new PopupDialogOkButton { - Text = "Yeah, let's start from scratch!", + Text = EditorDialogsStrings.CreateNew, Action = () => createNewDifficulty.Invoke(false) }, new PopupDialogCancelButton { - Text = "No, create an exact copy of this difficulty", + Text = EditorDialogsStrings.CreateCopy, Action = () => createNewDifficulty.Invoke(true) }, new PopupDialogCancelButton { - Text = "I changed my mind, I want to keep editing this difficulty", + Text = EditorDialogsStrings.KeepEditing, Action = () => { } } }; diff --git a/osu.Game/Screens/Edit/PromptForSaveDialog.cs b/osu.Game/Screens/Edit/PromptForSaveDialog.cs index 2a2cd019ea..7d78465e6c 100644 --- a/osu.Game/Screens/Edit/PromptForSaveDialog.cs +++ b/osu.Game/Screens/Edit/PromptForSaveDialog.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics.Sprites; using osu.Game.Overlays.Dialog; +using osu.Game.Localisation; namespace osu.Game.Screens.Edit { @@ -13,7 +12,7 @@ namespace osu.Game.Screens.Edit { public PromptForSaveDialog(Action exit, Action saveAndExit, Action cancel) { - HeaderText = "Did you want to save your changes?"; + HeaderText = EditorDialogsStrings.SaveDialogHeader; Icon = FontAwesome.Regular.Save; @@ -21,17 +20,17 @@ namespace osu.Game.Screens.Edit { new PopupDialogOkButton { - Text = @"Save my masterpiece!", + Text = EditorDialogsStrings.Save, Action = saveAndExit }, new PopupDialogDangerousButton { - Text = @"Forget all changes", + Text = EditorDialogsStrings.ForgetAllChanges, Action = exit }, new PopupDialogCancelButton { - Text = @"Oops, continue editing", + Text = EditorDialogsStrings.ContinueEditing, Action = cancel }, }; From 627d1725c37b2cdfeaaab2ae2f158f767a2e3d67 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sat, 14 Jan 2023 19:23:25 -0800 Subject: [PATCH 207/248] Fix kudosu wiki link from user profile not linking to in-game overlay --- osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index 5e0227de5b..d2f01ef9f7 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -14,6 +14,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.LocalisationExtensions; using osu.Game.Resources.Localisation.Web; using osu.Framework.Localisation; +using osu.Game.Online.Chat; namespace osu.Game.Overlays.Profile.Sections.Kudosu { @@ -42,7 +43,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu : base(UsersStrings.ShowExtraKudosuTotal) { DescriptionText.AddText("Based on how much of a contribution the user has made to beatmap moderation. See "); - DescriptionText.AddLink("this page", "https://osu.ppy.sh/wiki/Kudosu"); + DescriptionText.AddLink("this page", LinkAction.OpenWiki, @"Modding/Kudosu"); DescriptionText.AddText(" for more information."); } } From a75fc5108a35bdea5b01439e058b216f5d38c1d9 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:00:34 +0900 Subject: [PATCH 208/248] Remove #nullable disable from Catch.Edit namespace --- .../Edit/BananaShowerCompositionTool.cs | 2 -- .../Blueprints/BananaShowerPlacementBlueprint.cs | 2 -- .../Blueprints/BananaShowerSelectionBlueprint.cs | 2 -- .../Edit/Blueprints/CatchPlacementBlueprint.cs | 4 +--- .../Edit/Blueprints/CatchSelectionBlueprint.cs | 4 +--- .../Edit/Blueprints/Components/EditablePath.cs | 6 +----- .../Edit/Blueprints/Components/FruitOutline.cs | 2 -- .../Components/NestedOutlineContainer.cs | 2 -- .../Components/PlacementEditablePath.cs | 2 -- .../Edit/Blueprints/Components/ScrollingPath.cs | 2 -- .../Components/SelectionEditablePath.cs | 6 +----- .../Edit/Blueprints/Components/TimeSpanOutline.cs | 2 -- .../Edit/Blueprints/Components/VertexPiece.cs | 4 +--- .../Edit/Blueprints/FruitPlacementBlueprint.cs | 2 -- .../Edit/Blueprints/FruitSelectionBlueprint.cs | 2 -- .../Blueprints/JuiceStreamPlacementBlueprint.cs | 4 +--- .../Blueprints/JuiceStreamSelectionBlueprint.cs | 6 +----- .../Edit/CatchBeatmapVerifier.cs | 2 -- .../Edit/CatchBlueprintContainer.cs | 4 +--- .../Edit/CatchDistanceSnapGrid.cs | 8 ++------ .../Edit/CatchEditorPlayfield.cs | 2 -- .../Edit/CatchHitObjectComposer.cs | 15 +++++---------- .../Edit/CatchHitObjectUtils.cs | 2 -- .../Edit/CatchSelectionHandler.cs | 4 +--- .../Edit/DrawableCatchEditorRuleset.cs | 4 +--- .../Edit/FruitCompositionTool.cs | 2 -- .../Edit/JuiceStreamCompositionTool.cs | 2 -- 27 files changed, 17 insertions(+), 82 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs b/osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs index e64a51f03a..31075db7d1 100644 --- a/osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs +++ b/osu.Game.Rulesets.Catch/Edit/BananaShowerCompositionTool.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Edit.Blueprints; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs index 166fa44303..5f22ef5c12 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Input.Events; using osu.Game.Rulesets.Catch.Edit.Blueprints.Components; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs index 2c545e8f0e..f6dd67889e 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/BananaShowerSelectionBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch.Edit.Blueprints diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs index 94373147d2..d2d605a6fe 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Edit; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; [Resolved] - private Playfield playfield { get; set; } + private Playfield playfield { get; set; } = null!; public CatchPlacementBlueprint() : base(new THitObject()) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs index 87c33a9cb8..8220fb88b4 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/CatchSelectionBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Edit; @@ -31,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; [Resolved] - private Playfield playfield { get; set; } + private Playfield playfield { get; set; } = null!; protected CatchSelectionBlueprint(THitObject hitObject) : base(hitObject) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index 006ea6e9cf..c2a426de66 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -1,13 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -43,8 +40,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components private readonly List previousVertexStates = new List(); [Resolved(CanBeNull = true)] - [CanBeNull] - private IBeatSnapProvider beatSnapProvider { get; set; } + private IBeatSnapProvider? beatSnapProvider { get; set; } protected EditablePath(Func positionToTime) { diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs index dc2b038e01..c7805544ea 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/FruitOutline.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs index ac0c850bca..c1f46539fa 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/NestedOutlineContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs index ba2f5ed0eb..3a7d6d87f2 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/PlacementEditablePath.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Rulesets.Catch.Objects; using osuTK; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs index 6deb5a174f..a22abcb76d 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/ScrollingPath.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs index 3a44f7ac8a..95b17a197f 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.UserInterface; @@ -26,8 +23,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components private Vector2 dragStartPosition; [Resolved(CanBeNull = true)] - [CanBeNull] - private IEditorChangeHandler changeHandler { get; set; } + private IEditorChangeHandler? changeHandler { get; set; } public SelectionEditablePath(Func positionToTime) : base(positionToTime) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs index a1d5d7ae3e..9d450cd355 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/TimeSpanOutline.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Graphics; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs index 49570d3735..07d7c72698 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/VertexPiece.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -15,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components public partial class VertexPiece : Circle { [Resolved] - private OsuColour osuColour { get; set; } + private OsuColour osuColour { get; set; } = null!; public VertexPiece() { diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs index af75023e68..72592891fb 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Input.Events; using osu.Game.Rulesets.Catch.Edit.Blueprints.Components; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs index 319b1b5e20..2737b283ef 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/FruitSelectionBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Edit.Blueprints.Components; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs index 0e2ee334ff..03ec674abb 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamPlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; @@ -24,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints private int lastEditablePathId = -1; - private InputManager inputManager; + private InputManager inputManager = null!; public JuiceStreamPlacementBlueprint() { diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs index 99ec5e2b0c..1be5148d76 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs @@ -1,11 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Graphics; @@ -54,8 +51,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints private Vector2 rightMouseDownPosition; [Resolved(CanBeNull = true)] - [CanBeNull] - private EditorBeatmap editorBeatmap { get; set; } + private EditorBeatmap? editorBeatmap { get; set; } public JuiceStreamSelectionBlueprint(JuiceStream hitObject) : base(hitObject) diff --git a/osu.Game.Rulesets.Catch/Edit/CatchBeatmapVerifier.cs b/osu.Game.Rulesets.Catch/Edit/CatchBeatmapVerifier.cs index 6570a19a92..c7a41a4e22 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchBeatmapVerifier.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchBeatmapVerifier.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Game.Rulesets.Catch.Edit.Checks; diff --git a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs index 9408a9f95c..3979d30616 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchBlueprintContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Edit.Blueprints; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Edit; @@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Edit protected override SelectionHandler CreateSelectionHandler() => new CatchSelectionHandler(); - public override HitObjectSelectionBlueprint CreateHitObjectBlueprintFor(HitObject hitObject) + public override HitObjectSelectionBlueprint? CreateHitObjectBlueprintFor(HitObject hitObject) { switch (hitObject) { diff --git a/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs b/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs index 43918bda57..cf6ddc66ed 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchDistanceSnapGrid.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -39,7 +36,7 @@ namespace osu.Game.Rulesets.Catch.Edit private readonly List verticalLineVertices = new List(); [Resolved] - private Playfield playfield { get; set; } + private Playfield playfield { get; set; } = null!; private ScrollingHitObjectContainer hitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; @@ -106,8 +103,7 @@ namespace osu.Game.Rulesets.Catch.Edit } } - [CanBeNull] - public SnapResult GetSnappedPosition(Vector2 screenSpacePosition) + public SnapResult? GetSnappedPosition(Vector2 screenSpacePosition) { double time = hitObjectContainer.TimeAtScreenSpacePosition(screenSpacePosition); diff --git a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs index bca89c6024..c9481c2757 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchEditorPlayfield.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.UI; diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs index cdf0ccfae9..ea5f54a775 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectComposer.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.EnumExtensions; @@ -32,9 +29,9 @@ namespace osu.Game.Rulesets.Catch.Edit { private const float distance_snap_radius = 50; - private CatchDistanceSnapGrid distanceSnapGrid; + private CatchDistanceSnapGrid distanceSnapGrid = null!; - private InputManager inputManager; + private InputManager inputManager = null!; private readonly BindableDouble timeRangeMultiplier = new BindableDouble(1) { @@ -117,7 +114,7 @@ namespace osu.Game.Rulesets.Catch.Edit return base.OnPressed(e); } - protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) => + protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList? mods = null) => new DrawableCatchEditorRuleset(ruleset, beatmap, mods) { TimeRangeMultiplier = { BindTarget = timeRangeMultiplier, } @@ -150,8 +147,7 @@ namespace osu.Game.Rulesets.Catch.Edit protected override ComposeBlueprintContainer CreateBlueprintContainer() => new CatchBlueprintContainer(this); - [CanBeNull] - private PalpableCatchHitObject getLastSnappableHitObject(double time) + private PalpableCatchHitObject? getLastSnappableHitObject(double time) { var hitObject = EditorBeatmap.HitObjects.OfType().LastOrDefault(h => h.GetEndTime() < time && !(h is BananaShower)); @@ -168,8 +164,7 @@ namespace osu.Game.Rulesets.Catch.Edit } } - [CanBeNull] - private PalpableCatchHitObject getDistanceSnapGridSourceHitObject() + private PalpableCatchHitObject? getDistanceSnapGridSourceHitObject() { switch (BlueprintContainer.CurrentTool) { diff --git a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectUtils.cs b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectUtils.cs index 889d3909bd..bd33080109 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchHitObjectUtils.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchHitObjectUtils.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs b/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs index d9d7047920..418351e2f3 100644 --- a/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs +++ b/osu.Game.Rulesets.Catch/Edit/CatchSelectionHandler.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.Edit protected ScrollingHitObjectContainer HitObjectContainer => (ScrollingHitObjectContainer)playfield.HitObjectContainer; [Resolved] - private Playfield playfield { get; set; } + private Playfield playfield { get; set; } = null!; public override bool HandleMovement(MoveSelectionEvent moveEvent) { diff --git a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs index 0a50ad1df4..7ad2106ab9 100644 --- a/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs +++ b/osu.Game.Rulesets.Catch/Edit/DrawableCatchEditorRuleset.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Framework.Bindables; using osu.Game.Beatmaps; @@ -16,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.Edit { public readonly BindableDouble TimeRangeMultiplier = new BindableDouble(1); - public DrawableCatchEditorRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) + public DrawableCatchEditorRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList? mods = null) : base(ruleset, beatmap, mods) { } diff --git a/osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs b/osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs index 5c13692b51..f776fe39c1 100644 --- a/osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs +++ b/osu.Game.Rulesets.Catch/Edit/FruitCompositionTool.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Edit.Blueprints; diff --git a/osu.Game.Rulesets.Catch/Edit/JuiceStreamCompositionTool.cs b/osu.Game.Rulesets.Catch/Edit/JuiceStreamCompositionTool.cs index 85cf89f700..cb66e2952e 100644 --- a/osu.Game.Rulesets.Catch/Edit/JuiceStreamCompositionTool.cs +++ b/osu.Game.Rulesets.Catch/Edit/JuiceStreamCompositionTool.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Edit.Blueprints; From b049244b75d578f964a4d6b5b41d494ccc652fc3 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:21:56 +0900 Subject: [PATCH 209/248] Remove #nullable disable from Catch.Beatmaps --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs | 2 -- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs | 2 -- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 2 -- 3 files changed, 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs index ac39b91f00..f009c10a9c 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps; diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index 9f5d007114..7774a7da09 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using System.Collections.Generic; diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 835f7c2d27..ab61b14ac4 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; From 3ab3f556ae3044dd0689ae77c7f5911d49c86280 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:22:21 +0900 Subject: [PATCH 210/248] Remove #nullable disable from Catch.Difficulty --- .../Difficulty/CatchDifficultyCalculator.cs | 4 +--- .../Difficulty/CatchPerformanceAttributes.cs | 2 -- .../Difficulty/CatchPerformanceCalculator.cs | 2 -- .../Difficulty/Preprocessing/CatchDifficultyHitObject.cs | 2 -- osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs | 2 -- 5 files changed, 1 insertion(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs index f37479f84a..42cfde268e 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -51,7 +49,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) { - CatchHitObject lastObject = null; + CatchHitObject? lastObject = null; List objects = new List(); diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceAttributes.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceAttributes.cs index ccdfd30200..1335fc2d23 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceAttributes.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceAttributes.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets.Catch.Difficulty diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs index 2a07b8019e..b30b85be2d 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; diff --git a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs index c44480776f..3bcfce3a56 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using osu.Game.Rulesets.Catch.Objects; diff --git a/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs b/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs index 827c28f7de..cfb3fe40be 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Game.Rulesets.Catch.Difficulty.Preprocessing; using osu.Game.Rulesets.Difficulty.Preprocessing; From 2468911f4b2b1b8afaab986faf61b743c7b3687c Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:22:49 +0900 Subject: [PATCH 211/248] Remove #nullable disable from Catch.Judgements --- osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs | 2 -- osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs | 2 -- osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs | 2 -- osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs | 5 +---- .../Judgements/CatchTinyDropletJudgement.cs | 2 -- 5 files changed, 1 insertion(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs index 15f6e4a64d..b919102215 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs index 90aa6f41a1..8fd7b93e4c 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs index e5d6429660..ccafe0abc4 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs index 6cc79f9619..4cec61d016 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgementResult.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; @@ -22,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Judgements /// public bool CatcherHyperDash; - public CatchJudgementResult([NotNull] HitObject hitObject, [NotNull] Judgement judgement) + public CatchJudgementResult(HitObject hitObject, Judgement judgement) : base(hitObject, judgement) { } diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs index c9052e3c39..d957d4171b 100644 --- a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs +++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Judgements From 56fb315f32f6a15f000bf7aa38f2b3f54e03211e Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:23:45 +0900 Subject: [PATCH 212/248] Remove #nullable disable from Catch.Objects --- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 2 -- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Droplet.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Fruit.cs | 2 -- .../Objects/FruitVisualRepresentation.cs | 2 -- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 11 ++--------- .../Objects/PalpableCatchHitObject.cs | 6 ++---- osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs | 2 -- 8 files changed, 4 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index e5541e49c1..b45f95a8e6 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Threading; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Types; diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index cd2b8348e2..f4bd515995 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using Newtonsoft.Json; using osu.Framework.Bindables; diff --git a/osu.Game.Rulesets.Catch/Objects/Droplet.cs b/osu.Game.Rulesets.Catch/Objects/Droplet.cs index ecaa4bfaf4..9c1004a04b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Droplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Droplet.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Judgements; diff --git a/osu.Game.Rulesets.Catch/Objects/Fruit.cs b/osu.Game.Rulesets.Catch/Objects/Fruit.cs index bdf8b3f28d..4818fe2cad 100644 --- a/osu.Game.Rulesets.Catch/Objects/Fruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Fruit.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Judgements; diff --git a/osu.Game.Rulesets.Catch/Objects/FruitVisualRepresentation.cs b/osu.Game.Rulesets.Catch/Objects/FruitVisualRepresentation.cs index e5d013dafc..7ec7050245 100644 --- a/osu.Game.Rulesets.Catch/Objects/FruitVisualRepresentation.cs +++ b/osu.Game.Rulesets.Catch/Objects/FruitVisualRepresentation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.Objects { public enum FruitVisualRepresentation diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 015457e84f..96e2d5c4e5 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Collections.Generic; using System.Linq; @@ -142,13 +140,8 @@ namespace osu.Game.Rulesets.Catch.Objects set { path.ControlPoints.Clear(); - path.ExpectedDistance.Value = null; - - if (value != null) - { - path.ControlPoints.AddRange(value.ControlPoints.Select(c => new PathControlPoint(c.Position, c.Type))); - path.ExpectedDistance.Value = value.ExpectedDistance.Value; - } + path.ControlPoints.AddRange(value.ControlPoints.Select(c => new PathControlPoint(c.Position, c.Type))); + path.ExpectedDistance.Value = value.ExpectedDistance.Value; } } diff --git a/osu.Game.Rulesets.Catch/Objects/PalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/PalpableCatchHitObject.cs index c9bc9ca2ac..197029aeeb 100644 --- a/osu.Game.Rulesets.Catch/Objects/PalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/PalpableCatchHitObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using Newtonsoft.Json; using osu.Framework.Bindables; using osu.Game.Rulesets.Objects; @@ -34,13 +32,13 @@ namespace osu.Game.Rulesets.Catch.Objects /// public bool HyperDash => hyperDash.Value; - private CatchHitObject hyperDashTarget; + private CatchHitObject? hyperDashTarget; /// /// The target fruit if we are to initiate a hyperdash. /// [JsonIgnore] - public CatchHitObject HyperDashTarget + public CatchHitObject? HyperDashTarget { get => hyperDashTarget; set diff --git a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs index 6bd5f0ac2a..1bf160b5a6 100644 --- a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Judgements; From b08a1e3a0b4b0b85f0403c02c2deb57520531fb1 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:25:08 +0900 Subject: [PATCH 213/248] Remove #nullable disable from misc Catch files --- osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs | 2 -- osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs b/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs index 6c7f0478a7..26f20b223a 100644 --- a/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs +++ b/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Runtime.CompilerServices; // We publish our internal attributes to other sub-projects of the framework. diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index b784fc4c19..b6a42407da 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Scoring From b88091262db0b4ebf4d9405ab8e6eb1ee53914fb Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:26:11 +0900 Subject: [PATCH 214/248] Remove #nullable disable from Catch.UI --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 6 ++---- .../UI/CatchPlayfieldAdjustmentContainer.cs | 2 -- osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs | 2 -- osu.Game.Rulesets.Catch/UI/Catcher.cs | 14 ++++++-------- .../UI/CatcherAnimationState.cs | 2 -- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 4 +--- osu.Game.Rulesets.Catch/UI/CatcherTrail.cs | 2 -- .../UI/CatcherTrailAnimation.cs | 2 -- osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs | 7 +++---- osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs | 2 -- osu.Game.Rulesets.Catch/UI/Direction.cs | 2 -- osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs | 6 ++---- .../UI/DroppedObjectContainer.cs | 2 -- .../UI/HitExplosionContainer.cs | 2 -- osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs | 2 -- osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs | 2 -- 16 files changed, 14 insertions(+), 45 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 6167ee53f6..c33d021876 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; @@ -39,9 +37,9 @@ namespace osu.Game.Rulesets.Catch.UI // only check the X position; handle all vertical space. base.ReceivePositionalInputAt(new Vector2(screenSpacePos.X, ScreenSpaceDrawQuad.Centre.Y)); - internal Catcher Catcher { get; private set; } + internal Catcher Catcher { get; private set; } = null!; - internal CatcherArea CatcherArea { get; private set; } + internal CatcherArea CatcherArea { get; private set; } = null!; private readonly IBeatmapDifficultyInfo difficulty; diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs index c03179dc50..74cbc665c0 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.UI; diff --git a/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs b/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs index 9ea150a2cf..32ede8f205 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchReplayRecorder.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Replays; diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 086b4ff285..411330f6fc 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -1,11 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; +using System.Diagnostics; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -123,7 +121,7 @@ namespace osu.Game.Rulesets.Catch.UI private double hyperDashModifier = 1; private int hyperDashDirection; private float hyperDashTargetPosition; - private Bindable hitLighting; + private Bindable hitLighting = null!; private readonly HitExplosionContainer hitExplosionContainer; @@ -131,7 +129,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly DrawablePool caughtBananaPool; private readonly DrawablePool caughtDropletPool; - public Catcher([NotNull] DroppedObjectContainer droppedObjectTarget, IBeatmapDifficultyInfo difficulty = null) + public Catcher(DroppedObjectContainer droppedObjectTarget, IBeatmapDifficultyInfo? difficulty = null) { this.droppedObjectTarget = droppedObjectTarget; @@ -231,9 +229,8 @@ namespace osu.Game.Rulesets.Catch.UI // droplet doesn't affect the catcher state if (hitObject is TinyDroplet) return; - if (result.IsHit && hitObject.HyperDash) + if (result.IsHit && hitObject.HyperDashTarget is CatchHitObject target) { - var target = hitObject.HyperDashTarget; double timeDifference = target.StartTime - hitObject.StartTime; double positionDifference = target.EffectiveX - X; double velocity = positionDifference / Math.Max(1.0, timeDifference - 1000.0 / 60.0); @@ -385,7 +382,7 @@ namespace osu.Game.Rulesets.Catch.UI private void addLighting(JudgementResult judgementResult, Color4 colour, float x) => hitExplosionContainer.Add(new HitExplosionEntry(Time.Current, judgementResult, colour, x)); - private CaughtObject getCaughtObject(PalpableCatchHitObject source) + private CaughtObject? getCaughtObject(PalpableCatchHitObject source) { switch (source) { @@ -406,6 +403,7 @@ namespace osu.Game.Rulesets.Catch.UI private CaughtObject getDroppedObject(CaughtObject caughtObject) { var droppedObject = getCaughtObject(caughtObject.HitObject); + Debug.Assert(droppedObject != null); droppedObject.CopyStateFrom(caughtObject); droppedObject.Anchor = Anchor.TopLeft; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherAnimationState.cs b/osu.Game.Rulesets.Catch/UI/CatcherAnimationState.cs index 82591eb47f..566e9d1911 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherAnimationState.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherAnimationState.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.UI { public enum CatcherAnimationState diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index d0da05bc44..4f7535d13a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -35,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly CatcherTrailDisplay catcherTrails; - private Catcher catcher; + private Catcher catcher = null!; /// /// -1 when only left button is pressed. diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs index f486633e12..762f95828a 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrail.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Timing; using osu.Game.Rulesets.Objects.Pooling; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailAnimation.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailAnimation.cs index 02bc5be863..0a5281cd10 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailAnimation.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailAnimation.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.UI { public enum CatcherTrailAnimation diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs index e982be53d8..e3e01c1b39 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailDisplay.cs @@ -1,10 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.ObjectExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Pooling; @@ -41,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly Container hyperDashAfterImages; [Resolved] - private ISkinSource skin { get; set; } + private ISkinSource skin { get; set; } = null!; public CatcherTrailDisplay() { @@ -130,7 +129,7 @@ namespace osu.Game.Rulesets.Catch.UI { base.Dispose(isDisposing); - if (skin != null) + if (skin.IsNotNull()) skin.SourceChanged -= skinSourceChanged; } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs b/osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs index 78d6979b78..3a40ab26cc 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherTrailEntry.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics.Performance; using osuTK; diff --git a/osu.Game.Rulesets.Catch/UI/Direction.cs b/osu.Game.Rulesets.Catch/UI/Direction.cs index 15e4aed86b..65f064b7fb 100644 --- a/osu.Game.Rulesets.Catch/UI/Direction.cs +++ b/osu.Game.Rulesets.Catch/UI/Direction.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - namespace osu.Game.Rulesets.Catch.UI { public enum Direction diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index 0be271b236..7930a07551 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; @@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override bool UserScrollSpeedAdjustment => false; - public DrawableCatchRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) + public DrawableCatchRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList? mods = null) : base(ruleset, beatmap, mods) { Direction.Value = ScrollingDirection.Down; @@ -54,6 +52,6 @@ namespace osu.Game.Rulesets.Catch.UI protected override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); - public override DrawableHitObject CreateDrawableRepresentation(CatchHitObject h) => null; + public override DrawableHitObject? CreateDrawableRepresentation(CatchHitObject h) => null; } } diff --git a/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs b/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs index cb2d8498cc..df1e932ad5 100644 --- a/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/DroppedObjectContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Objects.Drawables; diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs b/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs index e1dd665bf2..1e2d94433c 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osu.Framework.Graphics.Pooling; using osu.Game.Rulesets.Objects.Pooling; diff --git a/osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs b/osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs index 5d027edbaa..cfb6879067 100644 --- a/osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs +++ b/osu.Game.Rulesets.Catch/UI/ICatchComboCounter.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Graphics; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs index 78a71f26a2..bcc59a5e4f 100644 --- a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs +++ b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; From 086604cd14eb48308b5b5ec43b97533ea180339b Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 16:27:49 +0900 Subject: [PATCH 215/248] Remove #nullable disable from Catch.Objects.Drawables Except DrawableCatchHitObject, it complains in base(hitObject) call. --- osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs | 2 -- osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs | 5 +---- .../Objects/Drawables/DrawableBananaShower.cs | 5 +---- .../Objects/Drawables/DrawableCatchHitObject.cs | 1 + .../Objects/Drawables/DrawableDroplet.cs | 5 +---- osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs | 5 +---- .../Objects/Drawables/DrawableJuiceStream.cs | 5 +---- .../Objects/Drawables/DrawablePalpableCatchHitObject.cs | 5 +---- .../Objects/Drawables/DrawableTinyDroplet.cs | 6 +----- .../Objects/Drawables/IHasCatchObjectState.cs | 2 -- 12 files changed, 8 insertions(+), 37 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs index 65d91bffe2..bfeb37b1b7 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtBanana.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Skinning.Default; namespace osu.Game.Rulesets.Catch.Objects.Drawables diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs index ed8bf17747..d228c629c0 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtDroplet.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Skinning.Default; namespace osu.Game.Rulesets.Catch.Objects.Drawables diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs index d296052220..99dcac5268 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtFruit.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Game.Rulesets.Catch.Skinning.Default; namespace osu.Game.Rulesets.Catch.Objects.Drawables diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index 51addaebd5..26e304cf3f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Skinning.Default; @@ -18,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableBanana([CanBeNull] Banana h) + public DrawableBanana(Banana? h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs index c5ae1b5526..03adbce885 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -19,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableBananaShower([CanBeNull] BananaShower s) + public DrawableBananaShower(BananaShower? s) : base(s) { RelativeSizeAxes = Axes.X; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index c25bc7d076..7f8c17861d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -53,6 +53,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables XOffsetBindable.UnbindFrom(HitObject.XOffsetBindable); } + [CanBeNull] public Func CheckPosition; protected override JudgementResult CreateResult(Judgement judgement) => new CatchJudgementResult(HitObject, judgement); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index e8b0c4a9fb..8f32cdcc31 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Skinning.Default; @@ -18,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableDroplet([CanBeNull] CatchHitObject h) + public DrawableDroplet(CatchHitObject? h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index 4347c77383..52c53523e6 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Skinning.Default; @@ -18,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableFruit([CanBeNull] Fruit h) + public DrawableFruit(Fruit? h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs index 1ad1664122..41ecf59276 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -19,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableJuiceStream([CanBeNull] JuiceStream s) + public DrawableJuiceStream(JuiceStream? s) : base(s) { RelativeSizeAxes = Axes.X; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs index 8468cc0a6a..4a9661f108 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawablePalpableCatchHitObject.cs @@ -1,9 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -42,7 +39,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables public float DisplayRotation => ScalingContainer.Rotation; - protected DrawablePalpableCatchHitObject([CanBeNull] CatchHitObject h) + protected DrawablePalpableCatchHitObject(CatchHitObject? h) : base(h) { Origin = Anchor.Centre; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs index 8e98efdbda..f820ccdc62 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs @@ -1,10 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using JetBrains.Annotations; - namespace osu.Game.Rulesets.Catch.Objects.Drawables { public partial class DrawableTinyDroplet : DrawableDroplet @@ -16,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables { } - public DrawableTinyDroplet([CanBeNull] TinyDroplet h) + public DrawableTinyDroplet(TinyDroplet? h) : base(h) { } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs index f30ef0831a..18fc0db6e3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/IHasCatchObjectState.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Bindables; using osuTK; using osuTK.Graphics; From 8777d5349bd9e816d9ceff9b0891bc51ca0014ea Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 14:39:34 +0300 Subject: [PATCH 216/248] Use existing strings --- osu.Game/Localisation/EditorStrings.cs | 15 --------------- osu.Game/Screens/Edit/BackgroundDimMenuItem.cs | 2 +- .../Compose/Components/Timeline/TimelineArea.cs | 3 ++- osu.Game/Screens/Edit/Editor.cs | 3 ++- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs index 32078468c9..6b16e43bd3 100644 --- a/osu.Game/Localisation/EditorStrings.cs +++ b/osu.Game/Localisation/EditorStrings.cs @@ -54,11 +54,6 @@ namespace osu.Game.Localisation /// public static LocalisableString View => new TranslatableString(getKey(@"view"), @"View"); - /// - /// "Background dim" - /// - public static LocalisableString BackgroundDim => new TranslatableString(getKey(@"background_dim"), @"Background dim"); - /// /// "Waveform opacity" /// @@ -79,11 +74,6 @@ namespace osu.Game.Localisation /// public static LocalisableString SetPreviewPointToCurrent => new TranslatableString(getKey(@"set_preview_point_to_current"), @"Set preview point to current time"); - /// - /// "Save" - /// - public static LocalisableString Save => new TranslatableString(getKey(@"save"), @"Save"); - /// /// "Export package" /// @@ -154,11 +144,6 @@ namespace osu.Game.Localisation /// public static LocalisableString TimelineTicks => new TranslatableString(getKey(@"timeline_ticks"), @"Ticks"); - /// - /// "BPM" - /// - public static LocalisableString TimelineBpm => new TranslatableString(getKey(@"timeline_bpm"), @"BPM"); - private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs index bff01385bb..2a1159eb27 100644 --- a/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs +++ b/osu.Game/Screens/Edit/BackgroundDimMenuItem.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Edit private readonly Dictionary menuItemLookup = new Dictionary(); public BackgroundDimMenuItem(Bindable backgroundDim) - : base(EditorStrings.BackgroundDim) + : base(GameplaySettingsStrings.BackgroundDim) { Items = new[] { diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs index f11c7b1d00..0b83258f8b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineArea.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; using osu.Game.Overlays; +using osu.Game.Resources.Localisation.Web; using osuTK; namespace osu.Game.Screens.Edit.Compose.Components.Timeline @@ -86,7 +87,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }, controlPointsCheckbox = new OsuCheckbox { - LabelText = EditorStrings.TimelineBpm, + LabelText = BeatmapsetsStrings.ShowStatsBpm, Current = { Value = true }, }, } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index c440cc8285..29be1a3881 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -51,6 +51,7 @@ using osu.Game.Screens.Edit.Verify; using osu.Game.Screens.Play; using osu.Game.Users; using osuTK.Input; +using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; namespace osu.Game.Screens.Edit { @@ -951,7 +952,7 @@ namespace osu.Game.Screens.Edit private List createFileMenuItems() => new List { - new EditorMenuItem(EditorStrings.Save, MenuItemType.Standard, () => Save()), + new EditorMenuItem(CommonStrings.ButtonsSave, MenuItemType.Standard, () => Save()), new EditorMenuItem(EditorStrings.ExportPackage, MenuItemType.Standard, exportBeatmap) { Action = { Disabled = !RuntimeInfo.IsDesktop } }, new EditorMenuItemSpacer(), createDifficultyCreationMenu(), From 5d2e09137cfed291d842458972c4c8c2e64073be Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 14:40:53 +0300 Subject: [PATCH 217/248] Remove text padding in editor menu for now --- osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs index 1bd8979347..368fe40977 100644 --- a/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs +++ b/osu.Game/Screens/Edit/Components/Menus/EditorMenuItem.cs @@ -9,15 +9,13 @@ namespace osu.Game.Screens.Edit.Components.Menus { public class EditorMenuItem : OsuMenuItem { - private const int min_text_length = 40; - public EditorMenuItem(LocalisableString text, MenuItemType type = MenuItemType.Standard) - : base(LocalisableString.Interpolate($"{text,-min_text_length}"), type) + : base(text, type) { } public EditorMenuItem(LocalisableString text, MenuItemType type, Action action) - : base(LocalisableString.Interpolate($"{text,-min_text_length}"), type, action) + : base(text, type, action) { } } From 13c1b8f5a49b1ba009ee687e824008b403f3e6e8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 15 Jan 2023 15:51:18 +0300 Subject: [PATCH 218/248] Fix intermittent failure in tests with restarting player instances --- .../Visual/Navigation/TestSceneScreenNavigation.cs | 8 +++++++- osu.Game/Online/Spectator/SpectatorClient.cs | 2 +- osu.Game/OsuGameBase.cs | 6 +++--- osu.Game/Tests/Visual/OsuGameTestScene.cs | 3 +++ osu.Game/Tests/Visual/TestPlayer.cs | 14 ++++++++++++++ 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 66c4cf8686..7bde2e747d 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -195,11 +195,17 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => { DismissAnyNotifications(); - return (player = Game.ScreenStack.CurrentScreen as Player) != null; + player = Game.ScreenStack.CurrentScreen as Player; + return player?.IsLoaded == true; }); AddAssert("retry count is 0", () => player.RestartCount == 0); + // todo: see https://github.com/ppy/osu/issues/22220 + // tests are supposed to be immune to this edge case by the logic in TestPlayer, + // but we're running a full game instance here, so we have to work around it manually. + AddStep("end spectator before retry", () => Game.SpectatorClient.EndPlaying(player.GameplayState)); + AddStep("attempt to retry", () => player.ChildrenOfType().First().Action()); AddUntilStep("wait for old player gone", () => Game.ScreenStack.CurrentScreen != player); diff --git a/osu.Game/Online/Spectator/SpectatorClient.cs b/osu.Game/Online/Spectator/SpectatorClient.cs index b60cef2835..55ec75f4ce 100644 --- a/osu.Game/Online/Spectator/SpectatorClient.cs +++ b/osu.Game/Online/Spectator/SpectatorClient.cs @@ -47,7 +47,7 @@ namespace osu.Game.Online.Spectator /// /// Whether the local user is playing. /// - protected bool IsPlaying { get; private set; } + protected internal bool IsPlaying { get; private set; } /// /// Called whenever new frames arrive from the server. diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 33d33fe181..b27be37591 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -189,7 +189,7 @@ namespace osu.Game private RulesetConfigCache rulesetConfigCache; - private SpectatorClient spectatorClient; + protected SpectatorClient SpectatorClient { get; private set; } protected MultiplayerClient MultiplayerClient { get; private set; } @@ -300,7 +300,7 @@ namespace osu.Game // TODO: OsuGame or OsuGameBase? dependencies.CacheAs(beatmapUpdater = new BeatmapUpdater(BeatmapManager, difficultyCache, API, Storage)); - dependencies.CacheAs(spectatorClient = new OnlineSpectatorClient(endpoints)); + dependencies.CacheAs(SpectatorClient = new OnlineSpectatorClient(endpoints)); dependencies.CacheAs(MultiplayerClient = new OnlineMultiplayerClient(endpoints)); dependencies.CacheAs(metadataClient = new OnlineMetadataClient(endpoints)); dependencies.CacheAs(soloStatisticsWatcher = new SoloStatisticsWatcher()); @@ -346,7 +346,7 @@ namespace osu.Game if (API is APIAccess apiAccess) base.Content.Add(apiAccess); - base.Content.Add(spectatorClient); + base.Content.Add(SpectatorClient); base.Content.Add(MultiplayerClient); base.Content.Add(metadataClient); base.Content.Add(soloStatisticsWatcher); diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs index 1bf1fbf6ab..94be4a375d 100644 --- a/osu.Game/Tests/Visual/OsuGameTestScene.cs +++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs @@ -20,6 +20,7 @@ using osu.Game.Database; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; +using osu.Game.Online.Spectator; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -148,6 +149,8 @@ namespace osu.Game.Tests.Visual public new Bindable> SelectedMods => base.SelectedMods; + public new SpectatorClient SpectatorClient => base.SpectatorClient; + // if we don't apply these changes, when running under nUnit the version that gets populated is that of nUnit. public override Version AssemblyVersion => new Version(0, 0); public override string Version => "test game"; diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs index 81195ebed9..d9cae6b03b 100644 --- a/osu.Game/Tests/Visual/TestPlayer.cs +++ b/osu.Game/Tests/Visual/TestPlayer.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Screens; using osu.Game.Online.API; using osu.Game.Online.Rooms; using osu.Game.Online.Spectator; @@ -103,6 +104,19 @@ namespace osu.Game.Tests.Visual ScoreProcessor.NewJudgement += r => Results.Add(r); } + public override bool OnExiting(ScreenExitEvent e) + { + bool exiting = base.OnExiting(e); + + // SubmittingPlayer performs EndPlaying on a fire-and-forget async task, which allows for the chance of BeginPlaying to be called before EndPlaying is called here. + // Until this is handled properly at game-side, ensure EndPlaying is called before exiting player. + // see: https://github.com/ppy/osu/issues/22220 + if (LoadedBeatmapSuccessfully) + spectatorClient?.EndPlaying(GameplayState); + + return exiting; + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); From f7af5a8115d5566a623a9ba8d3b6a5679bc13d29 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 15 Jan 2023 22:35:44 +0900 Subject: [PATCH 219/248] Revert some formatting changes --- osu.Game/Screens/Select/SongSelect.cs | 54 +++++++++++++-------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index ef5827fad7..0e108d3db0 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -314,17 +314,16 @@ namespace osu.Game.Screens.Select /// Creates the buttons to be displayed in the footer. /// /// A set of and an optional which the button opens when pressed. - protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() => - new (FooterButton, OverlayContainer?)[] + protected virtual IEnumerable<(FooterButton, OverlayContainer?)> CreateFooterButtons() => new (FooterButton, OverlayContainer?)[] + { + (new FooterButtonMods { Current = Mods }, ModSelect), + (new FooterButtonRandom { - (new FooterButtonMods { Current = Mods }, ModSelect), - (new FooterButtonRandom - { - NextRandom = () => Carousel.SelectNextRandom(), - PreviousRandom = Carousel.SelectPreviousRandom - }, null), - (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) - }; + NextRandom = () => Carousel.SelectNextRandom(), + PreviousRandom = Carousel.SelectPreviousRandom + }, null), + (beatmapOptionsButton = new FooterButtonOptions(), BeatmapOptions) + }; protected virtual ModSelectOverlay CreateModSelectOverlay() => new SoloModSelectOverlay(); @@ -425,25 +424,26 @@ namespace osu.Game.Screens.Select Logger.Log($"Song select working beatmap updated to {beatmap}"); - if (Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) return; - - // A selection may not have been possible with filters applied. - - // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. - if (!beatmap.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) + if (!Carousel.SelectBeatmap(beatmap.BeatmapInfo, false)) { - Ruleset.Value = beatmap.BeatmapInfo.Ruleset; - transferRulesetValue(); + // A selection may not have been possible with filters applied. + + // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. + if (!beatmap.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) + { + Ruleset.Value = beatmap.BeatmapInfo.Ruleset; + transferRulesetValue(); + } + + // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), + // we still want to temporarily show the new beatmap, bypassing filters. + // This will be undone the next time the user changes the filter. + var criteria = FilterControl.CreateCriteria(); + criteria.SelectedBeatmapSet = beatmap.BeatmapInfo.BeatmapSet; + Carousel.Filter(criteria); + + Carousel.SelectBeatmap(beatmap.BeatmapInfo); } - - // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), - // we still want to temporarily show the new beatmap, bypassing filters. - // This will be undone the next time the user changes the filter. - var criteria = FilterControl.CreateCriteria(); - criteria.SelectedBeatmapSet = beatmap.BeatmapInfo.BeatmapSet; - Carousel.Filter(criteria); - - Carousel.SelectBeatmap(beatmap.BeatmapInfo); } // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. From 4cf4a6685802831dee21b6d0cc0047c453ec608b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 15 Jan 2023 22:43:30 +0900 Subject: [PATCH 220/248] Make `MusicController` a required dependency of `SongSelect` --- osu.Game/Screens/Select/SongSelect.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 0e108d3db0..d7c1dbf543 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -34,6 +34,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Collections; using osu.Game.Graphics.UserInterface; using System.Diagnostics; +using osu.Framework.Extensions.ObjectExtensions; using osu.Game.Screens.Play; using osu.Game.Skinning; @@ -118,7 +119,7 @@ namespace osu.Game.Screens.Select private IDisposable? modSelectOverlayRegistration; [Resolved] - private MusicController? music { get; set; } + private MusicController music { get; set; } = null!; [Resolved] internal IOverlayManager? OverlayManager { get; private set; } @@ -616,7 +617,6 @@ namespace osu.Game.Screens.Select { // restart playback on returning to song select, regardless. // not sure this should be a permanent thing (we may want to leave a user pause paused even on returning) - Debug.Assert(music != null); music.ResetTrackAdjustments(); music.Play(requestedByUser: true); } @@ -692,7 +692,6 @@ namespace osu.Game.Screens.Select ensureTrackLooping(Beatmap.Value, TrackChangeDirection.None); - Debug.Assert(music != null); music.TrackChanged += ensureTrackLooping; } @@ -702,7 +701,6 @@ namespace osu.Game.Screens.Select if (!isHandlingLooping) return; - Debug.Assert(music != null); music.CurrentTrack.Looping = isHandlingLooping = false; music.TrackChanged -= ensureTrackLooping; @@ -728,7 +726,7 @@ namespace osu.Game.Screens.Select decoupledRuleset.UnbindAll(); - if (music != null) + if (music.IsNotNull()) music.TrackChanged -= ensureTrackLooping; modSelectOverlayRegistration?.Dispose(); @@ -774,7 +772,6 @@ namespace osu.Game.Screens.Select if (!ControlGlobalMusic) return; - Debug.Assert(music != null); ITrack track = music.CurrentTrack; bool isNewTrack = !lastTrack.TryGetTarget(out var last) || last != track; From d664a66a375cb649c04783c1d2936bffb521f33f Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 23:11:59 +0900 Subject: [PATCH 221/248] Remove redundant `canBeNull: true` --- .../Edit/Blueprints/Components/EditablePath.cs | 2 +- .../Edit/Blueprints/Components/SelectionEditablePath.cs | 2 +- .../Edit/Blueprints/JuiceStreamSelectionBlueprint.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs index c2a426de66..74d6565600 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/EditablePath.cs @@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components private readonly List previousVertexStates = new List(); - [Resolved(CanBeNull = true)] + [Resolved] private IBeatSnapProvider? beatSnapProvider { get; set; } protected EditablePath(Func positionToTime) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs index 95b17a197f..c7a26ca15a 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/Components/SelectionEditablePath.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components // To handle when the editor is scrolled while dragging. private Vector2 dragStartPosition; - [Resolved(CanBeNull = true)] + [Resolved] private IEditorChangeHandler? changeHandler { get; set; } public SelectionEditablePath(Func positionToTime) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs index 1be5148d76..49d778ad08 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints private Vector2 rightMouseDownPosition; - [Resolved(CanBeNull = true)] + [Resolved] private EditorBeatmap? editorBeatmap { get; set; } public JuiceStreamSelectionBlueprint(JuiceStream hitObject) diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs index ffdc5299d0..dbbe905879 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.UI { } - [Resolved(canBeNull: true)] + [Resolved] private Player? player { get; set; } protected override void LoadComplete() From 1f8b7b8f034bbcc0bfe1284d1b973135cd1d3e79 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 15 Jan 2023 23:21:38 +0900 Subject: [PATCH 222/248] Remove #nullable disable from CaughtObject --- osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs index 436edf6367..0c26c52171 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables [Cached(typeof(IHasCatchObjectState))] public abstract partial class CaughtObject : SkinnableDrawable, IHasCatchObjectState { - public PalpableCatchHitObject HitObject { get; private set; } + public PalpableCatchHitObject HitObject { get; private set; } = null!; public Bindable AccentColour { get; } = new Bindable(); public Bindable HyperDash { get; } = new Bindable(); public Bindable IndexInBeatmap { get; } = new Bindable(); From 9a29c9ae26a94f35d1a3cc4aff6678ab388847e7 Mon Sep 17 00:00:00 2001 From: mk56-spn Date: Sun, 15 Jan 2023 15:32:53 +0100 Subject: [PATCH 223/248] remove hacky method to check if carousel is null --- osu.Game/Screens/Select/SongSelect.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index d7c1dbf543..d4d75d0ad6 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -128,7 +128,7 @@ namespace osu.Game.Screens.Select private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog? manageCollectionsDialog, DifficultyRecommender? recommender) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). - transferRulesetValue(false); + transferRulesetValue(); LoadComponentAsync(Carousel = new BeatmapCarousel { @@ -852,7 +852,7 @@ namespace osu.Game.Screens.Select /// Will immediately run filter operations if required. /// /// Whether a transfer occurred. - private bool transferRulesetValue(bool carouselLoaded = true) + private bool transferRulesetValue() { if (decoupledRuleset.Value?.Equals(Ruleset.Value) == true) return false; @@ -860,8 +860,8 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; - // We don't want to declare the carousel as nullable, so this check allows us to avoid running the carousel flush during the loading process - if (!carouselLoaded) return true; + // We want to check for null since this method gets called before the loading of the carousel. + if (Carousel.IsNull()) return true; // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). From 00acea59fca4254630d4a21555be1ab8ffc9fccb Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 19:37:40 +0300 Subject: [PATCH 224/248] Move some strings to common --- osu.Game/Localisation/CommonStrings.cs | 50 ++++++++++++++++++++++++++ osu.Game/Localisation/EditorStrings.cs | 50 -------------------------- osu.Game/Screens/Edit/Editor.cs | 25 +++++++------ 3 files changed, 62 insertions(+), 63 deletions(-) diff --git a/osu.Game/Localisation/CommonStrings.cs b/osu.Game/Localisation/CommonStrings.cs index 385ebd0593..10178915a2 100644 --- a/osu.Game/Localisation/CommonStrings.cs +++ b/osu.Game/Localisation/CommonStrings.cs @@ -104,6 +104,56 @@ namespace osu.Game.Localisation /// public static LocalisableString Description => new TranslatableString(getKey(@"description"), @"Description"); + /// + /// "File" + /// + public static LocalisableString MenuBarFile => new TranslatableString(getKey(@"menu_bar_file"), @"File"); + + /// + /// "Edit" + /// + public static LocalisableString MenuBarEdit => new TranslatableString(getKey(@"menu_bar_edit"), @"Edit"); + + /// + /// "View" + /// + public static LocalisableString MenuBarView => new TranslatableString(getKey(@"menu_bar_view"), @"View"); + + /// + /// "Undo" + /// + public static LocalisableString Undo => new TranslatableString(getKey(@"undo"), @"Undo"); + + /// + /// "Redo" + /// + public static LocalisableString Redo => new TranslatableString(getKey(@"redo"), @"Redo"); + + /// + /// "Cut" + /// + public static LocalisableString Cut => new TranslatableString(getKey(@"cut"), @"Cut"); + + /// + /// "Copy" + /// + public static LocalisableString Copy => new TranslatableString(getKey(@"copy"), @"Copy"); + + /// + /// "Paste" + /// + public static LocalisableString Paste => new TranslatableString(getKey(@"paste"), @"Paste"); + + /// + /// "Clone" + /// + public static LocalisableString Clone => new TranslatableString(getKey(@"clone"), @"Clone"); + + /// + /// "Exit" + /// + public static LocalisableString Exit => new TranslatableString(getKey(@"exit"), @"Exit"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs index 6b16e43bd3..96c08aa6f8 100644 --- a/osu.Game/Localisation/EditorStrings.cs +++ b/osu.Game/Localisation/EditorStrings.cs @@ -9,51 +9,6 @@ namespace osu.Game.Localisation { private const string prefix = @"osu.Game.Resources.Localisation.Editor"; - /// - /// "File" - /// - public static LocalisableString File => new TranslatableString(getKey(@"file"), @"File"); - - /// - /// "Edit" - /// - public static LocalisableString Edit => new TranslatableString(getKey(@"edit"), @"Edit"); - - /// - /// "Undo" - /// - public static LocalisableString Undo => new TranslatableString(getKey(@"undo"), @"Undo"); - - /// - /// "Redo" - /// - public static LocalisableString Redo => new TranslatableString(getKey(@"redo"), @"Redo"); - - /// - /// "Cut" - /// - public static LocalisableString Cut => new TranslatableString(getKey(@"cut"), @"Cut"); - - /// - /// "Copy" - /// - public static LocalisableString Copy => new TranslatableString(getKey(@"copy"), @"Copy"); - - /// - /// "Paste" - /// - public static LocalisableString Paste => new TranslatableString(getKey(@"paste"), @"Paste"); - - /// - /// "Clone" - /// - public static LocalisableString Clone => new TranslatableString(getKey(@"clone"), @"Clone"); - - /// - /// "View" - /// - public static LocalisableString View => new TranslatableString(getKey(@"view"), @"View"); - /// /// "Waveform opacity" /// @@ -94,11 +49,6 @@ namespace osu.Game.Localisation /// public static LocalisableString DeleteDifficulty => new TranslatableString(getKey(@"delete_difficulty"), @"Delete difficulty"); - /// - /// "Exit" - /// - public static LocalisableString Exit => new TranslatableString(getKey(@"exit"), @"Exit"); - /// /// "setup" /// diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 29be1a3881..74ea933255 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -51,7 +51,7 @@ using osu.Game.Screens.Edit.Verify; using osu.Game.Screens.Play; using osu.Game.Users; using osuTK.Input; -using CommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; +using WebCommonStrings = osu.Game.Resources.Localisation.Web.CommonStrings; namespace osu.Game.Screens.Edit { @@ -294,24 +294,24 @@ namespace osu.Game.Screens.Edit RelativeSizeAxes = Axes.Both, Items = new[] { - new MenuItem(EditorStrings.File) + new MenuItem(CommonStrings.MenuBarFile) { Items = createFileMenuItems() }, - new MenuItem(EditorStrings.Edit) + new MenuItem(CommonStrings.MenuBarEdit) { Items = new[] { - undoMenuItem = new EditorMenuItem(EditorStrings.Undo, MenuItemType.Standard, Undo), - redoMenuItem = new EditorMenuItem(EditorStrings.Redo, MenuItemType.Standard, Redo), + undoMenuItem = new EditorMenuItem(CommonStrings.Undo, MenuItemType.Standard, Undo), + redoMenuItem = new EditorMenuItem(CommonStrings.Redo, MenuItemType.Standard, Redo), new EditorMenuItemSpacer(), - cutMenuItem = new EditorMenuItem(EditorStrings.Cut, MenuItemType.Standard, Cut), - copyMenuItem = new EditorMenuItem(EditorStrings.Copy, MenuItemType.Standard, Copy), - pasteMenuItem = new EditorMenuItem(EditorStrings.Paste, MenuItemType.Standard, Paste), - cloneMenuItem = new EditorMenuItem(EditorStrings.Clone, MenuItemType.Standard, Clone), + cutMenuItem = new EditorMenuItem(CommonStrings.Cut, MenuItemType.Standard, Cut), + copyMenuItem = new EditorMenuItem(CommonStrings.Copy, MenuItemType.Standard, Copy), + pasteMenuItem = new EditorMenuItem(CommonStrings.Paste, MenuItemType.Standard, Paste), + cloneMenuItem = new EditorMenuItem(CommonStrings.Clone, MenuItemType.Standard, Clone), } }, - new MenuItem(EditorStrings.View) + new MenuItem(CommonStrings.MenuBarView) { Items = new MenuItem[] { @@ -344,7 +344,6 @@ namespace osu.Game.Screens.Edit bottomBar = new BottomBar(), } }); - changeHandler?.CanUndo.BindValueChanged(v => undoMenuItem.Action.Disabled = !v.NewValue, true); changeHandler?.CanRedo.BindValueChanged(v => redoMenuItem.Action.Disabled = !v.NewValue, true); @@ -952,7 +951,7 @@ namespace osu.Game.Screens.Edit private List createFileMenuItems() => new List { - new EditorMenuItem(CommonStrings.ButtonsSave, MenuItemType.Standard, () => Save()), + new EditorMenuItem(WebCommonStrings.ButtonsSave, MenuItemType.Standard, () => Save()), new EditorMenuItem(EditorStrings.ExportPackage, MenuItemType.Standard, exportBeatmap) { Action = { Disabled = !RuntimeInfo.IsDesktop } }, new EditorMenuItemSpacer(), createDifficultyCreationMenu(), @@ -960,7 +959,7 @@ namespace osu.Game.Screens.Edit new EditorMenuItemSpacer(), new EditorMenuItem(EditorStrings.DeleteDifficulty, MenuItemType.Standard, deleteDifficulty) { Action = { Disabled = Beatmap.Value.BeatmapSetInfo.Beatmaps.Count < 2 } }, new EditorMenuItemSpacer(), - new EditorMenuItem(EditorStrings.Exit, MenuItemType.Standard, this.Exit) + new EditorMenuItem(CommonStrings.Exit, MenuItemType.Standard, this.Exit) }; private void exportBeatmap() From 9ce7c51b149401e3988eafbbe8461de7a86f1993 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 23:29:58 +0300 Subject: [PATCH 225/248] Localise osu! settings --- .../UI/OsuSettingsSubsection.cs | 11 +++++----- .../Localisation/RulesetSettingsStrings.cs | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs index f711a0fc31..64c4e7eef6 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettingsSubsection.cs @@ -1,11 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.UI; @@ -30,23 +29,23 @@ namespace osu.Game.Rulesets.Osu.UI { new SettingsCheckbox { - LabelText = "Snaking in sliders", + LabelText = RulesetSettingsStrings.SnakingInSliders, Current = config.GetBindable(OsuRulesetSetting.SnakingInSliders) }, new SettingsCheckbox { ClassicDefault = false, - LabelText = "Snaking out sliders", + LabelText = RulesetSettingsStrings.SnakingOutSliders, Current = config.GetBindable(OsuRulesetSetting.SnakingOutSliders) }, new SettingsCheckbox { - LabelText = "Cursor trail", + LabelText = RulesetSettingsStrings.CursorTrail, Current = config.GetBindable(OsuRulesetSetting.ShowCursorTrail) }, new SettingsEnumDropdown { - LabelText = "Playfield border style", + LabelText = RulesetSettingsStrings.PlayfieldBorderStyle, Current = config.GetBindable(OsuRulesetSetting.PlayfieldBorderStyle), }, }; diff --git a/osu.Game/Localisation/RulesetSettingsStrings.cs b/osu.Game/Localisation/RulesetSettingsStrings.cs index bc4be56c80..dd2b7b0040 100644 --- a/osu.Game/Localisation/RulesetSettingsStrings.cs +++ b/osu.Game/Localisation/RulesetSettingsStrings.cs @@ -14,6 +14,26 @@ namespace osu.Game.Localisation /// public static LocalisableString Rulesets => new TranslatableString(getKey(@"rulesets"), @"Rulesets"); + /// + /// "Snaking in sliders" + /// + public static LocalisableString SnakingInSliders => new TranslatableString(getKey(@"snaking_in_sliders"), @"Snaking in sliders"); + + /// + /// "Snaking out sliders" + /// + public static LocalisableString SnakingOutSliders => new TranslatableString(getKey(@"snaking_out_sliders"), @"Snaking out sliders"); + + /// + /// "Cursor trail" + /// + public static LocalisableString CursorTrail => new TranslatableString(getKey(@"cursor_trail"), @"Cursor trail"); + + /// + /// "Playfield border style" + /// + public static LocalisableString PlayfieldBorderStyle => new TranslatableString(getKey(@"playfield_border_style"), @"Playfield border style"); + /// /// "None" /// From 6f84641596871a0f64c2a82e702c21f2e32aef8e Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Sun, 15 Jan 2023 23:30:11 +0300 Subject: [PATCH 226/248] Localise osu!mania settings --- .../ManiaSettingsSubsection.cs | 9 +++--- .../UI/ManiaScrollingDirection.cs | 7 +++-- .../Localisation/RulesetSettingsStrings.cs | 30 +++++++++++++++++++ 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs index 9ed555da51..f5a5771386 100644 --- a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs +++ b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.UI; @@ -30,18 +31,18 @@ namespace osu.Game.Rulesets.Mania { new SettingsEnumDropdown { - LabelText = "Scrolling direction", + LabelText = RulesetSettingsStrings.ScrollingDirection, Current = config.GetBindable(ManiaRulesetSetting.ScrollDirection) }, new SettingsSlider { - LabelText = "Scroll speed", + LabelText = RulesetSettingsStrings.ScrollSpeed, Current = config.GetBindable(ManiaRulesetSetting.ScrollTime), KeyboardStep = 5 }, new SettingsCheckbox { - LabelText = "Timing-based note colouring", + LabelText = RulesetSettingsStrings.TimingBasedColouring, Current = config.GetBindable(ManiaRulesetSetting.TimingBasedNoteColouring), } }; @@ -49,7 +50,7 @@ namespace osu.Game.Rulesets.Mania private partial class ManiaScrollSlider : OsuSliderBar { - public override LocalisableString TooltipText => $"{Current.Value}ms (speed {(int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / Current.Value)})"; + public override LocalisableString TooltipText => RulesetSettingsStrings.ScrollSpeedTooltip(Current.Value, (int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / Current.Value)); } } } diff --git a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs index 44fe4b1b30..d36e6057bb 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs @@ -1,15 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - +using osu.Framework.Localisation; +using osu.Game.Localisation; using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.UI { public enum ManiaScrollingDirection { + [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.Up))] Up = ScrollingDirection.Up, + + [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.Down))] Down = ScrollingDirection.Down } } diff --git a/osu.Game/Localisation/RulesetSettingsStrings.cs b/osu.Game/Localisation/RulesetSettingsStrings.cs index dd2b7b0040..0374f81cee 100644 --- a/osu.Game/Localisation/RulesetSettingsStrings.cs +++ b/osu.Game/Localisation/RulesetSettingsStrings.cs @@ -49,6 +49,36 @@ namespace osu.Game.Localisation /// public static LocalisableString BorderFull => new TranslatableString(getKey(@"full_borders"), @"Full"); + /// + /// "Scrolling direction" + /// + public static LocalisableString ScrollingDirection => new TranslatableString(getKey(@"scrolling_direction"), @"Scrolling direction"); + + /// + /// "Up" + /// + public static LocalisableString Up => new TranslatableString(getKey(@"scrolling_up"), @"Up"); + + /// + /// "Down" + /// + public static LocalisableString Down => new TranslatableString(getKey(@"scrolling_down"), @"Down"); + + /// + /// "Scroll speed" + /// + public static LocalisableString ScrollSpeed => new TranslatableString(getKey(@"scroll_speed"), @"Scroll speed"); + + /// + /// "Timing-based note colouring" + /// + public static LocalisableString TimingBasedColouring => new TranslatableString(getKey(@"Timing_based_colouring"), @"Timing-based note colouring"); + + /// + /// "{0}ms (speed {1})" + /// + public static LocalisableString ScrollSpeedTooltip(double arg0, int arg1) => new TranslatableString(getKey(@"ruleset"), @"{0}ms (speed {1})", arg0, arg1); + private static string getKey(string key) => $@"{prefix}:{key}"; } } From 85c1932851bf71202805c9cbcfe133d32ee3088b Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 12:46:41 -0800 Subject: [PATCH 227/248] Mark `Converts` as nullable --- osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 2 +- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index d39ed1e1ed..d98715a42d 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -126,7 +126,7 @@ namespace osu.Game.Online.API.Requests.Responses public APIBeatmap[] Beatmaps { get; set; } = Array.Empty(); [JsonProperty(@"converts")] - public APIBeatmap[] Converts { get; set; } = Array.Empty(); + public APIBeatmap[]? Converts { get; set; } private BeatmapMetadata metadata => new BeatmapMetadata { diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 51b6b14579..0ee7dfc9bd 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -168,7 +168,7 @@ namespace osu.Game.Overlays.BeatmapSet if (BeatmapSet != null) { - Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.Concat(BeatmapSet.Converts) + Difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.Concat(BeatmapSet.Converts ?? Array.Empty()) .Where(b => b.Ruleset.MatchesOnlineID(ruleset.Value)) .OrderBy(b => !b.Convert) .ThenBy(b => b.StarRating) From b733f46c6fed49d930da4e0cf20d5949c5914ddd Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 14:15:36 -0800 Subject: [PATCH 228/248] Apply NRT to `BeatmapPicker` --- .../TestSceneStartupBeatmapDisplay.cs | 4 +--- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 22 +++++++++---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs b/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs index 0c165bc40e..25cef8440a 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneStartupBeatmapDisplay.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using NUnit.Framework; using osu.Framework.Graphics.Containers; @@ -50,7 +48,7 @@ namespace osu.Game.Tests.Visual.Navigation public void TestBeatmapLink() { AddUntilStep("Beatmap overlay displayed", () => Game.ChildrenOfType().FirstOrDefault()?.State.Value == Visibility.Visible); - AddUntilStep("Beatmap overlay showing content", () => Game.ChildrenOfType().FirstOrDefault()?.Beatmap.Value.OnlineID == requested_beatmap_id); + AddUntilStep("Beatmap overlay showing content", () => Game.ChildrenOfType().FirstOrDefault()?.Beatmap.Value?.OnlineID == requested_beatmap_id); } } } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 0ee7dfc9bd..76fc1bbf53 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System; using System.Linq; using osu.Framework; @@ -38,10 +36,10 @@ namespace osu.Game.Overlays.BeatmapSet public readonly DifficultiesContainer Difficulties; - public readonly Bindable Beatmap = new Bindable(); - private APIBeatmapSet beatmapSet; + public readonly Bindable Beatmap = new Bindable(); + private APIBeatmapSet? beatmapSet; - public APIBeatmapSet BeatmapSet + public APIBeatmapSet? BeatmapSet { get => beatmapSet; set @@ -142,7 +140,7 @@ namespace osu.Game.Overlays.BeatmapSet } [Resolved] - private IBindable ruleset { get; set; } + private IBindable ruleset { get; set; } = null!; [BackgroundDependencyLoader] private void load(OsuColour colours) @@ -200,9 +198,9 @@ namespace osu.Game.Overlays.BeatmapSet updateDifficultyButtons(); } - private void showBeatmap(IBeatmapInfo beatmapInfo) + private void showBeatmap(IBeatmapInfo? beatmapInfo) { - version.Text = beatmapInfo?.DifficultyName; + version.Text = beatmapInfo?.DifficultyName ?? string.Empty; } private void updateDifficultyButtons() @@ -212,7 +210,7 @@ namespace osu.Game.Overlays.BeatmapSet public partial class DifficultiesContainer : FillFlowContainer { - public Action OnLostHover; + public Action? OnLostHover; protected override void OnHoverLost(HoverLostEvent e) { @@ -233,9 +231,9 @@ namespace osu.Game.Overlays.BeatmapSet public readonly APIBeatmap Beatmap; - public Action OnHovered; - public Action OnClicked; - public event Action StateChanged; + public Action? OnHovered; + public Action? OnClicked; + public event Action? StateChanged; private DifficultySelectorState state; From ae49e724e43ebe449f1229c1efbed7157d00ba23 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 14:17:46 -0800 Subject: [PATCH 229/248] Move converted beatmap icons logic locally --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 4 ---- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index 41db2399ac..1665ec52fa 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets; using osuTK; using osuTK.Graphics; @@ -117,9 +116,6 @@ namespace osu.Game.Beatmaps.Drawables private Drawable getRulesetIcon() { - if ((beatmap as APIBeatmap)?.Convert == true) - return rulesets.GetRuleset(0)!.CreateInstance().CreateIcon(); - int? onlineID = ruleset.OnlineID; if (onlineID >= 0 && rulesets.GetRuleset(onlineID.Value)?.CreateInstance() is Ruleset rulesetInstance) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 76fc1bbf53..585e0dd1a2 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -170,7 +170,7 @@ namespace osu.Game.Overlays.BeatmapSet .Where(b => b.Ruleset.MatchesOnlineID(ruleset.Value)) .OrderBy(b => !b.Convert) .ThenBy(b => b.StarRating) - .Select(b => new DifficultySelectorButton(b) + .Select(b => new DifficultySelectorButton(b, b.Convert ? new RulesetInfo { OnlineID = 0 } : null) { State = DifficultySelectorState.NotSelected, OnHovered = beatmap => @@ -254,7 +254,7 @@ namespace osu.Game.Overlays.BeatmapSet } } - public DifficultySelectorButton(APIBeatmap beatmapInfo) + public DifficultySelectorButton(APIBeatmap beatmapInfo, IRulesetInfo? ruleset) { Beatmap = beatmapInfo; Size = new Vector2(size); @@ -273,7 +273,7 @@ namespace osu.Game.Overlays.BeatmapSet Alpha = 0.5f } }, - icon = new DifficultyIcon(beatmapInfo) + icon = new DifficultyIcon(beatmapInfo, ruleset) { ShowTooltip = false, Current = { Value = new StarDifficulty(beatmapInfo.StarRating, 0) }, From 0ff143d4c86d7e6ae19f703201046cab5592c01a Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 15:19:06 -0800 Subject: [PATCH 230/248] Add argument for play some ruleset string --- osu.Game/Localisation/ToolbarStrings.cs | 5 ++--- osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Localisation/ToolbarStrings.cs b/osu.Game/Localisation/ToolbarStrings.cs index b76c643332..02a68a6bdc 100644 --- a/osu.Game/Localisation/ToolbarStrings.cs +++ b/osu.Game/Localisation/ToolbarStrings.cs @@ -30,10 +30,9 @@ namespace osu.Game.Localisation public static LocalisableString HomeHeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); /// - /// "play some" + /// "play some {0}" /// - - public static LocalisableString RulesetHeaderDescription => new TranslatableString(getKey(@"header_description"), @"play some"); + public static LocalisableString PlaySomeRuleset(string arg0) => new TranslatableString(getKey(@"play_some_ruleset"), @"play some {0}", arg0); private static string getKey(string key) => $@"{prefix}:{key}"; } diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs index d603863888..07f7d52545 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetTabButton.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; -using osu.Framework.Localisation; using osu.Game.Localisation; using osu.Game.Rulesets; using osuTK.Graphics; @@ -31,7 +30,7 @@ namespace osu.Game.Overlays.Toolbar var rInstance = value.CreateInstance(); ruleset.TooltipMain = rInstance.Description; - ruleset.TooltipSub = LocalisableString.Format("{0} {1}", ToolbarStrings.RulesetHeaderDescription, ($"{rInstance.Description}")); + ruleset.TooltipSub = ToolbarStrings.PlaySomeRuleset(rInstance.Description); ruleset.SetIcon(rInstance.CreateIcon()); } From 6a847faea9ad82990e7aa2ab94eb10eb2767112b Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Sun, 15 Jan 2023 15:19:47 -0800 Subject: [PATCH 231/248] Make home string keys more specific --- osu.Game/Localisation/ToolbarStrings.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Localisation/ToolbarStrings.cs b/osu.Game/Localisation/ToolbarStrings.cs index 02a68a6bdc..e71a3fff9b 100644 --- a/osu.Game/Localisation/ToolbarStrings.cs +++ b/osu.Game/Localisation/ToolbarStrings.cs @@ -22,12 +22,12 @@ namespace osu.Game.Localisation /// /// "home" /// - public static LocalisableString HomeHeaderTitle => new TranslatableString(getKey(@"header_title"), @"home"); + public static LocalisableString HomeHeaderTitle => new TranslatableString(getKey(@"home_header_title"), @"home"); /// /// "return to the main menu" /// - public static LocalisableString HomeHeaderDescription => new TranslatableString(getKey(@"header_description"), @"return to the main menu"); + public static LocalisableString HomeHeaderDescription => new TranslatableString(getKey(@"home_header_description"), @"return to the main menu"); /// /// "play some {0}" From d19b35bd5fc225434a7f7288392b2c409ec2db8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 13:18:49 +0900 Subject: [PATCH 232/248] Rename ambiguous translation keys --- osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs | 4 ++-- osu.Game/Localisation/RulesetSettingsStrings.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs index d36e6057bb..4a8843c999 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs @@ -9,10 +9,10 @@ namespace osu.Game.Rulesets.Mania.UI { public enum ManiaScrollingDirection { - [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.Up))] + [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.ScrollingDirectionUp))] Up = ScrollingDirection.Up, - [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.Down))] + [LocalisableDescription(typeof(RulesetSettingsStrings), nameof(RulesetSettingsStrings.ScrollingDirectionDown))] Down = ScrollingDirection.Down } } diff --git a/osu.Game/Localisation/RulesetSettingsStrings.cs b/osu.Game/Localisation/RulesetSettingsStrings.cs index 0374f81cee..1b0df6ecf6 100644 --- a/osu.Game/Localisation/RulesetSettingsStrings.cs +++ b/osu.Game/Localisation/RulesetSettingsStrings.cs @@ -57,12 +57,12 @@ namespace osu.Game.Localisation /// /// "Up" /// - public static LocalisableString Up => new TranslatableString(getKey(@"scrolling_up"), @"Up"); + public static LocalisableString ScrollingDirectionUp => new TranslatableString(getKey(@"scrolling_up"), @"Up"); /// /// "Down" /// - public static LocalisableString Down => new TranslatableString(getKey(@"scrolling_down"), @"Down"); + public static LocalisableString ScrollingDirectionDown => new TranslatableString(getKey(@"scrolling_down"), @"Down"); /// /// "Scroll speed" From eb0f30c6414b84f73b22d56aaae543546cd2e111 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 16 Jan 2023 13:28:45 +0900 Subject: [PATCH 233/248] Use scroll speed localisation in one more usage --- .../Configuration/ManiaRulesetConfigManager.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs index d367c82ed8..99a80ef28d 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Configuration.Tracking; using osu.Game.Configuration; +using osu.Game.Localisation; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Mania.UI; @@ -30,8 +31,8 @@ namespace osu.Game.Rulesets.Mania.Configuration new TrackedSetting(ManiaRulesetSetting.ScrollTime, scrollTime => new SettingDescription( rawValue: scrollTime, - name: "Scroll Speed", - value: $"{scrollTime}ms (speed {(int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / scrollTime)})" + name: RulesetSettingsStrings.ScrollSpeed, + value: RulesetSettingsStrings.ScrollSpeedTooltip(scrollTime, (int)Math.Round(DrawableManiaRuleset.MAX_TIME_RANGE / scrollTime)) ) ) }; From 1552726150f2c6481f81a3d4b4f83022079aded2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 16 Jan 2023 14:03:09 +0300 Subject: [PATCH 234/248] Fix intermittent failure in beatmap options state test --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index cfee02dfb8..a61171abad 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -1064,6 +1064,7 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("options enabled", () => songSelect.ChildrenOfType().Single().Enabled.Value); AddStep("delete all beatmaps", () => manager.Delete()); + AddWaitStep("wait for debounce", 1); AddAssert("options disabled", () => !songSelect.ChildrenOfType().Single().Enabled.Value); } From 26f3b1dbfee45ed20d9bc62f003832f8bfca92c8 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 19:37:47 +0300 Subject: [PATCH 235/248] Localise "revert to default" tooltip --- osu.Game/Localisation/CommonStrings.cs | 5 +++++ osu.Game/Overlays/RestoreDefaultValueButton.cs | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Localisation/CommonStrings.cs b/osu.Game/Localisation/CommonStrings.cs index 10178915a2..fed7b6cab7 100644 --- a/osu.Game/Localisation/CommonStrings.cs +++ b/osu.Game/Localisation/CommonStrings.cs @@ -154,6 +154,11 @@ namespace osu.Game.Localisation /// public static LocalisableString Exit => new TranslatableString(getKey(@"exit"), @"Exit"); + /// + /// "Revert to default" + /// + public static LocalisableString RevertToDefault => new TranslatableString(getKey(@"revert_to_default"), @"Revert to default"); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/RestoreDefaultValueButton.cs b/osu.Game/Overlays/RestoreDefaultValueButton.cs index 9d5e5db6e6..97c66fdf02 100644 --- a/osu.Game/Overlays/RestoreDefaultValueButton.cs +++ b/osu.Game/Overlays/RestoreDefaultValueButton.cs @@ -6,6 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; @@ -17,6 +18,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osuTK; +using osu.Game.Localisation; namespace osu.Game.Overlays { @@ -96,7 +98,7 @@ namespace osu.Game.Overlays FinishTransforms(true); } - public override LocalisableString TooltipText => "revert to default"; + public override LocalisableString TooltipText => CommonStrings.RevertToDefault.ToLower(); protected override bool OnHover(HoverEvent e) { From 6eb5508404c5841fc0dc007bc9224efc8df0c55b Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 19:39:50 +0300 Subject: [PATCH 236/248] Localise menu bar --- osu.Game/Skinning/Editor/SkinEditor.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 0ed4e5afd2..5fe92b33aa 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -122,14 +122,14 @@ namespace osu.Game.Skinning.Editor RelativeSizeAxes = Axes.Both, Items = new[] { - new MenuItem("File") + new MenuItem(CommonStrings.MenuBarFile) { Items = new[] { - new EditorMenuItem("Save", MenuItemType.Standard, Save), - new EditorMenuItem("Revert to default", MenuItemType.Destructive, revert), + new EditorMenuItem(Resources.Localisation.Web.CommonStrings.ButtonsSave, MenuItemType.Standard, Save), + new EditorMenuItem(CommonStrings.RevertToDefault, MenuItemType.Destructive, revert), new EditorMenuItemSpacer(), - new EditorMenuItem("Exit", MenuItemType.Standard, () => skinEditorOverlay?.Hide()), + new EditorMenuItem(CommonStrings.Exit, MenuItemType.Standard, () => skinEditorOverlay?.Hide()), }, }, } From 17aeb0ec192b13e158233d2f299fabe759d61794 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 19:55:28 +0300 Subject: [PATCH 237/248] Localise editor's UI --- osu.Game/Localisation/SkinEditorStrings.cs | 49 +++++++++++++++++++ .../Skinning/Editor/SkinComponentToolbox.cs | 3 +- osu.Game/Skinning/Editor/SkinEditor.cs | 9 ++-- .../Skinning/Editor/SkinEditorSceneLibrary.cs | 9 ++-- .../Skinning/Editor/SkinSettingsToolbox.cs | 5 +- 5 files changed, 62 insertions(+), 13 deletions(-) create mode 100644 osu.Game/Localisation/SkinEditorStrings.cs diff --git a/osu.Game/Localisation/SkinEditorStrings.cs b/osu.Game/Localisation/SkinEditorStrings.cs new file mode 100644 index 0000000000..605b7d6a9d --- /dev/null +++ b/osu.Game/Localisation/SkinEditorStrings.cs @@ -0,0 +1,49 @@ +// 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.Localisation; + +namespace osu.Game.Localisation +{ + public static class SkinEditorStrings + { + private const string prefix = @"osu.Game.Resources.Localisation.SkinEditor"; + + /// + /// "Skin editor" + /// + public static LocalisableString SkinEditor => new TranslatableString(getKey(@"skin_editor"), @"Skin editor"); + + /// + /// "Currently editing" + /// + public static LocalisableString CurrentlyEditing => new TranslatableString(getKey(@"currently_editing"), @"Currently editing"); + + /// + /// "Components" + /// + public static LocalisableString Components => new TranslatableString(getKey(@"components"), @"Components"); + + /// + /// "Scene library" + /// + public static LocalisableString SceneLibrary => new TranslatableString(getKey(@"scene_library"), @"Scene library"); + + /// + /// "Song Select" + /// + public static LocalisableString SongSelect => new TranslatableString(getKey(@"song_select"), @"Song Select"); + + /// + /// "Gameplay" + /// + public static LocalisableString Gameplay => new TranslatableString(getKey(@"gameplay"), @"Gameplay"); + + /// + /// "Settings ({0})" + /// + public static LocalisableString Settings(string arg0) => new TranslatableString(getKey(@"settings"), @"Settings ({0})", arg0); + + private static string getKey(string key) => $@"{prefix}:{key}"; + } +} diff --git a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs index 053119557f..9985b81059 100644 --- a/osu.Game/Skinning/Editor/SkinComponentToolbox.cs +++ b/osu.Game/Skinning/Editor/SkinComponentToolbox.cs @@ -10,6 +10,7 @@ using osu.Framework.Logging; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Screens.Edit.Components; using osu.Game.Screens.Play.HUD; @@ -26,7 +27,7 @@ namespace osu.Game.Skinning.Editor private FillFlowContainer fill = null!; public SkinComponentToolbox(CompositeDrawable? target = null) - : base("Components") + : base(SkinEditorStrings.Components) { this.target = target; } diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 5fe92b33aa..74391e5269 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -109,7 +109,7 @@ namespace osu.Game.Skinning.Editor { new Container { - Name = "Menu container", + Name = @"Menu container", RelativeSizeAxes = Axes.X, Depth = float.MinValue, Height = MENU_HEIGHT, @@ -234,7 +234,6 @@ namespace osu.Game.Skinning.Editor // Immediately clear the previous blueprint container to ensure it doesn't try to interact with the old target. content?.Clear(); - Scheduler.AddOnce(loadBlueprintContainer); Scheduler.AddOnce(populateSettings); @@ -253,15 +252,15 @@ namespace osu.Game.Skinning.Editor { headerText.Clear(); - headerText.AddParagraph("Skin editor", cp => cp.Font = OsuFont.Default.With(size: 16)); + headerText.AddParagraph(SkinEditorStrings.SkinEditor, cp => cp.Font = OsuFont.Default.With(size: 16)); headerText.NewParagraph(); - headerText.AddText("Currently editing ", cp => + headerText.AddText(SkinEditorStrings.CurrentlyEditing, cp => { cp.Font = OsuFont.Default.With(size: 12); cp.Colour = colours.Yellow; }); - headerText.AddText($"{currentSkin.Value.SkinInfo}", cp => + headerText.AddText($" {currentSkin.Value.SkinInfo}", cp => { cp.Font = OsuFont.Default.With(size: 12, weight: FontWeight.Bold); cp.Colour = colours.Yellow; diff --git a/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs b/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs index c3907ea60d..44045e8916 100644 --- a/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs +++ b/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs @@ -16,6 +16,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -66,7 +67,7 @@ namespace osu.Game.Skinning.Editor { new FillFlowContainer { - Name = "Scene library", + Name = @"Scene library", AutoSizeAxes = Axes.X, RelativeSizeAxes = Axes.Y, Spacing = new Vector2(padding), @@ -76,14 +77,14 @@ namespace osu.Game.Skinning.Editor { new OsuSpriteText { - Text = "Scene library", + Text = SkinEditorStrings.SceneLibrary, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Margin = new MarginPadding(10), }, new SceneButton { - Text = "Song Select", + Text = SkinEditorStrings.SongSelect, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Action = () => performer?.PerformFromScreen(screen => @@ -96,7 +97,7 @@ namespace osu.Game.Skinning.Editor }, new SceneButton { - Text = "Gameplay", + Text = SkinEditorStrings.Gameplay, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Action = () => performer?.PerformFromScreen(screen => diff --git a/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs b/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs index 8c08f40b70..6afe92c6b2 100644 --- a/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs +++ b/osu.Game/Skinning/Editor/SkinSettingsToolbox.cs @@ -1,12 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Configuration; +using osu.Game.Localisation; using osu.Game.Screens.Edit.Components; using osuTK; @@ -17,7 +16,7 @@ namespace osu.Game.Skinning.Editor protected override Container Content { get; } public SkinSettingsToolbox(Drawable component) - : base($"Settings ({component.GetType().Name})") + : base(SkinEditorStrings.Settings(component.GetType().Name)) { base.Content.Add(Content = new FillFlowContainer { From 1a776eb546119761f1f1283956c65a5b4fae1347 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Jan 2023 14:36:56 +0300 Subject: [PATCH 238/248] Mark item-mutating queue mode tests with `FlakyTest` attribute --- .../TestSceneAllPlayersQueueMode.cs | 33 ++++++--- .../Multiplayer/TestSceneHostOnlyQueueMode.cs | 71 +++++++++++-------- 2 files changed, 64 insertions(+), 40 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs index 7b1abd104f..6da9d37648 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneAllPlayersQueueMode.cs @@ -34,6 +34,24 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + public void TestSingleItemExpiredAfterGameplay() + { + RunGameplay(); + + AddUntilStep("playlist has only one item", () => MultiplayerClient.ClientAPIRoom?.Playlist.Count == 1); + AddUntilStep("playlist item is expired", () => MultiplayerClient.ClientAPIRoom?.Playlist[0].Expired == true); + AddUntilStep("last item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); + } + + [Test] + [FlakyTest] + /* + * TearDown : System.TimeoutException : "wait for ongoing operation to complete" timed out + * --TearDown + * at osu.Framework.Testing.Drawables.Steps.UntilStepButton.<>c__DisplayClass11_0.<.ctor>b__0() + * at osu.Framework.Testing.Drawables.Steps.StepButton.PerformStep(Boolean userTriggered) + * at osu.Framework.Testing.TestScene.runNextStep(Action onCompletion, Action`1 onError, Func`2 stopCondition) + */ public void TestItemAddedToTheEndOfQueue() { addItem(() => OtherBeatmap); @@ -46,16 +64,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] - public void TestSingleItemExpiredAfterGameplay() - { - RunGameplay(); - - AddUntilStep("playlist has only one item", () => MultiplayerClient.ClientAPIRoom?.Playlist.Count == 1); - AddUntilStep("playlist item is expired", () => MultiplayerClient.ClientAPIRoom?.Playlist[0].Expired == true); - AddUntilStep("last item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); - } - - [Test] + [FlakyTest] // See above public void TestNextItemSelectedAfterGameplayFinish() { addItem(() => OtherBeatmap); @@ -73,6 +82,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestItemsNotClearedWhenSwitchToHostOnlyMode() { addItem(() => OtherBeatmap); @@ -88,6 +98,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestCorrectItemSelectedAfterNewItemAdded() { addItem(() => OtherBeatmap); @@ -95,6 +106,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestCorrectRulesetSelectedAfterNewItemAdded() { addItem(() => OtherBeatmap, new CatchRuleset().RulesetInfo); @@ -112,6 +124,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestCorrectModsSelectedAfterNewItemAdded() { addItem(() => OtherBeatmap, mods: new Mod[] { new OsuModDoubleTime() }); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs index 145c655c0a..dc36f539e3 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneHostOnlyQueueMode.cs @@ -27,22 +27,6 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("first item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); } - [Test] - public void TestItemStillSelectedAfterChangeToSameBeatmap() - { - selectNewItem(() => InitialBeatmap); - - AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); - } - - [Test] - public void TestItemStillSelectedAfterChangeToOtherBeatmap() - { - selectNewItem(() => OtherBeatmap); - - AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); - } - [Test] public void TestNewItemCreatedAfterGameplayFinished() { @@ -54,20 +38,6 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("second playlist item selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[1].ID); } - [Test] - public void TestOnlyLastItemChangedAfterGameplayFinished() - { - RunGameplay(); - - IBeatmapInfo firstBeatmap = null; - AddStep("get first playlist item beatmap", () => firstBeatmap = MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap); - - selectNewItem(() => OtherBeatmap); - - AddUntilStep("first playlist item hasn't changed", () => MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap == firstBeatmap); - AddUntilStep("second playlist item changed", () => MultiplayerClient.ClientAPIRoom?.Playlist[1].Beatmap != firstBeatmap); - } - [Test] public void TestSettingsUpdatedWhenChangingQueueMode() { @@ -80,6 +50,47 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] + /* + * TearDown : System.TimeoutException : "wait for ongoing operation to complete" timed out + * --TearDown + * at osu.Framework.Testing.Drawables.Steps.UntilStepButton.<>c__DisplayClass11_0.<.ctor>b__0() + * at osu.Framework.Testing.Drawables.Steps.StepButton.PerformStep(Boolean userTriggered) + * at osu.Framework.Testing.TestScene.runNextStep(Action onCompletion, Action`1 onError, Func`2 stopCondition) + */ + public void TestItemStillSelectedAfterChangeToSameBeatmap() + { + selectNewItem(() => InitialBeatmap); + + AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); + } + + [Test] + [FlakyTest] // See above + public void TestItemStillSelectedAfterChangeToOtherBeatmap() + { + selectNewItem(() => OtherBeatmap); + + AddUntilStep("playlist item still selected", () => MultiplayerClient.ClientRoom?.Settings.PlaylistItemId == MultiplayerClient.ClientAPIRoom?.Playlist[0].ID); + } + + [Test] + [FlakyTest] // See above + public void TestOnlyLastItemChangedAfterGameplayFinished() + { + RunGameplay(); + + IBeatmapInfo firstBeatmap = null; + AddStep("get first playlist item beatmap", () => firstBeatmap = MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap); + + selectNewItem(() => OtherBeatmap); + + AddUntilStep("first playlist item hasn't changed", () => MultiplayerClient.ServerAPIRoom?.Playlist[0].Beatmap == firstBeatmap); + AddUntilStep("second playlist item changed", () => MultiplayerClient.ClientAPIRoom?.Playlist[1].Beatmap != firstBeatmap); + } + + [Test] + [FlakyTest] // See above public void TestAddItemsAsHost() { addItem(() => OtherBeatmap); From f63de55a20a92f2669d6faae73cc5716c273a72d Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 16 Jan 2023 22:34:29 +0300 Subject: [PATCH 239/248] Mark ready-button-pressing multiplayer tests with `FlakyTest` attribute --- .../Multiplayer/TestSceneMultiplayer.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 5033347b15..d747d23229 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -377,6 +377,17 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] + /* + * On a slight investigation, this is occurring due to the ready button + * not receiving the click input generated by the manual input manager. + * + * TearDown : System.TimeoutException : "wait for ready button to be enabled" timed out + * --TearDown + * at osu.Framework.Testing.Drawables.Steps.UntilStepButton.<>c__DisplayClass11_0.<.ctor>b__0() + * at osu.Framework.Testing.Drawables.Steps.StepButton.PerformStep(Boolean userTriggered) + * at osu.Framework.Testing.TestScene.runNextStep(Action onCompletion, Action`1 onError, Func`2 stopCondition) + */ public void TestUserSetToIdleWhenBeatmapDeleted() { createRoom(() => new Room @@ -398,6 +409,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestPlayStartsWithCorrectBeatmapWhileAtSongSelect() { PlaylistItem? item = null; @@ -438,6 +450,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestPlayStartsWithCorrectRulesetWhileAtSongSelect() { PlaylistItem? item = null; @@ -478,6 +491,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestPlayStartsWithCorrectModsWhileAtSongSelect() { PlaylistItem? item = null; @@ -651,6 +665,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestGameplayFlow() { createRoom(() => new Room @@ -678,6 +693,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestGameplayExitFlow() { Bindable? holdDelay = null; @@ -715,6 +731,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestGameplayDoesntStartWithNonLoadedUser() { createRoom(() => new Room @@ -796,6 +813,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestSpectatingStateResetOnBackButtonDuringGameplay() { createRoom(() => new Room @@ -831,6 +849,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestSpectatingStateNotResetOnBackButtonOutsideOfGameplay() { createRoom(() => new Room @@ -869,6 +888,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestItemAddedByOtherUserDuringGameplay() { createRoom(() => new Room @@ -899,6 +919,7 @@ namespace osu.Game.Tests.Visual.Multiplayer } [Test] + [FlakyTest] // See above public void TestItemAddedAndDeletedByOtherUserDuringGameplay() { createRoom(() => new Room From 0ec608ec5d67dc341ea768ac7e3460cacbd96937 Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 22:46:57 +0300 Subject: [PATCH 240/248] Select button using its index in test --- .../Visual/Navigation/TestSceneSkinEditorNavigation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs index e0b61794e4..3b49161dd6 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs @@ -219,7 +219,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("Click gameplay scene button", () => { - InputManager.MoveMouseTo(skinEditor.ChildrenOfType().First(b => b.Text == "Gameplay")); + InputManager.MoveMouseTo(skinEditor.ChildrenOfType().Skip(1).First()); InputManager.Click(MouseButton.Left); }); From 133b9b79d768c41711429ff8c329729577c05dcf Mon Sep 17 00:00:00 2001 From: ansel <79257300125@ya.ru> Date: Mon, 16 Jan 2023 22:52:17 +0300 Subject: [PATCH 241/248] Do not touch "currently editing" line --- osu.Game/Localisation/SkinEditorStrings.cs | 5 ----- osu.Game/Skinning/Editor/SkinEditor.cs | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game/Localisation/SkinEditorStrings.cs b/osu.Game/Localisation/SkinEditorStrings.cs index 605b7d6a9d..b2e5f3aeb6 100644 --- a/osu.Game/Localisation/SkinEditorStrings.cs +++ b/osu.Game/Localisation/SkinEditorStrings.cs @@ -14,11 +14,6 @@ namespace osu.Game.Localisation /// public static LocalisableString SkinEditor => new TranslatableString(getKey(@"skin_editor"), @"Skin editor"); - /// - /// "Currently editing" - /// - public static LocalisableString CurrentlyEditing => new TranslatableString(getKey(@"currently_editing"), @"Currently editing"); - /// /// "Components" /// diff --git a/osu.Game/Skinning/Editor/SkinEditor.cs b/osu.Game/Skinning/Editor/SkinEditor.cs index 74391e5269..98b4e960dd 100644 --- a/osu.Game/Skinning/Editor/SkinEditor.cs +++ b/osu.Game/Skinning/Editor/SkinEditor.cs @@ -254,13 +254,13 @@ namespace osu.Game.Skinning.Editor headerText.AddParagraph(SkinEditorStrings.SkinEditor, cp => cp.Font = OsuFont.Default.With(size: 16)); headerText.NewParagraph(); - headerText.AddText(SkinEditorStrings.CurrentlyEditing, cp => + headerText.AddText("Currently editing ", cp => { cp.Font = OsuFont.Default.With(size: 12); cp.Colour = colours.Yellow; }); - headerText.AddText($" {currentSkin.Value.SkinInfo}", cp => + headerText.AddText($"{currentSkin.Value.SkinInfo}", cp => { cp.Font = OsuFont.Default.With(size: 12, weight: FontWeight.Bold); cp.Colour = colours.Yellow; From 6207a96a29f93733fbd1569d26f0ce02b78ae8f5 Mon Sep 17 00:00:00 2001 From: StanR Date: Mon, 16 Jan 2023 23:24:09 +0300 Subject: [PATCH 242/248] Refactor `LevelBadge` to use `LevelInfo` --- .../Profile/Header/CentreHeaderContainer.cs | 15 ++++++++++++--- .../Profile/Header/Components/LevelBadge.cs | 10 +++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 7721342ba8..fbd8f1e0c6 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -6,6 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Header.Components; using osuTK; @@ -15,6 +16,8 @@ namespace osu.Game.Overlays.Profile.Header { public readonly Bindable User = new Bindable(); + private LevelBadge levelBadge = null!; + public CentreHeaderContainer() { Height = 60; @@ -62,12 +65,11 @@ namespace osu.Game.Overlays.Profile.Header Margin = new MarginPadding { Right = UserProfileOverlay.CONTENT_X_MARGIN }, Children = new Drawable[] { - new LevelBadge + levelBadge = new LevelBadge { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Size = new Vector2(40), - User = { BindTarget = User } + Size = new Vector2(40) }, new Container { @@ -85,6 +87,13 @@ namespace osu.Game.Overlays.Profile.Header } } }; + + User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); + } + + private void updateDisplay(APIUser? user) + { + levelBadge.LevelInfo.Value = user?.Statistics?.Level; } } } diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 78c5231736..a0c17ccf93 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -11,14 +11,14 @@ using osu.Framework.Graphics.Textures; using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Resources.Localisation.Web; +using osu.Game.Users; namespace osu.Game.Overlays.Profile.Header.Components { public partial class LevelBadge : CompositeDrawable, IHasTooltip { - public readonly Bindable User = new Bindable(); + public readonly Bindable LevelInfo = new Bindable(); public LocalisableString TooltipText { get; private set; } @@ -48,12 +48,12 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - User.BindValueChanged(user => updateLevel(user.NewValue?.User)); + LevelInfo.BindValueChanged(user => updateLevel(user.NewValue)); } - private void updateLevel(APIUser? user) + private void updateLevel(UserStatistics.LevelInfo? levelInfo) { - string level = user?.Statistics?.Level.Current.ToString() ?? "0"; + string level = levelInfo?.Current.ToString() ?? "0"; levelText.Text = level; TooltipText = UsersStrings.ShowStatsLevel(level); } From c5d09c0e2c82ff4ae5c7259d6459994972ff3ca2 Mon Sep 17 00:00:00 2001 From: StanR Date: Mon, 16 Jan 2023 23:36:50 +0300 Subject: [PATCH 243/248] Rename variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartłomiej Dach --- osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index a0c17ccf93..251cd1bae5 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -48,7 +48,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } }; - LevelInfo.BindValueChanged(user => updateLevel(user.NewValue)); + LevelInfo.BindValueChanged(level => updateLevel(level.NewValue)); } private void updateLevel(UserStatistics.LevelInfo? levelInfo) From 3f75506552e9285534cfa47b69aa81cb41633df0 Mon Sep 17 00:00:00 2001 From: StanR Date: Mon, 16 Jan 2023 23:42:07 +0300 Subject: [PATCH 244/248] Move binding to `LoadComplete` --- osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index 251cd1bae5..b75ffcaf98 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -47,8 +47,11 @@ namespace osu.Game.Overlays.Profile.Header.Components Font = OsuFont.GetFont(size: 20) } }; + } - LevelInfo.BindValueChanged(level => updateLevel(level.NewValue)); + protected override void LoadComplete() + { + LevelInfo.BindValueChanged(level => updateLevel(level.NewValue), true); } private void updateLevel(UserStatistics.LevelInfo? levelInfo) From f79037cefb206f9e57a3dd450d51ec6f7af0c343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 16 Jan 2023 21:47:31 +0100 Subject: [PATCH 245/248] Move to `LoadComplete()` better --- osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs | 7 ++++++- osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index fbd8f1e0c6..0dab4d582d 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -87,8 +87,13 @@ namespace osu.Game.Overlays.Profile.Header } } }; + } - User.BindValueChanged(user => updateDisplay(user.NewValue?.User)); + protected override void LoadComplete() + { + base.LoadComplete(); + + User.BindValueChanged(user => updateDisplay(user.NewValue?.User), true); } private void updateDisplay(APIUser? user) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs index b75ffcaf98..00bb8cbc75 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelBadge.cs @@ -51,6 +51,8 @@ namespace osu.Game.Overlays.Profile.Header.Components protected override void LoadComplete() { + base.LoadComplete(); + LevelInfo.BindValueChanged(level => updateLevel(level.NewValue), true); } From 4cf448ec11898985fc56ea2f1178ef765aa412eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 11:51:17 +0900 Subject: [PATCH 246/248] Use `ToString()` for test instead of linq skip --- .../Visual/Navigation/TestSceneSkinEditorNavigation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs index 3b49161dd6..845cfdd6df 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs @@ -219,7 +219,7 @@ namespace osu.Game.Tests.Visual.Navigation AddStep("Click gameplay scene button", () => { - InputManager.MoveMouseTo(skinEditor.ChildrenOfType().Skip(1).First()); + InputManager.MoveMouseTo(skinEditor.ChildrenOfType().First(b => b.Text.ToString() == "Gameplay")); InputManager.Click(MouseButton.Left); }); From a02556d2fa93e7ca6242ba614af42ab37cc05a53 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 14:43:22 +0900 Subject: [PATCH 247/248] Move hover logic to `SettingsToolboxGroup` to avoid expanded state clash --- osu.Game/Overlays/SettingsToolboxGroup.cs | 4 +++- .../Play/PlayerSettings/PlayerSettingsGroup.cs | 18 ------------------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index 86964e7ed4..c0948c1eab 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -135,12 +135,14 @@ namespace osu.Game.Overlays protected override bool OnHover(HoverEvent e) { updateFadeState(); + updateExpandedState(true); return false; } protected override void OnHoverLost(HoverLostEvent e) { updateFadeState(); + updateExpandedState(true); base.OnHoverLost(e); } @@ -168,7 +170,7 @@ namespace osu.Game.Overlays // potentially continuing to get processed while content has changed to autosize. content.ClearTransforms(); - if (Expanded.Value) + if (Expanded.Value || IsHovered) { content.AutoSizeAxes = Axes.Y; content.AutoSizeDuration = animate ? transition_duration : 0; diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index ea4d983343..838106e198 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Input.Events; using osu.Game.Overlays; @@ -15,28 +13,12 @@ namespace osu.Game.Screens.Play.PlayerSettings { } - private bool expandedByDefault = true; - protected override bool OnHover(HoverEvent e) { - if (IsHovered && !Expanded.Value) - { - Expanded.Value = true; - expandedByDefault = false; - } - base.OnHover(e); // Importantly, return true to correctly take focus away from PlayerLoader. return true; } - - protected override void OnHoverLost(HoverLostEvent e) - { - if (!expandedByDefault) - Expanded.Value = false; - - base.OnHoverLost(e); - } } } From ef354938646837725471a384172021f95a8ed51b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jan 2023 15:27:19 +0900 Subject: [PATCH 248/248] Avoid need for weird null check by reordering initialisation process --- osu.Game/Screens/Select/SongSelect.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index d4d75d0ad6..64deb59026 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -127,9 +127,6 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader(true)] private void load(AudioManager audio, OsuColour colours, ManageCollectionsDialog? manageCollectionsDialog, DifficultyRecommender? recommender) { - // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). - transferRulesetValue(); - LoadComponentAsync(Carousel = new BeatmapCarousel { AllowSelection = false, // delay any selection until our bindables are ready to make a good choice. @@ -143,6 +140,9 @@ namespace osu.Game.Screens.Select GetRecommendedBeatmap = s => recommender?.GetRecommendedBeatmap(s), }, c => carouselContainer.Child = c); + // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). + transferRulesetValue(); + AddRangeInternal(new Drawable[] { new ResetScrollContainer(() => Carousel.ScrollToSelected()) @@ -860,9 +860,6 @@ namespace osu.Game.Screens.Select Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\")"); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; - // We want to check for null since this method gets called before the loading of the carousel. - if (Carousel.IsNull()) return true; - // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). Carousel.FlushPendingFilterOperations();