From e67e4f708ea996e594992321a0e01cf037a967ed Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 19:01:26 +0300 Subject: [PATCH 01/42] Adjust country name design --- .../Rankings/Tables/CountriesTable.cs | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs index a0e4f694bd..ed8e956e5e 100644 --- a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs @@ -8,6 +8,7 @@ using osu.Game.Users; using osu.Game.Graphics.Sprites; using osu.Game.Graphics; using System.Collections.Generic; +using osu.Framework.Allocation; namespace osu.Game.Overlays.Rankings.Tables { @@ -30,11 +31,7 @@ namespace osu.Game.Overlays.Rankings.Tables protected override Country GetCountry(CountryStatistics item) => item.Country; - protected override Drawable CreateFlagContent(CountryStatistics item) => new OsuSpriteText - { - Font = OsuFont.GetFont(size: TEXT_SIZE), - Text = $@"{item.Country.FullName}", - }; + protected override Drawable CreateFlagContent(CountryStatistics item) => new CountryName(item.Country); protected override Drawable[] CreateAdditionalContent(CountryStatistics item) => new Drawable[] { @@ -63,5 +60,20 @@ namespace osu.Game.Overlays.Rankings.Tables Text = $@"{item.Performance / Math.Max(item.ActiveUsers, 1):N0}", } }; + + private class CountryName : OsuSpriteText + { + public CountryName(Country country) + { + Font = OsuFont.GetFont(size: 12, italics: true); + Text = $@"{country.FullName}"; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Colour = colourProvider.Light2; + } + } } } From 791bf6bc0197118f44654f754f9a407f4bda5f6b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 19:03:07 +0300 Subject: [PATCH 02/42] Make username text italic --- osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs index 0e77d7d764..cad7364103 100644 --- a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Rankings.Tables protected sealed override Drawable CreateFlagContent(UserStatistics item) { - var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: TEXT_SIZE)) { AutoSizeAxes = Axes.Both }; + var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: TEXT_SIZE, italics: true)) { AutoSizeAxes = Axes.Both }; username.AddUserLink(item.User); return username; } From c68c347503df8514ca0337ec01f9716d643b7da7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 14 Feb 2020 00:40:52 +0300 Subject: [PATCH 03/42] Remove unwanted property interpolation --- osu.Game/Overlays/Rankings/Tables/CountriesTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs index ed8e956e5e..997438ac07 100644 --- a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs @@ -66,7 +66,7 @@ namespace osu.Game.Overlays.Rankings.Tables public CountryName(Country country) { Font = OsuFont.GetFont(size: 12, italics: true); - Text = $@"{country.FullName}"; + Text = country.FullName ?? string.Empty; } [BackgroundDependencyLoader] From f64eabc38b2f0f0659b437defe27b5a33c10995b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 14 Feb 2020 20:49:37 +0300 Subject: [PATCH 04/42] Make countries name non-italic --- osu.Game/Overlays/Rankings/Tables/CountriesTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs index 997438ac07..32ac1404bc 100644 --- a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs @@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Rankings.Tables { public CountryName(Country country) { - Font = OsuFont.GetFont(size: 12, italics: true); + Font = OsuFont.GetFont(size: 12); Text = country.FullName ?? string.Empty; } From 3888911eee7882f5131aa44b25bfcef29640a9d0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 16 Feb 2020 14:19:49 +0300 Subject: [PATCH 05/42] Implement BeatmapSearchFilter component --- .../TestSceneBeatmapSearchFilter.cs | 55 +++++++++ .../BeatmapListing/BeatmapSearchFilter.cs | 104 ++++++++++++++++++ .../BeatmapSearchRulesetFilter.cs | 36 ++++++ 3 files changed, 195 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs create mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs create mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilter.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs new file mode 100644 index 0000000000..e25b047fd0 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs @@ -0,0 +1,55 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.API.Requests; +using osu.Game.Overlays; +using osu.Game.Overlays.BeatmapListing; +using osuTK; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneBeatmapSearchFilter : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(BeatmapSearchFilter<>), + typeof(BeatmapSearchRulesetFilter) + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + + private readonly FillFlowContainer resizableContainer; + + public TestSceneBeatmapSearchFilter() + { + Add(resizableContainer = new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Y, + Width = 600, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + new BeatmapSearchRulesetFilter(), + new BeatmapSearchFilter(), + } + }); + } + + [Test] + public void TestResize() + { + AddStep("Resize to 100px", () => resizableContainer.ResizeWidthTo(100, 1000)); + AddStep("Resize to 600px", () => resizableContainer.ResizeWidthTo(600, 1000)); + } + } +} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs new file mode 100644 index 0000000000..bf9d48fa3e --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs @@ -0,0 +1,104 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osuTK; +using osuTK.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Overlays.BeatmapListing +{ + public class BeatmapSearchFilter : TabControl + { + public BeatmapSearchFilter() + { + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + + if (typeof(T).IsEnum) + { + foreach (var val in (T[])Enum.GetValues(typeof(T))) + AddItem(val); + } + } + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(T value) => new FilterTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Full, + Spacing = new Vector2(10), + AllowMultiline = true, + }; + + protected class FilterTabItem : TabItem + { + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + private readonly OsuSpriteText text; + + public FilterTabItem(T value) + : base(value) + { + AutoSizeAxes = Axes.Both; + AddRangeInternal(new Drawable[] + { + text = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 13, weight: FontWeight.Regular), + Text = GetText(value) + }, + new HoverClickSounds() + }); + + Enabled.Value = true; + } + + [BackgroundDependencyLoader] + private void load() + { + updateState(); + } + + protected virtual string GetText(T value) => (value as Enum)?.GetDescription() ?? value.ToString(); + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + updateState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + updateState(); + } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); + + private void updateState() + { + text.Font = text.Font.With(weight: Active.Value ? FontWeight.Medium : FontWeight.Regular); + text.FadeColour(Active.Value ? Color4.White : getStateColour(), 200, Easing.OutQuint); + } + + private Color4 getStateColour() => IsHovered ? colourProvider.Light1 : colourProvider.Light3; + } + } +} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilter.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilter.cs new file mode 100644 index 0000000000..ffe5693eeb --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilter.cs @@ -0,0 +1,36 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Game.Rulesets; +using osu.Framework.Graphics.UserInterface; + +namespace osu.Game.Overlays.BeatmapListing +{ + public class BeatmapSearchRulesetFilter : BeatmapSearchFilter + { + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + AddItem(new RulesetInfo + { + Name = @"Any" + }); + + foreach (var r in rulesets.AvailableRulesets) + AddItem(r); + } + + protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value); + + private class RulesetTabItem : FilterTabItem + { + public RulesetTabItem(RulesetInfo value) + : base(value) + { + } + + protected override string GetText(RulesetInfo value) => value.Name; + } + } +} From a71e410e5d622bba24979f76e9eed58230601260 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 16 Feb 2020 15:04:21 +0300 Subject: [PATCH 06/42] Make the filter autosized --- .../UserInterface/TestSceneBeatmapSearchFilter.cs | 15 ++------------- .../BeatmapListing/BeatmapSearchFilter.cs | 9 ++------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs index e25b047fd0..a237a8a5b5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -25,16 +24,13 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); - private readonly FillFlowContainer resizableContainer; - public TestSceneBeatmapSearchFilter() { - Add(resizableContainer = new FillFlowContainer + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, - AutoSizeAxes = Axes.Y, - Width = 600, + AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 10), Children = new Drawable[] @@ -44,12 +40,5 @@ namespace osu.Game.Tests.Visual.UserInterface } }); } - - [Test] - public void TestResize() - { - AddStep("Resize to 100px", () => resizableContainer.ResizeWidthTo(100, 1000)); - AddStep("Resize to 600px", () => resizableContainer.ResizeWidthTo(600, 1000)); - } } } diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs index bf9d48fa3e..6cd941495f 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs @@ -12,7 +12,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osuTK; using osuTK.Graphics; -using osu.Framework.Graphics.Containers; namespace osu.Game.Overlays.BeatmapListing { @@ -20,8 +19,7 @@ namespace osu.Game.Overlays.BeatmapListing { public BeatmapSearchFilter() { - AutoSizeAxes = Axes.Y; - RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Both; if (typeof(T).IsEnum) { @@ -36,11 +34,8 @@ namespace osu.Game.Overlays.BeatmapListing protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Full, + AutoSizeAxes = Axes.Both, Spacing = new Vector2(10), - AllowMultiline = true, }; protected class FilterTabItem : TabItem From 54a3705bdbaa2c1aac1af0a20303a10f8ffe806f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 16 Feb 2020 16:26:18 +0300 Subject: [PATCH 07/42] Remove font weight changes on selection --- osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs index 6cd941495f..acae5ce117 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs @@ -87,11 +87,7 @@ namespace osu.Game.Overlays.BeatmapListing protected override void OnDeactivated() => updateState(); - private void updateState() - { - text.Font = text.Font.With(weight: Active.Value ? FontWeight.Medium : FontWeight.Regular); - text.FadeColour(Active.Value ? Color4.White : getStateColour(), 200, Easing.OutQuint); - } + private void updateState() => text.FadeColour(Active.Value ? Color4.White : getStateColour(), 200, Easing.OutQuint); private Color4 getStateColour() => IsHovered ? colourProvider.Light1 : colourProvider.Light3; } From e62fec58c1846fdfb6df580f3be6d792a2e9dc40 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 16 Feb 2020 16:38:05 +0300 Subject: [PATCH 08/42] Add ability to override text size --- .../TestSceneBeatmapSearchFilter.cs | 1 + .../BeatmapListing/BeatmapSearchFilter.cs | 4 +++- .../SmallBeatmapSearchFilter.cs | 22 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs index a237a8a5b5..b82ad86fb8 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs @@ -37,6 +37,7 @@ namespace osu.Game.Tests.Visual.UserInterface { new BeatmapSearchRulesetFilter(), new BeatmapSearchFilter(), + new SmallBeatmapSearchFilter() } }); } diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs index acae5ce117..57e8282798 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs @@ -40,6 +40,8 @@ namespace osu.Game.Overlays.BeatmapListing protected class FilterTabItem : TabItem { + protected virtual float TextSize() => 13; + [Resolved] private OverlayColourProvider colourProvider { get; set; } @@ -53,7 +55,7 @@ namespace osu.Game.Overlays.BeatmapListing { text = new OsuSpriteText { - Font = OsuFont.GetFont(size: 13, weight: FontWeight.Regular), + Font = OsuFont.GetFont(size: TextSize(), weight: FontWeight.Regular), Text = GetText(value) }, new HoverClickSounds() diff --git a/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs new file mode 100644 index 0000000000..ca387f08cf --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs @@ -0,0 +1,22 @@ +// 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.UserInterface; + +namespace osu.Game.Overlays.BeatmapListing +{ + public class SmallBeatmapSearchFilter : BeatmapSearchFilter + { + protected override TabItem CreateTabItem(T value) => new SmallTabItem(value); + + protected class SmallTabItem : FilterTabItem + { + public SmallTabItem(T value) + : base(value) + { + } + + protected override float TextSize() => 10; + } + } +} From c85a8a14cc629bd919f4c692b9f6eff4eb6093b4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 00:08:28 +0300 Subject: [PATCH 09/42] Use property instead of function to set text size --- osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs | 4 ++-- osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs index 57e8282798..825d157918 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.BeatmapListing protected class FilterTabItem : TabItem { - protected virtual float TextSize() => 13; + protected virtual float TextSize => 13; [Resolved] private OverlayColourProvider colourProvider { get; set; } @@ -55,7 +55,7 @@ namespace osu.Game.Overlays.BeatmapListing { text = new OsuSpriteText { - Font = OsuFont.GetFont(size: TextSize(), weight: FontWeight.Regular), + Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Regular), Text = GetText(value) }, new HoverClickSounds() diff --git a/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs index ca387f08cf..b5d2ad5d4e 100644 --- a/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs +++ b/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.BeatmapListing { } - protected override float TextSize() => 10; + protected override float TextSize => 10; } } } From ea285fd005f07cf42f3f0e06bd4c57e749818136 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 00:44:55 +0300 Subject: [PATCH 10/42] Refactor with including headers --- .../TestSceneBeatmapSearchFilter.cs | 26 ++- .../BeatmapListing/BeatmapSearchFilter.cs | 97 ------------ .../BeatmapListing/BeatmapSearchFilterRow.cs | 149 ++++++++++++++++++ .../BeatmapSearchRulesetFilter.cs | 36 ----- .../BeatmapSearchRulesetFilterRow.cs | 46 ++++++ .../BeatmapSearchSmallFilterRow.cs | 32 ++++ .../SmallBeatmapSearchFilter.cs | 22 --- 7 files changed, 246 insertions(+), 162 deletions(-) delete mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs create mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs delete mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilter.cs create mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs create mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapSearchSmallFilterRow.cs delete mode 100644 osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs index b82ad86fb8..30cd34be50 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -17,29 +18,40 @@ namespace osu.Game.Tests.Visual.UserInterface { public override IReadOnlyList RequiredTypes => new[] { - typeof(BeatmapSearchFilter<>), - typeof(BeatmapSearchRulesetFilter) + typeof(BeatmapSearchFilterRow<>), + typeof(BeatmapSearchRulesetFilterRow), + typeof(BeatmapSearchSmallFilterRow<>), }; [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + private readonly FillFlowContainer resizableContainer; + public TestSceneBeatmapSearchFilter() { - Add(new FillFlowContainer + Add(resizableContainer = new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 10), Children = new Drawable[] { - new BeatmapSearchRulesetFilter(), - new BeatmapSearchFilter(), - new SmallBeatmapSearchFilter() + new BeatmapSearchRulesetFilterRow(), + new BeatmapSearchFilterRow("Categories"), + new BeatmapSearchSmallFilterRow("Header Name") } }); } + + [Test] + public void TestResize() + { + AddStep("Resize to 0.3", () => resizableContainer.ResizeWidthTo(0.3f, 1000)); + AddStep("Resize to 1", () => resizableContainer.ResizeWidthTo(1, 1000)); + } } } diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs deleted file mode 100644 index 825d157918..0000000000 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilter.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Overlays.BeatmapListing -{ - public class BeatmapSearchFilter : TabControl - { - public BeatmapSearchFilter() - { - AutoSizeAxes = Axes.Both; - - if (typeof(T).IsEnum) - { - foreach (var val in (T[])Enum.GetValues(typeof(T))) - AddItem(val); - } - } - - protected override Dropdown CreateDropdown() => null; - - protected override TabItem CreateTabItem(T value) => new FilterTabItem(value); - - protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer - { - AutoSizeAxes = Axes.Both, - Spacing = new Vector2(10), - }; - - protected class FilterTabItem : TabItem - { - protected virtual float TextSize => 13; - - [Resolved] - private OverlayColourProvider colourProvider { get; set; } - - private readonly OsuSpriteText text; - - public FilterTabItem(T value) - : base(value) - { - AutoSizeAxes = Axes.Both; - AddRangeInternal(new Drawable[] - { - text = new OsuSpriteText - { - Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Regular), - Text = GetText(value) - }, - new HoverClickSounds() - }); - - Enabled.Value = true; - } - - [BackgroundDependencyLoader] - private void load() - { - updateState(); - } - - protected virtual string GetText(T value) => (value as Enum)?.GetDescription() ?? value.ToString(); - - protected override bool OnHover(HoverEvent e) - { - base.OnHover(e); - updateState(); - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - updateState(); - } - - protected override void OnActivated() => updateState(); - - protected override void OnDeactivated() => updateState(); - - private void updateState() => text.FadeColour(Active.Value ? Color4.White : getStateColour(), 200, Easing.OutQuint); - - private Color4 getStateColour() => IsHovered ? colourProvider.Light1 : colourProvider.Light3; - } - } -} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs new file mode 100644 index 0000000000..05578a36b5 --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs @@ -0,0 +1,149 @@ +// 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 JetBrains.Annotations; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.BeatmapListing +{ + public class BeatmapSearchFilterRow : CompositeDrawable, IHasCurrentValue + { + private readonly BindableWithCurrent current = new BindableWithCurrent(); + + public Bindable Current + { + get => current.Current; + set => current.Current = value; + } + + public BeatmapSearchFilterRow(string headerName) + { + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + AddInternal(new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Spacing = new Vector2(0, 7), + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + Width = 100, + Child = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 10), + Text = headerName.ToUpper() + } + }, + CreateFilter().With(f => + { + f.Anchor = Anchor.CentreLeft; + f.Origin = Anchor.CentreLeft; + f.Current = current; + }) + } + }); + } + + [NotNull] + protected virtual BeatmapSearchFilter CreateFilter() => new BeatmapSearchFilter(); + + protected class BeatmapSearchFilter : TabControl + { + public BeatmapSearchFilter() + { + AutoSizeAxes = Axes.Both; + + if (typeof(T).IsEnum) + { + foreach (var val in (T[])Enum.GetValues(typeof(T))) + AddItem(val); + } + } + + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(T value) => new FilterTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(10), + }; + + protected class FilterTabItem : TabItem + { + protected virtual float TextSize => 13; + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + private readonly OsuSpriteText text; + + public FilterTabItem(T value) + : base(value) + { + AutoSizeAxes = Axes.Both; + AddRangeInternal(new Drawable[] + { + text = new OsuSpriteText + { + Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Regular), + Text = GetText(value) + }, + new HoverClickSounds() + }); + + Enabled.Value = true; + } + + [BackgroundDependencyLoader] + private void load() + { + updateState(); + } + + protected virtual string GetText(T value) => (value as Enum)?.GetDescription() ?? value.ToString(); + + protected override bool OnHover(HoverEvent e) + { + base.OnHover(e); + updateState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + updateState(); + } + + protected override void OnActivated() => updateState(); + + protected override void OnDeactivated() => updateState(); + + private void updateState() => text.FadeColour(Active.Value ? Color4.White : getStateColour(), 200, Easing.OutQuint); + + private Color4 getStateColour() => IsHovered ? colourProvider.Light1 : colourProvider.Light3; + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilter.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilter.cs deleted file mode 100644 index ffe5693eeb..0000000000 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilter.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Game.Rulesets; -using osu.Framework.Graphics.UserInterface; - -namespace osu.Game.Overlays.BeatmapListing -{ - public class BeatmapSearchRulesetFilter : BeatmapSearchFilter - { - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) - { - AddItem(new RulesetInfo - { - Name = @"Any" - }); - - foreach (var r in rulesets.AvailableRulesets) - AddItem(r); - } - - protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value); - - private class RulesetTabItem : FilterTabItem - { - public RulesetTabItem(RulesetInfo value) - : base(value) - { - } - - protected override string GetText(RulesetInfo value) => value.Name; - } - } -} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs new file mode 100644 index 0000000000..d30364ab0d --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs @@ -0,0 +1,46 @@ +// 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.UserInterface; +using osu.Game.Rulesets; + +namespace osu.Game.Overlays.BeatmapListing +{ + public class BeatmapSearchRulesetFilterRow : BeatmapSearchFilterRow + { + public BeatmapSearchRulesetFilterRow() + : base(@"Mode") + { + } + + protected override BeatmapSearchFilter CreateFilter() => new RulesetFilter(); + + private class RulesetFilter : BeatmapSearchFilter + { + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + AddItem(new RulesetInfo + { + Name = @"Any" + }); + + foreach (var r in rulesets.AvailableRulesets) + AddItem(r); + } + + protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value); + + private class RulesetTabItem : FilterTabItem + { + public RulesetTabItem(RulesetInfo value) + : base(value) + { + } + + protected override string GetText(RulesetInfo value) => value.Name; + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchSmallFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchSmallFilterRow.cs new file mode 100644 index 0000000000..6daa7cb0e0 --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchSmallFilterRow.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.UserInterface; + +namespace osu.Game.Overlays.BeatmapListing +{ + public class BeatmapSearchSmallFilterRow : BeatmapSearchFilterRow + { + public BeatmapSearchSmallFilterRow(string headerName) + : base(headerName) + { + } + + protected override BeatmapSearchFilter CreateFilter() => new SmallBeatmapSearchFilter(); + + private class SmallBeatmapSearchFilter : BeatmapSearchFilter + { + protected override TabItem CreateTabItem(T value) => new SmallTabItem(value); + + private class SmallTabItem : FilterTabItem + { + public SmallTabItem(T value) + : base(value) + { + } + + protected override float TextSize => 10; + } + } + } +} diff --git a/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs b/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs deleted file mode 100644 index b5d2ad5d4e..0000000000 --- a/osu.Game/Overlays/BeatmapListing/SmallBeatmapSearchFilter.cs +++ /dev/null @@ -1,22 +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.Graphics.UserInterface; - -namespace osu.Game.Overlays.BeatmapListing -{ - public class SmallBeatmapSearchFilter : BeatmapSearchFilter - { - protected override TabItem CreateTabItem(T value) => new SmallTabItem(value); - - protected class SmallTabItem : FilterTabItem - { - public SmallTabItem(T value) - : base(value) - { - } - - protected override float TextSize => 10; - } - } -} From a9f366fda3a74c2054d450251f9bbaf07f34f37d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 02:20:53 +0300 Subject: [PATCH 11/42] Implement OverlaySortTabControl component --- .../Online/TestSceneCommentsContainer.cs | 2 +- .../Visual/Online/TestSceneCommentsHeader.cs | 2 +- osu.Game/Overlays/Comments/CommentsHeader.cs | 33 ++-- osu.Game/Overlays/Comments/SortTabControl.cs | 110 ------------- osu.Game/Overlays/OverlaySortTabControl.cs | 147 ++++++++++++++++++ 5 files changed, 159 insertions(+), 135 deletions(-) delete mode 100644 osu.Game/Overlays/Comments/SortTabControl.cs create mode 100644 osu.Game/Overlays/OverlaySortTabControl.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 2a43ba3f99..ece280659c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Online typeof(CommentsHeader), typeof(DrawableComment), typeof(HeaderButton), - typeof(SortTabControl), + typeof(OverlaySortTabControl<>), typeof(ShowChildrenButton), typeof(DeletedCommentsCounter), typeof(VotePill), diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs index a60f220e4b..c688d600a3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsHeader.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Online { typeof(CommentsHeader), typeof(HeaderButton), - typeof(SortTabControl), + typeof(OverlaySortTabControl<>), }; [Cached] diff --git a/osu.Game/Overlays/Comments/CommentsHeader.cs b/osu.Game/Overlays/Comments/CommentsHeader.cs index ad80e67330..1aa40201f1 100644 --- a/osu.Game/Overlays/Comments/CommentsHeader.cs +++ b/osu.Game/Overlays/Comments/CommentsHeader.cs @@ -16,8 +16,6 @@ namespace osu.Game.Overlays.Comments { public class CommentsHeader : CompositeDrawable { - private const int font_size = 14; - public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); @@ -40,29 +38,11 @@ namespace osu.Game.Overlays.Comments Padding = new MarginPadding { Horizontal = 50 }, Children = new Drawable[] { - new FillFlowContainer + new OverlaySortTabControl { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Children = new Drawable[] - { - new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: font_size), - Text = @"Sort by" - }, - new SortTabControl - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Current = Sort - } - } + Current = Sort }, new ShowDeletedButton { @@ -106,7 +86,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: font_size), + Font = OsuFont.GetFont(size: 12), Text = @"Show deleted" } }, @@ -126,4 +106,11 @@ namespace osu.Game.Overlays.Comments } } } + + public enum CommentsSortCriteria + { + New, + Old, + Top + } } diff --git a/osu.Game/Overlays/Comments/SortTabControl.cs b/osu.Game/Overlays/Comments/SortTabControl.cs deleted file mode 100644 index 700d63351f..0000000000 --- a/osu.Game/Overlays/Comments/SortTabControl.cs +++ /dev/null @@ -1,110 +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.Graphics.Containers; -using osu.Framework.Graphics; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osuTK; -using osu.Game.Graphics.UserInterface; -using osu.Framework.Input.Events; -using osu.Framework.Bindables; -using osu.Framework.Allocation; -using osu.Game.Graphics.Sprites; -using osuTK.Graphics; - -namespace osu.Game.Overlays.Comments -{ - public class SortTabControl : OsuTabControl - { - protected override Dropdown CreateDropdown() => null; - - protected override TabItem CreateTabItem(CommentsSortCriteria value) => new SortTabItem(value); - - protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - }; - - public SortTabControl() - { - AutoSizeAxes = Axes.Both; - } - - private class SortTabItem : TabItem - { - public SortTabItem(CommentsSortCriteria value) - : base(value) - { - AutoSizeAxes = Axes.Both; - Child = new TabButton(value) { Active = { BindTarget = Active } }; - } - - protected override void OnActivated() - { - } - - protected override void OnDeactivated() - { - } - - private class TabButton : HeaderButton - { - public readonly BindableBool Active = new BindableBool(); - - [Resolved] - private OverlayColourProvider colourProvider { get; set; } - - private readonly SpriteText text; - - public TabButton(CommentsSortCriteria value) - { - Add(text = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 14), - Text = value.ToString() - }); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - Active.BindValueChanged(active => - { - updateBackgroundState(); - - text.Font = text.Font.With(weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium); - text.Colour = active.NewValue ? colourProvider.Light1 : Color4.White; - }, true); - } - - protected override bool OnHover(HoverEvent e) - { - updateBackgroundState(); - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) => updateBackgroundState(); - - private void updateBackgroundState() - { - if (Active.Value || IsHovered) - ShowBackground(); - else - HideBackground(); - } - } - } - } - - public enum CommentsSortCriteria - { - New, - Old, - Top - } -} diff --git a/osu.Game/Overlays/OverlaySortTabControl.cs b/osu.Game/Overlays/OverlaySortTabControl.cs new file mode 100644 index 0000000000..0b91de2682 --- /dev/null +++ b/osu.Game/Overlays/OverlaySortTabControl.cs @@ -0,0 +1,147 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osuTK; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Framework.Bindables; +using osu.Framework.Allocation; +using osu.Game.Graphics.Sprites; +using osuTK.Graphics; +using osu.Game.Overlays.Comments; +using JetBrains.Annotations; + +namespace osu.Game.Overlays +{ + public class OverlaySortTabControl : CompositeDrawable, IHasCurrentValue + { + private readonly BindableWithCurrent current = new BindableWithCurrent(); + + public Bindable Current + { + get => current.Current; + set => current.Current = value; + } + + public OverlaySortTabControl() + { + AutoSizeAxes = Axes.Both; + AddInternal(new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Text = @"Sort by" + }, + CreateControl().With(c => + { + c.Anchor = Anchor.CentreLeft; + c.Origin = Anchor.CentreLeft; + c.Current = current; + }) + } + }); + } + + [NotNull] + protected virtual SortTabControl CreateControl() => new SortTabControl(); + + protected class SortTabControl : OsuTabControl + { + protected override Dropdown CreateDropdown() => null; + + protected override TabItem CreateTabItem(T value) => new SortTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + }; + + public SortTabControl() + { + AutoSizeAxes = Axes.Both; + } + + protected class SortTabItem : TabItem + { + public SortTabItem(T value) + : base(value) + { + AutoSizeAxes = Axes.Both; + Child = new TabButton(value) { Active = { BindTarget = Active } }; + } + + protected override void OnActivated() + { + } + + protected override void OnDeactivated() + { + } + + private class TabButton : HeaderButton + { + public readonly BindableBool Active = new BindableBool(); + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + private readonly SpriteText text; + + public TabButton(T value) + { + Add(text = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12), + Text = value.ToString() + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Active.BindValueChanged(_ => updateState(), true); + } + + protected override bool OnHover(HoverEvent e) + { + updateHoverState(); + return true; + } + + protected override void OnHoverLost(HoverLostEvent e) => updateHoverState(); + + private void updateState() + { + updateHoverState(); + text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); + } + + private void updateHoverState() + { + if (Active.Value || IsHovered) + ShowBackground(); + else + HideBackground(); + + text.Colour = Active.Value && !IsHovered ? colourProvider.Light1 : Color4.White; + } + } + } + } + } +} From 2ba0bd872bd41428a9da62a020be1d231f73a321 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 02:35:46 +0300 Subject: [PATCH 12/42] Implement basic BeatmapListingSortTabControl --- .../TestSceneBeatmapListingSort.cs | 33 +++++++++++++++++++ .../BeatmapListingSortTabControl.cs | 24 ++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs create mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs new file mode 100644 index 0000000000..28549f4306 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Overlays; +using osu.Game.Overlays.BeatmapListing; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneBeatmapListingSort : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(BeatmapListingSortTabControl), + typeof(OverlaySortTabControl<>), + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + + public TestSceneBeatmapListingSort() + { + Add(new BeatmapListingSortTabControl + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + } + } +} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs new file mode 100644 index 0000000000..0a002325e7 --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.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. + +namespace osu.Game.Overlays.BeatmapListing +{ + public class BeatmapListingSortTabControl : OverlaySortTabControl + { + public BeatmapListingSortTabControl() + { + Current.Value = BeatmapSortCriteria.Ranked; + } + } + + public enum BeatmapSortCriteria + { + Title, + Artist, + Difficulty, + Ranked, + Rating, + Plays, + Favourites, + } +} From fe7923b7e824449c0d06baf2a6729ccf935ae4ed Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 03:38:14 +0300 Subject: [PATCH 13/42] Add SortDirection Bindable and refactor to make everything work --- .../TestSceneBeatmapListingSort.cs | 30 +++++- .../BeatmapListingSortTabControl.cs | 95 +++++++++++++++++++ osu.Game/Overlays/OverlaySortTabControl.cs | 53 +++++++---- 3 files changed, 161 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs index 28549f4306..40c694e224 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs @@ -5,8 +5,11 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.BeatmapListing; +using osuTK; namespace osu.Game.Tests.Visual.UserInterface { @@ -20,14 +23,39 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + private readonly FillFlowContainer placeholder; + private readonly BeatmapListingSortTabControl control; public TestSceneBeatmapListingSort() { - Add(new BeatmapListingSortTabControl + Add(control = new BeatmapListingSortTabControl { Anchor = Anchor.Centre, Origin = Anchor.Centre, }); + + Add(placeholder = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + control.SortDirection.BindValueChanged(_ => updateBindablesVisual()); + control.Current.BindValueChanged(_ => updateBindablesVisual(), true); + } + + private void updateBindablesVisual() + { + placeholder.Clear(); + + placeholder.Add(new OsuSpriteText { Text = $"Current: {control.Current.Value}" }); + placeholder.Add(new OsuSpriteText { Text = $"Sort direction: {control.SortDirection.Value}" }); } } } diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs index 0a002325e7..3f69c76da7 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs @@ -1,14 +1,109 @@ // 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.Bindables; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Graphics; +using osuTK.Graphics; +using osuTK; +using osu.Framework.Input.Events; + namespace osu.Game.Overlays.BeatmapListing { public class BeatmapListingSortTabControl : OverlaySortTabControl { + public readonly Bindable SortDirection = new Bindable(Overlays.SortDirection.Descending); + public BeatmapListingSortTabControl() { Current.Value = BeatmapSortCriteria.Ranked; } + + protected override SortTabControl CreateControl() => new BeatmapSortTabControl + { + SortDirection = { BindTarget = SortDirection } + }; + + private class BeatmapSortTabControl : SortTabControl + { + public readonly Bindable SortDirection = new Bindable(); + + protected override TabItem CreateTabItem(BeatmapSortCriteria value) => new BeatmapSortTabItem(value) + { + SortDirection = { BindTarget = SortDirection } + }; + + private class BeatmapSortTabItem : SortTabItem + { + public readonly Bindable SortDirection = new Bindable(); + + public BeatmapSortTabItem(BeatmapSortCriteria value) + : base(value) + { + } + + protected override TabButton CreateTabButton(BeatmapSortCriteria value) => new BeatmapTabButton(value) + { + Active = { BindTarget = Active }, + SortDirection = { BindTarget = SortDirection } + }; + + private class BeatmapTabButton : TabButton + { + public readonly Bindable SortDirection = new Bindable(); + + protected override Color4 ContentColour + { + set + { + base.ContentColour = value; + icon.Colour = value; + } + } + + private readonly SpriteIcon icon; + + public BeatmapTabButton(BeatmapSortCriteria value) + : base(value) + { + Add(icon = new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AlwaysPresent = true, + Alpha = 0, + Size = new Vector2(6) + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + SortDirection.BindValueChanged(direction => + { + icon.Icon = direction.NewValue == Overlays.SortDirection.Ascending ? FontAwesome.Solid.CaretUp : FontAwesome.Solid.CaretDown; + icon.Margin = direction.NewValue == Overlays.SortDirection.Ascending ? new MarginPadding { Top = 1 } : new MarginPadding { Top = 2 }; + }, true); + } + + protected override void UpdateState() + { + base.UpdateState(); + icon.FadeTo(Active.Value || IsHovered ? 1 : 0, 200, Easing.OutQuint); + } + + protected override bool OnClick(ClickEvent e) + { + if (Active.Value) + SortDirection.Value = SortDirection.Value == Overlays.SortDirection.Ascending ? Overlays.SortDirection.Descending : Overlays.SortDirection.Ascending; + + return base.OnClick(e); + } + } + } + } } public enum BeatmapSortCriteria diff --git a/osu.Game/Overlays/OverlaySortTabControl.cs b/osu.Game/Overlays/OverlaySortTabControl.cs index 0b91de2682..487dd70db9 100644 --- a/osu.Game/Overlays/OverlaySortTabControl.cs +++ b/osu.Game/Overlays/OverlaySortTabControl.cs @@ -82,9 +82,15 @@ namespace osu.Game.Overlays : base(value) { AutoSizeAxes = Axes.Both; - Child = new TabButton(value) { Active = { BindTarget = Active } }; + Child = CreateTabButton(value); } + [NotNull] + protected virtual TabButton CreateTabButton(T value) => new TabButton(value) + { + Active = { BindTarget = Active } + }; + protected override void OnActivated() { } @@ -93,52 +99,67 @@ namespace osu.Game.Overlays { } - private class TabButton : HeaderButton + protected class TabButton : HeaderButton { public readonly BindableBool Active = new BindableBool(); + protected override Container Content => content; + + protected virtual Color4 ContentColour + { + set => text.Colour = value; + } + [Resolved] private OverlayColourProvider colourProvider { get; set; } private readonly SpriteText text; + private readonly FillFlowContainer content; public TabButton(T value) { - Add(text = new OsuSpriteText + base.Content.Add(content = new FillFlowContainer { - Font = OsuFont.GetFont(size: 12), - Text = value.ToString() + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Children = new Drawable[] + { + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12), + Text = value.ToString() + } + } }); } protected override void LoadComplete() { base.LoadComplete(); - Active.BindValueChanged(_ => updateState(), true); + Active.BindValueChanged(_ => UpdateState(), true); } protected override bool OnHover(HoverEvent e) { - updateHoverState(); + UpdateState(); return true; } - protected override void OnHoverLost(HoverLostEvent e) => updateHoverState(); + protected override void OnHoverLost(HoverLostEvent e) => UpdateState(); - private void updateState() - { - updateHoverState(); - text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - } - - private void updateHoverState() + protected virtual void UpdateState() { if (Active.Value || IsHovered) ShowBackground(); else HideBackground(); - text.Colour = Active.Value && !IsHovered ? colourProvider.Light1 : Color4.White; + ContentColour = Active.Value && !IsHovered ? colourProvider.Light1 : Color4.White; + + text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); } } } From d985a22f7758b8de3651f15141178b6a5140a53a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 03:52:26 +0300 Subject: [PATCH 14/42] Add missing blank line --- .../Visual/UserInterface/TestSceneBeatmapListingSort.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs index 40c694e224..4638b2bb54 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs @@ -23,6 +23,7 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + private readonly FillFlowContainer placeholder; private readonly BeatmapListingSortTabControl control; From 480e5677edaa8cb93201042b8a1158bb3f4e9d51 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 04:29:41 +0300 Subject: [PATCH 15/42] Use OverlayColourProvider for CounterPill in profile overlay --- .../Visual/Online/TestSceneProfileCounterPill.cs | 5 +++++ osu.Game/Overlays/Profile/Sections/CounterPill.cs | 13 ++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileCounterPill.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileCounterPill.cs index 468239cf08..5e2b125521 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileCounterPill.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileCounterPill.cs @@ -4,8 +4,10 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Overlays; using osu.Game.Overlays.Profile.Sections; namespace osu.Game.Tests.Visual.Online @@ -17,6 +19,9 @@ namespace osu.Game.Tests.Visual.Online typeof(CounterPill) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Red); + private readonly CounterPill pill; private readonly BindableInt value = new BindableInt(); diff --git a/osu.Game/Overlays/Profile/Sections/CounterPill.cs b/osu.Game/Overlays/Profile/Sections/CounterPill.cs index bd760c4139..52adefa4ad 100644 --- a/osu.Game/Overlays/Profile/Sections/CounterPill.cs +++ b/osu.Game/Overlays/Profile/Sections/CounterPill.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Framework.Bindables; using osu.Game.Graphics.Sprites; +using osu.Framework.Allocation; namespace osu.Game.Overlays.Profile.Sections { @@ -16,9 +17,10 @@ namespace osu.Game.Overlays.Profile.Sections public readonly BindableInt Current = new BindableInt(); - private readonly OsuSpriteText counter; + private OsuSpriteText counter; - public CounterPill() + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) { AutoSizeAxes = Axes.Both; Alpha = 0; @@ -28,14 +30,15 @@ namespace osu.Game.Overlays.Profile.Sections new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.05f) + Colour = colourProvider.Background6 }, counter = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, Margin = new MarginPadding { Horizontal = 10, Vertical = 5 }, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold) + Font = OsuFont.GetFont(weight: FontWeight.Bold), + Colour = colourProvider.Foreground1 } }; } @@ -54,7 +57,7 @@ namespace osu.Game.Overlays.Profile.Sections return; } - counter.Text = value.NewValue.ToString(); + counter.Text = value.NewValue.ToString("N0"); this.FadeIn(duration, Easing.OutQuint); } } From b1e7d1f99588c865e49cf41459e787fabcb288c1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Feb 2020 11:09:33 +0900 Subject: [PATCH 16/42] Slight rewording --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 67027bb9f3..e6d297c47f 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the ## Status -This project is still heavily under development, but is in a state where users are encouraged to try it out and keep it installed alongside the stable *osu!* client. It will continue to evolve over the coming months and hopefully bring some new unique features to the table. +This project under heavy development, but is in a stable state. Users are encouraged to try it out and keep it installed alongside the stable *osu!* client. It will continue to evolve to the point of eventually replacing the existing stable client as an update. -We are accepting bug reports (please report with as much detail as possible). Feature requests are welcome as long as you read and understand the contribution guidelines listed below. +We are accepting bug reports (please report with as much detail as possible). Feature requests are also welcome, but understand that our focus is on completing the game to feature parity before adding new features. Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh/home/changelog). From 8b2b159a0c4b93a0eb844c8b75d7616d21f66f39 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Feb 2020 11:09:46 +0900 Subject: [PATCH 17/42] Link to details on project management --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e6d297c47f..0a3ed7f0e7 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This project under heavy development, but is in a stable state. Users are encour We are accepting bug reports (please report with as much detail as possible). Feature requests are also welcome, but understand that our focus is on completing the game to feature parity before adding new features. -Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh/home/changelog). +Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh/home/changelog). You can also learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management). ## Requirements From 2c3e510051b76a11b514d2879e83c935b168c5ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Feb 2020 11:10:26 +0900 Subject: [PATCH 18/42] Link directly to lazer changelog now that this is supported by osu-web --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a3ed7f0e7..3f50c39cfe 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This project under heavy development, but is in a stable state. Users are encour We are accepting bug reports (please report with as much detail as possible). Feature requests are also welcome, but understand that our focus is on completing the game to feature parity before adding new features. -Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh/home/changelog). You can also learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management). +Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer). You can also learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management). ## Requirements From 7e052e9894f5448b5cb7c4b16c38e97e75d54f95 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Feb 2020 12:49:47 +0900 Subject: [PATCH 19/42] Update README.md Co-Authored-By: Dan Balasescu --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f50c39cfe..90ec1d0b39 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the ## Status -This project under heavy development, but is in a stable state. Users are encouraged to try it out and keep it installed alongside the stable *osu!* client. It will continue to evolve to the point of eventually replacing the existing stable client as an update. +This project is under heavy development, but is in a stable state. Users are encouraged to try it out and keep it installed alongside the stable *osu!* client. It will continue to evolve to the point of eventually replacing the existing stable client as an update. We are accepting bug reports (please report with as much detail as possible). Feature requests are also welcome, but understand that our focus is on completing the game to feature parity before adding new features. From 958c891d1517dc2fb4a9cf1a59e2deb1d1902d43 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Feb 2020 15:06:14 +0900 Subject: [PATCH 20/42] Update with framework-side bindable list changes --- osu.Game.Rulesets.Osu/Objects/Slider.cs | 3 +- .../Online/TestSceneLeaderboardModSelector.cs | 43 +++++++++++-------- .../Screens/Editors/TournamentEditorScreen.cs | 17 +++++++- .../Ladder/Components/LadderEditorSettings.cs | 31 +++++++++++-- .../Screens/Ladder/LadderScreen.cs | 31 +++++++------ .../BeatmapSet/Scores/ScoresContainer.cs | 3 +- .../Objects/Drawables/DrawableHitObject.cs | 3 +- osu.Game/Rulesets/Objects/SliderPath.cs | 23 +++++----- .../Compose/Components/BlueprintContainer.cs | 23 +++++----- .../Screens/Multi/Components/BeatmapTitle.cs | 3 +- .../Multi/Components/BeatmapTypeInfo.cs | 3 +- .../Screens/Multi/Components/ModeTypeInfo.cs | 3 +- .../Components/MultiplayerBackgroundSprite.cs | 3 +- .../Screens/Multi/DrawableRoomPlaylist.cs | 12 ++++-- .../Screens/Multi/DrawableRoomPlaylistItem.cs | 3 +- 15 files changed, 127 insertions(+), 77 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 95fb6d9d48..77f8ec6cc8 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -116,8 +116,7 @@ namespace osu.Game.Rulesets.Osu.Objects public Slider() { - SamplesBindable.ItemsAdded += _ => updateNestedSamples(); - SamplesBindable.ItemsRemoved += _ => updateNestedSamples(); + SamplesBindable.CollectionChanged += (_, __) => updateNestedSamples(); Path.Version.ValueChanged += _ => updateNestedPositions(); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs index e0e5a088ce..7327e80d06 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardModSelector.cs @@ -4,6 +4,8 @@ using osu.Game.Overlays.BeatmapSet; using System; using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; using osu.Framework.Graphics; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Mania; @@ -15,6 +17,7 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Bindables; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; namespace osu.Game.Tests.Visual.Online { @@ -44,27 +47,31 @@ namespace osu.Game.Tests.Visual.Online Ruleset = { BindTarget = ruleset } }); - modSelector.SelectedMods.ItemsAdded += mods => + modSelector.SelectedMods.CollectionChanged += (_, args) => { - mods.ForEach(mod => selectedMods.Add(new OsuSpriteText + switch (args.Action) { - Text = mod.Acronym, - })); - }; - - modSelector.SelectedMods.ItemsRemoved += mods => - { - mods.ForEach(mod => - { - foreach (var selected in selectedMods) - { - if (selected.Text == mod.Acronym) + case NotifyCollectionChangedAction.Add: + args.NewItems.Cast().ForEach(mod => selectedMods.Add(new OsuSpriteText { - selectedMods.Remove(selected); - break; - } - } - }); + Text = mod.Acronym, + })); + break; + + case NotifyCollectionChangedAction.Remove: + args.OldItems.Cast().ForEach(mod => + { + foreach (var selected in selectedMods) + { + if (selected.Text == mod.Acronym) + { + selectedMods.Remove(selected); + break; + } + } + }); + break; + } }; AddStep("osu ruleset", () => ruleset.Value = new OsuRuleset().RulesetInfo); diff --git a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs index 32cf6bbcc8..5598910824 100644 --- a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs +++ b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Specialized; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; @@ -71,8 +73,19 @@ namespace osu.Game.Tournament.Screens.Editors } }); - Storage.ItemsAdded += items => items.ForEach(i => flow.Add(CreateDrawable(i))); - Storage.ItemsRemoved += items => items.ForEach(i => flow.RemoveAll(d => d.Model == i)); + Storage.CollectionChanged += (_, args) => + { + switch (args.Action) + { + case NotifyCollectionChangedAction.Add: + args.NewItems.Cast().ForEach(i => flow.Add(CreateDrawable(i))); + break; + + case NotifyCollectionChangedAction.Remove: + args.OldItems.Cast().ForEach(i => flow.RemoveAll(d => d.Model == i)); + break; + } + }; foreach (var model in Storage) flow.Add(CreateDrawable(model)); diff --git a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs index 0864d25a2f..8ab083ddaf 100644 --- a/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs +++ b/osu.Game.Tournament/Screens/Ladder/Components/LadderEditorSettings.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -90,8 +91,19 @@ namespace osu.Game.Tournament.Screens.Ladder.Components foreach (var r in rounds.Prepend(new TournamentRound())) add(r); - rounds.ItemsRemoved += items => items.ForEach(i => Control.RemoveDropdownItem(i)); - rounds.ItemsAdded += items => items.ForEach(add); + rounds.CollectionChanged += (_, args) => + { + switch (args.Action) + { + case NotifyCollectionChangedAction.Add: + args.NewItems.Cast().ForEach(add); + break; + + case NotifyCollectionChangedAction.Remove: + args.OldItems.Cast().ForEach(i => Control.RemoveDropdownItem(i)); + break; + } + }; } private readonly List refBindables = new List(); @@ -122,8 +134,19 @@ namespace osu.Game.Tournament.Screens.Ladder.Components foreach (var t in teams.Prepend(new TournamentTeam())) add(t); - teams.ItemsRemoved += items => items.ForEach(i => Control.RemoveDropdownItem(i)); - teams.ItemsAdded += items => items.ForEach(add); + teams.CollectionChanged += (_, args) => + { + switch (args.Action) + { + case NotifyCollectionChangedAction.Add: + args.NewItems.Cast().ForEach(add); + break; + + case NotifyCollectionChangedAction.Remove: + args.OldItems.Cast().ForEach(i => Control.RemoveDropdownItem(i)); + break; + } + }; } private readonly List refBindables = new List(); diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs index 66e68a0f37..8ea366e1b4 100644 --- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs +++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.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.Collections.Specialized; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Caching; @@ -68,22 +69,24 @@ namespace osu.Game.Tournament.Screens.Ladder foreach (var match in LadderInfo.Matches) addMatch(match); - LadderInfo.Rounds.ItemsAdded += _ => layout.Invalidate(); - LadderInfo.Rounds.ItemsRemoved += _ => layout.Invalidate(); - - LadderInfo.Matches.ItemsAdded += matches => + LadderInfo.Rounds.CollectionChanged += (_, __) => layout.Invalidate(); + LadderInfo.Matches.CollectionChanged += (_, args) => { - foreach (var p in matches) - addMatch(p); - layout.Invalidate(); - }; - - LadderInfo.Matches.ItemsRemoved += matches => - { - foreach (var p in matches) + switch (args.Action) { - foreach (var d in MatchesContainer.Where(d => d.Match == p)) - d.Expire(); + case NotifyCollectionChangedAction.Add: + foreach (var p in args.NewItems.Cast()) + addMatch(p); + break; + + case NotifyCollectionChangedAction.Remove: + foreach (var p in args.NewItems.Cast()) + { + foreach (var d in MatchesContainer.Where(d => d.Match == p)) + d.Expire(); + } + + break; } layout.Invalidate(); diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 8560232209..2d8bd10b13 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -191,8 +191,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores scope.BindValueChanged(_ => getScores()); ruleset.BindValueChanged(_ => getScores()); - modSelector.SelectedMods.ItemsAdded += _ => getScores(); - modSelector.SelectedMods.ItemsRemoved += _ => getScores(); + modSelector.SelectedMods.CollectionChanged += (_, __) => getScores(); Beatmap.BindValueChanged(onBeatmapChanged); user.BindValueChanged(onUserChanged, true); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index d3a0b3450f..6f20bcf595 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -125,8 +125,7 @@ namespace osu.Game.Rulesets.Objects.Drawables } samplesBindable = HitObject.SamplesBindable.GetBoundCopy(); - samplesBindable.ItemsAdded += _ => loadSamples(); - samplesBindable.ItemsRemoved += _ => loadSamples(); + samplesBindable.CollectionChanged += (_, __) => loadSamples(); updateState(ArmedState.Idle, true); onDefaultsApplied(); diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index 62a5b6f0b5..ff5f1e3e1e 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Linq; using Newtonsoft.Json; using osu.Framework.Bindables; @@ -47,18 +48,20 @@ namespace osu.Game.Rulesets.Objects { ExpectedDistance.ValueChanged += _ => invalidate(); - ControlPoints.ItemsAdded += items => + ControlPoints.CollectionChanged += (_, args) => { - foreach (var c in items) - c.Changed += invalidate; + switch (args.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (var c in args.NewItems.Cast()) + c.Changed += invalidate; + break; - invalidate(); - }; - - ControlPoints.ItemsRemoved += items => - { - foreach (var c in items) - c.Changed -= invalidate; + case NotifyCollectionChangedAction.Remove: + foreach (var c in args.NewItems.Cast()) + c.Changed -= invalidate; + break; + } invalidate(); }; diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 417d32ca4f..c81c6059cc 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using osu.Framework.Allocation; @@ -70,18 +71,20 @@ namespace osu.Game.Screens.Edit.Compose.Components AddBlueprintFor(obj); selectedHitObjects.BindTo(beatmap.SelectedHitObjects); - selectedHitObjects.ItemsAdded += objects => + selectedHitObjects.CollectionChanged += (selectedObjects, args) => { - foreach (var o in objects) - SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select(); + switch (args.Action) + { + case NotifyCollectionChangedAction.Add: + foreach (var o in args.NewItems) + SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select(); + break; - SelectionChanged?.Invoke(selectedHitObjects); - }; - - selectedHitObjects.ItemsRemoved += objects => - { - foreach (var o in objects) - SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect(); + case NotifyCollectionChangedAction.Remove: + foreach (var o in args.OldItems) + SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect(); + break; + } SelectionChanged?.Invoke(selectedHitObjects); }; diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index baf11dfe0d..9e7a59d7d2 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -26,8 +26,7 @@ namespace osu.Game.Screens.Multi.Components [BackgroundDependencyLoader] private void load() { - Playlist.ItemsAdded += _ => updateText(); - Playlist.ItemsRemoved += _ => updateText(); + Playlist.CollectionChanged += (_, __) => updateText(); updateText(); } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index a1334101b8..ce3b612262 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs @@ -51,8 +51,7 @@ namespace osu.Game.Screens.Multi.Components } }; - Playlist.ItemsAdded += _ => updateInfo(); - Playlist.ItemsRemoved += _ => updateInfo(); + Playlist.CollectionChanged += (_, __) => updateInfo(); updateInfo(); } diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 258541bbd6..0015feb26a 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -48,8 +48,7 @@ namespace osu.Game.Screens.Multi.Components Type.BindValueChanged(type => gameTypeContainer.Child = new DrawableGameType(type.NewValue) { Size = new Vector2(height) }, true); - Playlist.ItemsAdded += _ => updateBeatmap(); - Playlist.ItemsRemoved += _ => updateBeatmap(); + Playlist.CollectionChanged += (_, __) => updateBeatmap(); updateBeatmap(); } diff --git a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs index 5e2f2e530a..2240e55e2f 100644 --- a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs +++ b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs @@ -23,8 +23,7 @@ namespace osu.Game.Screens.Multi.Components { InternalChild = sprite = CreateBackgroundSprite(); - Playlist.ItemsAdded += _ => updateBeatmap(); - Playlist.ItemsRemoved += _ => updateBeatmap(); + Playlist.CollectionChanged += (_, __) => updateBeatmap(); updateBeatmap(); } diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs index b139c61166..9a3fcb1cdc 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylist.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.Collections.Specialized; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; @@ -29,10 +30,15 @@ namespace osu.Game.Screens.Multi base.LoadComplete(); // Scheduled since items are removed and re-added upon rearrangement - Items.ItemsRemoved += items => Schedule(() => + Items.CollectionChanged += (_, args) => Schedule(() => { - if (!Items.Contains(SelectedItem.Value)) - SelectedItem.Value = null; + switch (args.Action) + { + case NotifyCollectionChangedAction.Remove: + if (args.OldItems.Contains(SelectedItem)) + SelectedItem.Value = null; + break; + } }); } diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs index 75c751aa61..ca85aec4e4 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs @@ -84,8 +84,7 @@ namespace osu.Game.Screens.Multi beatmap.BindValueChanged(_ => scheduleRefresh()); ruleset.BindValueChanged(_ => scheduleRefresh()); - requiredMods.ItemsAdded += _ => scheduleRefresh(); - requiredMods.ItemsRemoved += _ => scheduleRefresh(); + requiredMods.CollectionChanged += (_, __) => scheduleRefresh(); refresh(); } From c78534d14e1e6455ace738296fb7b657887853eb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 10:07:32 +0300 Subject: [PATCH 21/42] Fix possible error in SpotlightsLayout --- osu.Game/Overlays/Rankings/SpotlightsLayout.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs index 33811cc982..e609fa1487 100644 --- a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs +++ b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Rankings private void getSpotlights() { spotlightsRequest = new GetSpotlightsRequest(); - spotlightsRequest.Success += response => selector.Spotlights = response.Spotlights; + spotlightsRequest.Success += response => Schedule(() => selector.Spotlights = response.Spotlights); api.Queue(spotlightsRequest); } @@ -151,11 +151,11 @@ namespace osu.Game.Overlays.Rankings protected override void Dispose(bool isDisposing) { - base.Dispose(isDisposing); - spotlightsRequest?.Cancel(); getRankingsRequest?.Cancel(); cancellationToken?.Cancel(); + + base.Dispose(isDisposing); } } } From f9145ce5b47555072d215c712809be66695952b1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Feb 2020 17:02:19 +0900 Subject: [PATCH 22/42] Fix playlist items added with the wrong IDs --- osu.Game/Screens/Select/MatchSongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index a115ab9841..2f3674642e 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -62,7 +62,7 @@ namespace osu.Game.Screens.Select { PlaylistItem item = new PlaylistItem { - ID = (Playlist.LastOrDefault()?.ID + 1) ?? 0, + ID = Playlist.Count == 0 ? 0 : Playlist.Max(p => p.ID) + 1 }; populateItemFromCurrent(item); From 84ea279c947b03be9ace0d9bd23e157983a648cd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Feb 2020 17:04:58 +0900 Subject: [PATCH 23/42] Add test --- .../Multiplayer/TestSceneMatchSongSelect.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs index 5820da811d..2c6f34d8a6 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs @@ -134,6 +134,22 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("playlist has 2 items", () => Room.Playlist.Count == 2); } + [Test] + public void TestAddItemAfterRearrangement() + { + AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem()); + AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem()); + AddStep("rearrange", () => + { + var item = Room.Playlist[0]; + Room.Playlist.RemoveAt(0); + Room.Playlist.Add(item); + }); + + AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem()); + AddAssert("new item has id 2", () => Room.Playlist.Last().ID == 2); + } + private class TestMatchSongSelect : MatchSongSelect { public new MatchBeatmapDetailArea BeatmapDetails => (MatchBeatmapDetailArea)base.BeatmapDetails; From 6ce25b39371522dbacc491ffae5c8e805fbd822b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2020 08:10:20 +0000 Subject: [PATCH 24/42] Bump Sentry from 2.0.2 to 2.0.3 Bumps [Sentry](https://github.com/getsentry/sentry-dotnet) from 2.0.2 to 2.0.3. - [Release notes](https://github.com/getsentry/sentry-dotnet/releases) - [Commits](https://github.com/getsentry/sentry-dotnet/compare/2.0.2...2.0.3) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6dcb529dc4..5e78c69f4d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + From 328ab8ba78eb4b14165ebe7d198373892de09269 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 17 Feb 2020 08:10:37 +0000 Subject: [PATCH 25/42] Bump ppy.osu.Framework.NativeLibs from 2019.1104.0 to 2020.213.0 Bumps [ppy.osu.Framework.NativeLibs](https://github.com/ppy/osu-framework) from 2019.1104.0 to 2020.213.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.1104.0...2020.213.0) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index 946d039195..351126e3b9 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -87,6 +87,6 @@ - + From 7c5ae75c0c8986377d0d856e05931ada0576bbf8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Feb 2020 18:19:41 +0900 Subject: [PATCH 26/42] Add link to blog faq --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 90ec1d0b39..df4cabc24f 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,11 @@ Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the This project is under heavy development, but is in a stable state. Users are encouraged to try it out and keep it installed alongside the stable *osu!* client. It will continue to evolve to the point of eventually replacing the existing stable client as an update. -We are accepting bug reports (please report with as much detail as possible). Feature requests are also welcome, but understand that our focus is on completing the game to feature parity before adding new features. +We are accepting bug reports (please report with as much detail as possible). Feature requests are also welcome, but understand that our focus is on completing the game to feature parity before adding new features. A few resources are available as starting points to getting involved and understanding the project: -Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer). You can also learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management). +- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer). +- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management). +- Read peppy's [latest blog post](https://blog.ppy.sh/a-definitive-lazer-faq/) exploring where lazer is currently and the roadmap going forward. ## Requirements From ede85d7be471724397377bf145f015738739609c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Feb 2020 00:59:08 +0900 Subject: [PATCH 27/42] Restructure readme to better define prerequisites that are required for development only --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index df4cabc24f..6071e3f473 100644 --- a/README.md +++ b/README.md @@ -21,19 +21,9 @@ We are accepting bug reports (please report with as much detail as possible). Fe - You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management). - Read peppy's [latest blog post](https://blog.ppy.sh/a-definitive-lazer-faq/) exploring where lazer is currently and the roadmap going forward. -## Requirements - -- A desktop platform with the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) or higher installed. -- When running on Linux, please have a system-wide FFmpeg installation available to support video decoding. -- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/install/dependencies?tabs=netcore31&pivots=os-windows)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. -- When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/). -- When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as [Visual Studio 2019+](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/). - ## Running osu! -### Releases - -If you are not interested in developing the game, you can still consume our [binary releases](https://github.com/ppy/osu/releases). +If you are looking to install or test osu! without setting up a development environment, you can consume our [binary releases](https://github.com/ppy/osu/releases). Handy links below will download the latest version for your operating system of choice: **Latest build:** @@ -41,9 +31,19 @@ If you are not interested in developing the game, you can still consume our [bin | ------------- | ------------- | ------------- | ------------- | - **Linux** users are recommended to self-compile until we have official deployment in place. +- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/install/dependencies?tabs=netcore31&pivots=os-windows)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. If your platform is not listed above, there is still a chance you can manually build it by following the instructions below. +## Developing or debugging + +Please make sure you have the following preqreuisites: + +- A desktop platform with the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) or higher installed. +- When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/). +- When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as [Visual Studio 2019+](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/). +- When running on Linux, please have a system-wide FFmpeg installation available to support video decoding. + ### Downloading the source code Clone the repository: From 19872d9e24009e29ae27f547d8ee568268f26b16 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 22:05:10 +0300 Subject: [PATCH 28/42] Simplify test scene --- .../TestSceneBeatmapListingSort.cs | 31 +++++++------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs index 4638b2bb54..a5fa085abf 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSort.cs @@ -24,39 +24,32 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); - private readonly FillFlowContainer placeholder; - private readonly BeatmapListingSortTabControl control; - public TestSceneBeatmapListingSort() { + BeatmapListingSortTabControl control; + OsuSpriteText current; + OsuSpriteText direction; + Add(control = new BeatmapListingSortTabControl { Anchor = Anchor.Centre, Origin = Anchor.Centre, }); - Add(placeholder = new FillFlowContainer + Add(new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + current = new OsuSpriteText(), + direction = new OsuSpriteText() + } }); - } - protected override void LoadComplete() - { - base.LoadComplete(); - - control.SortDirection.BindValueChanged(_ => updateBindablesVisual()); - control.Current.BindValueChanged(_ => updateBindablesVisual(), true); - } - - private void updateBindablesVisual() - { - placeholder.Clear(); - - placeholder.Add(new OsuSpriteText { Text = $"Current: {control.Current.Value}" }); - placeholder.Add(new OsuSpriteText { Text = $"Sort direction: {control.SortDirection.Value}" }); + control.SortDirection.BindValueChanged(sortDirection => direction.Text = $"Sort direction: {sortDirection.NewValue}", true); + control.Current.BindValueChanged(criteria => current.Text = $"Criteria: {criteria.NewValue}", true); } } } From 519548c99f5c1349bb3c774406897e0f14168e42 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 22:06:46 +0300 Subject: [PATCH 29/42] Remove not necessary icon margin changes --- osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs index 3f69c76da7..d6841da408 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs @@ -84,7 +84,6 @@ namespace osu.Game.Overlays.BeatmapListing SortDirection.BindValueChanged(direction => { icon.Icon = direction.NewValue == Overlays.SortDirection.Ascending ? FontAwesome.Solid.CaretUp : FontAwesome.Solid.CaretDown; - icon.Margin = direction.NewValue == Overlays.SortDirection.Ascending ? new MarginPadding { Top = 1 } : new MarginPadding { Top = 2 }; }, true); } From bce9e7a356912cd7eb7c1d4fd6a35a6cc2ad1163 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 22:32:58 +0300 Subject: [PATCH 30/42] Remove too much nesting for OverlaySortTabControl class --- .../BeatmapListingSortTabControl.cs | 112 ++++++------- osu.Game/Overlays/OverlaySortTabControl.cs | 150 +++++++++--------- 2 files changed, 131 insertions(+), 131 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs index d6841da408..cb41b33bc4 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs @@ -33,74 +33,74 @@ namespace osu.Game.Overlays.BeatmapListing { SortDirection = { BindTarget = SortDirection } }; + } - private class BeatmapSortTabItem : SortTabItem + private class BeatmapSortTabItem : SortTabItem + { + public readonly Bindable SortDirection = new Bindable(); + + public BeatmapSortTabItem(BeatmapSortCriteria value) + : base(value) { - public readonly Bindable SortDirection = new Bindable(); + } - public BeatmapSortTabItem(BeatmapSortCriteria value) - : base(value) + protected override TabButton CreateTabButton(BeatmapSortCriteria value) => new BeatmapTabButton(value) + { + Active = { BindTarget = Active }, + SortDirection = { BindTarget = SortDirection } + }; + } + + private class BeatmapTabButton : TabButton + { + public readonly Bindable SortDirection = new Bindable(); + + protected override Color4 ContentColour + { + set { + base.ContentColour = value; + icon.Colour = value; } + } - protected override TabButton CreateTabButton(BeatmapSortCriteria value) => new BeatmapTabButton(value) + private readonly SpriteIcon icon; + + public BeatmapTabButton(BeatmapSortCriteria value) + : base(value) + { + Add(icon = new SpriteIcon { - Active = { BindTarget = Active }, - SortDirection = { BindTarget = SortDirection } - }; + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AlwaysPresent = true, + Alpha = 0, + Size = new Vector2(6) + }); + } - private class BeatmapTabButton : TabButton + protected override void LoadComplete() + { + base.LoadComplete(); + + SortDirection.BindValueChanged(direction => { - public readonly Bindable SortDirection = new Bindable(); + icon.Icon = direction.NewValue == Overlays.SortDirection.Ascending ? FontAwesome.Solid.CaretUp : FontAwesome.Solid.CaretDown; + }, true); + } - protected override Color4 ContentColour - { - set - { - base.ContentColour = value; - icon.Colour = value; - } - } + protected override void UpdateState() + { + base.UpdateState(); + icon.FadeTo(Active.Value || IsHovered ? 1 : 0, 200, Easing.OutQuint); + } - private readonly SpriteIcon icon; + protected override bool OnClick(ClickEvent e) + { + if (Active.Value) + SortDirection.Value = SortDirection.Value == Overlays.SortDirection.Ascending ? Overlays.SortDirection.Descending : Overlays.SortDirection.Ascending; - public BeatmapTabButton(BeatmapSortCriteria value) - : base(value) - { - Add(icon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AlwaysPresent = true, - Alpha = 0, - Size = new Vector2(6) - }); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - SortDirection.BindValueChanged(direction => - { - icon.Icon = direction.NewValue == Overlays.SortDirection.Ascending ? FontAwesome.Solid.CaretUp : FontAwesome.Solid.CaretDown; - }, true); - } - - protected override void UpdateState() - { - base.UpdateState(); - icon.FadeTo(Active.Value || IsHovered ? 1 : 0, 200, Easing.OutQuint); - } - - protected override bool OnClick(ClickEvent e) - { - if (Active.Value) - SortDirection.Value = SortDirection.Value == Overlays.SortDirection.Ascending ? Overlays.SortDirection.Descending : Overlays.SortDirection.Ascending; - - return base.OnClick(e); - } - } + return base.OnClick(e); } } } diff --git a/osu.Game/Overlays/OverlaySortTabControl.cs b/osu.Game/Overlays/OverlaySortTabControl.cs index 487dd70db9..5a713ab08e 100644 --- a/osu.Game/Overlays/OverlaySortTabControl.cs +++ b/osu.Game/Overlays/OverlaySortTabControl.cs @@ -75,93 +75,93 @@ namespace osu.Game.Overlays { AutoSizeAxes = Axes.Both; } + } - protected class SortTabItem : TabItem + protected class SortTabItem : TabItem + { + public SortTabItem(T value) + : base(value) { - public SortTabItem(T value) - : base(value) + AutoSizeAxes = Axes.Both; + Child = CreateTabButton(value); + } + + [NotNull] + protected virtual TabButton CreateTabButton(T value) => new TabButton(value) + { + Active = { BindTarget = Active } + }; + + protected override void OnActivated() + { + } + + protected override void OnDeactivated() + { + } + } + + protected class TabButton : HeaderButton + { + public readonly BindableBool Active = new BindableBool(); + + protected override Container Content => content; + + protected virtual Color4 ContentColour + { + set => text.Colour = value; + } + + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + private readonly SpriteText text; + private readonly FillFlowContainer content; + + public TabButton(T value) + { + base.Content.Add(content = new FillFlowContainer { - AutoSizeAxes = Axes.Both; - Child = CreateTabButton(value); - } - - [NotNull] - protected virtual TabButton CreateTabButton(T value) => new TabButton(value) - { - Active = { BindTarget = Active } - }; - - protected override void OnActivated() - { - } - - protected override void OnDeactivated() - { - } - - protected class TabButton : HeaderButton - { - public readonly BindableBool Active = new BindableBool(); - - protected override Container Content => content; - - protected virtual Color4 ContentColour + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Children = new Drawable[] { - set => text.Colour = value; - } - - [Resolved] - private OverlayColourProvider colourProvider { get; set; } - - private readonly SpriteText text; - private readonly FillFlowContainer content; - - public TabButton(T value) - { - base.Content.Add(content = new FillFlowContainer + text = new OsuSpriteText { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(3, 0), - Children = new Drawable[] - { - text = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 12), - Text = value.ToString() - } - } - }); + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12), + Text = value.ToString() + } } + }); + } - protected override void LoadComplete() - { - base.LoadComplete(); - Active.BindValueChanged(_ => UpdateState(), true); - } + protected override void LoadComplete() + { + base.LoadComplete(); + Active.BindValueChanged(_ => UpdateState(), true); + } - protected override bool OnHover(HoverEvent e) - { - UpdateState(); - return true; - } + protected override bool OnHover(HoverEvent e) + { + UpdateState(); + return true; + } - protected override void OnHoverLost(HoverLostEvent e) => UpdateState(); + protected override void OnHoverLost(HoverLostEvent e) => UpdateState(); - protected virtual void UpdateState() - { - if (Active.Value || IsHovered) - ShowBackground(); - else - HideBackground(); + protected virtual void UpdateState() + { + if (Active.Value || IsHovered) + ShowBackground(); + else + HideBackground(); - ContentColour = Active.Value && !IsHovered ? colourProvider.Light1 : Color4.White; + ContentColour = Active.Value && !IsHovered ? colourProvider.Light1 : Color4.White; - text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - } - } + text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); } } } From ea99b613c9c499fc21b038fe808ca57dafa07d5c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 23:41:07 +0300 Subject: [PATCH 31/42] Use GridContainer for layout --- .../BeatmapListing/BeatmapSearchFilterRow.cs | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs index 05578a36b5..0c4f63baca 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs @@ -32,33 +32,37 @@ namespace osu.Game.Overlays.BeatmapListing { AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; - AddInternal(new FillFlowContainer + AddInternal(new GridContainer { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Spacing = new Vector2(0, 7), - Children = new Drawable[] + ColumnDimensions = new[] { - new Container + new Dimension(GridSizeMode.Absolute, size: 100), + new Dimension() + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Y, - Width = 100, - Child = new OsuSpriteText + new OsuSpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Font = OsuFont.GetFont(size: 10), Text = headerName.ToUpper() - } - }, - CreateFilter().With(f => - { - f.Anchor = Anchor.CentreLeft; - f.Origin = Anchor.CentreLeft; - f.Current = current; - }) + }, + CreateFilter().With(f => + { + f.Anchor = Anchor.CentreLeft; + f.Origin = Anchor.CentreLeft; + f.Current = current; + }) + } } }); } From ae942388a2aeb83bf382701e83cc06f7f6c9f65e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 17 Feb 2020 23:56:35 +0300 Subject: [PATCH 32/42] Move OsuTabDropdown to it's own file --- .../Graphics/UserInterface/OsuTabControl.cs | 97 +--------------- .../Graphics/UserInterface/OsuTabDropdown.cs | 107 ++++++++++++++++++ 2 files changed, 108 insertions(+), 96 deletions(-) create mode 100644 osu.Game/Graphics/UserInterface/OsuTabDropdown.cs diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 9fa6085035..6c883d9893 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -39,7 +39,7 @@ namespace osu.Game.Graphics.UserInterface private readonly Box strip; - protected override Dropdown CreateDropdown() => new OsuTabDropdown(); + protected override Dropdown CreateDropdown() => new OsuTabDropdown(); protected override TabItem CreateTabItem(T value) => new OsuTabItem(value); @@ -180,100 +180,5 @@ namespace osu.Game.Graphics.UserInterface protected override void OnDeactivated() => fadeInactive(); } - - // todo: this needs to go - private class OsuTabDropdown : OsuDropdown - { - public OsuTabDropdown() - { - RelativeSizeAxes = Axes.X; - } - - protected override DropdownMenu CreateMenu() => new OsuTabDropdownMenu(); - - protected override DropdownHeader CreateHeader() => new OsuTabDropdownHeader - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight - }; - - private class OsuTabDropdownMenu : OsuDropdownMenu - { - public OsuTabDropdownMenu() - { - Anchor = Anchor.TopRight; - Origin = Anchor.TopRight; - - BackgroundColour = Color4.Black.Opacity(0.7f); - MaxHeight = 400; - } - - protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item) { AccentColour = AccentColour }; - - private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem - { - public DrawableOsuTabDropdownMenuItem(MenuItem item) - : base(item) - { - ForegroundColourHover = Color4.Black; - } - } - } - - protected class OsuTabDropdownHeader : OsuDropdownHeader - { - public override Color4 AccentColour - { - get => base.AccentColour; - set - { - base.AccentColour = value; - Foreground.Colour = value; - } - } - - public OsuTabDropdownHeader() - { - RelativeSizeAxes = Axes.None; - AutoSizeAxes = Axes.X; - - BackgroundColour = Color4.Black.Opacity(0.5f); - - Background.Height = 0.5f; - Background.CornerRadius = 5; - Background.Masking = true; - - Foreground.RelativeSizeAxes = Axes.None; - Foreground.AutoSizeAxes = Axes.X; - Foreground.RelativeSizeAxes = Axes.Y; - Foreground.Margin = new MarginPadding(5); - - Foreground.Children = new Drawable[] - { - new SpriteIcon - { - Icon = FontAwesome.Solid.EllipsisH, - Size = new Vector2(14), - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - } - }; - - Padding = new MarginPadding { Left = 5, Right = 5 }; - } - - protected override bool OnHover(HoverEvent e) - { - Foreground.Colour = BackgroundColour; - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - Foreground.Colour = BackgroundColourHover; - base.OnHoverLost(e); - } - } - } } } diff --git a/osu.Game/Graphics/UserInterface/OsuTabDropdown.cs b/osu.Game/Graphics/UserInterface/OsuTabDropdown.cs new file mode 100644 index 0000000000..24b9ca8d90 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/OsuTabDropdown.cs @@ -0,0 +1,107 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osuTK; +using osuTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; + +namespace osu.Game.Graphics.UserInterface +{ + public class OsuTabDropdown : OsuDropdown + { + public OsuTabDropdown() + { + RelativeSizeAxes = Axes.X; + } + + protected override DropdownMenu CreateMenu() => new OsuTabDropdownMenu(); + + protected override DropdownHeader CreateHeader() => new OsuTabDropdownHeader + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }; + + private class OsuTabDropdownMenu : OsuDropdownMenu + { + public OsuTabDropdownMenu() + { + Anchor = Anchor.TopRight; + Origin = Anchor.TopRight; + + BackgroundColour = Color4.Black.Opacity(0.7f); + MaxHeight = 400; + } + + protected override DrawableDropdownMenuItem CreateDrawableDropdownMenuItem(MenuItem item) => new DrawableOsuTabDropdownMenuItem(item) { AccentColour = AccentColour }; + + private class DrawableOsuTabDropdownMenuItem : DrawableOsuDropdownMenuItem + { + public DrawableOsuTabDropdownMenuItem(MenuItem item) + : base(item) + { + ForegroundColourHover = Color4.Black; + } + } + } + + protected class OsuTabDropdownHeader : OsuDropdownHeader + { + public override Color4 AccentColour + { + get => base.AccentColour; + set + { + base.AccentColour = value; + Foreground.Colour = value; + } + } + + public OsuTabDropdownHeader() + { + RelativeSizeAxes = Axes.None; + AutoSizeAxes = Axes.X; + + BackgroundColour = Color4.Black.Opacity(0.5f); + + Background.Height = 0.5f; + Background.CornerRadius = 5; + Background.Masking = true; + + Foreground.RelativeSizeAxes = Axes.None; + Foreground.AutoSizeAxes = Axes.X; + Foreground.RelativeSizeAxes = Axes.Y; + Foreground.Margin = new MarginPadding(5); + + Foreground.Children = new Drawable[] + { + new SpriteIcon + { + Icon = FontAwesome.Solid.EllipsisH, + Size = new Vector2(14), + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + } + }; + + Padding = new MarginPadding { Left = 5, Right = 5 }; + } + + protected override bool OnHover(HoverEvent e) + { + Foreground.Colour = BackgroundColour; + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + Foreground.Colour = BackgroundColourHover; + base.OnHoverLost(e); + } + } + } +} From 410686c8b9dfbe393f23b3bbc1cefb21c499da40 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Feb 2020 01:04:25 +0300 Subject: [PATCH 33/42] Use dropdown in BeatmapSearchFilterRow --- .../TestSceneBeatmapSearchFilter.cs | 5 +- .../BeatmapListing/BeatmapSearchFilterRow.cs | 46 ++++++++++++++----- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs index 30cd34be50..7b4424e568 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapSearchFilter.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Overlays; using osu.Game.Overlays.BeatmapListing; @@ -26,11 +27,11 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); - private readonly FillFlowContainer resizableContainer; + private readonly ReverseChildIDFillFlowContainer resizableContainer; public TestSceneBeatmapSearchFilter() { - Add(resizableContainer = new FillFlowContainer + Add(resizableContainer = new ReverseChildIDFillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs index 0c4f63baca..8be0fca629 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs @@ -51,15 +51,13 @@ namespace osu.Game.Overlays.BeatmapListing { new OsuSpriteText { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, Font = OsuFont.GetFont(size: 10), Text = headerName.ToUpper() }, CreateFilter().With(f => { - f.Anchor = Anchor.CentreLeft; - f.Origin = Anchor.CentreLeft; f.Current = current; }) } @@ -74,7 +72,12 @@ namespace osu.Game.Overlays.BeatmapListing { public BeatmapSearchFilter() { - AutoSizeAxes = Axes.Both; + Anchor = Anchor.BottomLeft; + Origin = Anchor.BottomLeft; + RelativeSizeAxes = Axes.X; + Height = 15; + + TabContainer.Spacing = new Vector2(10, 0); if (typeof(T).IsEnum) { @@ -83,16 +86,16 @@ namespace osu.Game.Overlays.BeatmapListing } } - protected override Dropdown CreateDropdown() => null; + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + ((FilterDropdown)Dropdown).AccentColour = colourProvider.Light2; + } + + protected override Dropdown CreateDropdown() => new FilterDropdown(); protected override TabItem CreateTabItem(T value) => new FilterTabItem(value); - protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer - { - AutoSizeAxes = Axes.Both, - Spacing = new Vector2(10), - }; - protected class FilterTabItem : TabItem { protected virtual float TextSize => 13; @@ -106,6 +109,8 @@ namespace osu.Game.Overlays.BeatmapListing : base(value) { AutoSizeAxes = Axes.Both; + Anchor = Anchor.BottomLeft; + Origin = Anchor.BottomLeft; AddRangeInternal(new Drawable[] { text = new OsuSpriteText @@ -148,6 +153,23 @@ namespace osu.Game.Overlays.BeatmapListing private Color4 getStateColour() => IsHovered ? colourProvider.Light1 : colourProvider.Light3; } + + private class FilterDropdown : OsuTabDropdown + { + protected override DropdownHeader CreateHeader() => new FilterHeader + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight + }; + + private class FilterHeader : OsuTabDropdownHeader + { + public FilterHeader() + { + Background.Height = 1; + } + } + } } } } From 316c6b2a945ad9c7524d53e23de15eb0b29a87ec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Feb 2020 01:17:12 +0300 Subject: [PATCH 34/42] Simplify RulesetInfo string presentation --- .../BeatmapListing/BeatmapSearchFilterRow.cs | 4 +--- .../BeatmapListing/BeatmapSearchRulesetFilterRow.cs | 13 ------------- osu.Game/Rulesets/RulesetInfo.cs | 2 +- 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs index 8be0fca629..2c046a2bbf 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchFilterRow.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.BeatmapListing text = new OsuSpriteText { Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Regular), - Text = GetText(value) + Text = (value as Enum)?.GetDescription() ?? value.ToString() }, new HoverClickSounds() }); @@ -130,8 +130,6 @@ namespace osu.Game.Overlays.BeatmapListing updateState(); } - protected virtual string GetText(T value) => (value as Enum)?.GetDescription() ?? value.ToString(); - protected override bool OnHover(HoverEvent e) { base.OnHover(e); diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs index d30364ab0d..eebd896cf9 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapSearchRulesetFilterRow.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Graphics.UserInterface; using osu.Game.Rulesets; namespace osu.Game.Overlays.BeatmapListing @@ -29,18 +28,6 @@ namespace osu.Game.Overlays.BeatmapListing foreach (var r in rulesets.AvailableRulesets) AddItem(r); } - - protected override TabItem CreateTabItem(RulesetInfo value) => new RulesetTabItem(value); - - private class RulesetTabItem : FilterTabItem - { - public RulesetTabItem(RulesetInfo value) - : base(value) - { - } - - protected override string GetText(RulesetInfo value) => value.Name; - } } } } diff --git a/osu.Game/Rulesets/RulesetInfo.cs b/osu.Game/Rulesets/RulesetInfo.cs index ececc18c96..afd499cb9e 100644 --- a/osu.Game/Rulesets/RulesetInfo.cs +++ b/osu.Game/Rulesets/RulesetInfo.cs @@ -50,6 +50,6 @@ namespace osu.Game.Rulesets } } - public override string ToString() => $"{Name} ({ShortName}) ID: {ID}"; + public override string ToString() => Name ?? $"{Name} ({ShortName}) ID: {ID}"; } } From a4891c13e460d1df77e4d2c26ec55fdb4572bd88 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 18 Feb 2020 09:17:04 +0900 Subject: [PATCH 35/42] Fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6071e3f473..6cc110280c 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ If your platform is not listed above, there is still a chance you can manually b ## Developing or debugging -Please make sure you have the following preqreuisites: +Please make sure you have the following prerequisites: - A desktop platform with the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) or higher installed. - When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/). From c51e5a8c1d0499cfb52640c02eb3ae1af0a9b502 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Feb 2020 12:11:30 +0900 Subject: [PATCH 36/42] Fix osu!catch fruit exploding multiple timed is skin is changed during explode animation --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 1de0b6bfa3..62a7b6f0ab 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -63,6 +63,7 @@ namespace osu.Game.Rulesets.Catch.UI if (result.IsHit && fruit.CanBePlated) { + // create a new (cloned) fruit to stay on the plate. the original is faded out immediately. var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject); if (caughtFruit == null) return; @@ -442,14 +443,22 @@ namespace osu.Game.Rulesets.Catch.UI ExplodingFruitTarget.Add(fruit); } - fruit.ClearTransforms(); - fruit.MoveToY(fruit.Y - 50, 250, Easing.OutSine).Then().MoveToY(fruit.Y + 50, 500, Easing.InSine); - fruit.MoveToX(fruit.X + originalX * 6, 1000); - fruit.FadeOut(750); + double explodeTime = Clock.CurrentTime; - // todo: this shouldn't exist once DrawableHitObject's ClearTransformsAfter overrides are repaired. - fruit.LifetimeStart = Time.Current; - fruit.Expire(); + fruit.ApplyCustomUpdateState += onFruitOnApplyCustomUpdateState; + onFruitOnApplyCustomUpdateState(fruit, fruit.State.Value); + + void onFruitOnApplyCustomUpdateState(DrawableHitObject o, ArmedState state) + { + using (fruit.BeginAbsoluteSequence(explodeTime)) + { + fruit.MoveToY(fruit.Y - 50, 250, Easing.OutSine).Then().MoveToY(fruit.Y + 50, 500, Easing.InSine); + fruit.MoveToX(fruit.X + originalX * 6, 1000); + fruit.FadeOut(750); + } + + fruit.Expire(); + } } public void UpdatePosition(float position) From b4887f912071713ccbaa70ad4d5b2ff405073e32 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Feb 2020 12:24:22 +0900 Subject: [PATCH 37/42] Fix dropping fruit as well (with tidying along the way) --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 71 ++++++++++------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 62a7b6f0ab..cfe2a3abd2 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -389,32 +389,24 @@ namespace osu.Game.Rulesets.Catch.UI } } + public void UpdatePosition(float position) + { + position = Math.Clamp(position, 0, 1); + + if (position == X) + return; + + Scale = new Vector2(Math.Abs(Scale.X) * (position > X ? 1 : -1), Scale.Y); + X = position; + } + /// /// Drop any fruit off the plate. /// public void Drop() { - var fruit = caughtFruit.ToArray(); - - foreach (var f in fruit) - { - if (ExplodingFruitTarget != null) - { - f.Anchor = Anchor.TopLeft; - f.Position = caughtFruit.ToSpaceOfOtherDrawable(f.DrawPosition, ExplodingFruitTarget); - - caughtFruit.Remove(f); - - ExplodingFruitTarget.Add(f); - } - - f.MoveToY(f.Y + 75, 750, Easing.InSine); - f.FadeOut(750); - - // todo: this shouldn't exist once DrawableHitObject's ClearTransformsAfter overrides are repaired. - f.LifetimeStart = Time.Current; - f.Expire(); - } + foreach (var f in caughtFruit.ToArray()) + Drop(f); } /// @@ -426,10 +418,26 @@ namespace osu.Game.Rulesets.Catch.UI Explode(f); } + public void Drop(DrawableHitObject fruit) => removeFromPlatWithTransform(fruit, f => + { + f.MoveToY(f.Y + 75, 750, Easing.InSine); + f.FadeOut(750); + }); + public void Explode(DrawableHitObject fruit) { var originalX = fruit.X * Scale.X; + removeFromPlatWithTransform(fruit, f => + { + f.MoveToY(f.Y - 50, 250, Easing.OutSine).Then().MoveToY(f.Y + 50, 500, Easing.InSine); + f.MoveToX(f.X + originalX * 6, 1000); + f.FadeOut(750); + }); + } + + private void removeFromPlatWithTransform(DrawableHitObject fruit, Action action) + { if (ExplodingFruitTarget != null) { fruit.Anchor = Anchor.TopLeft; @@ -443,34 +451,19 @@ namespace osu.Game.Rulesets.Catch.UI ExplodingFruitTarget.Add(fruit); } - double explodeTime = Clock.CurrentTime; + double actionTime = Clock.CurrentTime; fruit.ApplyCustomUpdateState += onFruitOnApplyCustomUpdateState; onFruitOnApplyCustomUpdateState(fruit, fruit.State.Value); void onFruitOnApplyCustomUpdateState(DrawableHitObject o, ArmedState state) { - using (fruit.BeginAbsoluteSequence(explodeTime)) - { - fruit.MoveToY(fruit.Y - 50, 250, Easing.OutSine).Then().MoveToY(fruit.Y + 50, 500, Easing.InSine); - fruit.MoveToX(fruit.X + originalX * 6, 1000); - fruit.FadeOut(750); - } + using (fruit.BeginAbsoluteSequence(actionTime)) + action(fruit); fruit.Expire(); } } - - public void UpdatePosition(float position) - { - position = Math.Clamp(position, 0, 1); - - if (position == X) - return; - - Scale = new Vector2(Math.Abs(Scale.X) * (position > X ? 1 : -1), Scale.Y); - X = position; - } } } } From ee13632375ea570a6da28e0926f908d8e3bdc4b9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Feb 2020 13:21:55 +0900 Subject: [PATCH 38/42] Fix ogg beatmap/skin samples not loading --- .../Resources/Archives/ogg-beatmap.osz | Bin 0 -> 6428 bytes .../Resources/Archives/ogg-skin.osk | Bin 0 -> 3429 bytes .../Skins/TestSceneBeatmapSkinResources.cs | 37 ++++++++++++++++++ .../Skins/TestSceneSkinResources.cs | 33 ++++++++++++++++ osu.Game/Skinning/LegacySkin.cs | 2 + 5 files changed, 72 insertions(+) create mode 100644 osu.Game.Tests/Resources/Archives/ogg-beatmap.osz create mode 100644 osu.Game.Tests/Resources/Archives/ogg-skin.osk create mode 100644 osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs create mode 100644 osu.Game.Tests/Skins/TestSceneSkinResources.cs diff --git a/osu.Game.Tests/Resources/Archives/ogg-beatmap.osz b/osu.Game.Tests/Resources/Archives/ogg-beatmap.osz new file mode 100644 index 0000000000000000000000000000000000000000..f264a8dda23f57f24acdef7b6838b71747f02186 GIT binary patch literal 6428 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 TKSOu2l$P4use+QZPM-b)-C={F literal 0 HcmV?d00001 diff --git a/osu.Game.Tests/Resources/Archives/ogg-skin.osk b/osu.Game.Tests/Resources/Archives/ogg-skin.osk new file mode 100644 index 0000000000000000000000000000000000000000..d7379446aac247b2310c38b3870dfddd1a2ed07b GIT binary patch literal 3429 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 SF}9;xmcw!UuoA_6wEGvU{_X4l literal 0 HcmV?d00001 diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs new file mode 100644 index 0000000000..4d3b73fb32 --- /dev/null +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Audio.Track; +using osu.Framework.Testing; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.IO.Archives; +using osu.Game.Tests.Resources; +using osu.Game.Tests.Visual; + +namespace osu.Game.Tests.Skins +{ + [HeadlessTest] + public class TestSceneBeatmapSkinResources : OsuTestScene + { + [Resolved] + private BeatmapManager beatmaps { get; set; } + + private WorkingBeatmap beatmap; + + [BackgroundDependencyLoader] + private void load() + { + var imported = beatmaps.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-beatmap.osz"))).Result; + beatmap = beatmaps.GetWorkingBeatmap(imported.Beatmaps[0]); + } + + [Test] + public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo("sample")) != null); + + [Test] + public void TestRetrieveOggTrack() => AddAssert("track is non-null", () => !(beatmap.Track is TrackVirtual)); + } +} diff --git a/osu.Game.Tests/Skins/TestSceneSkinResources.cs b/osu.Game.Tests/Skins/TestSceneSkinResources.cs new file mode 100644 index 0000000000..107a96292f --- /dev/null +++ b/osu.Game.Tests/Skins/TestSceneSkinResources.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Testing; +using osu.Game.Audio; +using osu.Game.IO.Archives; +using osu.Game.Skinning; +using osu.Game.Tests.Resources; +using osu.Game.Tests.Visual; + +namespace osu.Game.Tests.Skins +{ + [HeadlessTest] + public class TestSceneSkinResources : OsuTestScene + { + [Resolved] + private SkinManager skins { get; set; } + + private ISkin skin; + + [BackgroundDependencyLoader] + private void load() + { + var imported = skins.Import(new ZipArchiveReader(TestResources.OpenResource("Archives/ogg-skin.osk"))).Result; + skin = skins.GetSkin(imported); + } + + [Test] + public void TestRetrieveOggSample() => AddAssert("sample is non-null", () => skin.GetSample(new SampleInfo("sample")) != null); + } +} diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 94611317d5..29bcd2e210 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -54,6 +54,8 @@ namespace osu.Game.Skinning { Samples = audioManager?.GetSampleStore(storage); Textures = new TextureStore(new TextureLoaderStore(storage)); + + (storage as ResourceStore)?.AddExtension("ogg"); } } From 79f3249d370ab7f1d8d549fc61a31103e6ee2c84 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Feb 2020 13:40:50 +0900 Subject: [PATCH 39/42] Fix typo in method --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index cfe2a3abd2..8fdea8a4ef 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -418,7 +418,7 @@ namespace osu.Game.Rulesets.Catch.UI Explode(f); } - public void Drop(DrawableHitObject fruit) => removeFromPlatWithTransform(fruit, f => + public void Drop(DrawableHitObject fruit) => removeFromPlateWithTransform(fruit, f => { f.MoveToY(f.Y + 75, 750, Easing.InSine); f.FadeOut(750); @@ -428,7 +428,7 @@ namespace osu.Game.Rulesets.Catch.UI { var originalX = fruit.X * Scale.X; - removeFromPlatWithTransform(fruit, f => + removeFromPlateWithTransform(fruit, f => { f.MoveToY(f.Y - 50, 250, Easing.OutSine).Then().MoveToY(f.Y + 50, 500, Easing.InSine); f.MoveToX(f.X + originalX * 6, 1000); @@ -436,7 +436,7 @@ namespace osu.Game.Rulesets.Catch.UI }); } - private void removeFromPlatWithTransform(DrawableHitObject fruit, Action action) + private void removeFromPlateWithTransform(DrawableHitObject fruit, Action action) { if (ExplodingFruitTarget != null) { From b7849dd91acf398f7433519f1461702c4d185f65 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Feb 2020 18:47:21 +0900 Subject: [PATCH 40/42] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index cb044afcc6..b9b127309a 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -54,6 +54,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 5e78c69f4d..bd5219b872 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 351126e3b9..2c1aff7d3c 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From a1bfb18ce04fbd752c5d6f622893d7a21ad87f51 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Feb 2020 19:00:02 +0900 Subject: [PATCH 41/42] Fix accessing incorrect items list in event --- osu.Game/Rulesets/Objects/SliderPath.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs index ff5f1e3e1e..d577e8fdda 100644 --- a/osu.Game/Rulesets/Objects/SliderPath.cs +++ b/osu.Game/Rulesets/Objects/SliderPath.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Objects break; case NotifyCollectionChangedAction.Remove: - foreach (var c in args.NewItems.Cast()) + foreach (var c in args.OldItems.Cast()) c.Changed -= invalidate; break; } From 2f4c252fc09df0325c7c6d9c459222b3b395443b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Feb 2020 19:19:04 +0900 Subject: [PATCH 42/42] Fix playlist items potentially not updating to the correct selected state --- osu.Game/Overlays/Music/PlaylistItem.cs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 8cafbc694a..de2f916946 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -26,8 +26,9 @@ namespace osu.Game.Overlays.Music private TextFlowContainer text; private IEnumerable titleSprites; - private ILocalisedBindableString titleBind; - private ILocalisedBindableString artistBind; + + private ILocalisedBindableString title; + private ILocalisedBindableString artist; private Color4 selectedColour; private Color4 artistColour; @@ -47,24 +48,24 @@ namespace osu.Game.Overlays.Music artistColour = colours.Gray9; HandleColour = colours.Gray5; - titleBind = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.TitleUnicode, Model.Metadata.Title))); - artistBind = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.ArtistUnicode, Model.Metadata.Artist))); + title = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.TitleUnicode, Model.Metadata.Title))); + artist = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.ArtistUnicode, Model.Metadata.Artist))); } protected override void LoadComplete() { base.LoadComplete(); + artist.BindValueChanged(_ => recreateText(), true); + SelectedSet.BindValueChanged(set => { - if (set.OldValue != Model && set.NewValue != Model) + if (set.OldValue?.Equals(Model) != true && set.NewValue?.Equals(Model) != true) return; foreach (Drawable s in titleSprites) - s.FadeColour(set.NewValue == Model ? selectedColour : Color4.White, FADE_DURATION); + s.FadeColour(set.NewValue.Equals(Model) ? selectedColour : Color4.White, FADE_DURATION); }, true); - - artistBind.BindValueChanged(_ => recreateText(), true); } protected override Drawable CreateContent() => text = new OsuTextFlowContainer @@ -78,9 +79,9 @@ namespace osu.Game.Overlays.Music text.Clear(); //space after the title to put a space between the title and artist - titleSprites = text.AddText(titleBind.Value + @" ", sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular)).OfType(); + titleSprites = text.AddText(title.Value + @" ", sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular)).OfType(); - text.AddText(artistBind.Value, sprite => + text.AddText(artist.Value, sprite => { sprite.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); sprite.Colour = artistColour;