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 001/172] 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 002/172] 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 003/172] 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 004/172] 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 005/172] 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 006/172] 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 007/172] 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 008/172] 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 009/172] 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 010/172] 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 011/172] 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 012/172] 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 013/172] 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 014/172] 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 015/172] 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 016/172] 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 017/172] 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 018/172] 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 019/172] 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 020/172] 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 021/172] 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 022/172] 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 023/172] 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 4ab7ef9af9ca0eae3b6b47c26de162d59dde16e5 Mon Sep 17 00:00:00 2001 From: Dylan Nantz Date: Mon, 5 Dec 2022 15:12:50 -0500 Subject: [PATCH 024/172] 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 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 025/172] 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 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 026/172] 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 027/172] 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 028/172] 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 029/172] 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 030/172] 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 031/172] 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 13b00928c81f9e212c9618108660cfa205c55361 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 9 Jan 2023 15:52:08 +0900 Subject: [PATCH 032/172] 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 91eab7985bb2a3fd83bd1202c81c16847dacf6af Mon Sep 17 00:00:00 2001 From: tsrk Date: Mon, 9 Jan 2023 21:35:27 +0100 Subject: [PATCH 033/172] 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 034/172] 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 23a78e6fad219de63eabdbe20ae36a3e61034e15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 10 Jan 2023 23:57:38 +0900 Subject: [PATCH 035/172] 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 21073f36012ede15d245f2813520ba5b4267c406 Mon Sep 17 00:00:00 2001 From: tsrk Date: Tue, 10 Jan 2023 22:49:35 +0100 Subject: [PATCH 036/172] 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 037/172] 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 df544100755827e7a3888756ed3b1a0b780b3833 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jan 2023 17:31:26 +0900 Subject: [PATCH 038/172] 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 578d16f2bce9f21fa4b5c01ba5ea78e76d31f3cb Mon Sep 17 00:00:00 2001 From: tsrk Date: Wed, 11 Jan 2023 11:11:31 +0100 Subject: [PATCH 039/172] 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 040/172] 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 041/172] 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 042/172] 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 043/172] 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 044/172] 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 045/172] 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 046/172] 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 047/172] 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 048/172] 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 049/172] 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 050/172] 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 051/172] 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 052/172] 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 053/172] 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 054/172] 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 055/172] 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 056/172] 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 057/172] 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 058/172] 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 059/172] 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 060/172] 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 061/172] 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 062/172] 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 063/172] 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 064/172] 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 065/172] 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 066/172] 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 067/172] 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 068/172] 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 069/172] 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 070/172] 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 071/172] 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 072/172] 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 073/172] 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 074/172] 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 075/172] 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 076/172] 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 077/172] 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 078/172] 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 079/172] 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 080/172] 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 081/172] 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 082/172] 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 083/172] 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 084/172] 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 085/172] 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 086/172] 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 087/172] 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 088/172] 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 089/172] 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 090/172] 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 091/172] 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 092/172] 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 093/172] 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 094/172] 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 095/172] 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 096/172] 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 097/172] 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 098/172] 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 099/172] 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 100/172] 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 101/172] 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 102/172] 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 103/172] 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 104/172] 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 105/172] 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 106/172] 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 107/172] 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 108/172] 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 109/172] 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 110/172] 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 111/172] 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 112/172] 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 113/172] 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 114/172] 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 115/172] 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 116/172] 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 117/172] 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 118/172] 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 119/172] 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 120/172] 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 121/172] 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 122/172] 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 123/172] 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 124/172] 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 125/172] 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 126/172] 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 127/172] 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 128/172] 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 129/172] 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 130/172] 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 131/172] 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 132/172] 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 133/172] 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 134/172] 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 135/172] 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 136/172] 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 137/172] 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 138/172] 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 139/172] 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 140/172] 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 141/172] 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 142/172] 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 143/172] 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 144/172] 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 145/172] 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 146/172] 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 147/172] 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 148/172] 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 149/172] 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 150/172] 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 151/172] 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 152/172] 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 153/172] 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 154/172] 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 155/172] 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 156/172] 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 157/172] 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 158/172] 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 159/172] 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 160/172] 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 161/172] 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 162/172] 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 163/172] 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 164/172] 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 165/172] 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 166/172] 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 167/172] 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 168/172] 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 169/172] 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 170/172] 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 171/172] 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 172/172] 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();