From af248457b02b9380c49dc09d8dd2085b9ebe7766 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 22:49:04 +0300 Subject: [PATCH 0001/1142] Implement OverlayRulesetSelector --- .../TestSceneOverlayRulesetSelector.cs | 68 +++++++++++++ osu.Game/Overlays/OverlayRulesetSelector.cs | 44 +++++++++ osu.Game/Overlays/OverlayRulesetTabItem.cs | 98 +++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs create mode 100644 osu.Game/Overlays/OverlayRulesetSelector.cs create mode 100644 osu.Game/Overlays/OverlayRulesetTabItem.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs new file mode 100644 index 0000000000..6c921b13b4 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -0,0 +1,68 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using System; +using System.Collections.Generic; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; +using osu.Framework.Bindables; +using osu.Game.Overlays; +using osu.Game.Rulesets; +using NUnit.Framework; +using osu.Game.Graphics; +using osu.Framework.Allocation; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneOverlayRulesetSelector : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(OverlayRulesetSelector), + typeof(OverlayRulesetTabItem), + }; + + private readonly OverlayRulesetSelector selector; + private readonly Bindable ruleset = new Bindable(); + + public TestSceneOverlayRulesetSelector() + { + Add(selector = new OverlayRulesetSelector + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Current = ruleset, + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + selector.AccentColour = colours.Lime; + } + + [Test] + public void TestSelection() + { + var osuRuleset = new OsuRuleset().RulesetInfo; + var maniaRuleset = new ManiaRuleset().RulesetInfo; + var taikoRuleset = new TaikoRuleset().RulesetInfo; + var catchRuleset = new CatchRuleset().RulesetInfo; + + AddStep("Select osu!", () => ruleset.Value = osuRuleset); + AddAssert("Check osu! selected", () => selector.Current.Value == osuRuleset); + + AddStep("Select mania", () => ruleset.Value = maniaRuleset); + AddAssert("Check mania selected", () => selector.Current.Value == maniaRuleset); + + AddStep("Select taiko", () => ruleset.Value = taikoRuleset); + AddAssert("Check taiko selected", () => selector.Current.Value == taikoRuleset); + + AddStep("Select catch", () => ruleset.Value = catchRuleset); + AddAssert("Check catch selected", () => selector.Current.Value == catchRuleset); + } + } +} diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs new file mode 100644 index 0000000000..1dcfc97562 --- /dev/null +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -0,0 +1,44 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Game.Rulesets; +using osuTK; +using osuTK.Graphics; +using System.Linq; + +namespace osu.Game.Overlays +{ + public class OverlayRulesetSelector : RulesetSelector + { + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + accentColour = value; + foreach (var i in TabContainer.Children.OfType()) + i.AccentColour = value; + } + } + + public OverlayRulesetSelector() + { + AutoSizeAxes = Axes.Both; + } + + protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); + + protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(25, 0), + }; + } +} diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs new file mode 100644 index 0000000000..9d6d28a81f --- /dev/null +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -0,0 +1,98 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; +using osuTK.Graphics; +using osuTK; + +namespace osu.Game.Overlays +{ + public class OverlayRulesetTabItem : TabItem, IHasAccentColour + { + protected readonly OsuSpriteText Text; + private readonly FillFlowContainer content; + + public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; + + private Color4 accentColour; + + public Color4 AccentColour + { + get => accentColour; + set + { + if (accentColour == value) + return; + + accentColour = value; + + UpdateState(); + } + } + + protected override Container Content => content; + + public OverlayRulesetTabItem(RulesetInfo value) + : base(value) + { + AutoSizeAxes = Axes.Both; + + AddRangeInternal(new Drawable[] + { + content = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Child = Text = new OsuSpriteText + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Text = value.Name, + } + }, + new HoverClickSounds() + }); + + Enabled.Value = true; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Enabled.BindValueChanged(_ => UpdateState(), true); + } + + 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(); + + protected virtual void UpdateState() + { + Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); + Text.FadeColour(GetColour(), 120, Easing.OutQuint); + } + + protected Color4 GetColour() => IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; + } +} From b016238c16f8ac0d8e2c6e97d1e2559c6c58930e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 22:55:28 +0300 Subject: [PATCH 0002/1142] Make ProfileRulesetSelector inherit from OverlayRulesetSelector --- .../Online/TestSceneProfileRulesetSelector.cs | 2 +- .../Components/ProfileRulesetSelector.cs | 33 +------ .../Components/ProfileRulesetTabItem.cs | 97 +++---------------- 3 files changed, 20 insertions(+), 112 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index 1f5ba67e03..a36b6880d2 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Online public TestSceneProfileRulesetSelector() { ProfileRulesetSelector selector; - Bindable user = new Bindable(); + var user = new Bindable(); Child = selector = new ProfileRulesetSelector { diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index 2c9a3dd5f9..e63102f989 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -3,37 +3,21 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; using osu.Game.Rulesets; using osu.Game.Users; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetSelector : RulesetSelector + public class ProfileRulesetSelector : OverlayRulesetSelector { - private Color4 accentColour = Color4.White; - public readonly Bindable User = new Bindable(); - public ProfileRulesetSelector() - { - TabContainer.Masking = false; - TabContainer.Spacing = new Vector2(10, 0); - AutoSizeAxes = Axes.Both; - } - [BackgroundDependencyLoader] private void load(OsuColour colours) { - accentColour = colours.Seafoam; - - foreach (TabItem tabItem in TabContainer) - ((ProfileRulesetTabItem)tabItem).AccentColour = accentColour; + AccentColour = colours.Seafoam; } protected override void LoadComplete() @@ -45,19 +29,10 @@ namespace osu.Game.Overlays.Profile.Header.Components public void SetDefaultRuleset(RulesetInfo ruleset) { - foreach (TabItem tabItem in TabContainer) + foreach (var tabItem in TabContainer) ((ProfileRulesetTabItem)tabItem).IsDefault = ((ProfileRulesetTabItem)tabItem).Value.ID == ruleset.ID; } - protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value) - { - AccentColour = accentColour - }; - - protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - }; + protected override TabItem CreateTabItem(RulesetInfo value) => new ProfileRulesetTabItem(value); } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index b5170ea3a2..adf324b259 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -2,38 +2,21 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -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 osu.Game.Rulesets; using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { - public class ProfileRulesetTabItem : TabItem, IHasAccentColour + public class ProfileRulesetTabItem : OverlayRulesetTabItem { - private readonly OsuSpriteText text; private readonly SpriteIcon icon; - private Color4 accentColour; - - public Color4 AccentColour + public new Color4 AccentColour { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - - updateState(); - } + get => base.AccentColour; + set => base.AccentColour = icon.Colour = value; } private bool isDefault; @@ -55,71 +38,21 @@ namespace osu.Game.Overlays.Profile.Header.Components public ProfileRulesetTabItem(RulesetInfo value) : base(value) { - AutoSizeAxes = Axes.Both; - - Children = new Drawable[] + Add(icon = new SpriteIcon { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Origin = Anchor.BottomLeft, - Anchor = Anchor.BottomLeft, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(3, 0), - Children = new Drawable[] - { - text = new OsuSpriteText - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Text = value.Name, - }, - icon = new SpriteIcon - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Alpha = 0, - AlwaysPresent = true, - Icon = FontAwesome.Solid.Star, - Size = new Vector2(12), - }, - } - }, - new HoverClickSounds() - }; + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Alpha = 0, + AlwaysPresent = true, + Icon = FontAwesome.Solid.Star, + Size = new Vector2(12), + }); } - protected override bool OnHover(HoverEvent e) + protected override void UpdateState() { - 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.Bold : FontWeight.Medium); - - if (IsHovered || Active.Value) - { - text.FadeColour(Color4.White, 120, Easing.InQuad); - icon.FadeColour(Color4.White, 120, Easing.InQuad); - } - else - { - text.FadeColour(AccentColour, 120, Easing.InQuad); - icon.FadeColour(AccentColour, 120, Easing.InQuad); - } + base.UpdateState(); + icon.FadeColour(GetColour(), 120, Easing.OutQuint); } } } From 2d6a07e970420893feea193e778f1ff3cc28e4f9 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 23:14:26 +0300 Subject: [PATCH 0003/1142] Fix OverlayRulesetSelector don't have default colour --- .../TestSceneOverlayRulesetSelector.cs | 35 +++++++++---------- osu.Game/Overlays/OverlayRulesetSelector.cs | 8 +++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs index 6c921b13b4..93aa414c94 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -25,6 +25,9 @@ namespace osu.Game.Tests.Visual.UserInterface typeof(OverlayRulesetTabItem), }; + [Resolved] + private OsuColour colours { get; set; } + private readonly OverlayRulesetSelector selector; private readonly Bindable ruleset = new Bindable(); @@ -38,31 +41,27 @@ namespace osu.Game.Tests.Visual.UserInterface }); } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - selector.AccentColour = colours.Lime; - } - [Test] public void TestSelection() { - var osuRuleset = new OsuRuleset().RulesetInfo; - var maniaRuleset = new ManiaRuleset().RulesetInfo; - var taikoRuleset = new TaikoRuleset().RulesetInfo; - var catchRuleset = new CatchRuleset().RulesetInfo; + AddStep("Select osu!", () => ruleset.Value = new OsuRuleset().RulesetInfo); + AddAssert("Check osu! selected", () => selector.Current.Value.Equals(new OsuRuleset().RulesetInfo)); - AddStep("Select osu!", () => ruleset.Value = osuRuleset); - AddAssert("Check osu! selected", () => selector.Current.Value == osuRuleset); + AddStep("Select mania", () => ruleset.Value = new ManiaRuleset().RulesetInfo); + AddAssert("Check mania selected", () => selector.Current.Value.Equals(new ManiaRuleset().RulesetInfo)); - AddStep("Select mania", () => ruleset.Value = maniaRuleset); - AddAssert("Check mania selected", () => selector.Current.Value == maniaRuleset); + AddStep("Select taiko", () => ruleset.Value = new TaikoRuleset().RulesetInfo); + AddAssert("Check taiko selected", () => selector.Current.Value.Equals(new TaikoRuleset().RulesetInfo)); - AddStep("Select taiko", () => ruleset.Value = taikoRuleset); - AddAssert("Check taiko selected", () => selector.Current.Value == taikoRuleset); + AddStep("Select catch", () => ruleset.Value = new CatchRuleset().RulesetInfo); + AddAssert("Check catch selected", () => selector.Current.Value.Equals(new CatchRuleset().RulesetInfo)); + } - AddStep("Select catch", () => ruleset.Value = catchRuleset); - AddAssert("Check catch selected", () => selector.Current.Value == catchRuleset); + [Test] + public void TestColours() + { + AddStep("Set colour to blue", () => selector.AccentColour = colours.Blue); + AddAssert("Check colour is blue", () => selector.AccentColour == colours.Blue); } } } diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index 1dcfc97562..da49335250 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.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 osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; @@ -32,6 +33,13 @@ namespace osu.Game.Overlays AutoSizeAxes = Axes.Both; } + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + if (accentColour == default) + AccentColour = colours.Pink; + } + protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer From 904b068a15c5bb55629d70c8bb5ca035a1d65649 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 2 Jan 2020 13:18:18 +0300 Subject: [PATCH 0004/1142] Simplify colour setting for additional elements in OverlayRulesetTabItem --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 23 +++++++++++-------- .../Components/ProfileRulesetTabItem.cs | 13 +---------- 2 files changed, 14 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 9d6d28a81f..e1cc1de8de 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -11,6 +11,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK.Graphics; using osuTK; +using System; namespace osu.Game.Overlays { @@ -33,10 +34,12 @@ namespace osu.Game.Overlays accentColour = value; - UpdateState(); + updateState(); } } + protected Action OnStateUpdated; + protected override Container Content => content; public OverlayRulesetTabItem(RulesetInfo value) @@ -67,32 +70,32 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); - Enabled.BindValueChanged(_ => UpdateState(), true); + Enabled.BindValueChanged(_ => updateState(), true); } protected override bool OnHover(HoverEvent e) { base.OnHover(e); - UpdateState(); + updateState(); return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - UpdateState(); + updateState(); } - protected override void OnActivated() => UpdateState(); + protected override void OnActivated() => updateState(); - protected override void OnDeactivated() => UpdateState(); + protected override void OnDeactivated() => updateState(); - protected virtual void UpdateState() + private void updateState() { + var updatedColour = IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - Text.FadeColour(GetColour(), 120, Easing.OutQuint); + Text.FadeColour(updatedColour, 120, Easing.OutQuint); + OnStateUpdated?.Invoke(updatedColour); } - - protected Color4 GetColour() => IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index adf324b259..d416e98b31 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -5,7 +5,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { @@ -13,12 +12,6 @@ namespace osu.Game.Overlays.Profile.Header.Components { private readonly SpriteIcon icon; - public new Color4 AccentColour - { - get => base.AccentColour; - set => base.AccentColour = icon.Colour = value; - } - private bool isDefault; public bool IsDefault @@ -47,12 +40,8 @@ namespace osu.Game.Overlays.Profile.Header.Components Icon = FontAwesome.Solid.Star, Size = new Vector2(12), }); - } - protected override void UpdateState() - { - base.UpdateState(); - icon.FadeColour(GetColour(), 120, Easing.OutQuint); + OnStateUpdated += colour => icon.FadeColour(colour, 120, Easing.OutQuint); } } } From 79a6655e1f6d64cb4246fc197560e607cccbbe87 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 3 Jan 2020 21:02:56 +0300 Subject: [PATCH 0005/1142] Use bindables for colour updates --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 31 +++++++++---------- .../Components/ProfileRulesetTabItem.cs | 12 +++++-- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index e1cc1de8de..bf24895306 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -11,7 +11,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK.Graphics; using osuTK; -using System; +using osu.Framework.Bindables; namespace osu.Game.Overlays { @@ -22,24 +22,15 @@ namespace osu.Game.Overlays public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; - private Color4 accentColour; + private readonly Bindable accentColour = new Bindable(); + private readonly Bindable currentColour = new Bindable(); public Color4 AccentColour { - get => accentColour; - set - { - if (accentColour == value) - return; - - accentColour = value; - - updateState(); - } + get => accentColour.Value; + set => accentColour.Value = value; } - protected Action OnStateUpdated; - protected override Container Content => content; public OverlayRulesetTabItem(RulesetInfo value) @@ -70,6 +61,9 @@ namespace osu.Game.Overlays protected override void LoadComplete() { base.LoadComplete(); + + currentColour.BindValueChanged(OnCurrentColourChanged); + accentColour.BindValueChanged(_ => updateState()); Enabled.BindValueChanged(_ => updateState(), true); } @@ -92,10 +86,13 @@ namespace osu.Game.Overlays private void updateState() { - var updatedColour = IsHovered || Active.Value ? Color4.White : Enabled.Value ? AccentColour : Color4.DimGray; Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - Text.FadeColour(updatedColour, 120, Easing.OutQuint); - OnStateUpdated?.Invoke(updatedColour); + + currentColour.Value = IsHovered || Active.Value + ? Color4.White + : Enabled.Value ? AccentColour : Color4.DimGray; } + + protected virtual void OnCurrentColourChanged(ValueChangedEvent colour) => Text.FadeColour(colour.NewValue, 120, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index d416e98b31..038509d371 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -1,17 +1,17 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets; using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { public class ProfileRulesetTabItem : OverlayRulesetTabItem { - private readonly SpriteIcon icon; - private bool isDefault; public bool IsDefault @@ -28,6 +28,8 @@ namespace osu.Game.Overlays.Profile.Header.Components } } + private readonly SpriteIcon icon; + public ProfileRulesetTabItem(RulesetInfo value) : base(value) { @@ -40,8 +42,12 @@ namespace osu.Game.Overlays.Profile.Header.Components Icon = FontAwesome.Solid.Star, Size = new Vector2(12), }); + } - OnStateUpdated += colour => icon.FadeColour(colour, 120, Easing.OutQuint); + protected override void OnCurrentColourChanged(ValueChangedEvent colour) + { + base.OnCurrentColourChanged(colour); + icon.FadeColour(colour.NewValue, 120, Easing.OutQuint); } } } From bd5140c3fa72b79d8f03b6e1eda6ccbd919e12f8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 3 Jan 2020 21:20:31 +0300 Subject: [PATCH 0006/1142] Add missing line breaks --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index bf24895306..91cf2d6b96 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -90,7 +90,9 @@ namespace osu.Game.Overlays currentColour.Value = IsHovered || Active.Value ? Color4.White - : Enabled.Value ? AccentColour : Color4.DimGray; + : Enabled.Value + ? AccentColour + : Color4.DimGray; } protected virtual void OnCurrentColourChanged(ValueChangedEvent colour) => Text.FadeColour(colour.NewValue, 120, Easing.OutQuint); From f65f030e79ff6756fe11156311e1bceaf95720f0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 15:48:54 +0300 Subject: [PATCH 0007/1142] Implement GetSpotlightsRequest --- .../API/Requests/GetSpotlightsRequest.cs | 13 +++++++ .../API/Requests/Responses/APISpotlight.cs | 34 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 osu.Game/Online/API/Requests/GetSpotlightsRequest.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APISpotlight.cs diff --git a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs new file mode 100644 index 0000000000..7a6a988c09 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs @@ -0,0 +1,13 @@ +// 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.Generic; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetSpotlightsRequest : APIRequest> + { + protected override string Target => "spotlights"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs new file mode 100644 index 0000000000..210ef04dac --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs @@ -0,0 +1,34 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APISpotlight + { + [JsonProperty("id")] + public int Id; + + [JsonProperty("name")] + public string Name; + + [JsonProperty("type")] + public string Type; + + [JsonProperty("mode_specific")] + public bool ModeSpecific; + + [JsonProperty(@"start_date")] + public DateTimeOffset StartDate; + + [JsonProperty(@"end_date")] + public DateTimeOffset EndDate; + + [JsonProperty(@"participant_count")] + public int? ParticipiantCount; + + public override string ToString() => Name; + } +} From 08fb68ddfeddb891b2ddc9972544a0bf6f2bff68 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 16:28:52 +0300 Subject: [PATCH 0008/1142] Fix incorrect return type for spotlight request --- osu.Game/Online/API/Requests/GetSpotlightsRequest.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs index 7a6a988c09..d5b03e52e2 100644 --- a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs +++ b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs @@ -2,12 +2,19 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using Newtonsoft.Json; using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetSpotlightsRequest : APIRequest> + public class GetSpotlightsRequest : APIRequest { protected override string Target => "spotlights"; } + + public class SpotlightsArray + { + [JsonProperty("spotlights")] + public List Spotlights; + } } From d48b161662ec0058d8f1aed526bb5fa1d9d1af50 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 16:33:00 +0300 Subject: [PATCH 0009/1142] Implement basic SpotlightSelector component --- .../TestSceneRankingsSpotlightSelector.cs | 28 ++++++++ .../Overlays/Rankings/SpotlightSelector.cs | 67 +++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs create mode 100644 osu.Game/Overlays/Rankings/SpotlightSelector.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs new file mode 100644 index 0000000000..9320213844 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -0,0 +1,28 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Game.Overlays.Rankings; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneRankingsSpotlightSelector : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(SpotlightSelector), + }; + + protected override bool UseOnlineAPI => true; + + public TestSceneRankingsSpotlightSelector() + { + SpotlightSelector selector; + + Add(selector = new SpotlightSelector()); + + AddStep("Fetch spotlights", selector.FetchSpotlights); + } + } +} diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs new file mode 100644 index 0000000000..95bcc10631 --- /dev/null +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -0,0 +1,67 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Overlays.Rankings +{ + public class SpotlightSelector : Container + { + private readonly Box background; + private readonly OsuDropdown dropdown; + private readonly DimmedLoadingLayer loading; + + [Resolved] + private IAPIProvider api { get; set; } + + public SpotlightSelector() + { + RelativeSizeAxes = Axes.X; + Height = 200; + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + dropdown = new OsuDropdown + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Width = 0.8f, + Margin = new MarginPadding { Top = 10 } + }, + loading = new DimmedLoadingLayer(), + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoam; + dropdown.AccentColour = colours.GreySeafoamDarker; + } + + public void FetchSpotlights() + { + loading.Show(); + + var request = new GetSpotlightsRequest(); + request.Success += response => + { + dropdown.Items = response.Spotlights; + loading.Hide(); + }; + api.Queue(request); + } + } +} From 474d7e92d92ef7a20dc07ee4a75cb2e62b5bd2e2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 16:41:17 +0300 Subject: [PATCH 0010/1142] Fix incorrect dropdown menu height --- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 95bcc10631..482db10796 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Rankings public class SpotlightSelector : Container { private readonly Box background; - private readonly OsuDropdown dropdown; + private readonly SpotlightsDropdown dropdown; private readonly DimmedLoadingLayer loading; [Resolved] @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Rankings { RelativeSizeAxes = Axes.Both, }, - dropdown = new OsuDropdown + dropdown = new SpotlightsDropdown { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -63,5 +63,10 @@ namespace osu.Game.Overlays.Rankings }; api.Queue(request); } + + private class SpotlightsDropdown : OsuDropdown + { + protected override DropdownMenu CreateMenu() => base.CreateMenu().With(menu => menu.MaxHeight = 400); + } } } From 2e627f4b7c4f52d827941399cf67fce87087ebc3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 17:30:51 +0300 Subject: [PATCH 0011/1142] Implement InfoColumn component --- .../Overlays/Rankings/SpotlightSelector.cs | 111 ++++++++++++++++-- 1 file changed, 102 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 482db10796..66c5f37917 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -2,14 +2,18 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osuTK; +using System; namespace osu.Game.Overlays.Rankings { @@ -22,23 +26,49 @@ namespace osu.Game.Overlays.Rankings [Resolved] private IAPIProvider api { get; set; } + public readonly Bindable SelectedSpotlight = new Bindable(); + + private readonly InfoCoulmn startDateColumn; + private readonly InfoCoulmn endDateColumn; + public SpotlightSelector() { RelativeSizeAxes = Axes.X; - Height = 200; + Height = 100; Children = new Drawable[] { background = new Box { RelativeSizeAxes = Axes.Both, }, - dropdown = new SpotlightsDropdown + new Container { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Width = 0.8f, - Margin = new MarginPadding { Top = 10 } + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Children = new Drawable[] + { + dropdown = new SpotlightsDropdown + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Current = SelectedSpotlight, + Depth = -float.MaxValue + }, + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(15, 0), + Children = new Drawable[] + { + startDateColumn = new InfoCoulmn(@"Start Date"), + endDateColumn = new InfoCoulmn(@"End Date"), + } + } + } }, loading = new DimmedLoadingLayer(), }; @@ -48,7 +78,12 @@ namespace osu.Game.Overlays.Rankings private void load(OsuColour colours) { background.Colour = colours.GreySeafoam; - dropdown.AccentColour = colours.GreySeafoamDarker; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + SelectedSpotlight.BindValueChanged(onSelectionChanged); } public void FetchSpotlights() @@ -64,9 +99,67 @@ namespace osu.Game.Overlays.Rankings api.Queue(request); } + private void onSelectionChanged(ValueChangedEvent spotlight) + { + startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); + endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); + } + + private string dateToString(DateTimeOffset date) => $"{date.Year}-{date.Month:D2}-{date.Day:D2}"; + + private class InfoCoulmn : FillFlowContainer + { + public string Value + { + set => valueText.Text = value; + } + + private readonly OsuSpriteText valueText; + + public InfoCoulmn(string name) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Vertical; + Children = new Drawable[] + { + new OsuSpriteText + { + Text = name, + Font = OsuFont.GetFont(size: 10), + }, + new Container + { + AutoSizeAxes = Axes.X, + Height = 20, + Child = valueText = new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Light), + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + valueText.Colour = colours.GreySeafoamLighter; + } + } + private class SpotlightsDropdown : OsuDropdown { - protected override DropdownMenu CreateMenu() => base.CreateMenu().With(menu => menu.MaxHeight = 400); + private DropdownMenu menu; + + protected override DropdownMenu CreateMenu() => menu = base.CreateMenu().With(m => m.MaxHeight = 400); + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + menu.BackgroundColour = colours.Gray1; + AccentColour = colours.GreySeafoamDarker; + } } } } From 9260ea91955fdcf56e4edbbb3770e39ac0eb21a0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 10 Jan 2020 20:46:35 +0300 Subject: [PATCH 0012/1142] Apply suggestions --- .../Online/API/Requests/GetSpotlightsRequest.cs | 4 ++-- .../Online/API/Requests/Responses/APISpotlight.cs | 2 +- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs index d5b03e52e2..6fafb3933c 100644 --- a/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs +++ b/osu.Game/Online/API/Requests/GetSpotlightsRequest.cs @@ -7,12 +7,12 @@ using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetSpotlightsRequest : APIRequest + public class GetSpotlightsRequest : APIRequest { protected override string Target => "spotlights"; } - public class SpotlightsArray + public class SpotlightsCollection { [JsonProperty("spotlights")] public List Spotlights; diff --git a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs index 210ef04dac..63c47e7812 100644 --- a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs +++ b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs @@ -27,7 +27,7 @@ namespace osu.Game.Online.API.Requests.Responses public DateTimeOffset EndDate; [JsonProperty(@"participant_count")] - public int? ParticipiantCount; + public int? ParticipantCount; public override string ToString() => Name; } diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 66c5f37917..fb61555c20 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -28,8 +28,8 @@ namespace osu.Game.Overlays.Rankings public readonly Bindable SelectedSpotlight = new Bindable(); - private readonly InfoCoulmn startDateColumn; - private readonly InfoCoulmn endDateColumn; + private readonly InfoColumn startDateColumn; + private readonly InfoColumn endDateColumn; public SpotlightSelector() { @@ -64,8 +64,8 @@ namespace osu.Game.Overlays.Rankings Spacing = new Vector2(15, 0), Children = new Drawable[] { - startDateColumn = new InfoCoulmn(@"Start Date"), - endDateColumn = new InfoCoulmn(@"End Date"), + startDateColumn = new InfoColumn(@"Start Date"), + endDateColumn = new InfoColumn(@"End Date"), } } } @@ -105,9 +105,9 @@ namespace osu.Game.Overlays.Rankings endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); } - private string dateToString(DateTimeOffset date) => $"{date.Year}-{date.Month:D2}-{date.Day:D2}"; + private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); - private class InfoCoulmn : FillFlowContainer + private class InfoColumn : FillFlowContainer { public string Value { @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.Rankings private readonly OsuSpriteText valueText; - public InfoCoulmn(string name) + public InfoColumn(string name) { AutoSizeAxes = Axes.Both; Direction = FillDirection.Vertical; From e1eda89ea69234164ae055d1f129626d8fc970f7 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 8 Jan 2020 17:41:44 +0100 Subject: [PATCH 0013/1142] Implement OnlineContainer --- osu.Game/Online/OnlineContainer.cs | 76 ++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 osu.Game/Online/OnlineContainer.cs diff --git a/osu.Game/Online/OnlineContainer.cs b/osu.Game/Online/OnlineContainer.cs new file mode 100644 index 0000000000..6ab5203fe6 --- /dev/null +++ b/osu.Game/Online/OnlineContainer.cs @@ -0,0 +1,76 @@ +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.API; +using osu.Game.Online.Placeholders; + +namespace osu.Game.Online +{ + /// + /// A for dislaying online content who require a local user to be logged in. + /// Shows its children only when the local user is logged in and supports displaying a placeholder if not. + /// + public class OnlineViewContainer : Container, IOnlineComponent + { + private readonly Container content; + private readonly Container placeholderContainer; + private readonly Placeholder placeholder; + + private const int transform_time = 300; + + protected override Container Content => content; + + public OnlineViewContainer(string placeholder_message) + { + InternalChildren = new Drawable[] + { + content = new Container + { + RelativeSizeAxes = Axes.Both, + }, + placeholderContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Child = placeholder = new LoginPlaceholder() + }, + }; + } + + public void APIStateChanged(IAPIProvider api, APIState state) + { + switch (state) + { + case APIState.Offline: + case APIState.Connecting: + Schedule(() =>updatePlaceholderVisibility(true)); + break; + + default: + Schedule(() => updatePlaceholderVisibility(false)); + break; + } + } + + private void updatePlaceholderVisibility(bool show_placeholder) + { + if (show_placeholder) + { + content.FadeOut(transform_time / 2, Easing.OutQuint); + placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_time, Easing.OutQuint); + placeholderContainer.FadeInFromZero(2 * transform_time, Easing.OutQuint); + } + else + { + placeholderContainer.FadeOut(transform_time / 2, Easing.OutQuint); + content.FadeIn(transform_time, Easing.OutQuint); + } + } + + [BackgroundDependencyLoader] + private void load(IAPIProvider api) + { + api.Register(this); + } + } +} From e9a52984845e9a39cab5a5dd09081aa7045d6436 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 12 Jan 2020 15:50:35 +0100 Subject: [PATCH 0014/1142] Allow setting the displayed text on LoginPlaceholder --- osu.Game/Online/Leaderboards/Leaderboard.cs | 2 +- osu.Game/Online/OnlineContainer.cs | 2 +- osu.Game/Online/Placeholders/LoginPlaceholder.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 55233bef6e..095e552ddd 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -151,7 +151,7 @@ namespace osu.Game.Online.Leaderboards break; case PlaceholderState.NotLoggedIn: - replacePlaceholder(new LoginPlaceholder()); + replacePlaceholder(new LoginPlaceholder(@"Please sign in to view online leaderboards!")); break; case PlaceholderState.NotSupporter: diff --git a/osu.Game/Online/OnlineContainer.cs b/osu.Game/Online/OnlineContainer.cs index 6ab5203fe6..6a8963599f 100644 --- a/osu.Game/Online/OnlineContainer.cs +++ b/osu.Game/Online/OnlineContainer.cs @@ -32,7 +32,7 @@ namespace osu.Game.Online { RelativeSizeAxes = Axes.Both, Alpha = 0, - Child = placeholder = new LoginPlaceholder() + Child = placeholder = new LoginPlaceholder(placeholder_message) }, }; } diff --git a/osu.Game/Online/Placeholders/LoginPlaceholder.cs b/osu.Game/Online/Placeholders/LoginPlaceholder.cs index ffc6623229..f3b5a86785 100644 --- a/osu.Game/Online/Placeholders/LoginPlaceholder.cs +++ b/osu.Game/Online/Placeholders/LoginPlaceholder.cs @@ -14,7 +14,7 @@ namespace osu.Game.Online.Placeholders [Resolved(CanBeNull = true)] private LoginOverlay login { get; set; } - public LoginPlaceholder() + public LoginPlaceholder(string actionMessage) { AddIcon(FontAwesome.Solid.UserLock, cp => { @@ -22,7 +22,7 @@ namespace osu.Game.Online.Placeholders cp.Padding = new MarginPadding { Right = 10 }; }); - AddText(@"Please sign in to view online leaderboards!"); + AddText(actionMessage); } protected override bool OnMouseDown(MouseDownEvent e) From 8f6c6ad77a6198c8954195e656099b6fc4450732 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 12 Jan 2020 17:43:44 +0100 Subject: [PATCH 0015/1142] Fix class name not corresponding to filename --- osu.Game/Online/{OnlineContainer.cs => OnlineViewContainer.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename osu.Game/Online/{OnlineContainer.cs => OnlineViewContainer.cs} (100%) diff --git a/osu.Game/Online/OnlineContainer.cs b/osu.Game/Online/OnlineViewContainer.cs similarity index 100% rename from osu.Game/Online/OnlineContainer.cs rename to osu.Game/Online/OnlineViewContainer.cs From 90e4def4bd0d782f24b4d987639f33a1388fe621 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 14 Jan 2020 07:07:21 +0300 Subject: [PATCH 0016/1142] Remove online stuff out of the selector --- .../TestSceneRankingsSpotlightSelector.cs | 18 ++++++-- .../Overlays/Rankings/SpotlightSelector.cs | 45 +++++++------------ 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index 9320213844..0862b3251a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Rankings; namespace osu.Game.Tests.Visual.Online @@ -14,15 +15,26 @@ namespace osu.Game.Tests.Visual.Online typeof(SpotlightSelector), }; - protected override bool UseOnlineAPI => true; - public TestSceneRankingsSpotlightSelector() { SpotlightSelector selector; Add(selector = new SpotlightSelector()); - AddStep("Fetch spotlights", selector.FetchSpotlights); + var spotlights = new APISpotlight[] + { + new APISpotlight { Name = "Spotlight 1" }, + new APISpotlight { Name = "Spotlight 2" }, + new APISpotlight { Name = "Spotlight 3" }, + }; + + AddStep("Load spotlights", () => selector.Spotlights = spotlights); + AddStep("Load info", () => selector.UpdateInfo(new APISpotlight + { + StartDate = DateTimeOffset.Now, + EndDate = DateTimeOffset.Now, + ParticipantCount = 15155151, + }, 18)); } } } diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index fb61555c20..a275f4ed50 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -9,11 +9,10 @@ using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osuTK; using System; +using System.Collections.Generic; namespace osu.Game.Overlays.Rankings { @@ -21,15 +20,19 @@ namespace osu.Game.Overlays.Rankings { private readonly Box background; private readonly SpotlightsDropdown dropdown; - private readonly DimmedLoadingLayer loading; - - [Resolved] - private IAPIProvider api { get; set; } public readonly Bindable SelectedSpotlight = new Bindable(); + public IEnumerable Spotlights + { + get => dropdown.Items; + set => dropdown.Items = value; + } + private readonly InfoColumn startDateColumn; private readonly InfoColumn endDateColumn; + private readonly InfoColumn mapCountColumn; + private readonly InfoColumn participants; public SpotlightSelector() { @@ -66,11 +69,12 @@ namespace osu.Game.Overlays.Rankings { startDateColumn = new InfoColumn(@"Start Date"), endDateColumn = new InfoColumn(@"End Date"), + mapCountColumn = new InfoColumn(@"Map Count"), + participants = new InfoColumn(@"Participants"), } } } }, - loading = new DimmedLoadingLayer(), }; } @@ -80,29 +84,12 @@ namespace osu.Game.Overlays.Rankings background.Colour = colours.GreySeafoam; } - protected override void LoadComplete() + public void UpdateInfo(APISpotlight spotlight, int mapCount) { - base.LoadComplete(); - SelectedSpotlight.BindValueChanged(onSelectionChanged); - } - - public void FetchSpotlights() - { - loading.Show(); - - var request = new GetSpotlightsRequest(); - request.Success += response => - { - dropdown.Items = response.Spotlights; - loading.Hide(); - }; - api.Queue(request); - } - - private void onSelectionChanged(ValueChangedEvent spotlight) - { - startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); - endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); + startDateColumn.Value = dateToString(spotlight.StartDate); + endDateColumn.Value = dateToString(spotlight.EndDate); + mapCountColumn.Value = mapCount.ToString(); + participants.Value = spotlight.ParticipantCount?.ToString("N0"); } private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); From 18ebd309788124c12ae3d5bf8388f97e4822939c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 14 Jan 2020 07:20:03 +0300 Subject: [PATCH 0017/1142] CI fix --- .../Visual/Online/TestSceneRankingsSpotlightSelector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index 0862b3251a..1a62cb6dad 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online Add(selector = new SpotlightSelector()); - var spotlights = new APISpotlight[] + var spotlights = new[] { new APISpotlight { Name = "Spotlight 1" }, new APISpotlight { Name = "Spotlight 2" }, From 7349c023d1b9696559d5190469024544d064204a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Jan 2020 14:01:51 +0900 Subject: [PATCH 0018/1142] Cleanup spotlight selection --- .../TestSceneRankingsSpotlightSelector.cs | 4 +-- .../API/Requests/Responses/APISpotlight.cs | 2 +- .../Overlays/Rankings/SpotlightSelector.cs | 30 ++++++++++++++----- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index 1a62cb6dad..d714d5fb7d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -29,12 +29,12 @@ namespace osu.Game.Tests.Visual.Online }; AddStep("Load spotlights", () => selector.Spotlights = spotlights); - AddStep("Load info", () => selector.UpdateInfo(new APISpotlight + AddStep("Load info", () => selector.Current.Value = new APISpotlight { StartDate = DateTimeOffset.Now, EndDate = DateTimeOffset.Now, ParticipantCount = 15155151, - }, 18)); + }); } } } diff --git a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs index 63c47e7812..2191ed4743 100644 --- a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs +++ b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs @@ -27,7 +27,7 @@ namespace osu.Game.Online.API.Requests.Responses public DateTimeOffset EndDate; [JsonProperty(@"participant_count")] - public int? ParticipantCount; + public int ParticipantCount; public override string ToString() => Name; } diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index a275f4ed50..def7469b16 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -13,15 +13,22 @@ using osu.Game.Online.API.Requests.Responses; using osuTK; using System; using System.Collections.Generic; +using osu.Framework.Graphics.UserInterface; namespace osu.Game.Overlays.Rankings { - public class SpotlightSelector : Container + public class SpotlightSelector : Container, IHasCurrentValue { private readonly Box background; private readonly SpotlightsDropdown dropdown; - public readonly Bindable SelectedSpotlight = new Bindable(); + private readonly BindableWithCurrent current = new BindableWithCurrent(); + + public Bindable Current + { + get => current.Current; + set => current.Current = value; + } public IEnumerable Spotlights { @@ -55,7 +62,7 @@ namespace osu.Game.Overlays.Rankings Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, - Current = SelectedSpotlight, + Current = Current, Depth = -float.MaxValue }, new FillFlowContainer @@ -84,12 +91,19 @@ namespace osu.Game.Overlays.Rankings background.Colour = colours.GreySeafoam; } - public void UpdateInfo(APISpotlight spotlight, int mapCount) + protected override void LoadComplete() { - startDateColumn.Value = dateToString(spotlight.StartDate); - endDateColumn.Value = dateToString(spotlight.EndDate); - mapCountColumn.Value = mapCount.ToString(); - participants.Value = spotlight.ParticipantCount?.ToString("N0"); + base.LoadComplete(); + + Current.BindValueChanged(onCurrentChanged); + } + + private void onCurrentChanged(ValueChangedEvent spotlight) + { + startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); + endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); + // mapCountColumn.Value = spotlight.NewValue.ParticipantCount.ToString(); + participants.Value = spotlight.NewValue.ParticipantCount.ToString(); } private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); From cb1984a3c3f7b23b0c76465be334b89596edbd41 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Jan 2020 14:37:14 +0900 Subject: [PATCH 0019/1142] Improve test scene data --- .../TestSceneRankingsSpotlightSelector.cs | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index d714d5fb7d..c3df1f055b 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -3,6 +3,10 @@ using System; using System.Collections.Generic; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Rankings; @@ -15,25 +19,67 @@ namespace osu.Game.Tests.Visual.Online typeof(SpotlightSelector), }; + protected override bool UseOnlineAPI => true; + + [Resolved] + private IAPIProvider api { get; set; } + + private readonly SpotlightSelector selector; + public TestSceneRankingsSpotlightSelector() { - SpotlightSelector selector; - Add(selector = new SpotlightSelector()); + } + [Test] + public void TestLocalSpotlights() + { var spotlights = new[] { - new APISpotlight { Name = "Spotlight 1" }, - new APISpotlight { Name = "Spotlight 2" }, - new APISpotlight { Name = "Spotlight 3" }, + new APISpotlight + { + Name = "Spotlight 1", + StartDate = DateTimeOffset.Now, + EndDate = DateTimeOffset.Now, + ParticipantCount = 100 + }, + new APISpotlight + { + Name = "Spotlight 2", + StartDate = DateTimeOffset.Now, + EndDate = DateTimeOffset.Now, + ParticipantCount = 200 + }, + new APISpotlight + { + Name = "Spotlight 3", + StartDate = DateTimeOffset.Now, + EndDate = DateTimeOffset.Now, + ParticipantCount = 300 + }, }; - AddStep("Load spotlights", () => selector.Spotlights = spotlights); - AddStep("Load info", () => selector.Current.Value = new APISpotlight + AddStep("load spotlights", () => selector.Spotlights = spotlights); + AddStep("change to spotlight 3", () => selector.Current.Value = spotlights[2]); + } + + [Test] + public void TestOnlineSpotlights() + { + List spotlights = null; + + AddStep("retrieve spotlights", () => { - StartDate = DateTimeOffset.Now, - EndDate = DateTimeOffset.Now, - ParticipantCount = 15155151, + var req = new GetSpotlightsRequest(); + req.Success += res => spotlights = res.Spotlights; + + api.Perform(req); + }); + + AddStep("set spotlights", () => + { + if (spotlights != null) + selector.Spotlights = spotlights; }); } } From 05702af9054797578deebf03f3ab654d653035d4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Jan 2020 14:37:24 +0900 Subject: [PATCH 0020/1142] Remove map count (not returned by API) --- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index def7469b16..d6efff626d 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -38,7 +38,6 @@ namespace osu.Game.Overlays.Rankings private readonly InfoColumn startDateColumn; private readonly InfoColumn endDateColumn; - private readonly InfoColumn mapCountColumn; private readonly InfoColumn participants; public SpotlightSelector() @@ -76,7 +75,6 @@ namespace osu.Game.Overlays.Rankings { startDateColumn = new InfoColumn(@"Start Date"), endDateColumn = new InfoColumn(@"End Date"), - mapCountColumn = new InfoColumn(@"Map Count"), participants = new InfoColumn(@"Participants"), } } @@ -102,7 +100,6 @@ namespace osu.Game.Overlays.Rankings { startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); - // mapCountColumn.Value = spotlight.NewValue.ParticipantCount.ToString(); participants.Value = spotlight.NewValue.ParticipantCount.ToString(); } From 33993837b7f175421c0b34cbdff0ac0e36d962d2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Jan 2020 14:41:38 +0900 Subject: [PATCH 0021/1142] Remove participant count (not returned by API) --- .../Visual/Online/TestSceneRankingsSpotlightSelector.cs | 3 --- osu.Game/Online/API/Requests/Responses/APISpotlight.cs | 3 --- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 3 --- 3 files changed, 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index c3df1f055b..009fe7cc8c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -41,21 +41,18 @@ namespace osu.Game.Tests.Visual.Online Name = "Spotlight 1", StartDate = DateTimeOffset.Now, EndDate = DateTimeOffset.Now, - ParticipantCount = 100 }, new APISpotlight { Name = "Spotlight 2", StartDate = DateTimeOffset.Now, EndDate = DateTimeOffset.Now, - ParticipantCount = 200 }, new APISpotlight { Name = "Spotlight 3", StartDate = DateTimeOffset.Now, EndDate = DateTimeOffset.Now, - ParticipantCount = 300 }, }; diff --git a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs index 2191ed4743..3a002e57b2 100644 --- a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs +++ b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs @@ -26,9 +26,6 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"end_date")] public DateTimeOffset EndDate; - [JsonProperty(@"participant_count")] - public int ParticipantCount; - public override string ToString() => Name; } } diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index d6efff626d..c538a80786 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -38,7 +38,6 @@ namespace osu.Game.Overlays.Rankings private readonly InfoColumn startDateColumn; private readonly InfoColumn endDateColumn; - private readonly InfoColumn participants; public SpotlightSelector() { @@ -75,7 +74,6 @@ namespace osu.Game.Overlays.Rankings { startDateColumn = new InfoColumn(@"Start Date"), endDateColumn = new InfoColumn(@"End Date"), - participants = new InfoColumn(@"Participants"), } } } @@ -100,7 +98,6 @@ namespace osu.Game.Overlays.Rankings { startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); - participants.Value = spotlight.NewValue.ParticipantCount.ToString(); } private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); From d6bd0b7106b215441348b1192979d9611677abf7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 14 Jan 2020 14:43:57 +0900 Subject: [PATCH 0022/1142] Container -> CompositeDrawable --- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index c538a80786..4da3daa62a 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -17,7 +17,7 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Overlays.Rankings { - public class SpotlightSelector : Container, IHasCurrentValue + public class SpotlightSelector : CompositeDrawable, IHasCurrentValue { private readonly Box background; private readonly SpotlightsDropdown dropdown; @@ -43,7 +43,8 @@ namespace osu.Game.Overlays.Rankings { RelativeSizeAxes = Axes.X; Height = 100; - Children = new Drawable[] + + InternalChildren = new Drawable[] { background = new Box { From 0422b326ad3faa719ba34852a4d80e3b22ce273d Mon Sep 17 00:00:00 2001 From: Lucas A Date: Mon, 13 Jan 2020 21:12:19 +0100 Subject: [PATCH 0023/1142] Add visual tests --- .../Online/TestSceneOnlineViewContainer.cs | 75 +++++++++++++++++++ osu.Game/Online/API/DummyAPIAccess.cs | 2 +- osu.Game/Online/OnlineViewContainer.cs | 25 ++++--- 3 files changed, 90 insertions(+), 12 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs new file mode 100644 index 0000000000..a8c50a37e7 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -0,0 +1,75 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Sprites; +using osu.Game.Online; +using osu.Game.Online.API; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestSceneOnlineViewContainer : OsuTestScene + { + private OnlineViewContainer onlineView; + private Box box; + + public TestSceneOnlineViewContainer() + { + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Child = onlineView = new OnlineViewContainer(@"Please login to view dummy test content") + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + box = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Blue.Opacity(0.8f), + }, + new OsuSpriteText + { + Text = "dummy online content", + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + } + } + }; + } + + [BackgroundDependencyLoader] + private void load() + { + AddStep("set status to offline", () => + { + (API as DummyAPIAccess).State = APIState.Offline; + }); + + AddAssert("children are hidden", () => + { + return !onlineView.Children.First().Parent.IsPresent; + }); + + AddStep("set status to online", () => + { + (API as DummyAPIAccess).State = APIState.Online; + }); + + AddAssert("children are visible", () => + { + return onlineView.Children.First().Parent.IsPresent; + }); + } + } +} diff --git a/osu.Game/Online/API/DummyAPIAccess.cs b/osu.Game/Online/API/DummyAPIAccess.cs index 7f23f9b5d5..a1c3475fd9 100644 --- a/osu.Game/Online/API/DummyAPIAccess.cs +++ b/osu.Game/Online/API/DummyAPIAccess.cs @@ -33,7 +33,7 @@ namespace osu.Game.Online.API public APIState State { get => state; - private set + set { if (state == value) return; diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 6a8963599f..a7f81b4776 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -1,4 +1,7 @@ -using osu.Framework.Allocation; +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.API; @@ -20,7 +23,7 @@ namespace osu.Game.Online protected override Container Content => content; - public OnlineViewContainer(string placeholder_message) + public OnlineViewContainer(string placeholderMessage) { InternalChildren = new Drawable[] { @@ -32,7 +35,7 @@ namespace osu.Game.Online { RelativeSizeAxes = Axes.Both, Alpha = 0, - Child = placeholder = new LoginPlaceholder(placeholder_message) + Child = placeholder = new LoginPlaceholder(placeholderMessage) }, }; } @@ -43,7 +46,7 @@ namespace osu.Game.Online { case APIState.Offline: case APIState.Connecting: - Schedule(() =>updatePlaceholderVisibility(true)); + Schedule(() => updatePlaceholderVisibility(true)); break; default: @@ -52,18 +55,18 @@ namespace osu.Game.Online } } - private void updatePlaceholderVisibility(bool show_placeholder) + private void updatePlaceholderVisibility(bool showPlaceholder) { - if (show_placeholder) + if (showPlaceholder) { - content.FadeOut(transform_time / 2, Easing.OutQuint); - placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_time, Easing.OutQuint); - placeholderContainer.FadeInFromZero(2 * transform_time, Easing.OutQuint); + content.FadeOut(transform_time / 2, Easing.OutQuint); + placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_time, Easing.OutQuint); + placeholderContainer.FadeInFromZero(2 * transform_time, Easing.OutQuint); } else { - placeholderContainer.FadeOut(transform_time / 2, Easing.OutQuint); - content.FadeIn(transform_time, Easing.OutQuint); + placeholderContainer.FadeOut(transform_time / 2, Easing.OutQuint); + content.FadeIn(transform_time, Easing.OutQuint); } } From f00938971eda2ba95c451792a6ce56234f073532 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 17 Jan 2020 18:53:17 +0100 Subject: [PATCH 0024/1142] Apply review suggestions --- .../Online/TestSceneOnlineViewContainer.cs | 2 +- osu.Game/Online/OnlineViewContainer.cs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index a8c50a37e7..9b7de2b7f4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual.Online Child = new Container { RelativeSizeAxes = Axes.Both, - Child = onlineView = new OnlineViewContainer(@"Please login to view dummy test content") + Child = onlineView = new OnlineViewContainer(@"view dummy test content") { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index a7f81b4776..ac3a3edd67 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -23,6 +23,9 @@ namespace osu.Game.Online protected override Container Content => content; + [Resolved] + protected IAPIProvider API { get; private set; } + public OnlineViewContainer(string placeholderMessage) { InternalChildren = new Drawable[] @@ -35,12 +38,12 @@ namespace osu.Game.Online { RelativeSizeAxes = Axes.Both, Alpha = 0, - Child = placeholder = new LoginPlaceholder(placeholderMessage) + Child = placeholder = new LoginPlaceholder($@"Please sign in to {placeholderMessage}") }, }; } - public void APIStateChanged(IAPIProvider api, APIState state) + public virtual void APIStateChanged(IAPIProvider api, APIState state) { switch (state) { @@ -70,10 +73,16 @@ namespace osu.Game.Online } } - [BackgroundDependencyLoader] - private void load(IAPIProvider api) + protected override void LoadComplete() { - api.Register(this); + API?.Register(this); + base.LoadComplete(); + } + + protected override void Dispose(bool isDisposing) + { + API?.Unregister(this); + base.Dispose(isDisposing); } } } From e1f172e3f820c88b481f546b49752a71a1b754bc Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 17 Jan 2020 19:29:42 +0100 Subject: [PATCH 0025/1142] Fix CI issues --- .../Online/TestSceneOnlineViewContainer.cs | 25 +++++-------------- osu.Game/Online/OnlineViewContainer.cs | 4 +-- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index 9b7de2b7f4..4579e4f428 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -18,8 +18,7 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneOnlineViewContainer : OsuTestScene { - private OnlineViewContainer onlineView; - private Box box; + private readonly OnlineViewContainer onlineView; public TestSceneOnlineViewContainer() { @@ -31,7 +30,7 @@ namespace osu.Game.Tests.Visual.Online RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - box = new Box + new Box { RelativeSizeAxes = Axes.Both, Colour = Color4.Blue.Opacity(0.8f), @@ -51,25 +50,13 @@ namespace osu.Game.Tests.Visual.Online [BackgroundDependencyLoader] private void load() { - AddStep("set status to offline", () => - { - (API as DummyAPIAccess).State = APIState.Offline; - }); + AddStep("set status to offline", () => ((DummyAPIAccess)API).State = APIState.Offline); - AddAssert("children are hidden", () => - { - return !onlineView.Children.First().Parent.IsPresent; - }); + AddAssert("children are hidden", () => !onlineView.Children.First().Parent.IsPresent); - AddStep("set status to online", () => - { - (API as DummyAPIAccess).State = APIState.Online; - }); + AddStep("set status to online", () => ((DummyAPIAccess)API).State = APIState.Online); - AddAssert("children are visible", () => - { - return onlineView.Children.First().Parent.IsPresent; - }); + AddAssert("children are visible", () => onlineView.Children.First().Parent.IsPresent); } } } diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index ac3a3edd67..0a8432ee12 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -62,13 +62,13 @@ namespace osu.Game.Online { if (showPlaceholder) { - content.FadeOut(transform_time / 2, Easing.OutQuint); + content.FadeOut(150, Easing.OutQuint); placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_time, Easing.OutQuint); placeholderContainer.FadeInFromZero(2 * transform_time, Easing.OutQuint); } else { - placeholderContainer.FadeOut(transform_time / 2, Easing.OutQuint); + placeholderContainer.FadeOut(150, Easing.OutQuint); content.FadeIn(transform_time, Easing.OutQuint); } } From 11e7c8be3f3f3da461a65a22d1be2b5ec8017a7d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 20 Jan 2020 08:34:46 +0300 Subject: [PATCH 0026/1142] Use colour schemes for OverlayRulesetSelector --- .../Online/TestSceneProfileRulesetSelector.cs | 3 +- .../TestSceneOverlayRulesetSelector.cs | 28 ++++++++++--------- osu.Game/Overlays/OverlayRulesetSelector.cs | 9 ++++-- .../Components/ProfileRulesetSelector.cs | 7 ++--- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index a36b6880d2..1a9dca51c9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -11,6 +11,7 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Taiko; using osu.Game.Users; using osu.Framework.Bindables; +using osu.Game.Graphics; namespace osu.Game.Tests.Visual.Online { @@ -27,7 +28,7 @@ namespace osu.Game.Tests.Visual.Online ProfileRulesetSelector selector; var user = new Bindable(); - Child = selector = new ProfileRulesetSelector + Child = selector = new ProfileRulesetSelector(OverlayColourScheme.Green) { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs index 93aa414c94..bc5f66da0b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -13,7 +13,8 @@ using osu.Game.Overlays; using osu.Game.Rulesets; using NUnit.Framework; using osu.Game.Graphics; -using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osuTK; namespace osu.Game.Tests.Visual.UserInterface { @@ -25,19 +26,27 @@ namespace osu.Game.Tests.Visual.UserInterface typeof(OverlayRulesetTabItem), }; - [Resolved] - private OsuColour colours { get; set; } - private readonly OverlayRulesetSelector selector; private readonly Bindable ruleset = new Bindable(); public TestSceneOverlayRulesetSelector() { - Add(selector = new OverlayRulesetSelector + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Current = ruleset, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new[] + { + selector = new OverlayRulesetSelector(OverlayColourScheme.Green) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Blue) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Orange) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Pink) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Purple) { Current = ruleset }, + new OverlayRulesetSelector(OverlayColourScheme.Red) { Current = ruleset } + } }); } @@ -56,12 +65,5 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Select catch", () => ruleset.Value = new CatchRuleset().RulesetInfo); AddAssert("Check catch selected", () => selector.Current.Value.Equals(new CatchRuleset().RulesetInfo)); } - - [Test] - public void TestColours() - { - AddStep("Set colour to blue", () => selector.AccentColour = colours.Blue); - AddAssert("Check colour is blue", () => selector.AccentColour == colours.Blue); - } } } diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index da49335250..b70d6a08f2 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -28,16 +28,19 @@ namespace osu.Game.Overlays } } - public OverlayRulesetSelector() + protected OverlayColourScheme ColourScheme { get; } + + public OverlayRulesetSelector(OverlayColourScheme colourScheme) { + ColourScheme = colourScheme; + AutoSizeAxes = Axes.Both; } [BackgroundDependencyLoader] private void load(OsuColour colours) { - if (accentColour == default) - AccentColour = colours.Pink; + AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.7f); } protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index e63102f989..f7e8d4b1f5 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics; @@ -14,16 +13,14 @@ namespace osu.Game.Overlays.Profile.Header.Components { public readonly Bindable User = new Bindable(); - [BackgroundDependencyLoader] - private void load(OsuColour colours) + public ProfileRulesetSelector(OverlayColourScheme colourScheme) + : base(colourScheme) { - AccentColour = colours.Seafoam; } protected override void LoadComplete() { base.LoadComplete(); - User.BindValueChanged(u => SetDefaultRuleset(Rulesets.GetRuleset(u.NewValue?.PlayMode ?? "osu")), true); } From 7cd60e3193a615c4ce71311693762ec6c01aa57e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 26 Jan 2020 17:07:17 +0300 Subject: [PATCH 0027/1142] Make OverlayRulesetSelector use colour provider --- .../Online/TestSceneProfileRulesetSelector.cs | 8 ++++-- .../TestSceneOverlayRulesetSelector.cs | 27 ++++++++++++++----- osu.Game/Overlays/OverlayRulesetSelector.cs | 10 +++---- .../Components/ProfileRulesetSelector.cs | 6 ----- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs index 1a9dca51c9..826624f686 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneProfileRulesetSelector.cs @@ -11,7 +11,8 @@ using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Taiko; using osu.Game.Users; using osu.Framework.Bindables; -using osu.Game.Graphics; +using osu.Game.Overlays; +using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.Online { @@ -23,12 +24,15 @@ namespace osu.Game.Tests.Visual.Online typeof(ProfileRulesetTabItem), }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneProfileRulesetSelector() { ProfileRulesetSelector selector; var user = new Bindable(); - Child = selector = new ProfileRulesetSelector(OverlayColourScheme.Green) + Child = selector = new ProfileRulesetSelector { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs index bc5f66da0b..8a98127793 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayRulesetSelector.cs @@ -12,9 +12,9 @@ using osu.Framework.Bindables; using osu.Game.Overlays; using osu.Game.Rulesets; using NUnit.Framework; -using osu.Game.Graphics; using osu.Framework.Graphics.Containers; using osuTK; +using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.UserInterface { @@ -40,16 +40,29 @@ namespace osu.Game.Tests.Visual.UserInterface Spacing = new Vector2(0, 5), Children = new[] { - selector = new OverlayRulesetSelector(OverlayColourScheme.Green) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Blue) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Orange) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Pink) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Purple) { Current = ruleset }, - new OverlayRulesetSelector(OverlayColourScheme.Red) { Current = ruleset } + new ColourProvidedContainer(OverlayColourScheme.Green, selector = new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Blue, new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Orange, new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Pink, new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Purple, new OverlayRulesetSelector { Current = ruleset }), + new ColourProvidedContainer(OverlayColourScheme.Red, new OverlayRulesetSelector { Current = ruleset }), } }); } + private class ColourProvidedContainer : Container + { + [Cached] + private readonly OverlayColourProvider colourProvider; + + public ColourProvidedContainer(OverlayColourScheme colourScheme, OverlayRulesetSelector rulesetSelector) + { + colourProvider = new OverlayColourProvider(colourScheme); + AutoSizeAxes = Axes.Both; + Add(rulesetSelector); + } + } + [Test] public void TestSelection() { diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index b70d6a08f2..0c87686f6f 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -28,19 +28,15 @@ namespace osu.Game.Overlays } } - protected OverlayColourScheme ColourScheme { get; } - - public OverlayRulesetSelector(OverlayColourScheme colourScheme) + public OverlayRulesetSelector() { - ColourScheme = colourScheme; - AutoSizeAxes = Axes.Both; } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - AccentColour = colours.ForOverlayElement(ColourScheme, 1, 0.7f); + AccentColour = colourProvider.Highlight1; } protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs index f7e8d4b1f5..41a3ee8ad6 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetSelector.cs @@ -3,7 +3,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Game.Rulesets; using osu.Game.Users; @@ -13,11 +12,6 @@ namespace osu.Game.Overlays.Profile.Header.Components { public readonly Bindable User = new Bindable(); - public ProfileRulesetSelector(OverlayColourScheme colourScheme) - : base(colourScheme) - { - } - protected override void LoadComplete() { base.LoadComplete(); From 2b2cfd91a6a48b7804870f4dfb19753372b54e9a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 28 Jan 2020 17:59:14 +0900 Subject: [PATCH 0028/1142] Initial re-implementation using rearrangeable list --- .../UserInterface/TestScenePlaylistOverlay.cs | 59 ++++ osu.Game/Overlays/Music/PlaylistList.cs | 301 ++++-------------- osu.Game/Overlays/Music/PlaylistOverlay.cs | 12 +- 3 files changed, 135 insertions(+), 237 deletions(-) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs new file mode 100644 index 0000000000..a470244f53 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs @@ -0,0 +1,59 @@ +// 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 NUnit.Framework; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Utils; +using osu.Game.Beatmaps; +using osu.Game.Overlays.Music; +using osuTK; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestScenePlaylistOverlay : OsuTestScene + { + private readonly BindableList beatmapSets = new BindableList(); + + [SetUp] + public void Setup() => Schedule(() => + { + PlaylistOverlay overlay; + + Child = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(300, 500), + Child = overlay = new PlaylistOverlay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + State = { Value = Visibility.Visible } + } + }; + + beatmapSets.Clear(); + + for (int i = 0; i < 100; i++) + { + beatmapSets.Add(new BeatmapSetInfo + { + Metadata = new BeatmapMetadata + { + // Create random metadata, then we can check if sorting works based on these + Artist = "Some Artist " + RNG.Next(0, 9), + Title = $"Some Song {i + 1}", + AuthorString = "Some Guy " + RNG.Next(0, 9), + }, + DateAdded = DateTimeOffset.UtcNow, + }); + } + + overlay.BeatmapSets.BindTo(beatmapSets); + }); + } +} diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 7bdcab6dff..5c091a21db 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -6,30 +6,16 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input.Events; +using osu.Framework.Graphics.UserInterface; using osu.Game.Beatmaps; -using osu.Game.Graphics.Containers; -using osuTK; namespace osu.Game.Overlays.Music { - public class PlaylistList : CompositeDrawable + public class PlaylistList2 : BasicRearrangeableListContainer { - public Action Selected; - - private readonly ItemsScrollContainer items; - - public PlaylistList() - { - InternalChild = items = new ItemsScrollContainer - { - RelativeSizeAxes = Axes.Both, - Selected = set => Selected?.Invoke(set), - }; - } + public readonly BindableList BeatmapSets = new BindableList(); public new MarginPadding Padding { @@ -37,232 +23,81 @@ namespace osu.Game.Overlays.Music set => base.Padding = value; } - public BeatmapSetInfo FirstVisibleSet => items.FirstVisibleSet; - - public void Filter(string searchTerm) => items.SearchTerm = searchTerm; - - private class ItemsScrollContainer : OsuScrollContainer + [BackgroundDependencyLoader] + private void load() { - public Action Selected; + BeatmapSets.ItemsAdded += addBeatmapSets; + BeatmapSets.ItemsRemoved += removeBeatmapSets; + } - private readonly SearchContainer search; - private readonly FillFlowContainer items; + public void Filter(string searchTerm) => ((PlaylistListFlowContainer)ListContainer).SearchTerm = searchTerm; - private readonly IBindable beatmapBacking = new Bindable(); + public BeatmapSetInfo FirstVisibleSet => ListContainer.FlowingChildren.Cast().FirstOrDefault(i => i.MatchingFilter)?.Model.BeatmapSetInfo; - private IBindableList beatmaps; + private void addBeatmapSets(IEnumerable sets) => Schedule(() => + { + foreach (var item in sets) + AddItem(new PlaylistListItem(item)); + }); - [Resolved] - private MusicController musicController { get; set; } + private void removeBeatmapSets(IEnumerable sets) => Schedule(() => + { + foreach (var item in sets) + RemoveItem(ListContainer.Children.Select(d => d.Model).FirstOrDefault(m => m.BeatmapSetInfo == item)); + }); - public ItemsScrollContainer() + protected override BasicDrawableRearrangeableListItem CreateBasicItem(PlaylistListItem item) => new DrawablePlaylistListItem(item); + + protected override FillFlowContainer CreateListFillFlowContainer() => new PlaylistListFlowContainer + { + LayoutDuration = 200, + LayoutEasing = Easing.OutQuint + }; + } + + public class PlaylistListFlowContainer : SearchContainer.DrawableRearrangeableListItem> + { + } + + public class PlaylistListItem : IEquatable + { + public readonly BeatmapSetInfo BeatmapSetInfo; + + public PlaylistListItem(BeatmapSetInfo beatmapSetInfo) + { + BeatmapSetInfo = beatmapSetInfo; + } + + public override string ToString() => BeatmapSetInfo.ToString(); + + public bool Equals(PlaylistListItem other) => BeatmapSetInfo.Equals(other?.BeatmapSetInfo); + } + + public class DrawablePlaylistListItem : BasicRearrangeableListContainer.BasicDrawableRearrangeableListItem, IFilterable + { + public DrawablePlaylistListItem(PlaylistListItem item) + : base(item) + { + FilterTerms = item.BeatmapSetInfo.Metadata.SearchableTerms; + } + + public IEnumerable FilterTerms { get; } + + private bool matching = true; + + public bool MatchingFilter + { + get => matching; + set { - Children = new Drawable[] - { - search = new SearchContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - items = new ItemSearchContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }, - } - } - }; - } + if (matching == value) return; - [BackgroundDependencyLoader] - private void load(IBindable beatmap) - { - beatmaps = musicController.BeatmapSets.GetBoundCopy(); - beatmaps.ItemsAdded += i => i.ForEach(addBeatmapSet); - beatmaps.ItemsRemoved += i => i.ForEach(removeBeatmapSet); - beatmaps.ForEach(addBeatmapSet); + matching = value; - beatmapBacking.BindTo(beatmap); - beatmapBacking.ValueChanged += _ => Scheduler.AddOnce(updateSelectedSet); - } - - private void addBeatmapSet(BeatmapSetInfo obj) - { - if (obj == draggedItem?.BeatmapSetInfo) return; - - Schedule(() => items.Insert(items.Count - 1, new PlaylistItem(obj) { OnSelect = set => Selected?.Invoke(set) })); - } - - private void removeBeatmapSet(BeatmapSetInfo obj) - { - if (obj == draggedItem?.BeatmapSetInfo) return; - - Schedule(() => - { - var itemToRemove = items.FirstOrDefault(i => i.BeatmapSetInfo.ID == obj.ID); - if (itemToRemove != null) - items.Remove(itemToRemove); - }); - } - - private void updateSelectedSet() - { - foreach (PlaylistItem s in items.Children) - { - s.Selected = s.BeatmapSetInfo.ID == beatmapBacking.Value.BeatmapSetInfo?.ID; - if (s.Selected) - ScrollIntoView(s); - } - } - - public string SearchTerm - { - get => search.SearchTerm; - set => search.SearchTerm = value; - } - - public BeatmapSetInfo FirstVisibleSet => items.FirstOrDefault(i => i.MatchingFilter)?.BeatmapSetInfo; - - private Vector2 nativeDragPosition; - private PlaylistItem draggedItem; - - private int? dragDestination; - - protected override bool OnDragStart(DragStartEvent e) - { - nativeDragPosition = e.ScreenSpaceMousePosition; - draggedItem = items.FirstOrDefault(d => d.IsDraggable); - return draggedItem != null || base.OnDragStart(e); - } - - protected override void OnDrag(DragEvent e) - { - nativeDragPosition = e.ScreenSpaceMousePosition; - - if (draggedItem == null) - base.OnDrag(e); - } - - protected override void OnDragEnd(DragEndEvent e) - { - nativeDragPosition = e.ScreenSpaceMousePosition; - - if (draggedItem == null) - { - base.OnDragEnd(e); - return; - } - - if (dragDestination != null) - musicController.ChangeBeatmapSetPosition(draggedItem.BeatmapSetInfo, dragDestination.Value); - - draggedItem = null; - dragDestination = null; - } - - protected override void Update() - { - base.Update(); - - if (draggedItem == null) - return; - - updateScrollPosition(); - updateDragPosition(); - } - - private void updateScrollPosition() - { - const float start_offset = 10; - const double max_power = 50; - const double exp_base = 1.05; - - var localPos = ToLocalSpace(nativeDragPosition); - - if (localPos.Y < start_offset) - { - if (Current <= 0) - return; - - var power = Math.Min(max_power, Math.Abs(start_offset - localPos.Y)); - ScrollBy(-(float)Math.Pow(exp_base, power)); - } - else if (localPos.Y > DrawHeight - start_offset) - { - if (IsScrolledToEnd()) - return; - - var power = Math.Min(max_power, Math.Abs(DrawHeight - start_offset - localPos.Y)); - ScrollBy((float)Math.Pow(exp_base, power)); - } - } - - private void updateDragPosition() - { - var itemsPos = items.ToLocalSpace(nativeDragPosition); - - int srcIndex = (int)items.GetLayoutPosition(draggedItem); - - // Find the last item with position < mouse position. Note we can't directly use - // the item positions as they are being transformed - float heightAccumulator = 0; - int dstIndex = 0; - - for (; dstIndex < items.Count; dstIndex++) - { - // Using BoundingBox here takes care of scale, paddings, etc... - heightAccumulator += items[dstIndex].BoundingBox.Height; - if (heightAccumulator > itemsPos.Y) - break; - } - - dstIndex = Math.Clamp(dstIndex, 0, items.Count - 1); - - if (srcIndex == dstIndex) - return; - - if (srcIndex < dstIndex) - { - for (int i = srcIndex + 1; i <= dstIndex; i++) - items.SetLayoutPosition(items[i], i - 1); - } - else - { - for (int i = dstIndex; i < srcIndex; i++) - items.SetLayoutPosition(items[i], i + 1); - } - - items.SetLayoutPosition(draggedItem, dstIndex); - dragDestination = dstIndex; - } - - private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren - { - public IEnumerable FilterTerms => Array.Empty(); - - public bool MatchingFilter - { - set - { - if (value) - InvalidateLayout(); - } - } - - public bool FilteringActive - { - set { } - } - - public IEnumerable FilterableChildren => Children; - - public ItemSearchContainer() - { - LayoutDuration = 200; - LayoutEasing = Easing.OutQuint; - } + this.FadeTo(matching ? 1 : 0, 200); } } + + public bool FilteringActive { get; set; } } } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index b89a577282..ff1b26e335 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -21,12 +21,14 @@ namespace osu.Game.Overlays.Music private const float transition_duration = 600; private const float playlist_height = 510; + public readonly BindableList BeatmapSets = new BindableList(); + private readonly Bindable beatmap = new Bindable(); private BeatmapManager beatmaps; private FilterControl filter; - private PlaylistList list; - + private PlaylistList2 list; + [BackgroundDependencyLoader] private void load(OsuColour colours, Bindable beatmap, BeatmapManager beatmaps) { @@ -53,11 +55,11 @@ namespace osu.Game.Overlays.Music Colour = colours.Gray3, RelativeSizeAxes = Axes.Both, }, - list = new PlaylistList + list = new PlaylistList2 { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 }, - Selected = itemSelected, + // Selected = itemSelected, }, filter = new FilterControl { @@ -70,6 +72,8 @@ namespace osu.Game.Overlays.Music }, }; + list.BeatmapSets.BindTo(BeatmapSets); + filter.Search.OnCommit = (sender, newText) => { BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); From b947e89a6b11946110ec66709657fc70bfbe73ec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 28 Jan 2020 16:53:22 +0300 Subject: [PATCH 0029/1142] Add placeholder for no comments case in CommentsContainer --- .../Online/TestSceneCommentsContainer.cs | 1 + .../Overlays/Comments/CommentsContainer.cs | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 3d63e2b07e..2af191945c 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -48,6 +48,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); + AddStep("Beatmap with no comments", () => comments.ShowComments(CommentableType.Beatmapset, 1291)); AddStep("Idle state", () => { scroll.Clear(); diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 78df73eb0d..fd5c390f0f 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -12,6 +12,7 @@ using osu.Game.Online.API.Requests.Responses; using System.Threading; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Comments { @@ -34,6 +35,7 @@ namespace osu.Game.Overlays.Comments private DeletedChildrenPlaceholder deletedChildrenPlaceholder; private CommentsShowMoreButton moreButton; private TotalCommentsCounter commentCounter; + private Container noCommentsPlaceholder; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -60,6 +62,27 @@ namespace osu.Game.Overlays.Comments Sort = { BindTarget = Sort }, ShowDeleted = { BindTarget = ShowDeleted } }, + noCommentsPlaceholder = new Container + { + Height = 80, + RelativeSizeAxes = Axes.X, + Alpha = 0, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background4 + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 50 }, + Text = @"No comments yet." + } + } + }, content = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -68,6 +91,7 @@ namespace osu.Game.Overlays.Comments }, new Container { + Name = @"Footer", RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Children = new Drawable[] @@ -154,12 +178,21 @@ namespace osu.Game.Overlays.Comments { currentPage = 1; deletedChildrenPlaceholder.DeletedCount.Value = 0; + moreButton.Show(); moreButton.IsLoading = true; content.Clear(); + noCommentsPlaceholder.Hide(); } private void onSuccess(CommentBundle response) { + if (!response.Comments.Any()) + { + noCommentsPlaceholder.Show(); + moreButton.Hide(); + return; + } + loadCancellation = new CancellationTokenSource(); var page = new FillFlowContainer From c5e0c77bcadb98cd252684dcb5adbb6c4fff9886 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:08:11 +0300 Subject: [PATCH 0030/1142] Refactor NoCommentsPlaceholder --- .../Online/TestSceneCommentsContainer.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 50 ++++++++++--------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 2af191945c..c81e850cc9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -48,7 +48,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); - AddStep("Beatmap with no comments", () => comments.ShowComments(CommentableType.Beatmapset, 1291)); + AddStep("Beatmap with no comments", () => comments.ShowComments(CommentableType.Beatmapset, 1288)); AddStep("Idle state", () => { scroll.Clear(); diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index fd5c390f0f..6abb85088f 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -35,7 +35,6 @@ namespace osu.Game.Overlays.Comments private DeletedChildrenPlaceholder deletedChildrenPlaceholder; private CommentsShowMoreButton moreButton; private TotalCommentsCounter commentCounter; - private Container noCommentsPlaceholder; [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) @@ -62,27 +61,6 @@ namespace osu.Game.Overlays.Comments Sort = { BindTarget = Sort }, ShowDeleted = { BindTarget = ShowDeleted } }, - noCommentsPlaceholder = new Container - { - Height = 80, - RelativeSizeAxes = Axes.X, - Alpha = 0, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4 - }, - new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 50 }, - Text = @"No comments yet." - } - } - }, content = new FillFlowContainer { RelativeSizeAxes = Axes.X, @@ -181,14 +159,13 @@ namespace osu.Game.Overlays.Comments moreButton.Show(); moreButton.IsLoading = true; content.Clear(); - noCommentsPlaceholder.Hide(); } private void onSuccess(CommentBundle response) { if (!response.Comments.Any()) { - noCommentsPlaceholder.Show(); + content.Add(new NoCommentsPlaceholder()); moreButton.Hide(); return; } @@ -240,5 +217,30 @@ namespace osu.Game.Overlays.Comments loadCancellation?.Cancel(); base.Dispose(isDisposing); } + + private class NoCommentsPlaceholder : CompositeDrawable + { + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Height = 80; + RelativeSizeAxes = Axes.X; + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background4 + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 50 }, + Text = @"No comments yet." + } + }); + } + } } } From ebf15c6a1ceacb45aae17b8c384eb7daf2236581 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 29 Jan 2020 12:17:03 +0900 Subject: [PATCH 0031/1142] General work towards completion + framework updates --- .../UserInterface/TestScenePlaylistOverlay.cs | 7 + osu.Game/Overlays/Music/PlaylistList.cs | 197 ++++++++++++++++-- osu.Game/Overlays/Music/PlaylistOverlay.cs | 12 +- osu.Game/Overlays/NowPlayingOverlay.cs | 1 + 4 files changed, 200 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs index a470244f53..986cf458ab 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -15,6 +16,12 @@ namespace osu.Game.Tests.Visual.UserInterface { public class TestScenePlaylistOverlay : OsuTestScene { + public override IReadOnlyList RequiredTypes => new Type[] + { + typeof(PlaylistOverlay), + typeof(PlaylistList) + }; + private readonly BindableList beatmapSets = new BindableList(); [SetUp] diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 5c091a21db..f7be69e1f2 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -8,14 +8,23 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.UserInterface; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Framework.Localisation; using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Music { - public class PlaylistList2 : BasicRearrangeableListContainer + public class PlaylistList : RearrangeableListContainer { - public readonly BindableList BeatmapSets = new BindableList(); + public Action RequestSelection; + + public readonly Bindable SelectedSet = new Bindable(); + public readonly IBindableList BeatmapSets = new BindableList(); public new MarginPadding Padding { @@ -23,21 +32,35 @@ namespace osu.Game.Overlays.Music set => base.Padding = value; } + private readonly HashSet existingItems = new HashSet(); + [BackgroundDependencyLoader] private void load() { BeatmapSets.ItemsAdded += addBeatmapSets; BeatmapSets.ItemsRemoved += removeBeatmapSets; + + foreach (var item in BeatmapSets) + addBeatmapSet(item); } public void Filter(string searchTerm) => ((PlaylistListFlowContainer)ListContainer).SearchTerm = searchTerm; public BeatmapSetInfo FirstVisibleSet => ListContainer.FlowingChildren.Cast().FirstOrDefault(i => i.MatchingFilter)?.Model.BeatmapSetInfo; - private void addBeatmapSets(IEnumerable sets) => Schedule(() => + private void addBeatmapSets(IEnumerable sets) { - foreach (var item in sets) - AddItem(new PlaylistListItem(item)); + foreach (var set in sets) + addBeatmapSet(set); + } + + private void addBeatmapSet(BeatmapSetInfo set) => Schedule(() => + { + if (existingItems.Contains(set)) + return; + + AddItem(new PlaylistListItem(set)); + existingItems.Add(set); }); private void removeBeatmapSets(IEnumerable sets) => Schedule(() => @@ -46,16 +69,23 @@ namespace osu.Game.Overlays.Music RemoveItem(ListContainer.Children.Select(d => d.Model).FirstOrDefault(m => m.BeatmapSetInfo == item)); }); - protected override BasicDrawableRearrangeableListItem CreateBasicItem(PlaylistListItem item) => new DrawablePlaylistListItem(item); - - protected override FillFlowContainer CreateListFillFlowContainer() => new PlaylistListFlowContainer + protected override DrawableRearrangeableListItem CreateDrawable(PlaylistListItem item) => new DrawablePlaylistListItem(item) { + SelectedSet = { BindTarget = SelectedSet }, + RequestSelection = set => RequestSelection?.Invoke(set) + }; + + protected override ScrollContainer CreateScrollContainer() => new OsuScrollContainer(); + + protected override FillFlowContainer> CreateListFillFlowContainer() => new PlaylistListFlowContainer + { + Spacing = new Vector2(0, 3), LayoutDuration = 200, - LayoutEasing = Easing.OutQuint + LayoutEasing = Easing.OutQuint, }; } - public class PlaylistListFlowContainer : SearchContainer.DrawableRearrangeableListItem> + public class PlaylistListFlowContainer : SearchContainer> { } @@ -73,14 +103,118 @@ namespace osu.Game.Overlays.Music public bool Equals(PlaylistListItem other) => BeatmapSetInfo.Equals(other?.BeatmapSetInfo); } - public class DrawablePlaylistListItem : BasicRearrangeableListContainer.BasicDrawableRearrangeableListItem, IFilterable + public class DrawablePlaylistListItem : DrawableRearrangeableListItem, IFilterable { + private const float fade_duration = 100; + + public readonly Bindable SelectedSet = new Bindable(); + public Action RequestSelection; + + private PlaylistItemHandle handle; + private TextFlowContainer text; + private IEnumerable titleSprites; + private ILocalisedBindableString titleBind; + private ILocalisedBindableString artistBind; + + private Color4 hoverColour; + private Color4 artistColour; + public DrawablePlaylistListItem(PlaylistListItem item) : base(item) { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + + Padding = new MarginPadding { Left = 5 }; + FilterTerms = item.BeatmapSetInfo.Metadata.SearchableTerms; } + [BackgroundDependencyLoader] + private void load(OsuColour colours, LocalisationManager localisation) + { + hoverColour = colours.Yellow; + artistColour = colours.Gray9; + + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Content = new[] + { + new Drawable[] + { + handle = new PlaylistItemHandle + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(12), + Colour = colours.Gray5, + Alpha = 0 + }, + text = new OsuTextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Left = 5 }, + }, + } + }, + ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } + }; + + titleBind = localisation.GetLocalisedString(new LocalisedString((Model.BeatmapSetInfo.Metadata.TitleUnicode, Model.BeatmapSetInfo.Metadata.Title))); + artistBind = localisation.GetLocalisedString(new LocalisedString((Model.BeatmapSetInfo.Metadata.ArtistUnicode, Model.BeatmapSetInfo.Metadata.Artist))); + + artistBind.BindValueChanged(_ => recreateText(), true); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + SelectedSet.BindValueChanged(set => + { + if (set.OldValue != Model.BeatmapSetInfo && set.NewValue != Model.BeatmapSetInfo) + return; + + foreach (Drawable s in titleSprites) + s.FadeColour(set.NewValue == Model.BeatmapSetInfo ? hoverColour : Color4.White, fade_duration); + }, true); + } + + private void recreateText() + { + 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(); + + text.AddText(artistBind.Value, sprite => + { + sprite.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); + sprite.Colour = artistColour; + sprite.Padding = new MarginPadding { Top = 1 }; + }); + } + + protected override bool OnClick(ClickEvent e) + { + RequestSelection?.Invoke(Model.BeatmapSetInfo); + return true; + } + + protected override bool IsDraggableAt(Vector2 screenSpacePos) => handle.HandlingDrag; + + protected override bool OnHover(HoverEvent e) + { + handle.UpdateHoverState(true); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) => handle.UpdateHoverState(false); + public IEnumerable FilterTerms { get; } private bool matching = true; @@ -99,5 +233,44 @@ namespace osu.Game.Overlays.Music } public bool FilteringActive { get; set; } + + private class PlaylistItemHandle : SpriteIcon + { + public bool HandlingDrag { get; private set; } + private bool isHovering; + + public PlaylistItemHandle() + { + Icon = FontAwesome.Solid.Bars; + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + base.OnMouseDown(e); + + HandlingDrag = true; + UpdateHoverState(isHovering); + + return false; + } + + protected override void OnMouseUp(MouseUpEvent e) + { + base.OnMouseUp(e); + + HandlingDrag = false; + UpdateHoverState(isHovering); + } + + public void UpdateHoverState(bool hovering) + { + isHovering = hovering; + + if (isHovering || HandlingDrag) + this.FadeIn(fade_duration); + else + this.FadeOut(fade_duration); + } + } } } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index ff1b26e335..87abbd142c 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -21,14 +21,14 @@ namespace osu.Game.Overlays.Music private const float transition_duration = 600; private const float playlist_height = 510; - public readonly BindableList BeatmapSets = new BindableList(); + public readonly IBindableList BeatmapSets = new BindableList(); private readonly Bindable beatmap = new Bindable(); private BeatmapManager beatmaps; private FilterControl filter; - private PlaylistList2 list; - + private PlaylistList list; + [BackgroundDependencyLoader] private void load(OsuColour colours, Bindable beatmap, BeatmapManager beatmaps) { @@ -55,11 +55,11 @@ namespace osu.Game.Overlays.Music Colour = colours.Gray3, RelativeSizeAxes = Axes.Both, }, - list = new PlaylistList2 + list = new PlaylistList { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 }, - // Selected = itemSelected, + RequestSelection = itemSelected }, filter = new FilterControl { @@ -84,6 +84,8 @@ namespace osu.Game.Overlays.Music beatmap.Value.Track.Restart(); } }; + + beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo, true); } protected override void PopIn() diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index 042e95c6d7..dfcf99d30c 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -183,6 +183,7 @@ namespace osu.Game.Overlays } }; + playlist.BeatmapSets.BindTo(musicController.BeatmapSets); playlist.State.ValueChanged += s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); } From e7964023aed0a6d8eeebd6762de8e6e6aff04ad1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:22:08 +0300 Subject: [PATCH 0032/1142] Implement CommentsPage class --- .../Overlays/Comments/CommentsContainer.cs | 54 +------------ osu.Game/Overlays/Comments/CommentsPage.cs | 76 +++++++++++++++++++ 2 files changed, 79 insertions(+), 51 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CommentsPage.cs diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 6abb85088f..0e307d4d0d 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -12,7 +12,6 @@ using osu.Game.Online.API.Requests.Responses; using System.Threading; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Comments { @@ -163,34 +162,12 @@ namespace osu.Game.Overlays.Comments private void onSuccess(CommentBundle response) { - if (!response.Comments.Any()) - { - content.Add(new NoCommentsPlaceholder()); - moreButton.Hide(); - return; - } - loadCancellation = new CancellationTokenSource(); - var page = new FillFlowContainer + LoadComponentAsync(new CommentsPage(response) { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - }; - - foreach (var c in response.Comments) - { - if (c.IsTopLevel) - { - page.Add(new DrawableComment(c) - { - ShowDeleted = { BindTarget = ShowDeleted } - }); - } - } - - LoadComponentAsync(page, loaded => + ShowDeleted = { BindTarget = ShowDeleted } + }, loaded => { content.Add(loaded); @@ -217,30 +194,5 @@ namespace osu.Game.Overlays.Comments loadCancellation?.Cancel(); base.Dispose(isDisposing); } - - private class NoCommentsPlaceholder : CompositeDrawable - { - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - Height = 80; - RelativeSizeAxes = Axes.X; - AddRangeInternal(new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background4 - }, - new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 50 }, - Text = @"No comments yet." - } - }); - } - } } } diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs new file mode 100644 index 0000000000..1bc9c89dfc --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -0,0 +1,76 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Bindables; +using osu.Game.Online.API.Requests.Responses; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Sprites; +using System.Linq; + +namespace osu.Game.Overlays.Comments +{ + public class CommentsPage : FillFlowContainer + { + public readonly BindableBool ShowDeleted = new BindableBool(); + + private readonly CommentBundle commentBundle; + + public CommentsPage(CommentBundle commentBundle) + { + this.commentBundle = commentBundle; + } + + [BackgroundDependencyLoader] + private void load() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + Direction = FillDirection.Vertical; + + if (!commentBundle.Comments.Any()) + { + Add(new NoCommentsPlaceholder()); + return; + } + + foreach (var c in commentBundle.Comments) + { + if (c.IsTopLevel) + { + Add(new DrawableComment(c) + { + ShowDeleted = { BindTarget = ShowDeleted } + }); + } + } + } + + private class NoCommentsPlaceholder : CompositeDrawable + { + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Height = 80; + RelativeSizeAxes = Axes.X; + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background4 + }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 50 }, + Text = @"No comments yet." + } + }); + } + } + } +} From dc10e58b4f1f4c4e39fa68ebefdf88f919855905 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:44:39 +0300 Subject: [PATCH 0033/1142] Add tests for CommentsPage --- .../Online/TestSceneCommentsContainer.cs | 3 +- .../Visual/Online/TestSceneCommentsPage.cs | 165 ++++++++++++++++++ .../Online/API/Requests/Responses/Comment.cs | 6 +- .../API/Requests/Responses/CommentBundle.cs | 20 ++- osu.Game/Overlays/Comments/DrawableComment.cs | 4 +- 5 files changed, 184 insertions(+), 14 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index c81e850cc9..c877176adf 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -25,7 +25,8 @@ namespace osu.Game.Tests.Visual.Online typeof(SortTabControl), typeof(ShowChildrenButton), typeof(DeletedChildrenPlaceholder), - typeof(VotePill) + typeof(VotePill), + typeof(CommentsPage), }; protected override bool UseOnlineAPI => true; diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs new file mode 100644 index 0000000000..706b1ca1ba --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs @@ -0,0 +1,165 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Game.Overlays.Comments; +using osu.Game.Overlays; +using osu.Framework.Allocation; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Users; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneCommentsPage : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(DrawableComment), + typeof(CommentsPage), + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + + private readonly BindableBool showDeleted = new BindableBool(); + private readonly Container content; + + public TestSceneCommentsPage() + { + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + new OsuCheckbox + { + Current = showDeleted, + LabelText = @"Show Deleted" + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + } + } + } + }); + + AddStep("load comments", () => createPage(comment_bundle)); + AddStep("load empty comments", () => createPage(empty_comment_bundle)); + } + + private void createPage(CommentBundle commentBundle) + { + content.Clear(); + content.Add(new CommentsPage(commentBundle) + { + ShowDeleted = { BindTarget = showDeleted } + }); + } + + private static readonly CommentBundle empty_comment_bundle = new CommentBundle + { + Comments = new List(), + Total = 0, + }; + + private static readonly CommentBundle comment_bundle = new CommentBundle + { + Comments = new List + { + new Comment + { + Id = 1, + Message = "Simple test comment", + LegacyName = "TestUser1", + CreatedAt = DateTimeOffset.Now, + VotesCount = 5 + }, + new Comment + { + Id = 2, + Message = "This comment has been deleted :( but visible for admins", + LegacyName = "TestUser2", + CreatedAt = DateTimeOffset.Now, + DeletedAt = DateTimeOffset.Now, + VotesCount = 5 + }, + new Comment + { + Id = 3, + Message = "This comment is a top level", + LegacyName = "TestUser3", + CreatedAt = DateTimeOffset.Now, + RepliesCount = 2, + }, + new Comment + { + Id = 4, + ParentId = 3, + Message = "And this is a reply", + RepliesCount = 1, + LegacyName = "TestUser1", + CreatedAt = DateTimeOffset.Now, + }, + new Comment + { + Id = 15, + ParentId = 4, + Message = "Reply to reply", + LegacyName = "TestUser1", + CreatedAt = DateTimeOffset.Now, + }, + new Comment + { + Id = 6, + ParentId = 3, + LegacyName = "TestUser11515", + CreatedAt = DateTimeOffset.Now, + DeletedAt = DateTimeOffset.Now, + }, + new Comment + { + Id = 5, + Message = "This comment is voted and edited", + LegacyName = "BigBrainUser", + CreatedAt = DateTimeOffset.Now, + EditedAt = DateTimeOffset.Now, + VotesCount = 1000, + EditedById = 1, + } + }, + IncludedComments = new List(), + UserVotes = new List + { + 5 + }, + Users = new List + { + new User + { + Id = 1, + Username = "Good_Admin" + } + }, + TopLevelCount = 4, + Total = 7 + }; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 5510e9afff..3e38c3067b 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -6,8 +6,6 @@ using osu.Game.Users; using System; using System.Collections.Generic; using System.Linq; -using System.Net; -using System.Text.RegularExpressions; namespace osu.Game.Online.API.Requests.Responses { @@ -70,12 +68,10 @@ namespace osu.Game.Online.API.Requests.Responses public bool IsDeleted => DeletedAt.HasValue; - public bool HasMessage => !string.IsNullOrEmpty(MessageHtml); + public bool HasMessage => !string.IsNullOrEmpty(Message); public bool IsVoted { get; set; } - public string GetMessage => HasMessage ? WebUtility.HtmlDecode(Regex.Replace(MessageHtml, @"<(.|\n)*?>", string.Empty)) : string.Empty; - public int DeletedChildrenCount => ChildComments.Count(c => c.IsDeleted); } } diff --git a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs index 8db5d8d6ad..c3dc775bd0 100644 --- a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs +++ b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs @@ -47,17 +47,25 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"included_comments")] public List IncludedComments { get; set; } + private List userVotes; + [JsonProperty(@"user_votes")] - private List userVotes + public List UserVotes { - set => value.ForEach(v => + get => userVotes; + set { - Comments.ForEach(c => + userVotes = value; + + value.ForEach(v => { - if (v == c.Id) - c.IsVoted = true; + Comments.ForEach(c => + { + if (v == c.Id) + c.IsVoted = true; + }); }); - }); + } } private List users; diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index bdae9da226..d77ba5e298 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -213,7 +213,7 @@ namespace osu.Game.Overlays.Comments if (comment.HasMessage) { - var formattedSource = MessageFormatter.FormatText(comment.GetMessage); + var formattedSource = MessageFormatter.FormatText(comment.Message); message.AddLinks(formattedSource.Text, formattedSource.Links); } @@ -343,7 +343,7 @@ namespace osu.Game.Overlays.Comments if (parentComment == null) return string.Empty; - return parentComment.HasMessage ? parentComment.GetMessage : parentComment.IsDeleted ? @"deleted" : string.Empty; + return parentComment.HasMessage ? parentComment.Message : parentComment.IsDeleted ? @"deleted" : string.Empty; } } } From 5fcda013469f133efb573496fd0a398c65621785 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:58:53 +0300 Subject: [PATCH 0034/1142] Cleanup pass --- .../Visual/Online/TestSceneCommentsPage.cs | 35 +++++++++---------- osu.Game/Overlays/Comments/CommentsPage.cs | 26 +++++++++++--- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs index 706b1ca1ba..1217ce6b42 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs @@ -12,8 +12,7 @@ using osu.Game.Graphics.UserInterface; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics; -using osu.Framework.Graphics.Shapes; -using osuTK.Graphics; +using osuTK; namespace osu.Game.Tests.Visual.Online { @@ -33,30 +32,28 @@ namespace osu.Game.Tests.Visual.Online public TestSceneCommentsPage() { - AddRange(new Drawable[] + Add(new FillFlowContainer { - new Box + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new Container { - new OsuCheckbox + AutoSizeAxes = Axes.Y, + Width = 200, + Child = new OsuCheckbox { Current = showDeleted, LabelText = @"Show Deleted" - }, - content = new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, } + }, + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, } } }); diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 1bc9c89dfc..153ce676eb 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -12,7 +12,7 @@ using System.Linq; namespace osu.Game.Overlays.Comments { - public class CommentsPage : FillFlowContainer + public class CommentsPage : CompositeDrawable { public readonly BindableBool ShowDeleted = new BindableBool(); @@ -24,15 +24,31 @@ namespace osu.Game.Overlays.Comments } [BackgroundDependencyLoader] - private void load() + private void load(OverlayColourProvider colourProvider) { + FillFlowContainer flow; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - Direction = FillDirection.Vertical; + + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background5 + }, + flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + } + }); if (!commentBundle.Comments.Any()) { - Add(new NoCommentsPlaceholder()); + flow.Add(new NoCommentsPlaceholder()); return; } @@ -40,7 +56,7 @@ namespace osu.Game.Overlays.Comments { if (c.IsTopLevel) { - Add(new DrawableComment(c) + flow.Add(new DrawableComment(c) { ShowDeleted = { BindTarget = ShowDeleted } }); From 7588c574a21e7a0a54a509f4c50013714769f810 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 19:37:54 +0900 Subject: [PATCH 0035/1142] Fix presenting a beatmap from a different ruleset not working --- .../Navigation/TestScenePresentBeatmap.cs | 1 - osu.Game/Screens/Select/SongSelect.cs | 39 +++++++++++-------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs index de330004c2..909409835c 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -30,7 +30,6 @@ namespace osu.Game.Tests.Visual.Navigation } [Test] - [Ignore("will be fixed soon")] public void TestFromMainMenuDifferentRuleset() { var firstImport = importBeatmap(1); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a5352c4eeb..a1959ff17d 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -277,7 +277,7 @@ namespace osu.Game.Screens.Select // if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter). bool shouldDebounce = this.IsCurrentScreen(); - Schedule(() => Carousel.Filter(criteria, shouldDebounce)); + Carousel.Filter(criteria, shouldDebounce); } private DependencyContainer dependencies; @@ -310,8 +310,10 @@ namespace osu.Game.Screens.Select if (!Carousel.BeatmapSetsLoaded) return; - // if we have a pending filter operation, we want to run it now. - // it could change selection (ie. if the ruleset has been changed). + transferRulesetValue(); + + // while transferRulesetValue will flush, it only does so if the ruleset changes. + // the user could have changed a filter, and we want to ensure we are 100% up-to-date and consistent here. Carousel.FlushPendingFilterOperations(); // avoid attempting to continue before a selection has been obtained. @@ -397,20 +399,10 @@ namespace osu.Game.Screens.Select { Logger.Log($"updating selection with beatmap:{beatmap?.ID.ToString() ?? "null"} ruleset:{ruleset?.ID.ToString() ?? "null"}"); - if (ruleset?.Equals(decoupledRuleset.Value) == false) + if (transferRulesetValue()) { - Logger.Log($"ruleset changed from \"{decoupledRuleset.Value}\" to \"{ruleset}\""); - + // if the ruleset changed, the rest of the selection update will happen via updateSelectedRuleset. Mods.Value = Array.Empty(); - decoupledRuleset.Value = ruleset; - - // force a filter before attempting to change the beatmap. - // we may still be in the wrong ruleset as there is a debounce delay on ruleset changes. - Carousel.Filter(null, false); - - // Filtering only completes after the carousel runs Update. - // If we also have a pending beatmap change we should delay it one frame. - selectionChangedDebounce = Schedule(run); return; } @@ -634,6 +626,7 @@ namespace osu.Game.Screens.Select // manual binding to parent ruleset to allow for delayed load in the incoming direction. transferRulesetValue(); + Ruleset.ValueChanged += r => updateSelectedRuleset(r.NewValue); decoupledRuleset.ValueChanged += r => Ruleset.Value = r.NewValue; @@ -645,9 +638,23 @@ namespace osu.Game.Screens.Select boundLocalBindables = true; } - private void transferRulesetValue() + /// + /// Transfer the game-wide ruleset to the local decoupled ruleset. + /// Will immediately run filter operations is required. + /// + /// Whether a transfer occurred. + private bool transferRulesetValue() { + if (decoupledRuleset.Value?.Equals(Ruleset.Value) == true) + return false; + + Logger.Log($"decoupled ruleset transferred (\"{decoupledRuleset.Value}\" -> \"{Ruleset.Value}\""); rulesetNoDebounce = decoupledRuleset.Value = Ruleset.Value; + + // if we have a pending filter operation, we want to run it now. + // it could change selection (ie. if the ruleset has been changed). + Carousel?.FlushPendingFilterOperations(); + return true; } private void delete(BeatmapSetInfo beatmap) From 3d6e00095edc737f247b6a93e20b4608d0206b7b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 14:08:10 +0300 Subject: [PATCH 0036/1142] Remove useless test --- osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index c877176adf..de6f7fd29d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -49,7 +49,6 @@ namespace osu.Game.Tests.Visual.Online AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); - AddStep("Beatmap with no comments", () => comments.ShowComments(CommentableType.Beatmapset, 1288)); AddStep("Idle state", () => { scroll.Clear(); From 13eb32fea25b0e02d8e4e0a8af9a7b0c5c3a2c1e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 22:20:34 +0900 Subject: [PATCH 0037/1142] Fix editor being accessible for multiplayer song select --- osu.Game/Screens/Select/MatchSongSelect.cs | 2 ++ osu.Game/Screens/Select/SongSelect.cs | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index c5fa9e2396..a78477c771 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -24,6 +24,8 @@ namespace osu.Game.Screens.Select [Resolved(typeof(Room))] protected Bindable CurrentItem { get; private set; } + public override bool AllowEditing => false; + [Resolved] private BeatmapManager beatmaps { get; set; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a5352c4eeb..f36b7ae059 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -35,6 +35,7 @@ using System.Linq; using System.Threading.Tasks; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; +using osu.Game.Overlays.Notifications; using osu.Game.Scoring; namespace osu.Game.Screens.Select @@ -66,6 +67,14 @@ namespace osu.Game.Screens.Select /// protected Container FooterPanels { get; private set; } + /// + /// Whether entering editor mode should be allowed. + /// + public virtual bool AllowEditing => true; + + [Resolved] + private NotificationOverlay notificationOverlay { get; set; } + protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); protected BeatmapCarousel Carousel { get; private set; } @@ -295,6 +304,12 @@ namespace osu.Game.Screens.Select public void Edit(BeatmapInfo beatmap = null) { + if (!AllowEditing) + { + notificationOverlay?.Post(new SimpleNotification { Text = "Editing is not available from the current mode." }); + return; + } + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap ?? beatmapNoDebounce); this.Push(new Editor()); } From da6952407ea04b5f4e752c0d2587b77d4f3ce103 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 23:01:57 +0900 Subject: [PATCH 0038/1142] Allow null DI --- osu.Game/Screens/Select/SongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f36b7ae059..74a4aea033 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -72,7 +72,7 @@ namespace osu.Game.Screens.Select /// public virtual bool AllowEditing => true; - [Resolved] + [Resolved(canBeNull: true)] private NotificationOverlay notificationOverlay { get; set; } protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); From 786ed038683f49ebd105b7668da9b95007c4e6d1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 21:01:40 +0300 Subject: [PATCH 0039/1142] Update profile recent activities in line with the web design --- .../Online/TestSceneHistoricalSection.cs | 6 +- .../TestSceneUserProfileRecentSection.cs | 5 + .../Sections/BeatmapMetadataContainer.cs | 2 +- .../Profile/Sections/DrawableProfileRow.cs | 124 ------------------ .../Sections/Recent/DrawableRecentActivity.cs | 78 +++++++---- .../Profile/Sections/Recent/MedalIcon.cs | 3 +- .../PaginatedRecentActivityContainer.cs | 4 +- 7 files changed, 68 insertions(+), 154 deletions(-) delete mode 100644 osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index d3b037f499..5825bc72f7 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -4,10 +4,12 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Overlays; using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections.Historical; using osu.Game.Users; @@ -24,9 +26,11 @@ namespace osu.Game.Tests.Visual.Online typeof(HistoricalSection), typeof(PaginatedMostPlayedBeatmapContainer), typeof(DrawableMostPlayedBeatmap), - typeof(DrawableProfileRow) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneHistoricalSection() { HistoricalSection section; diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs index f022425bf6..532aaa9c92 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -12,6 +13,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays; using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections.Recent; @@ -28,6 +30,9 @@ namespace osu.Game.Tests.Visual.Online typeof(MedalIcon) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneUserProfileRecentSection() { Children = new Drawable[] diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index 13b547eed3..67a976fe6f 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Profile.Sections { /// - /// Display artist/title/mapper information, commonly used as the left portion of a profile or score display row (see ). + /// Display artist/title/mapper information, commonly used as the left portion of a profile or score display row. /// public abstract class BeatmapMetadataContainer : OsuHoverContainer { diff --git a/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs b/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs deleted file mode 100644 index 03ee29d0c2..0000000000 --- a/osu.Game/Overlays/Profile/Sections/DrawableProfileRow.cs +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; -using osu.Game.Graphics; -using osuTK; -using osuTK.Graphics; - -namespace osu.Game.Overlays.Profile.Sections -{ - public abstract class DrawableProfileRow : Container - { - private const int fade_duration = 200; - - private Box underscoreLine; - private Box coloredBackground; - private Container background; - - /// - /// A visual element displayed to the left of content. - /// - protected abstract Drawable CreateLeftVisual(); - - protected FillFlowContainer LeftFlowContainer { get; private set; } - protected FillFlowContainer RightFlowContainer { get; private set; } - - protected override Container Content { get; } - - protected DrawableProfileRow() - { - RelativeSizeAxes = Axes.X; - Height = 60; - - Content = new Container - { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Width = 0.97f, - }; - } - - [BackgroundDependencyLoader(true)] - private void load(OsuColour colour) - { - InternalChildren = new Drawable[] - { - background = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 3, - Alpha = 0, - EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Shadow, - Offset = new Vector2(0f, 1f), - Radius = 1f, - Colour = Color4.Black.Opacity(0.2f), - }, - Child = coloredBackground = new Box { RelativeSizeAxes = Axes.Both } - }, - Content, - underscoreLine = new Box - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - Height = 1, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new[] - { - CreateLeftVisual(), - LeftFlowContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 10 }, - Direction = FillDirection.Vertical, - }, - } - }, - RightFlowContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Direction = FillDirection.Vertical, - }, - }; - - coloredBackground.Colour = underscoreLine.Colour = colour.Gray4; - } - - protected override bool OnClick(ClickEvent e) => true; - - protected override bool OnHover(HoverEvent e) - { - background.FadeIn(fade_duration, Easing.OutQuint); - underscoreLine.FadeOut(fade_duration, Easing.OutQuint); - return true; - } - - protected override void OnHoverLost(HoverLostEvent e) - { - background.FadeOut(fade_duration, Easing.OutQuint); - underscoreLine.FadeIn(fade_duration, Easing.OutQuint); - base.OnHoverLost(e); - } - } -} diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 4e856845ac..aef8044b12 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -14,7 +14,7 @@ using osu.Game.Online.Leaderboards; namespace osu.Game.Overlays.Profile.Sections.Recent { - public class DrawableRecentActivity : DrawableProfileRow + public class DrawableRecentActivity : CompositeDrawable { private IAPIProvider api; @@ -28,24 +28,55 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } [BackgroundDependencyLoader] - private void load(IAPIProvider api) + private void load(IAPIProvider api, OverlayColourProvider colourProvider) { this.api = api; - LeftFlowContainer.Padding = new MarginPadding { Left = 10, Right = 160 }; - - LeftFlowContainer.Add(content = new LinkFlowContainer + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + AddInternal(new GridContainer { - AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - }); - - RightFlowContainer.Add(new DrawableDate(activity.CreatedAt) - { - Font = OsuFont.GetFont(size: 13), - Colour = OsuColour.Gray(0xAA), - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Y, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.Absolute, size: 40), + new Dimension(), + new Dimension(GridSizeMode.AutoSize) + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = createIcon().With(icon => + { + icon.Anchor = Anchor.Centre; + icon.Origin = Anchor.Centre; + }) + }, + content = new LinkFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + }, + new DrawableDate(activity.CreatedAt) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Colour = colourProvider.Foreground1, + } + } + } }); var formatted = createMessage(); @@ -53,36 +84,33 @@ namespace osu.Game.Overlays.Profile.Sections.Recent content.AddLinks(formatted.Text, formatted.Links); } - protected override Drawable CreateLeftVisual() + private Drawable createIcon() { switch (activity.Type) { case RecentActivityType.Rank: return new UpdateableRank(activity.ScoreRank) { - RelativeSizeAxes = Axes.Y, - Width = 60, + RelativeSizeAxes = Axes.X, + Height = 16, FillMode = FillMode.Fit, }; case RecentActivityType.Achievement: return new DelayedLoadWrapper(new MedalIcon(activity.Achievement.Slug) { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, }) { - RelativeSizeAxes = Axes.Y, - Width = 60, + RelativeSizeAxes = Axes.X, + Height = 20 }; default: - return new Container - { - RelativeSizeAxes = Axes.Y, - Width = 60, - FillMode = FillMode.Fit, - }; + return Empty(); } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs index 4563510046..0c1f8b2e92 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs @@ -23,8 +23,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent Child = sprite = new Sprite { - Height = 40, - Width = 40, + RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, }; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 3f9d4dc93e..7a9cce4675 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -8,6 +8,7 @@ using osu.Framework.Bindables; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API; using System.Collections.Generic; +using osuTK; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -16,7 +17,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent public PaginatedRecentActivityContainer(Bindable user, string header, string missing) : base(user, header, missing) { - ItemsPerPage = 5; + ItemsPerPage = 10; + ItemsContainer.Spacing = new Vector2(0, 5); } protected override APIRequest> CreateRequest() => From 65f71b8c12757a1085d971d77fcd65c2fca23e9c Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 21:23:19 +0100 Subject: [PATCH 0040/1142] Make colourProvider accessable from derived classes --- osu.Game/Overlays/FullscreenOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 959f6749d2..44e6ce086b 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays protected IAPIProvider API { get; private set; } [Cached] - private readonly OverlayColourProvider colourProvider; + protected readonly OverlayColourProvider colourProvider; protected FullscreenOverlay(OverlayColourScheme colourScheme) { From 0ce18256e02af52ae5feb156659b1ce998d11c5f Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 21:35:17 +0100 Subject: [PATCH 0041/1142] Recolor ProfileTabControl --- osu.Game/Overlays/UserProfileOverlay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 07c0dbed43..8ba79efe18 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -165,9 +165,9 @@ namespace osu.Game.Overlays }; [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - AccentColour = colours.Seafoam; + AccentColour = colourProvider.Highlight1; } private class ProfileTabItem : OverlayTabItem From c091b31fe875a98e70a0c37258b49674176406a7 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 21:37:51 +0100 Subject: [PATCH 0042/1142] Recolor basic background boxes --- osu.Game/Overlays/UserProfileOverlay.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 8ba79efe18..a8e11ec124 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile; @@ -74,7 +73,7 @@ namespace osu.Game.Overlays Add(new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.1f) + Colour = colourProvider.Background6 }); Add(sectionsContainer = new ProfileSectionsContainer @@ -83,7 +82,8 @@ namespace osu.Game.Overlays FixedHeader = tabs, HeaderBackground = new Box { - Colour = OsuColour.Gray(34), + // this is only visible as the ProfileTabControl background + Colour = colourProvider.Background5, RelativeSizeAxes = Axes.Both }, }); From 12a49b74bb19e8e6151ad8a828dcd4c039669023 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 21:48:02 +0100 Subject: [PATCH 0043/1142] Recolor TopHeaderContainer --- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index b0d7070994..19a24dd576 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Overlays.Profile.Header private FillFlowContainer userStats; [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { Height = 150; @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Profile.Header new Box { RelativeSizeAxes = Axes.Both, - Colour = colours.GreySeafoamDark, + Colour = colourProvider.Background5, }, new FillFlowContainer { @@ -117,7 +117,7 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.X, Height = 1.5f, Margin = new MarginPadding { Top = 10 }, - Colour = colours.GreySeafoamLighter, + Colour = colourProvider.Light1, }, new FillFlowContainer { @@ -137,7 +137,7 @@ namespace osu.Game.Overlays.Profile.Header Margin = new MarginPadding { Left = 10 }, Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, - Colour = colours.GreySeafoamLighter, + Colour = colourProvider.Light1, } } }, From 088064523bdd2a67c7d758de98351bb73583a6f7 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 21:55:41 +0100 Subject: [PATCH 0044/1142] Recolor CentreHeaderContainer --- osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 68fd77dd84..4f36a7e240 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Overlays.Profile.Header } [BackgroundDependencyLoader] - private void load(OsuColour colours, TextureStore textures) + private void load(OverlayColourProvider colourProvider, TextureStore textures) { Container hiddenDetailContainer; Container expandedDetailContainer; @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Profile.Header new Box { RelativeSizeAxes = Axes.Both, - Colour = colours.GreySeafoam + Colour = colourProvider.Background4 }, new FillFlowContainer { @@ -119,12 +119,12 @@ namespace osu.Game.Overlays.Profile.Header hiddenDetailGlobal = new OverlinedInfoContainer { Title = "Global Ranking", - LineColour = colours.Yellow + LineColour = colourProvider.Highlight1 }, hiddenDetailCountry = new OverlinedInfoContainer { Title = "Country Ranking", - LineColour = colours.Yellow + LineColour = colourProvider.Highlight1 }, } } From 799a86544f577e5a627b4b9e74d0e3b8c9886a99 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 21:57:43 +0100 Subject: [PATCH 0045/1142] Recolor play time border --- .../Profile/Header/Components/OverlinedTotalPlayTime.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index 2c88a83680..06c9dc2602 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -27,12 +27,12 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { InternalChild = info = new OverlinedInfoContainer { Title = "Total Play Time", - LineColour = colours.Yellow, + LineColour = colourProvider.Highlight1, }; User.BindValueChanged(updateTime, true); From 83d5691ba3eab76fc98b62ff16f7bedd32f5fb0b Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 22:00:37 +0100 Subject: [PATCH 0046/1142] Match web border height --- .../Profile/Header/Components/OverlinedInfoContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs index c40ddca688..c306e3db2e 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs @@ -43,7 +43,7 @@ namespace osu.Game.Overlays.Profile.Header.Components line = new Circle { RelativeSizeAxes = Axes.X, - Height = 4, + Height = 2, }, title = new OsuSpriteText { From fa0a96c3f5981dadafb5e03f31eba101acb77ed5 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 22:05:40 +0100 Subject: [PATCH 0047/1142] Match web margins --- .../Profile/Header/Components/OverlinedInfoContainer.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs index c306e3db2e..e9d22139ae 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs @@ -12,6 +12,11 @@ namespace osu.Game.Overlays.Profile.Header.Components { public class OverlinedInfoContainer : CompositeDrawable { + /// + /// The amount of space between the overline and the underneath text. + /// + private const float line_bottom_margin = 2; + private readonly Circle line; private readonly OsuSpriteText title; private readonly OsuSpriteText content; @@ -44,6 +49,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { RelativeSizeAxes = Axes.X, Height = 2, + Margin = new MarginPadding { Bottom = line_bottom_margin } }, title = new OsuSpriteText { From 0f9ab7c98050286d90044a18383ea1307c95b2bf Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 22:10:19 +0100 Subject: [PATCH 0048/1142] Recolor BottomHeaderContainer --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 158641d816..b6c6f33678 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -33,16 +33,16 @@ namespace osu.Game.Overlays.Profile.Header } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - iconColour = colours.GreySeafoamLighter; + iconColour = colourProvider.Foreground1; InternalChildren = new Drawable[] { new Box { RelativeSizeAxes = Axes.Both, - Colour = colours.GreySeafoamDark, + Colour = colourProvider.Background4 }, new FillFlowContainer { From 85990cdcdb4d714673afa1b569f6efdc48b484f7 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 22:10:48 +0100 Subject: [PATCH 0049/1142] Recolor MedalHeaderContainer --- osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index 45bc60f794..bbba9a3538 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.Profile.Header public readonly Bindable User = new Bindable(); [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { Alpha = 0; AutoSizeAxes = Axes.Y; @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Profile.Header new Box { RelativeSizeAxes = Axes.Both, - Colour = colours.GreySeafoamDarker, + Colour = colourProvider.Background5, }, new Container //artificial shadow { From 06eded16e282a754d0ed672d342b53a11e18995f Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 22:10:58 +0100 Subject: [PATCH 0050/1142] Recolor DetailHeaderContainer --- osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs index 6ee0d9ee8f..cf6ae1a3fc 100644 --- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs @@ -54,7 +54,7 @@ namespace osu.Game.Overlays.Profile.Header } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider, OsuColour colours) { AutoSizeAxes = Axes.Y; @@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Profile.Header new Box { RelativeSizeAxes = Axes.Both, - Colour = colours.GreySeafoamDarker, + Colour = colourProvider.Background5, }, fillFlow = new FillFlowContainer { @@ -152,12 +152,12 @@ namespace osu.Game.Overlays.Profile.Header detailGlobalRank = new OverlinedInfoContainer(true, 110) { Title = "Global Ranking", - LineColour = colours.Yellow, + LineColour = colourProvider.Highlight1, }, detailCountryRank = new OverlinedInfoContainer(false, 110) { Title = "Country Ranking", - LineColour = colours.Yellow, + LineColour = colourProvider.Highlight1, }, } } From 87521f35ed6e98d99a3ef5b30b5f8a707714349e Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 22:25:28 +0100 Subject: [PATCH 0051/1142] Recolor buttons --- .../Profile/Header/Components/ExpandDetailsButton.cs | 6 +++--- .../Overlays/Profile/Sections/ProfileShowMoreButton.cs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs index 46d24608ed..859cf0cc0b 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs @@ -25,10 +25,10 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - IdleColour = colours.GreySeafoamLight; - HoverColour = colours.GreySeafoamLight.Darken(0.2f); + IdleColour = colourProvider.Background2; + HoverColour = colourProvider.Background2.Lighten(0.2f); Child = icon = new SpriteIcon { diff --git a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs index 28486cc743..b009ab90d7 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs @@ -10,11 +10,11 @@ namespace osu.Game.Overlays.Profile.Sections public class ProfileShowMoreButton : ShowMoreButton { [BackgroundDependencyLoader] - private void load(OsuColour colors) + private void load(OverlayColourProvider colourProvider) { - IdleColour = colors.GreySeafoamDark; - HoverColour = colors.GreySeafoam; - ChevronIconColour = colors.Yellow; + IdleColour = colourProvider.Background2; + HoverColour = colourProvider.Background1; + ChevronIconColour = colourProvider.Foreground1; } } } From f7c38da0306dad4b461fef1d66b03efac8e239df Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 22:25:56 +0100 Subject: [PATCH 0052/1142] Match web border height --- osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index aabfa56ee6..d4d0976724 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -101,7 +101,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu { Masking = true, RelativeSizeAxes = Axes.X, - Height = 5, + Height = 2, Child = lineBackground = new Box { RelativeSizeAxes = Axes.Both, @@ -128,10 +128,10 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - lineBackground.Colour = colours.Yellow; - DescriptionText.Colour = colours.GreySeafoamLighter; + lineBackground.Colour = colourProvider.Highlight1; + DescriptionText.Colour = colourProvider.Foreground1; } } } From ef92c26c17aa0704ae37ed1cbdd75df441a4e024 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 22:26:21 +0100 Subject: [PATCH 0053/1142] Recolor ProfileSection --- osu.Game/Overlays/Profile/ProfileSection.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileSection.cs b/osu.Game/Overlays/Profile/ProfileSection.cs index f3590d4bb7..2e19ae4b64 100644 --- a/osu.Game/Overlays/Profile/ProfileSection.cs +++ b/osu.Game/Overlays/Profile/ProfileSection.cs @@ -95,10 +95,10 @@ namespace osu.Game.Overlays.Profile } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - background.Colour = colours.GreySeafoamDarker; - underscore.Colour = colours.Seafoam; + background.Colour = colourProvider.Background5; + underscore.Colour = colourProvider.Highlight1; } private class SectionTriangles : Container @@ -128,11 +128,11 @@ namespace osu.Game.Overlays.Profile } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - triangles.ColourLight = colours.GreySeafoamDark; - triangles.ColourDark = colours.GreySeafoamDarker.Darken(0.2f); - foreground.Colour = ColourInfo.GradientVertical(colours.GreySeafoamDarker, colours.GreySeafoamDarker.Opacity(0)); + triangles.ColourLight = colourProvider.Background4; + triangles.ColourDark = colourProvider.Background5.Darken(0.2f); + foreground.Colour = ColourInfo.GradientVertical(colourProvider.Background5, colourProvider.Background5.Opacity(0)); } } } From d20c48d15146b1c5e69616bb71afbc6441ade761 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 00:53:05 +0300 Subject: [PATCH 0054/1142] Resolve possible UserVotes issues --- osu.Game/Online/API/Requests/Responses/CommentBundle.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs index c3dc775bd0..9b3ef8b6e5 100644 --- a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs +++ b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs @@ -57,14 +57,7 @@ namespace osu.Game.Online.API.Requests.Responses { userVotes = value; - value.ForEach(v => - { - Comments.ForEach(c => - { - if (v == c.Id) - c.IsVoted = true; - }); - }); + Comments.ForEach(c => c.IsVoted = value.Contains(c.Id)); } } From ebdb425c508c34894048e40a66c84b8cd1aacea7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 11:17:26 +0900 Subject: [PATCH 0055/1142] Rename and tidy up DeletedCommentsCounter --- .../Online/TestSceneCommentsContainer.cs | 2 +- .../Overlays/Comments/CommentsContainer.cs | 8 ++-- ...aceholder.cs => DeletedCommentsCounter.cs} | 45 ++++++++++--------- osu.Game/Overlays/Comments/DrawableComment.cs | 6 +-- 4 files changed, 33 insertions(+), 28 deletions(-) rename osu.Game/Overlays/Comments/{DeletedChildrenPlaceholder.cs => DeletedCommentsCounter.cs} (51%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 3d63e2b07e..3deb9cb1fa 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(HeaderButton), typeof(SortTabControl), typeof(ShowChildrenButton), - typeof(DeletedChildrenPlaceholder), + typeof(DeletedCommentsCounter), typeof(VotePill) }; diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 78df73eb0d..e641cd8ddf 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Comments private int currentPage; private FillFlowContainer content; - private DeletedChildrenPlaceholder deletedChildrenPlaceholder; + private DeletedCommentsCounter deletedCommentsCounter; private CommentsShowMoreButton moreButton; private TotalCommentsCounter commentCounter; @@ -84,7 +84,7 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - deletedChildrenPlaceholder = new DeletedChildrenPlaceholder + deletedCommentsCounter = new DeletedCommentsCounter { ShowDeleted = { BindTarget = ShowDeleted } }, @@ -153,7 +153,7 @@ namespace osu.Game.Overlays.Comments private void clearComments() { currentPage = 1; - deletedChildrenPlaceholder.DeletedCount.Value = 0; + deletedCommentsCounter.Count.Value = 0; moreButton.IsLoading = true; content.Clear(); } @@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Comments { content.Add(loaded); - deletedChildrenPlaceholder.DeletedCount.Value += response.Comments.Count(c => c.IsDeleted && c.IsTopLevel); + deletedCommentsCounter.Count.Value += response.Comments.Count(c => c.IsDeleted && c.IsTopLevel); if (response.HasMore) { diff --git a/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs b/osu.Game/Overlays/Comments/DeletedCommentsCounter.cs similarity index 51% rename from osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs rename to osu.Game/Overlays/Comments/DeletedCommentsCounter.cs index 6b41453b91..f22086bf23 100644 --- a/osu.Game/Overlays/Comments/DeletedChildrenPlaceholder.cs +++ b/osu.Game/Overlays/Comments/DeletedCommentsCounter.cs @@ -12,51 +12,56 @@ using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays.Comments { - public class DeletedChildrenPlaceholder : FillFlowContainer + public class DeletedCommentsCounter : CompositeDrawable { public readonly BindableBool ShowDeleted = new BindableBool(); - public readonly BindableInt DeletedCount = new BindableInt(); + + public readonly BindableInt Count = new BindableInt(); private readonly SpriteText countText; - public DeletedChildrenPlaceholder() + public DeletedCommentsCounter() { AutoSizeAxes = Axes.Both; - Direction = FillDirection.Horizontal; - Spacing = new Vector2(3, 0); Margin = new MarginPadding { Vertical = 10, Left = 80 }; - Children = new Drawable[] + + InternalChild = new FillFlowContainer { - new SpriteIcon + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(3, 0), + Children = new Drawable[] { - Icon = FontAwesome.Solid.Trash, - Size = new Vector2(14), - }, - countText = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + new SpriteIcon + { + Icon = FontAwesome.Solid.Trash, + Size = new Vector2(14), + }, + countText = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + } } }; } protected override void LoadComplete() { - DeletedCount.BindValueChanged(_ => updateDisplay(), true); - ShowDeleted.BindValueChanged(_ => updateDisplay(), true); base.LoadComplete(); + + Count.BindValueChanged(_ => updateDisplay(), true); + ShowDeleted.BindValueChanged(_ => updateDisplay(), true); } private void updateDisplay() { - if (DeletedCount.Value != 0) + if (!ShowDeleted.Value && Count.Value != 0) { - countText.Text = @"deleted comment".ToQuantity(DeletedCount.Value); - this.FadeTo(ShowDeleted.Value ? 0 : 1); + countText.Text = @"deleted comment".ToQuantity(Count.Value); + Show(); } else - { Hide(); - } } } } diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index bdae9da226..0f217f057d 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Comments { LinkFlowContainer username; FillFlowContainer childCommentsContainer; - DeletedChildrenPlaceholder deletedChildrenPlaceholder; + DeletedCommentsCounter deletedCommentsCounter; FillFlowContainer info; LinkFlowContainer message; GridContainer content; @@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical }, - deletedChildrenPlaceholder = new DeletedChildrenPlaceholder + deletedCommentsCounter = new DeletedCommentsCounter { ShowDeleted = { BindTarget = ShowDeleted } } @@ -193,7 +193,7 @@ namespace osu.Game.Overlays.Comments } }; - deletedChildrenPlaceholder.DeletedCount.Value = comment.DeletedChildrenCount; + deletedCommentsCounter.Count.Value = comment.DeletedChildrenCount; if (comment.UserId.HasValue) username.AddUserLink(comment.User); From c158570249cfc5867ebd1a79f0766e8f33e2762d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 11:31:34 +0900 Subject: [PATCH 0056/1142] Fix typo in comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- osu.Game/Screens/Select/SongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a1959ff17d..ea852d26f1 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -640,7 +640,7 @@ namespace osu.Game.Screens.Select /// /// Transfer the game-wide ruleset to the local decoupled ruleset. - /// Will immediately run filter operations is required. + /// Will immediately run filter operations if required. /// /// Whether a transfer occurred. private bool transferRulesetValue() From d7d7ab48d354e00fb6c29dba5e148dbc73c66e65 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 12:36:38 +0900 Subject: [PATCH 0057/1142] Cleanup --- osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs | 1 - .../Profile/Header/Components/ExpandDetailsButton.cs | 1 - .../Profile/Header/Components/OverlinedInfoContainer.cs | 7 +------ .../Profile/Header/Components/OverlinedTotalPlayTime.cs | 1 - osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs | 1 - .../Overlays/Profile/Sections/ProfileShowMoreButton.cs | 1 - 6 files changed, 1 insertion(+), 11 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs index 4f36a7e240..658cdb8ce3 100644 --- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Textures; -using osu.Game.Graphics; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; using osuTK; diff --git a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs index 859cf0cc0b..29e13e4f51 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ExpandDetailsButton.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; using osuTK; namespace osu.Game.Overlays.Profile.Header.Components diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs index e9d22139ae..b11e41f90f 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedInfoContainer.cs @@ -12,11 +12,6 @@ namespace osu.Game.Overlays.Profile.Header.Components { public class OverlinedInfoContainer : CompositeDrawable { - /// - /// The amount of space between the overline and the underneath text. - /// - private const float line_bottom_margin = 2; - private readonly Circle line; private readonly OsuSpriteText title; private readonly OsuSpriteText content; @@ -49,7 +44,7 @@ namespace osu.Game.Overlays.Profile.Header.Components { RelativeSizeAxes = Axes.X, Height = 2, - Margin = new MarginPadding { Bottom = line_bottom_margin } + Margin = new MarginPadding { Bottom = 2 } }, title = new OsuSpriteText { diff --git a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs index 06c9dc2602..be96840217 100644 --- a/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs +++ b/osu.Game/Overlays/Profile/Header/Components/OverlinedTotalPlayTime.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; -using osu.Game.Graphics; using osu.Game.Users; namespace osu.Game.Overlays.Profile.Header.Components diff --git a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs index bbba9a3538..a5938a3fe7 100644 --- a/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/MedalHeaderContainer.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; using osuTK; diff --git a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs index b009ab90d7..426ebeebe6 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileShowMoreButton.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Profile.Sections From da2c2450833acacf2f68f3d207768088d0806aaf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 12:36:47 +0900 Subject: [PATCH 0058/1142] Change to pink colour scheme --- osu.Game/Overlays/UserProfileOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index a8e11ec124..d6a9b82ca1 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays public const float CONTENT_X_MARGIN = 70; public UserProfileOverlay() - : base(OverlayColourScheme.Green) + : base(OverlayColourScheme.Pink) { } From 17978035ea90466a1f4625012197b3105d813bf6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 12:50:15 +0900 Subject: [PATCH 0059/1142] Fix uncaught inconsistent naming --- osu.Game/Overlays/FullscreenOverlay.cs | 12 ++++++------ osu.Game/Overlays/UserProfileOverlay.cs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/FullscreenOverlay.cs b/osu.Game/Overlays/FullscreenOverlay.cs index 44e6ce086b..3464ce6086 100644 --- a/osu.Game/Overlays/FullscreenOverlay.cs +++ b/osu.Game/Overlays/FullscreenOverlay.cs @@ -18,11 +18,11 @@ namespace osu.Game.Overlays protected IAPIProvider API { get; private set; } [Cached] - protected readonly OverlayColourProvider colourProvider; + protected readonly OverlayColourProvider ColourProvider; protected FullscreenOverlay(OverlayColourScheme colourScheme) { - colourProvider = new OverlayColourProvider(colourScheme); + ColourProvider = new OverlayColourProvider(colourScheme); RelativeSizeAxes = Axes.Both; RelativePositionAxes = Axes.Both; @@ -43,10 +43,10 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - Waves.FirstWaveColour = colourProvider.Light4; - Waves.SecondWaveColour = colourProvider.Light3; - Waves.ThirdWaveColour = colourProvider.Dark4; - Waves.FourthWaveColour = colourProvider.Dark3; + Waves.FirstWaveColour = ColourProvider.Light4; + Waves.SecondWaveColour = ColourProvider.Light3; + Waves.ThirdWaveColour = ColourProvider.Dark4; + Waves.FourthWaveColour = ColourProvider.Dark3; } public override void Show() diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index d6a9b82ca1..6f0d96c226 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -73,7 +73,7 @@ namespace osu.Game.Overlays Add(new Box { RelativeSizeAxes = Axes.Both, - Colour = colourProvider.Background6 + Colour = ColourProvider.Background6 }); Add(sectionsContainer = new ProfileSectionsContainer @@ -83,7 +83,7 @@ namespace osu.Game.Overlays HeaderBackground = new Box { // this is only visible as the ProfileTabControl background - Colour = colourProvider.Background5, + Colour = ColourProvider.Background5, RelativeSizeAxes = Axes.Both }, }); From 4ca3f216b82790ab026dea5c2914baa6033bcfca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 13:11:35 +0900 Subject: [PATCH 0060/1142] Fix test scene --- osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs index d3b037f499..1b7a2160d0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneHistoricalSection.cs @@ -4,10 +4,12 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Overlays; using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections.Historical; using osu.Game.Users; @@ -27,6 +29,9 @@ namespace osu.Game.Tests.Visual.Online typeof(DrawableProfileRow) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); + public TestSceneHistoricalSection() { HistoricalSection section; From d8ce1fd86cda5d00ec78ce3c63ae4b2fb9023012 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 13:23:39 +0900 Subject: [PATCH 0061/1142] Fix osu!catch not handling all vertical space --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 589503c35b..2d71fb93fb 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -20,7 +20,9 @@ namespace osu.Game.Rulesets.Catch.UI internal readonly CatcherArea CatcherArea; - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || CatcherArea.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + // only check the X position; handle all vertical space. + base.ReceivePositionalInputAt(new Vector2(screenSpacePos.X, ScreenSpaceDrawQuad.Centre.Y)); public CatchPlayfield(BeatmapDifficulty difficulty, Func> createDrawableRepresentation) { From ce36e5458fa74640b9d8cbc3d7c68f7e19991074 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 14:35:03 +0900 Subject: [PATCH 0062/1142] Fix possible crash with no channel topic --- .../Visual/Online/TestSceneChatOverlay.cs | 17 ++++++++++++++--- .../Overlays/Chat/Selection/ChannelListItem.cs | 12 ++++++------ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 9196513a55..6626640a32 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -3,12 +3,15 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Testing; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Chat; using osu.Game.Overlays; using osu.Game.Overlays.Chat; @@ -35,8 +38,9 @@ namespace osu.Game.Tests.Visual.Online private TestChatOverlay chatOverlay; private ChannelManager channelManager; - private readonly Channel channel1 = new Channel(new User()) { Name = "test really long username" }; - private readonly Channel channel2 = new Channel(new User()) { Name = "test2" }; + private readonly Channel channel1 = new Channel(new User()) { Name = "test really long username", Topic = "Topic for channel 1" }; + private readonly Channel channel2 = new Channel(new User()) { Name = "test2", Topic = "Topic for channel 2" }; + private readonly Channel channel3 = new Channel(new User()) { Name = "channel with no topic" }; [SetUp] public void Setup() @@ -45,7 +49,7 @@ namespace osu.Game.Tests.Visual.Online { ChannelManagerContainer container; - Child = container = new ChannelManagerContainer(new List { channel1, channel2 }) + Child = container = new ChannelManagerContainer(new List { channel1, channel2, channel3 }) { RelativeSizeAxes = Axes.Both, }; @@ -96,6 +100,13 @@ namespace osu.Game.Tests.Visual.Online AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible); } + [Test] + public void TestSearchInSelector() + { + AddStep("search for 'test2'", () => chatOverlay.ChildrenOfType().First().Text = "test2"); + AddAssert("only channel 2 visible", () => chatOverlay.ChildrenOfType().Single(c => c.IsPresent).Channel == channel2); + } + private void clickDrawable(Drawable d) { InputManager.MoveMouseTo(d); diff --git a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs index 31c48deee0..e6f61e4fbb 100644 --- a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Chat.Selection private const float text_size = 15; private const float transition_duration = 100; - private readonly Channel channel; + public readonly Channel Channel; private readonly Bindable joinedBind = new Bindable(); private readonly OsuSpriteText name; @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Chat.Selection private Color4 topicColour; private Color4 hoverColour; - public IEnumerable FilterTerms => new[] { channel.Name, channel.Topic }; + public IEnumerable FilterTerms => new[] { Channel.Name, Channel.Topic ?? string.Empty }; public bool MatchingFilter { @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Chat.Selection public ChannelListItem(Channel channel) { - this.channel = channel; + this.Channel = channel; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -148,7 +148,7 @@ namespace osu.Game.Overlays.Chat.Selection hoverColour = colours.Yellow; joinedBind.ValueChanged += joined => updateColour(joined.NewValue); - joinedBind.BindTo(channel.Joined); + joinedBind.BindTo(Channel.Joined); joinedBind.TriggerChange(); FinishTransforms(true); @@ -156,7 +156,7 @@ namespace osu.Game.Overlays.Chat.Selection protected override bool OnHover(HoverEvent e) { - if (!channel.Joined.Value) + if (!Channel.Joined.Value) name.FadeColour(hoverColour, 50, Easing.OutQuint); return base.OnHover(e); @@ -164,7 +164,7 @@ namespace osu.Game.Overlays.Chat.Selection protected override void OnHoverLost(HoverLostEvent e) { - if (!channel.Joined.Value) + if (!Channel.Joined.Value) name.FadeColour(Color4.White, transition_duration); } From 7b4a658264ba82938d7967bd233cc35e7ba8175e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 14:54:57 +0900 Subject: [PATCH 0063/1142] Fix negative replay frames being played back incorrectly --- osu.Game/Scoring/Legacy/LegacyScoreParser.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs index 0029c843b4..85c5d414df 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs @@ -220,9 +220,11 @@ namespace osu.Game.Scoring.Legacy float lastTime = 0; ReplayFrame currentFrame = null; - foreach (var l in reader.ReadToEnd().Split(',')) + var frames = reader.ReadToEnd().Split(','); + + for (var i = 0; i < frames.Length; i++) { - var split = l.Split('|'); + var split = frames[i].Split('|'); if (split.Length < 4) continue; @@ -234,8 +236,14 @@ namespace osu.Game.Scoring.Legacy } var diff = Parsing.ParseFloat(split[0]); + lastTime += diff; + if (i == 0 && diff == 0) + // osu-stable adds a zero-time frame before potentially valid negative user frames. + // we need to ignroe this. + continue; + // Todo: At some point we probably want to rewind and play back the negative-time frames // but for now we'll achieve equal playback to stable by skipping negative frames if (diff < 0) From 2fb640f57f88a58008fe9c1ecd6bc855cf2972b8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 15:00:39 +0900 Subject: [PATCH 0064/1142] Change to until step + fix CI error --- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 2 +- osu.Game/Overlays/Chat/Selection/ChannelListItem.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 6626640a32..29bda524e8 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual.Online public void TestSearchInSelector() { AddStep("search for 'test2'", () => chatOverlay.ChildrenOfType().First().Text = "test2"); - AddAssert("only channel 2 visible", () => chatOverlay.ChildrenOfType().Single(c => c.IsPresent).Channel == channel2); + AddUntilStep("only channel 2 visible", () => chatOverlay.ChildrenOfType().Single(c => c.IsPresent).Channel == channel2); } private void clickDrawable(Drawable d) diff --git a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs index e6f61e4fbb..1e58e8b640 100644 --- a/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs +++ b/osu.Game/Overlays/Chat/Selection/ChannelListItem.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Chat.Selection public ChannelListItem(Channel channel) { - this.Channel = channel; + Channel = channel; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; From d03723303d0402c8dac21d045086519aedf96a42 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 16:29:15 +0900 Subject: [PATCH 0065/1142] Fix typo in comment --- osu.Game/Scoring/Legacy/LegacyScoreParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs index 85c5d414df..19d8410cc2 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreParser.cs @@ -241,7 +241,7 @@ namespace osu.Game.Scoring.Legacy if (i == 0 && diff == 0) // osu-stable adds a zero-time frame before potentially valid negative user frames. - // we need to ignroe this. + // we need to ignore this. continue; // Todo: At some point we probably want to rewind and play back the negative-time frames From ea2f66da1d9d10a9608a87cfed312b46a95afc4d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 10:34:22 +0300 Subject: [PATCH 0066/1142] Simplify OverlayRulesetTabItem.AccentColour --- osu.Game/Overlays/OverlayRulesetSelector.cs | 23 ----------- osu.Game/Overlays/OverlayRulesetTabItem.cs | 40 ++++++++----------- .../Components/ProfileRulesetTabItem.cs | 17 ++++---- 3 files changed, 27 insertions(+), 53 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetSelector.cs b/osu.Game/Overlays/OverlayRulesetSelector.cs index 0c87686f6f..b73d38eeb3 100644 --- a/osu.Game/Overlays/OverlayRulesetSelector.cs +++ b/osu.Game/Overlays/OverlayRulesetSelector.cs @@ -1,44 +1,21 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Game.Rulesets; using osuTK; -using osuTK.Graphics; -using System.Linq; namespace osu.Game.Overlays { public class OverlayRulesetSelector : RulesetSelector { - private Color4 accentColour; - - public Color4 AccentColour - { - get => accentColour; - set - { - accentColour = value; - foreach (var i in TabContainer.Children.OfType()) - i.AccentColour = value; - } - } - public OverlayRulesetSelector() { AutoSizeAxes = Axes.Both; } - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - AccentColour = colourProvider.Highlight1; - } - protected override TabItem CreateTabItem(RulesetInfo value) => new OverlayRulesetTabItem(value); protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 91cf2d6b96..5b53d9d1fa 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -11,27 +11,31 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osuTK.Graphics; using osuTK; -using osu.Framework.Bindables; +using osu.Framework.Allocation; namespace osu.Game.Overlays { - public class OverlayRulesetTabItem : TabItem, IHasAccentColour + public class OverlayRulesetTabItem : TabItem { protected readonly OsuSpriteText Text; private readonly FillFlowContainer content; - public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; + protected override Container Content => content; - private readonly Bindable accentColour = new Bindable(); - private readonly Bindable currentColour = new Bindable(); + private Color4 accentColour; - public Color4 AccentColour + protected virtual Color4 AccentColour { - get => accentColour.Value; - set => accentColour.Value = value; + get => accentColour; + set + { + accentColour = value; + Text.FadeColour(value, 120, Easing.OutQuint); + } } - protected override Container Content => content; + [Resolved] + private OverlayColourProvider colourProvider { get; set; } public OverlayRulesetTabItem(RulesetInfo value) : base(value) @@ -58,13 +62,10 @@ namespace osu.Game.Overlays Enabled.Value = true; } - protected override void LoadComplete() + [BackgroundDependencyLoader] + private void load() { - base.LoadComplete(); - - currentColour.BindValueChanged(OnCurrentColourChanged); - accentColour.BindValueChanged(_ => updateState()); - Enabled.BindValueChanged(_ => updateState(), true); + updateState(); } protected override bool OnHover(HoverEvent e) @@ -87,14 +88,7 @@ namespace osu.Game.Overlays private void updateState() { Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - - currentColour.Value = IsHovered || Active.Value - ? Color4.White - : Enabled.Value - ? AccentColour - : Color4.DimGray; + AccentColour = IsHovered || Active.Value ? Color4.White : colourProvider.Highlight1; } - - protected virtual void OnCurrentColourChanged(ValueChangedEvent colour) => Text.FadeColour(colour.NewValue, 120, Easing.OutQuint); } } diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs index 038509d371..3d20fba542 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileRulesetTabItem.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Game.Rulesets; @@ -28,6 +27,16 @@ namespace osu.Game.Overlays.Profile.Header.Components } } + protected override Color4 AccentColour + { + get => base.AccentColour; + set + { + base.AccentColour = value; + icon.FadeColour(value, 120, Easing.OutQuint); + } + } + private readonly SpriteIcon icon; public ProfileRulesetTabItem(RulesetInfo value) @@ -43,11 +52,5 @@ namespace osu.Game.Overlays.Profile.Header.Components Size = new Vector2(12), }); } - - protected override void OnCurrentColourChanged(ValueChangedEvent colour) - { - base.OnCurrentColourChanged(colour); - icon.FadeColour(colour.NewValue, 120, Easing.OutQuint); - } } } From b2c501a4393751eb58cd220400688b5fd52f08dc Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 10:54:58 +0300 Subject: [PATCH 0067/1142] Adjust font size --- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index aef8044b12..b8b53f6ab6 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -16,6 +16,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { public class DrawableRecentActivity : CompositeDrawable { + private const int font_size = 14; + private IAPIProvider api; private readonly APIRecentActivity activity; @@ -62,7 +64,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent icon.Origin = Anchor.Centre; }) }, - content = new LinkFlowContainer + content = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: font_size)) { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, @@ -74,6 +76,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Colour = colourProvider.Foreground1, + Font = OsuFont.GetFont(size: font_size), } } } From 2f7076f91c15b21896a92c08b2c3c86969e13a35 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 11:16:58 +0300 Subject: [PATCH 0068/1142] Adjust icons size --- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index b8b53f6ab6..0387f79131 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent AutoSizeAxes = Axes.Y, ColumnDimensions = new[] { - new Dimension(GridSizeMode.Absolute, size: 40), + new Dimension(GridSizeMode.Absolute, size: 28), new Dimension(), new Dimension(GridSizeMode.AutoSize) }, @@ -95,8 +95,9 @@ namespace osu.Game.Overlays.Profile.Sections.Recent return new UpdateableRank(activity.ScoreRank) { RelativeSizeAxes = Axes.X, - Height = 16, + Height = 11, FillMode = FillMode.Fit, + Margin = new MarginPadding { Top = 2 } }; case RecentActivityType.Achievement: @@ -109,7 +110,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent }) { RelativeSizeAxes = Axes.X, - Height = 20 + Width = 0.5f, + Height = 18 }; default: From 7bf2e9b36989dddd793b997fef8a254e993ee9a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 17:37:52 +0900 Subject: [PATCH 0069/1142] Decouple ModSelectOverlay from global SelectedMods --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 5 ++--- osu.Game/Screens/Select/SongSelect.cs | 12 ++++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 38f5d54714..6afe398172 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.Mods protected readonly Container ModSettingsContainer; - protected readonly Bindable> SelectedMods = new Bindable>(Array.Empty()); + public readonly Bindable> SelectedMods = new Bindable>(Array.Empty()); private Bindable>> availableMods; @@ -321,14 +321,13 @@ namespace osu.Game.Overlays.Mods } [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, AudioManager audio, Bindable> selectedMods, OsuGameBase osu) + private void load(OsuColour colours, AudioManager audio, OsuGameBase osu) { LowMultiplierColour = colours.Red; HighMultiplierColour = colours.Green; UnrankedLabel.Colour = colours.Blue; availableMods = osu.AvailableMods.GetBoundCopy(); - SelectedMods.BindTo(selectedMods); sampleOn = audio.Samples.Get(@"UI/check-on"); sampleOff = audio.Samples.Get(@"UI/check-off"); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 74a4aea033..018c487250 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -75,6 +75,9 @@ namespace osu.Game.Screens.Select [Resolved(canBeNull: true)] private NotificationOverlay notificationOverlay { get; set; } + [Resolved] + private Bindable> selectedMods { get; set; } + protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); protected BeatmapCarousel Carousel { get; private set; } @@ -468,6 +471,8 @@ namespace osu.Game.Screens.Select this.FadeInFromZero(250); FilterControl.Activate(); + + ModSelect.SelectedMods.BindTo(selectedMods); } private const double logo_transition = 250; @@ -508,6 +513,12 @@ namespace osu.Game.Screens.Select public override void OnResuming(IScreen last) { + base.OnResuming(last); + + // required due to https://github.com/ppy/osu-framework/issues/3218 + ModSelect.SelectedMods.Disabled = false; + ModSelect.SelectedMods.BindTo(selectedMods); + BeatmapDetails.Leaderboard.RefreshScores(); Beatmap.Value.Track.Looping = true; @@ -532,6 +543,7 @@ namespace osu.Game.Screens.Select public override void OnSuspending(IScreen next) { + ModSelect.SelectedMods.UnbindFrom(selectedMods); ModSelect.Hide(); BeatmapOptions.Hide(); From bc21e30b09ef42fa17f8297a58bab4873181a100 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 17:35:54 +0900 Subject: [PATCH 0070/1142] Allow specifying a valid list of types to performFromMenu --- osu.Game/OsuGame.cs | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ff46c6d849..f54e6c02af 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -327,10 +327,10 @@ namespace osu.Game return; } - performFromMainMenu(() => + performFromScreen(screen => { // we might already be at song select, so a check is required before performing the load to solo. - if (menuScreen.IsCurrentScreen()) + if (screen is MainMenu) menuScreen.LoadToSolo(); // we might even already be at the song @@ -344,7 +344,7 @@ namespace osu.Game Ruleset.Value = first.Ruleset; Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); - }, $"load {beatmap}", bypassScreenAllowChecks: true, targetScreen: typeof(PlaySongSelect)); + }, $"load {beatmap}", bypassScreenAllowChecks: true, validScreens: new[] { typeof(PlaySongSelect) }); } /// @@ -381,11 +381,11 @@ namespace osu.Game return; } - performFromMainMenu(() => + performFromScreen(screen => { Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); - menuScreen.Push(new ReplayPlayerLoader(databasedScore)); + screen.Push(new ReplayPlayerLoader(databasedScore)); }, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true); } @@ -441,17 +441,20 @@ namespace osu.Game private ScheduledDelegate performFromMainMenuTask; /// - /// Perform an action only after returning to the main menu. + /// Perform an action only after returning to a specific screen specification. /// Eagerly tries to exit the current screen until it succeeds. /// /// The action to perform once we are in the correct state. /// The task name to display in a notification (if we can't immediately reach the main menu state). - /// An optional target screen type. If this screen is already current we can immediately perform the action without returning to the menu. + /// An optional collection of valid screen types. If any of these screens are already current we can immediately perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. /// Whether checking should be bypassed. - private void performFromMainMenu(Action action, string taskName, Type targetScreen = null, bool bypassScreenAllowChecks = false) + private void performFromScreen(Action action, string taskName, IEnumerable validScreens = null, bool bypassScreenAllowChecks = false) { performFromMainMenuTask?.Cancel(); + validScreens ??= Enumerable.Empty(); + validScreens = validScreens.Append(typeof(MainMenu)); + // if the current screen does not allow screen changing, give the user an option to try again later. if (!bypassScreenAllowChecks && (ScreenStack.CurrentScreen as IOsuScreen)?.AllowExternalScreenChange == false) { @@ -460,7 +463,7 @@ namespace osu.Game Text = $"Click here to {taskName}", Activated = () => { - performFromMainMenu(action, taskName, targetScreen, true); + performFromScreen(action, taskName, validScreens, true); return true; } }); @@ -471,23 +474,27 @@ namespace osu.Game CloseAllOverlays(false); // we may already be at the target screen type. - if (targetScreen != null && ScreenStack.CurrentScreen?.GetType() == targetScreen) + if (validScreens.Contains(ScreenStack.CurrentScreen?.GetType()) && !Beatmap.Disabled) { - action(); + action(ScreenStack.CurrentScreen); return; } - // all conditions have been met to continue with the action. - if (menuScreen?.IsCurrentScreen() == true && !Beatmap.Disabled) + // find closest valid target + IScreen screen = ScreenStack.CurrentScreen; + + while (screen != null) { - action(); - return; + if (validScreens.Contains(screen.GetType())) + { + screen.MakeCurrent(); + break; + } + + screen = screen.GetParentScreen(); } - // menuScreen may not be initialised yet (null check required). - menuScreen?.MakeCurrent(); - - performFromMainMenuTask = Schedule(() => performFromMainMenu(action, taskName)); + performFromMainMenuTask = Schedule(() => performFromScreen(action, taskName, validScreens)); } /// From f637e0e5a73c356cccf03580cee858c9a737996f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 18:08:34 +0900 Subject: [PATCH 0071/1142] Remove unused bypassScreenAllowChecks argument --- osu.Game/OsuGame.cs | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f54e6c02af..374bacde00 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -344,7 +344,7 @@ namespace osu.Game Ruleset.Value = first.Ruleset; Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); - }, $"load {beatmap}", bypassScreenAllowChecks: true, validScreens: new[] { typeof(PlaySongSelect) }); + }, $"load {beatmap}", validScreens: new[] { typeof(PlaySongSelect) }); } /// @@ -386,7 +386,7 @@ namespace osu.Game Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); screen.Push(new ReplayPlayerLoader(databasedScore)); - }, $"watch {databasedScoreInfo}", bypassScreenAllowChecks: true); + }, $"watch {databasedScoreInfo}"); } protected virtual Loader CreateLoader() => new Loader(); @@ -447,30 +447,13 @@ namespace osu.Game /// The action to perform once we are in the correct state. /// The task name to display in a notification (if we can't immediately reach the main menu state). /// An optional collection of valid screen types. If any of these screens are already current we can immediately perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. - /// Whether checking should be bypassed. - private void performFromScreen(Action action, string taskName, IEnumerable validScreens = null, bool bypassScreenAllowChecks = false) + private void performFromScreen(Action action, string taskName, IEnumerable validScreens = null) { performFromMainMenuTask?.Cancel(); validScreens ??= Enumerable.Empty(); validScreens = validScreens.Append(typeof(MainMenu)); - // if the current screen does not allow screen changing, give the user an option to try again later. - if (!bypassScreenAllowChecks && (ScreenStack.CurrentScreen as IOsuScreen)?.AllowExternalScreenChange == false) - { - notifications.Post(new SimpleNotification - { - Text = $"Click here to {taskName}", - Activated = () => - { - performFromScreen(action, taskName, validScreens, true); - return true; - } - }); - - return; - } - CloseAllOverlays(false); // we may already be at the target screen type. From 8e0d51766b3c9ca8e90e9ba74f45f0e0c45a4360 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 18:10:19 +0900 Subject: [PATCH 0072/1142] 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 5497a82a7a..a31db201b2 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 0ea558bbc7..6c3aea04a1 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 a215bc65e8..6f9d27a93a 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From 0975002ef503841177a69bc6c5bccc3a80465fef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 18:16:28 +0900 Subject: [PATCH 0073/1142] Allow presenting scores from PlaySongSelect --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 374bacde00..597b318c90 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -386,7 +386,7 @@ namespace osu.Game Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); screen.Push(new ReplayPlayerLoader(databasedScore)); - }, $"watch {databasedScoreInfo}"); + }, $"watch {databasedScoreInfo}", new[] { typeof(PlaySongSelect) }); } protected virtual Loader CreateLoader() => new Loader(); From 29ba82ee448ecab176c603ea4582e0edf3021912 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 12:29:35 +0300 Subject: [PATCH 0074/1142] Apply different font styles for different content parts --- .../Sections/Recent/DrawableRecentActivity.cs | 80 ++++++++++++------- 1 file changed, 52 insertions(+), 28 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 0387f79131..e9377bb00b 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API; @@ -82,9 +83,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } }); - var formatted = createMessage(); - - content.AddLinks(formatted.Text, formatted.Links); + createMessage(); } private Drawable createIcon() @@ -119,81 +118,106 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } - private string toAbsoluteUrl(string url) => $"{api.Endpoint}{url}"; + private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; - private MessageFormatter.MessageFormatterResult createMessage() + private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) + => OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true); + + private void addUserLink() + => content.AddLink(activity.User?.Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User?.Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold)); + + private void addBeatmapLink() + => content.AddLink(activity.Beatmap?.Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap?.Url), creationParameters: t => t.Font = getLinkFont()); + + private void addBeatmapsetLink() + => content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont()); + + private void addText(string text) + => content.AddText(text, t => t.Font = OsuFont.GetFont(size: font_size, weight: FontWeight.SemiBold)); + + private void createMessage() { - string userLinkTemplate() => $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]"; - string beatmapLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; - string beatmapsetLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; - - string message; - switch (activity.Type) { case RecentActivityType.Achievement: - message = $"{userLinkTemplate()} unlocked the {activity.Achievement.Name} medal!"; + addUserLink(); + addText($" unlocked the \"{activity.Achievement.Name}\" medal!"); break; case RecentActivityType.BeatmapPlaycount: - message = $"{beatmapLinkTemplate()} has been played {activity.Count} times!"; + addBeatmapLink(); + addText($" has been played {activity.Count} times!"); break; case RecentActivityType.BeatmapsetApprove: - message = $"{beatmapsetLinkTemplate()} has been {activity.Approval.ToString().ToLowerInvariant()}!"; + addBeatmapsetLink(); + addText($" has been {activity.Approval.ToString().ToLowerInvariant()}!"); break; case RecentActivityType.BeatmapsetDelete: - message = $"{beatmapsetLinkTemplate()} has been deleted."; + addBeatmapsetLink(); + addText(" has been deleted."); break; case RecentActivityType.BeatmapsetRevive: - message = $"{beatmapsetLinkTemplate()} has been revived from eternal slumber by {userLinkTemplate()}."; + addBeatmapsetLink(); + addText(" has been revived from eternal slumber by "); + addUserLink(); break; case RecentActivityType.BeatmapsetUpdate: - message = $"{userLinkTemplate()} has updated the beatmap {beatmapsetLinkTemplate()}!"; + addUserLink(); + addText(" has updated the beatmap "); + addBeatmapsetLink(); break; case RecentActivityType.BeatmapsetUpload: - message = $"{userLinkTemplate()} has submitted a new beatmap {beatmapsetLinkTemplate()}!"; + addUserLink(); + addText(" has submitted a new beatmap "); + addBeatmapsetLink(); break; case RecentActivityType.Medal: // apparently this shouldn't exist look at achievement instead (https://github.com/ppy/osu-web/blob/master/resources/assets/coffee/react/profile-page/recent-activity.coffee#L111) - message = string.Empty; break; case RecentActivityType.Rank: - message = $"{userLinkTemplate()} achieved rank #{activity.Rank} on {beatmapLinkTemplate()} ({activity.Mode}!)"; + addUserLink(); + addText($" achieved rank #{activity.Rank} on "); + addBeatmapLink(); + addText($" ({activity.Mode}!)"); break; case RecentActivityType.RankLost: - message = $"{userLinkTemplate()} has lost first place on {beatmapLinkTemplate()} ({activity.Mode}!)"; + addUserLink(); + addText(" has lost first place on "); + addBeatmapLink(); + addText($" ({activity.Mode}!)"); break; case RecentActivityType.UserSupportAgain: - message = $"{userLinkTemplate()} has once again chosen to support osu! - thanks for your generosity!"; + addUserLink(); + addText(" has once again chosen to support osu! - thanks for your generosity!"); break; case RecentActivityType.UserSupportFirst: - message = $"{userLinkTemplate()} has become an osu!supporter - thanks for your generosity!"; + addUserLink(); + addText(" has become an osu!supporter - thanks for your generosity!"); break; case RecentActivityType.UserSupportGift: - message = $"{userLinkTemplate()} has received the gift of osu!supporter!"; + addUserLink(); + addText(" has received the gift of osu!supporter!"); break; case RecentActivityType.UsernameChange: - message = $"{activity.User?.PreviousUsername} has changed their username to {userLinkTemplate()}!"; + addText($"{activity.User?.PreviousUsername} has changed their username to "); + addUserLink(); break; default: - message = string.Empty; break; } - - return MessageFormatter.FormatText(message); } } } From f6ba98eec0f1087d9d7214681f41b8a35c1c47bd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 19:00:59 +0900 Subject: [PATCH 0075/1142] Apply refactorings for framework-side changes --- osu.Game/Overlays/Music/PlaylistList.cs | 70 +++++----------------- osu.Game/Overlays/Music/PlaylistOverlay.cs | 6 +- 2 files changed, 18 insertions(+), 58 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index f7be69e1f2..e183c14f10 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -19,12 +19,11 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Music { - public class PlaylistList : RearrangeableListContainer + public class PlaylistList : RearrangeableListContainer { public Action RequestSelection; public readonly Bindable SelectedSet = new Bindable(); - public readonly IBindableList BeatmapSets = new BindableList(); public new MarginPadding Padding { @@ -32,44 +31,17 @@ namespace osu.Game.Overlays.Music set => base.Padding = value; } - private readonly HashSet existingItems = new HashSet(); - - [BackgroundDependencyLoader] - private void load() - { - BeatmapSets.ItemsAdded += addBeatmapSets; - BeatmapSets.ItemsRemoved += removeBeatmapSets; - - foreach (var item in BeatmapSets) - addBeatmapSet(item); - } - public void Filter(string searchTerm) => ((PlaylistListFlowContainer)ListContainer).SearchTerm = searchTerm; - public BeatmapSetInfo FirstVisibleSet => ListContainer.FlowingChildren.Cast().FirstOrDefault(i => i.MatchingFilter)?.Model.BeatmapSetInfo; - - private void addBeatmapSets(IEnumerable sets) - { - foreach (var set in sets) - addBeatmapSet(set); - } - - private void addBeatmapSet(BeatmapSetInfo set) => Schedule(() => - { - if (existingItems.Contains(set)) - return; - - AddItem(new PlaylistListItem(set)); - existingItems.Add(set); - }); + public BeatmapSetInfo FirstVisibleSet => ListContainer.FlowingChildren.Cast().FirstOrDefault(i => i.MatchingFilter)?.Model; private void removeBeatmapSets(IEnumerable sets) => Schedule(() => { foreach (var item in sets) - RemoveItem(ListContainer.Children.Select(d => d.Model).FirstOrDefault(m => m.BeatmapSetInfo == item)); + Items.Remove(ListContainer.Children.Select(d => d.Model).FirstOrDefault(m => m == item)); }); - protected override DrawableRearrangeableListItem CreateDrawable(PlaylistListItem item) => new DrawablePlaylistListItem(item) + protected override DrawableRearrangeableListItem CreateDrawable(BeatmapSetInfo item) => new DrawablePlaylistListItem(item) { SelectedSet = { BindTarget = SelectedSet }, RequestSelection = set => RequestSelection?.Invoke(set) @@ -77,7 +49,7 @@ namespace osu.Game.Overlays.Music protected override ScrollContainer CreateScrollContainer() => new OsuScrollContainer(); - protected override FillFlowContainer> CreateListFillFlowContainer() => new PlaylistListFlowContainer + protected override FillFlowContainer> CreateListFillFlowContainer() => new PlaylistListFlowContainer { Spacing = new Vector2(0, 3), LayoutDuration = 200, @@ -85,25 +57,11 @@ namespace osu.Game.Overlays.Music }; } - public class PlaylistListFlowContainer : SearchContainer> + public class PlaylistListFlowContainer : SearchContainer> { } - public class PlaylistListItem : IEquatable - { - public readonly BeatmapSetInfo BeatmapSetInfo; - - public PlaylistListItem(BeatmapSetInfo beatmapSetInfo) - { - BeatmapSetInfo = beatmapSetInfo; - } - - public override string ToString() => BeatmapSetInfo.ToString(); - - public bool Equals(PlaylistListItem other) => BeatmapSetInfo.Equals(other?.BeatmapSetInfo); - } - - public class DrawablePlaylistListItem : DrawableRearrangeableListItem, IFilterable + public class DrawablePlaylistListItem : DrawableRearrangeableListItem, IFilterable { private const float fade_duration = 100; @@ -119,7 +77,7 @@ namespace osu.Game.Overlays.Music private Color4 hoverColour; private Color4 artistColour; - public DrawablePlaylistListItem(PlaylistListItem item) + public DrawablePlaylistListItem(BeatmapSetInfo item) : base(item) { RelativeSizeAxes = Axes.X; @@ -127,7 +85,7 @@ namespace osu.Game.Overlays.Music Padding = new MarginPadding { Left = 5 }; - FilterTerms = item.BeatmapSetInfo.Metadata.SearchableTerms; + FilterTerms = item.Metadata.SearchableTerms; } [BackgroundDependencyLoader] @@ -164,8 +122,8 @@ namespace osu.Game.Overlays.Music RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } }; - titleBind = localisation.GetLocalisedString(new LocalisedString((Model.BeatmapSetInfo.Metadata.TitleUnicode, Model.BeatmapSetInfo.Metadata.Title))); - artistBind = localisation.GetLocalisedString(new LocalisedString((Model.BeatmapSetInfo.Metadata.ArtistUnicode, Model.BeatmapSetInfo.Metadata.Artist))); + titleBind = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.TitleUnicode, Model.Metadata.Title))); + artistBind = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.ArtistUnicode, Model.Metadata.Artist))); artistBind.BindValueChanged(_ => recreateText(), true); } @@ -176,11 +134,11 @@ namespace osu.Game.Overlays.Music SelectedSet.BindValueChanged(set => { - if (set.OldValue != Model.BeatmapSetInfo && set.NewValue != Model.BeatmapSetInfo) + if (set.OldValue != Model && set.NewValue != Model) return; foreach (Drawable s in titleSprites) - s.FadeColour(set.NewValue == Model.BeatmapSetInfo ? hoverColour : Color4.White, fade_duration); + s.FadeColour(set.NewValue == Model ? hoverColour : Color4.White, fade_duration); }, true); } @@ -201,7 +159,7 @@ namespace osu.Game.Overlays.Music protected override bool OnClick(ClickEvent e) { - RequestSelection?.Invoke(Model.BeatmapSetInfo); + RequestSelection?.Invoke(Model); return true; } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 87abbd142c..a814712907 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -21,7 +21,9 @@ namespace osu.Game.Overlays.Music private const float transition_duration = 600; private const float playlist_height = 510; - public readonly IBindableList BeatmapSets = new BindableList(); + public IBindableList BeatmapSets => beatmapSets; + + private readonly BindableList beatmapSets = new BindableList(); private readonly Bindable beatmap = new Bindable(); private BeatmapManager beatmaps; @@ -72,7 +74,7 @@ namespace osu.Game.Overlays.Music }, }; - list.BeatmapSets.BindTo(BeatmapSets); + list.Items.BindTo(beatmapSets); filter.Search.OnCommit = (sender, newText) => { From a7a3372a984bd9ad79c3414a4e75d16d883df2b5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 13:01:40 +0300 Subject: [PATCH 0076/1142] Remove redundant empty switch section --- .../Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index e9377bb00b..d5bdcffeef 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -214,9 +214,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent addText($"{activity.User?.PreviousUsername} has changed their username to "); addUserLink(); break; - - default: - break; } } } From 00a7adcdca53ccc475372b5f9d5221944d17a696 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 19:21:24 +0900 Subject: [PATCH 0077/1142] Further refactorings --- .../UserInterface/TestScenePlaylistOverlay.cs | 4 +- ...laylistList.cs => DrawablePlaylistItem.cs} | 48 +---- osu.Game/Overlays/Music/Playlist.cs | 46 +++++ osu.Game/Overlays/Music/PlaylistItem.cs | 183 ------------------ osu.Game/Overlays/Music/PlaylistOverlay.cs | 4 +- 5 files changed, 53 insertions(+), 232 deletions(-) rename osu.Game/Overlays/Music/{PlaylistList.cs => DrawablePlaylistItem.cs} (75%) create mode 100644 osu.Game/Overlays/Music/Playlist.cs delete mode 100644 osu.Game/Overlays/Music/PlaylistItem.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs index 986cf458ab..7476b52b49 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestScenePlaylistOverlay.cs @@ -16,10 +16,10 @@ namespace osu.Game.Tests.Visual.UserInterface { public class TestScenePlaylistOverlay : OsuTestScene { - public override IReadOnlyList RequiredTypes => new Type[] + public override IReadOnlyList RequiredTypes => new[] { typeof(PlaylistOverlay), - typeof(PlaylistList) + typeof(Playlist) }; private readonly BindableList beatmapSets = new BindableList(); diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/DrawablePlaylistItem.cs similarity index 75% rename from osu.Game/Overlays/Music/PlaylistList.cs rename to osu.Game/Overlays/Music/DrawablePlaylistItem.cs index e183c14f10..e3dd72ae8b 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/DrawablePlaylistItem.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -19,49 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Music { - public class PlaylistList : RearrangeableListContainer - { - public Action RequestSelection; - - public readonly Bindable SelectedSet = new Bindable(); - - public new MarginPadding Padding - { - get => base.Padding; - set => base.Padding = value; - } - - public void Filter(string searchTerm) => ((PlaylistListFlowContainer)ListContainer).SearchTerm = searchTerm; - - public BeatmapSetInfo FirstVisibleSet => ListContainer.FlowingChildren.Cast().FirstOrDefault(i => i.MatchingFilter)?.Model; - - private void removeBeatmapSets(IEnumerable sets) => Schedule(() => - { - foreach (var item in sets) - Items.Remove(ListContainer.Children.Select(d => d.Model).FirstOrDefault(m => m == item)); - }); - - protected override DrawableRearrangeableListItem CreateDrawable(BeatmapSetInfo item) => new DrawablePlaylistListItem(item) - { - SelectedSet = { BindTarget = SelectedSet }, - RequestSelection = set => RequestSelection?.Invoke(set) - }; - - protected override ScrollContainer CreateScrollContainer() => new OsuScrollContainer(); - - protected override FillFlowContainer> CreateListFillFlowContainer() => new PlaylistListFlowContainer - { - Spacing = new Vector2(0, 3), - LayoutDuration = 200, - LayoutEasing = Easing.OutQuint, - }; - } - - public class PlaylistListFlowContainer : SearchContainer> - { - } - - public class DrawablePlaylistListItem : DrawableRearrangeableListItem, IFilterable + public class DrawablePlaylistItem : RearrangeableListItem, IFilterable { private const float fade_duration = 100; @@ -77,7 +35,7 @@ namespace osu.Game.Overlays.Music private Color4 hoverColour; private Color4 artistColour; - public DrawablePlaylistListItem(BeatmapSetInfo item) + public DrawablePlaylistItem(BeatmapSetInfo item) : base(item) { RelativeSizeAxes = Axes.X; diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs new file mode 100644 index 0000000000..ba9aaf03d4 --- /dev/null +++ b/osu.Game/Overlays/Music/Playlist.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 System; +using System.Linq; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Containers; +using osuTK; + +namespace osu.Game.Overlays.Music +{ + public class Playlist : RearrangeableListContainer + { + public Action RequestSelection; + + public readonly Bindable SelectedSet = new Bindable(); + + public new MarginPadding Padding + { + get => base.Padding; + set => base.Padding = value; + } + + public void Filter(string searchTerm) => ((SearchContainer>)ListContainer).SearchTerm = searchTerm; + + public BeatmapSetInfo FirstVisibleSet => Items.FirstOrDefault(i => ((DrawablePlaylistItem)ItemMap[i]).MatchingFilter); + + protected override RearrangeableListItem CreateDrawable(BeatmapSetInfo item) => new DrawablePlaylistItem(item) + { + SelectedSet = { BindTarget = SelectedSet }, + RequestSelection = set => RequestSelection?.Invoke(set) + }; + + protected override ScrollContainer CreateScrollContainer() => new OsuScrollContainer(); + + protected override FillFlowContainer> CreateListFillFlowContainer() => new SearchContainer> + { + Spacing = new Vector2(0, 3), + LayoutDuration = 200, + LayoutEasing = Easing.OutQuint, + }; + } +} diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs deleted file mode 100644 index d40f391982..0000000000 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ /dev/null @@ -1,183 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using System.Linq; -using osuTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Events; -using osu.Framework.Localisation; -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osuTK; - -namespace osu.Game.Overlays.Music -{ - public class PlaylistItem : Container, IFilterable, IDraggable - { - private const float fade_duration = 100; - - private Color4 hoverColour; - private Color4 artistColour; - - private SpriteIcon handle; - private TextFlowContainer text; - private IEnumerable titleSprites; - private ILocalisedBindableString titleBind; - private ILocalisedBindableString artistBind; - - public readonly BeatmapSetInfo BeatmapSetInfo; - - public Action OnSelect; - - public bool IsDraggable { get; private set; } - - protected override bool OnMouseDown(MouseDownEvent e) - { - IsDraggable = handle.IsHovered; - return base.OnMouseDown(e); - } - - protected override void OnMouseUp(MouseUpEvent e) - { - IsDraggable = false; - base.OnMouseUp(e); - } - - private bool selected; - - public bool Selected - { - get => selected; - set - { - if (value == selected) return; - - selected = value; - - FinishTransforms(true); - foreach (Drawable s in titleSprites) - s.FadeColour(Selected ? hoverColour : Color4.White, fade_duration); - } - } - - public PlaylistItem(BeatmapSetInfo setInfo) - { - BeatmapSetInfo = setInfo; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Padding = new MarginPadding { Top = 3, Bottom = 3 }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours, LocalisationManager localisation) - { - hoverColour = colours.Yellow; - artistColour = colours.Gray9; - - var metadata = BeatmapSetInfo.Metadata; - FilterTerms = metadata.SearchableTerms; - - Children = new Drawable[] - { - handle = new PlaylistItemHandle - { - Colour = colours.Gray5 - }, - text = new OsuTextFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = 20 }, - ContentIndent = 10f, - }, - }; - - titleBind = localisation.GetLocalisedString(new LocalisedString((metadata.TitleUnicode, metadata.Title))); - artistBind = localisation.GetLocalisedString(new LocalisedString((metadata.ArtistUnicode, metadata.Artist))); - - artistBind.BindValueChanged(_ => recreateText(), true); - } - - private void recreateText() - { - 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(); - - text.AddText(artistBind.Value, sprite => - { - sprite.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); - sprite.Colour = artistColour; - sprite.Padding = new MarginPadding { Top = 1 }; - }); - } - - protected override bool OnHover(HoverEvent e) - { - handle.FadeIn(fade_duration); - - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - handle.FadeOut(fade_duration); - } - - protected override bool OnClick(ClickEvent e) - { - OnSelect?.Invoke(BeatmapSetInfo); - return true; - } - - public IEnumerable FilterTerms { get; private set; } - - private bool matching = true; - - public bool MatchingFilter - { - get => matching; - set - { - if (matching == value) return; - - matching = value; - - this.FadeTo(matching ? 1 : 0, 200); - } - } - - public bool FilteringActive { get; set; } - - private class PlaylistItemHandle : SpriteIcon - { - public PlaylistItemHandle() - { - Anchor = Anchor.CentreLeft; - Origin = Anchor.CentreLeft; - Size = new Vector2(12); - Icon = FontAwesome.Solid.Bars; - Alpha = 0f; - Margin = new MarginPadding { Left = 5 }; - } - - public override bool HandlePositionalInput => IsPresent; - } - } - - public interface IDraggable : IDrawable - { - /// - /// Whether this can be dragged in its current state. - /// - bool IsDraggable { get; } - } -} diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index a814712907..7c391e27f9 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Music private BeatmapManager beatmaps; private FilterControl filter; - private PlaylistList list; + private Playlist list; [BackgroundDependencyLoader] private void load(OsuColour colours, Bindable beatmap, BeatmapManager beatmaps) @@ -57,7 +57,7 @@ namespace osu.Game.Overlays.Music Colour = colours.Gray3, RelativeSizeAxes = Axes.Both, }, - list = new PlaylistList + list = new Playlist { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 95, Bottom = 10, Right = 10 }, From 0c4540b551138d3ca0676469071c0f0d18315ce5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 30 Jan 2020 19:23:53 +0900 Subject: [PATCH 0078/1142] Rename PlaylistItem --- osu.Game/Overlays/Music/Playlist.cs | 4 ++-- .../Music/{DrawablePlaylistItem.cs => PlaylistItem.cs} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Overlays/Music/{DrawablePlaylistItem.cs => PlaylistItem.cs} (97%) diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index ba9aaf03d4..8744a6db8b 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -26,9 +26,9 @@ namespace osu.Game.Overlays.Music public void Filter(string searchTerm) => ((SearchContainer>)ListContainer).SearchTerm = searchTerm; - public BeatmapSetInfo FirstVisibleSet => Items.FirstOrDefault(i => ((DrawablePlaylistItem)ItemMap[i]).MatchingFilter); + public BeatmapSetInfo FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); - protected override RearrangeableListItem CreateDrawable(BeatmapSetInfo item) => new DrawablePlaylistItem(item) + protected override RearrangeableListItem CreateDrawable(BeatmapSetInfo item) => new PlaylistItem(item) { SelectedSet = { BindTarget = SelectedSet }, RequestSelection = set => RequestSelection?.Invoke(set) diff --git a/osu.Game/Overlays/Music/DrawablePlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs similarity index 97% rename from osu.Game/Overlays/Music/DrawablePlaylistItem.cs rename to osu.Game/Overlays/Music/PlaylistItem.cs index e3dd72ae8b..4ce67c2d66 100644 --- a/osu.Game/Overlays/Music/DrawablePlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -19,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Music { - public class DrawablePlaylistItem : RearrangeableListItem, IFilterable + public class PlaylistItem : RearrangeableListItem, IFilterable { private const float fade_duration = 100; @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Music private Color4 hoverColour; private Color4 artistColour; - public DrawablePlaylistItem(BeatmapSetInfo item) + public PlaylistItem(BeatmapSetInfo item) : base(item) { RelativeSizeAxes = Axes.X; From 8e966624e02345c593501f69cabd8c78b34ec384 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 19:55:25 +0900 Subject: [PATCH 0079/1142] Fix regressing tests --- .../Visual/UserInterface/TestSceneModSelectOverlay.cs | 1 + .../Visual/UserInterface/TestSceneModSettings.cs | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 12ee4ceb2e..cd0ce26ea5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -63,6 +63,7 @@ namespace osu.Game.Tests.Visual.UserInterface RelativeSizeAxes = Axes.X, Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, + SelectedMods = { BindTarget = SelectedMods } }, modDisplay = new ModDisplay diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index e2ce2341e5..a89b4f5ba9 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -27,6 +27,13 @@ namespace osu.Game.Tests.Visual.UserInterface private readonly Mod testCustomisableAutoOpenMod = new TestModCustomisable2(); + [SetUp] + public void SetUp() => Schedule(() => + { + SelectedMods.Value = Array.Empty(); + Ruleset.Value = new TestRulesetInfo(); + }); + [Test] public void TestButtonShowsOnCustomisableMod() { @@ -70,13 +77,12 @@ namespace osu.Game.Tests.Visual.UserInterface { AddStep("create mod select", () => { - Ruleset.Value = new TestRulesetInfo(); - Child = modSelect = new TestModSelectOverlay { RelativeSizeAxes = Axes.X, Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, + SelectedMods = { BindTarget = SelectedMods } }; }); } From 3f62c40e709bd1ac2d66abe6f33578fa99ed8aec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 13:55:50 +0300 Subject: [PATCH 0080/1142] Increase spacing --- .../Profile/Sections/Recent/PaginatedRecentActivityContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 7a9cce4675..a37f398272 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent : base(user, header, missing) { ItemsPerPage = 10; - ItemsContainer.Spacing = new Vector2(0, 5); + ItemsContainer.Spacing = new Vector2(0, 8); } protected override APIRequest> CreateRequest() => From 3002366e70281b1bc600c741239a529b114ae9f1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 13:56:19 +0300 Subject: [PATCH 0081/1142] Adjust mode part --- .../Requests/Responses/APIRecentActivity.cs | 31 ++++++++++++++++++- .../Sections/Recent/DrawableRecentActivity.cs | 4 +-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs index 8695d09570..92b520c36b 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -41,8 +41,37 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("count")] public int Count; + public string Mode { get; private set; } + [JsonProperty("mode")] - public string Mode; + private string mode + { + set + { + switch (value) + { + default: + Mode = value; + return; + + case "osu": + Mode = "osu!"; + return; + + case "mania": + Mode = "osu!mania"; + return; + + case "taiko": + Mode = "osu!taiko"; + return; + + case "fruits": + Mode = "osu!catch"; + return; + } + } + } [JsonProperty("beatmap")] public RecentActivityBeatmap Beatmap; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index d5bdcffeef..3f8ab93abd 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -185,14 +185,14 @@ namespace osu.Game.Overlays.Profile.Sections.Recent addUserLink(); addText($" achieved rank #{activity.Rank} on "); addBeatmapLink(); - addText($" ({activity.Mode}!)"); + addText($" ({activity.Mode})"); break; case RecentActivityType.RankLost: addUserLink(); addText(" has lost first place on "); addBeatmapLink(); - addText($" ({activity.Mode}!)"); + addText($" ({activity.Mode})"); break; case RecentActivityType.UserSupportAgain: From 3db4c11f29979057147f0e3589ed3009e917ec13 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 14:05:55 +0300 Subject: [PATCH 0082/1142] CI fix --- osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs index 92b520c36b..b416085217 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -41,7 +41,7 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("count")] public int Count; - public string Mode { get; private set; } + public string Mode; [JsonProperty("mode")] private string mode From 878250056c1dc4096c76c8ace223a6cc202f6787 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 23:34:04 +0900 Subject: [PATCH 0083/1142] Remove unused parameter --- osu.Game/OsuGame.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 374bacde00..321cb25088 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -327,7 +327,7 @@ namespace osu.Game return; } - performFromScreen(screen => + PerformFromScreen(screen => { // we might already be at song select, so a check is required before performing the load to solo. if (screen is MainMenu) @@ -344,7 +344,7 @@ namespace osu.Game Ruleset.Value = first.Ruleset; Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); - }, $"load {beatmap}", validScreens: new[] { typeof(PlaySongSelect) }); + }, validScreens: new[] { typeof(PlaySongSelect) }); } /// @@ -381,12 +381,12 @@ namespace osu.Game return; } - performFromScreen(screen => + PerformFromScreen(screen => { Beatmap.Value = BeatmapManager.GetWorkingBeatmap(databasedBeatmap); screen.Push(new ReplayPlayerLoader(databasedScore)); - }, $"watch {databasedScoreInfo}"); + }); } protected virtual Loader CreateLoader() => new Loader(); @@ -445,9 +445,8 @@ namespace osu.Game /// Eagerly tries to exit the current screen until it succeeds. /// /// The action to perform once we are in the correct state. - /// The task name to display in a notification (if we can't immediately reach the main menu state). /// An optional collection of valid screen types. If any of these screens are already current we can immediately perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. - private void performFromScreen(Action action, string taskName, IEnumerable validScreens = null) + protected void PerformFromScreen(Action action, IEnumerable validScreens = null) { performFromMainMenuTask?.Cancel(); @@ -477,7 +476,7 @@ namespace osu.Game screen = screen.GetParentScreen(); } - performFromMainMenuTask = Schedule(() => performFromScreen(action, taskName, validScreens)); + performFromMainMenuTask = Schedule(() => PerformFromScreen(action, validScreens)); } /// From 6b24b7687f68137c6dfca6fdb10b7121275eba3f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 23:45:15 +0900 Subject: [PATCH 0084/1142] Add test coverage --- .../Visual/Navigation/OsuGameTestScene.cs | 11 +++ .../Navigation/TestScenePerformFromScreen.cs | 72 +++++++++++++++++++ .../Navigation/TestSceneScreenNavigation.cs | 19 ++--- 3 files changed, 88 insertions(+), 14 deletions(-) create mode 100644 osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index 662d9977ba..8d2e4a614d 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.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; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Configuration; @@ -76,6 +78,13 @@ namespace osu.Game.Tests.Visual.Navigation ConfirmAtMainMenu(); } + protected void PushAndConfirm(Func newScreen) + { + Screen screen = null; + AddStep("Push new screen", () => Game.ScreenStack.Push(screen = newScreen())); + AddUntilStep("Wait for new screen", () => Game.ScreenStack.CurrentScreen == screen && screen.IsLoaded); + } + protected void ConfirmAtMainMenu() => AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded); public class TestOsuGame : OsuGame @@ -96,6 +105,8 @@ namespace osu.Game.Tests.Visual.Navigation protected override Loader CreateLoader() => new TestLoader(); + public new void PerformFromScreen(Action action, IEnumerable validScreens = null) => base.PerformFromScreen(action, validScreens); + public TestOsuGame(Storage storage, IAPIProvider api) { Storage = storage; diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs new file mode 100644 index 0000000000..75c6a2b733 --- /dev/null +++ b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs @@ -0,0 +1,72 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Game.Screens.Menu; +using osu.Game.Screens.Play; +using osu.Game.Screens.Select; + +namespace osu.Game.Tests.Visual.Navigation +{ + public class TestScenePerformFromScreen : OsuGameTestScene + { + [Test] + public void TestPerformAtMenu() + { + AddAssert("could perform immediately", () => + { + bool actionPerformed = false; + Game.PerformFromScreen(_ => actionPerformed = true); + return actionPerformed; + }); + } + + [Test] + public void TestPerformAtSongSelect() + { + PushAndConfirm(() => new PlaySongSelect()); + + AddAssert("could perform immediately", () => + { + bool actionPerformed = false; + Game.PerformFromScreen(_ => actionPerformed = true, new[] { typeof(PlaySongSelect) }); + return actionPerformed; + }); + } + + [Test] + public void TestPerformAtMenuFromSongSelect() + { + PushAndConfirm(() => new PlaySongSelect()); + + bool actionPerformed = false; + AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true)); + AddUntilStep("returned to menu", () => Game.ScreenStack.CurrentScreen is MainMenu); + AddAssert("did perform", () => actionPerformed); + } + + [Test] + public void TestPerformAtSongSelectFromPlayerLoader() + { + PushAndConfirm(() => new PlaySongSelect()); + PushAndConfirm(() => new PlayerLoader(() => new Player())); + + bool actionPerformed = false; + AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true, new[] { typeof(PlaySongSelect) })); + AddUntilStep("returned to song select", () => Game.ScreenStack.CurrentScreen is PlaySongSelect); + AddAssert("did perform", () => actionPerformed); + } + + [Test] + public void TestPerformAtMenuFromPlayerLoader() + { + PushAndConfirm(() => new PlaySongSelect()); + PushAndConfirm(() => new PlayerLoader(() => new Player())); + + bool actionPerformed = false; + AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true)); + AddUntilStep("returned to song select", () => Game.ScreenStack.CurrentScreen is MainMenu); + AddAssert("did perform", () => actionPerformed); + } + } +} diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index d706d47384..8258cc9465 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -1,13 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Containers; -using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Overlays; using osu.Game.Overlays.Mods; @@ -32,7 +30,7 @@ namespace osu.Game.Tests.Visual.Navigation { TestSongSelect songSelect = null; - pushAndConfirm(() => songSelect = new TestSongSelect()); + PushAndConfirm(() => songSelect = new TestSongSelect()); AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show()); AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible); pushEscape(); @@ -49,7 +47,7 @@ namespace osu.Game.Tests.Visual.Navigation WorkingBeatmap beatmap() => Game.Beatmap.Value; Track track() => beatmap().Track; - pushAndConfirm(() => new TestSongSelect()); + PushAndConfirm(() => new TestSongSelect()); AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait()); @@ -77,7 +75,7 @@ namespace osu.Game.Tests.Visual.Navigation { TestSongSelect songSelect = null; - pushAndConfirm(() => songSelect = new TestSongSelect()); + PushAndConfirm(() => songSelect = new TestSongSelect()); AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show()); AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible); AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition)); @@ -93,14 +91,14 @@ namespace osu.Game.Tests.Visual.Navigation [Test] public void TestExitMultiWithEscape() { - pushAndConfirm(() => new Screens.Multi.Multiplayer()); + PushAndConfirm(() => new Screens.Multi.Multiplayer()); exitViaEscapeAndConfirm(); } [Test] public void TestExitMultiWithBackButton() { - pushAndConfirm(() => new Screens.Multi.Multiplayer()); + PushAndConfirm(() => new Screens.Multi.Multiplayer()); exitViaBackButtonAndConfirm(); } @@ -116,13 +114,6 @@ namespace osu.Game.Tests.Visual.Navigation AddAssert("Options overlay was closed", () => Game.Settings.State.Value == Visibility.Hidden); } - private void pushAndConfirm(Func newScreen) - { - Screen screen = null; - AddStep("Push new screen", () => Game.ScreenStack.Push(screen = newScreen())); - AddUntilStep("Wait for new screen", () => Game.ScreenStack.CurrentScreen == screen && screen.IsLoaded); - } - private void pushEscape() => AddStep("Press escape", () => pressAndRelease(Key.Escape)); From f51cfa22204c3b4da2ebbd3eb3d32912f11d576f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 00:24:00 +0900 Subject: [PATCH 0085/1142] Fix too many ticks being displayed on beatmaps with multiple timing sections Closes https://github.com/ppy/osu/issues/7681. --- .../Edit/Compose/Components/Timeline/TimelineTickDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index f9b92c0504..b565a42c5a 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = beatmap.ControlPointInfo.TimingPoints.Count < i + 1 ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; + var until = beatmap.ControlPointInfo.TimingPoints.Count > i + 1 ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; int beat = 0; From 40a44357925e9e0479aaf8b315935655e12605eb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 00:33:24 +0900 Subject: [PATCH 0086/1142] Fix chat test intermittently failing Was throwing exception instead of returning false due to LINQ Single() call. --- osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 29bda524e8..1561d0d11d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -104,7 +104,11 @@ namespace osu.Game.Tests.Visual.Online public void TestSearchInSelector() { AddStep("search for 'test2'", () => chatOverlay.ChildrenOfType().First().Text = "test2"); - AddUntilStep("only channel 2 visible", () => chatOverlay.ChildrenOfType().Single(c => c.IsPresent).Channel == channel2); + AddUntilStep("only channel 2 visible", () => + { + var listItems = chatOverlay.ChildrenOfType().Where(c => c.IsPresent); + return listItems.Count() == 1 && listItems.Single().Channel == channel2; + }); } private void clickDrawable(Drawable d) From 682d0e6e712984007307e0d3679d23f53da0860b Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 17:46:59 +0100 Subject: [PATCH 0087/1142] Fix typo in variable --- .../Overlays/Profile/Header/BottomHeaderContainer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index b6c6f33678..aa8b332bd3 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -111,14 +111,14 @@ namespace osu.Game.Overlays.Profile.Header topLinkContainer.AddText("Contributed "); topLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: embolden); - string websiteWithoutProtcol = user.Website; + string websiteWithoutProtocol = user.Website; - if (!string.IsNullOrEmpty(websiteWithoutProtcol)) + if (!string.IsNullOrEmpty(websiteWithoutProtocol)) { - if (Uri.TryCreate(websiteWithoutProtcol, UriKind.Absolute, out var uri)) + if (Uri.TryCreate(websiteWithoutProtocol, UriKind.Absolute, out var uri)) { - websiteWithoutProtcol = uri.Host + uri.PathAndQuery + uri.Fragment; - websiteWithoutProtcol = websiteWithoutProtcol.TrimEnd('/'); + websiteWithoutProtocol = uri.Host + uri.PathAndQuery + uri.Fragment; + websiteWithoutProtocol = websiteWithoutProtocol.TrimEnd('/'); } } @@ -131,7 +131,7 @@ namespace osu.Game.Overlays.Profile.Header tryAddInfo(FontAwesome.Brands.Discord, user.Discord); tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); - tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtcol, user.Website); + tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); } private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); From 754200d84358b740f80c744be45018d6968a32f6 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 18:10:40 +0100 Subject: [PATCH 0088/1142] Fix padding when user has no additional info --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index aa8b332bd3..7531cab024 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -132,6 +132,10 @@ namespace osu.Game.Overlays.Profile.Header tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); + + // Hide the container to prevent adding unnecessary padding if it has no children other than the NewLine + if (!bottomLinkContainer.Children.Skip(1).Any()) + bottomLinkContainer.Hide(); } private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); From de9a1737a5f04800c5c1ee2f1dbb9c23a9ffa226 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 18:18:42 +0100 Subject: [PATCH 0089/1142] Recolour LevelProgressBar --- .../Overlays/Profile/Header/Components/LevelProgressBar.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs index a73ce56a2b..c97df3bc4d 100644 --- a/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs +++ b/osu.Game/Overlays/Profile/Header/Components/LevelProgressBar.cs @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { InternalChildren = new Drawable[] { @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.Profile.Header.Components RelativeSizeAxes = Axes.Both, BackgroundColour = Color4.Black, Direction = BarDirection.LeftToRight, - AccentColour = colours.Yellow + AccentColour = colourProvider.Highlight1 } }, levelProgressText = new OsuSpriteText From e69d93ae5c01b90d0a5d6fea4c0aa58bd4f86e2e Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 19:26:42 +0100 Subject: [PATCH 0090/1142] Adjust ProfileTabControl height --- osu.Game/Overlays/UserProfileOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 6f0d96c226..045a52a0c7 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -67,7 +67,7 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Height = 30 + Height = 34 }; Add(new Box From 1751e96840e345d6c51b95eec54dd9f692052807 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 19:45:12 +0100 Subject: [PATCH 0091/1142] Recolour ProfileHeaderButton --- .../Profile/Header/Components/ProfileHeaderButton.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs index ddcf011277..ae94f3485f 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -24,9 +25,6 @@ namespace osu.Game.Overlays.Profile.Header.Components { AutoSizeAxes = Axes.X; - IdleColour = Color4.Black; - HoverColour = OsuColour.Gray(0.1f); - base.Content.Add(new CircularContainer { Masking = true, @@ -47,5 +45,12 @@ namespace osu.Game.Overlays.Profile.Header.Components } }); } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + IdleColour = colourProvider.Background6; + HoverColour = colourProvider.Background5; + } } } From 3970151e31bbc571fbee4b3fe4f7fc159488827f Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 20:51:33 +0100 Subject: [PATCH 0092/1142] Improve condition check --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 7531cab024..86e816a28c 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -15,6 +15,7 @@ using osu.Game.Graphics.Containers; using osu.Game.Users; using osuTK; using osuTK.Graphics; +using static osu.Framework.Graphics.Containers.TextFlowContainer; namespace osu.Game.Overlays.Profile.Header { @@ -133,9 +134,12 @@ namespace osu.Game.Overlays.Profile.Header tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); - // Hide the container to prevent adding unnecessary padding if it has no children other than the NewLine - if (!bottomLinkContainer.Children.Skip(1).Any()) + // Hide the container to prevent adding unnecessary padding if it has no children other than the NewLineContainer + if (!bottomLinkContainer.Children.Any(child => !(child is NewLineContainer))) bottomLinkContainer.Hide(); + else + // this is needed if user gets changed without the whole header being reloaded + bottomLinkContainer.Show(); } private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); From a3877cc29e549999d82bd8e45c2de37e50b2c83d Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 20:55:44 +0100 Subject: [PATCH 0093/1142] Recolour RankGraph circle --- osu.Game/Overlays/Profile/Header/Components/RankGraph.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 250b345db7..aed63293ea 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -167,9 +167,9 @@ namespace osu.Game.Overlays.Profile.Header.Components } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider, OsuColour colours) { - ballBg.Colour = colours.GreySeafoamDarker; + ballBg.Colour = colourProvider.Background5; movingBall.BorderColour = line.Colour = colours.Yellow; } From fcd05b5a3c1ddd70a0afcd314fa732d2d481bf76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 30 Jan 2020 21:17:46 +0100 Subject: [PATCH 0094/1142] Add failing test --- .../Visual/Online/TestSceneChatOverlay.cs | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs index 1561d0d11d..19bdaff6ff 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs @@ -38,9 +38,21 @@ namespace osu.Game.Tests.Visual.Online private TestChatOverlay chatOverlay; private ChannelManager channelManager; - private readonly Channel channel1 = new Channel(new User()) { Name = "test really long username", Topic = "Topic for channel 1" }; - private readonly Channel channel2 = new Channel(new User()) { Name = "test2", Topic = "Topic for channel 2" }; - private readonly Channel channel3 = new Channel(new User()) { Name = "channel with no topic" }; + private readonly List channels; + + private Channel channel1 => channels[0]; + private Channel channel2 => channels[1]; + + public TestSceneChatOverlay() + { + channels = Enumerable.Range(1, 10) + .Select(index => new Channel(new User()) + { + Name = $"Channel no. {index}", + Topic = index == 3 ? null : $"We talk about the number {index} here" + }) + .ToList(); + } [SetUp] public void Setup() @@ -49,7 +61,7 @@ namespace osu.Game.Tests.Visual.Online { ChannelManagerContainer container; - Child = container = new ChannelManagerContainer(new List { channel1, channel2, channel3 }) + Child = container = new ChannelManagerContainer(channels) { RelativeSizeAxes = Axes.Both, }; @@ -103,7 +115,7 @@ namespace osu.Game.Tests.Visual.Online [Test] public void TestSearchInSelector() { - AddStep("search for 'test2'", () => chatOverlay.ChildrenOfType().First().Text = "test2"); + AddStep("search for 'no. 2'", () => chatOverlay.ChildrenOfType().First().Text = "no. 2"); AddUntilStep("only channel 2 visible", () => { var listItems = chatOverlay.ChildrenOfType().Where(c => c.IsPresent); @@ -111,6 +123,36 @@ namespace osu.Game.Tests.Visual.Online }); } + [Test] + public void TestChannelShortcutKeys() + { + AddStep("join 10 channels", () => channels.ForEach(channel => channelManager.JoinChannel(channel))); + AddStep("close channel selector", () => + { + InputManager.PressKey(Key.Escape); + InputManager.ReleaseKey(Key.Escape); + }); + AddUntilStep("wait for close", () => chatOverlay.SelectionOverlayState == Visibility.Hidden); + + for (int zeroBasedIndex = 0; zeroBasedIndex < 10; ++zeroBasedIndex) + { + var oneBasedIndex = zeroBasedIndex + 1; + var targetNumberKey = oneBasedIndex % 10; + var targetChannel = channels[zeroBasedIndex]; + AddStep($"press Alt+{targetNumberKey}", () => pressChannelHotkey(targetNumberKey)); + AddAssert($"channel #{oneBasedIndex} is selected", () => channelManager.CurrentChannel.Value == targetChannel); + } + } + + private void pressChannelHotkey(int number) + { + var channelKey = Key.Number0 + number; + InputManager.PressKey(Key.AltLeft); + InputManager.PressKey(channelKey); + InputManager.ReleaseKey(Key.AltLeft); + InputManager.ReleaseKey(channelKey); + } + private void clickDrawable(Drawable d) { InputManager.MoveMouseTo(d); From c38dc815351616ff14ce3b7941ab736d9df18c94 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 21:39:06 +0100 Subject: [PATCH 0095/1142] Remove unnecessary using --- .../Overlays/Profile/Header/Components/ProfileHeaderButton.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs index ae94f3485f..e14d73dd98 100644 --- a/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs +++ b/osu.Game/Overlays/Profile/Header/Components/ProfileHeaderButton.cs @@ -6,9 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { From 155344400181a321a79cb100a3490c6cc128848a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 30 Jan 2020 21:44:53 +0100 Subject: [PATCH 0096/1142] Fix channel tab keyboard shortcut Filter out the selector tab item at the point of enumerating tabs to fix the regression of the Alt+number key shortcut. --- osu.Game/Overlays/ChatOverlay.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 2c0fa49b5d..9e48ee5041 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -321,8 +321,11 @@ namespace osu.Game.Overlays private void selectTab(int index) { - var channel = ChannelTabControl.Items.Skip(index).FirstOrDefault(); - if (channel != null && !(channel is ChannelSelectorTabItem.ChannelSelectorTabChannel)) + var channel = ChannelTabControl.Items + .Where(tab => !(tab is ChannelSelectorTabItem.ChannelSelectorTabChannel)) + .Skip(index) + .FirstOrDefault(); + if (channel != null) ChannelTabControl.Current.Value = channel; } From caf76511a73d8b7b73965bba85b7fa5ebe2ea402 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 21:45:42 +0100 Subject: [PATCH 0097/1142] Remove double negation --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 86e816a28c..469f9caf4a 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -135,7 +135,7 @@ namespace osu.Game.Overlays.Profile.Header tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); // Hide the container to prevent adding unnecessary padding if it has no children other than the NewLineContainer - if (!bottomLinkContainer.Children.Any(child => !(child is NewLineContainer))) + if (bottomLinkContainer.Children.All(child => child is NewLineContainer)) bottomLinkContainer.Hide(); else // this is needed if user gets changed without the whole header being reloaded From c050eed79b08e07087e337ac582da48fae0e4470 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 30 Jan 2020 22:05:06 +0100 Subject: [PATCH 0098/1142] Recolour RankGraphTooltip --- osu.Game/Overlays/Profile/Header/Components/RankGraph.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index aed63293ea..a742711d26 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -16,6 +16,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Users; using osuTK; +using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { @@ -270,7 +271,8 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load(OsuColour colours) { - background.Colour = colours.GreySeafoamDark; + // To match osu-web, background and text should both be coloured using OverlayColourProvider + background.Colour = colours.Gray1; } public bool SetContent(object content) From b03e7f12ff0e22b0b7c0279bd27ac75fc79b0bcf Mon Sep 17 00:00:00 2001 From: Tree Date: Thu, 30 Jan 2020 22:51:35 +0100 Subject: [PATCH 0099/1142] Remove unused directive --- osu.Game/Overlays/Profile/Header/Components/RankGraph.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index a742711d26..83c6d80dae 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -16,7 +16,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Users; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Header.Components { From 9a1907d8e07fe2a3bfa92d71dbe8a4912ebbea1a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 09:48:20 +0900 Subject: [PATCH 0100/1142] Apply doc fixes from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- osu.Game/OsuGame.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 321cb25088..fb3ce00824 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -441,11 +441,11 @@ namespace osu.Game private ScheduledDelegate performFromMainMenuTask; /// - /// Perform an action only after returning to a specific screen specification. + /// Perform an action only after returning to a specific screen as indicated by . /// Eagerly tries to exit the current screen until it succeeds. /// /// The action to perform once we are in the correct state. - /// An optional collection of valid screen types. If any of these screens are already current we can immediately perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. + /// An optional collection of valid screen types. If any of these screens are already current we can perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. protected void PerformFromScreen(Action action, IEnumerable validScreens = null) { performFromMainMenuTask?.Cancel(); From 5f48affcbaa3d8a9a36bb44474fbc0fb616ee296 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 13:54:26 +0900 Subject: [PATCH 0101/1142] Centralise screen exit logic to ScreenTestScene --- .../Gameplay/TestSceneAllRulesetPlayers.cs | 57 ++++++++++++------- .../Visual/Gameplay/TestSceneAutoplay.cs | 2 +- .../Visual/Gameplay/TestSceneFailAnimation.cs | 4 +- .../Visual/Gameplay/TestSceneFailJudgement.cs | 2 +- .../Visual/Gameplay/TestScenePause.cs | 1 + .../TestScenePlayerReferenceLeaking.cs | 2 +- .../Visual/Gameplay/TestSceneReplay.cs | 2 +- .../SongSelect/TestScenePlaySongSelect.cs | 27 ++++----- osu.Game/Screens/Play/Player.cs | 2 + osu.Game/Tests/Visual/PlayerTestScene.cs | 4 +- osu.Game/Tests/Visual/ScreenTestScene.cs | 20 ++++++- 11 files changed, 76 insertions(+), 47 deletions(-) rename osu.Game/Tests/Visual/AllPlayersTestScene.cs => osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs (59%) diff --git a/osu.Game/Tests/Visual/AllPlayersTestScene.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs similarity index 59% rename from osu.Game/Tests/Visual/AllPlayersTestScene.cs rename to osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs index dd65c8c382..83a7b896d2 100644 --- a/osu.Game/Tests/Visual/AllPlayersTestScene.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs @@ -2,49 +2,66 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Screens; using osu.Game.Configuration; using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; using osu.Game.Screens.Play; -namespace osu.Game.Tests.Visual +namespace osu.Game.Tests.Visual.Gameplay { /// /// A base class which runs test for all available rulesets. /// Steps to be run for each ruleset should be added via . /// - public abstract class AllPlayersTestScene : RateAdjustedBeatmapTestScene + public abstract class TestSceneAllRulesetPlayers : RateAdjustedBeatmapTestScene { protected Player Player; [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - foreach (var r in rulesets.AvailableRulesets) - { - Player p = null; - AddStep(r.Name, () => p = loadPlayerFor(r)); - AddUntilStep("player loaded", () => - { - if (p?.IsLoaded == true) - { - p = null; - return true; - } - - return false; - }); - - AddCheckSteps(); - } - OsuConfigManager manager; Dependencies.Cache(manager = new OsuConfigManager(LocalStorage)); manager.GetBindable(OsuSetting.DimLevel).Value = 1.0; } + [Test] + public void TestOsu() => runForRuleset(new OsuRuleset().RulesetInfo); + + [Test] + public void TestTaiko() => runForRuleset(new TaikoRuleset().RulesetInfo); + + [Test] + public void TestCatch() => runForRuleset(new CatchRuleset().RulesetInfo); + + [Test] + public void TestMania() => runForRuleset(new ManiaRuleset().RulesetInfo); + + private void runForRuleset(RulesetInfo ruleset) + { + Player p = null; + AddStep($"load {ruleset.Name} player", () => p = loadPlayerFor(ruleset)); + AddUntilStep("player loaded", () => + { + if (p?.IsLoaded == true) + { + p = null; + return true; + } + + return false; + }); + + AddCheckSteps(); + } + protected abstract void AddCheckSteps(); private Player loadPlayerFor(RulesetInfo rulesetInfo) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs index 069b965d9b..4daab8d137 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs @@ -12,7 +12,7 @@ using osu.Game.Storyboards; namespace osu.Game.Tests.Visual.Gameplay { [Description("Player instantiated with an autoplay mod.")] - public class TestSceneAutoplay : AllPlayersTestScene + public class TestSceneAutoplay : TestSceneAllRulesetPlayers { private ClockBackedTestWorkingBeatmap.TrackVirtualManual track; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs index 81050b1637..de257c9e53 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneFailAnimation : AllPlayersTestScene + public class TestSceneFailAnimation : TestSceneAllRulesetPlayers { protected override Player CreatePlayer(Ruleset ruleset) { @@ -20,7 +20,7 @@ namespace osu.Game.Tests.Visual.Gameplay public override IReadOnlyList RequiredTypes => new[] { - typeof(AllPlayersTestScene), + typeof(TestSceneAllRulesetPlayers), typeof(TestPlayer), typeof(Player), }; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs index 2045072c79..d80efb2c6e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneFailJudgement.cs @@ -10,7 +10,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Gameplay { - public class TestSceneFailJudgement : AllPlayersTestScene + public class TestSceneFailJudgement : TestSceneAllRulesetPlayers { protected override Player CreatePlayer(Ruleset ruleset) { diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs index 1a83e35e4f..ad5bab4681 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs @@ -36,6 +36,7 @@ namespace osu.Game.Tests.Visual.Gameplay public override void SetUpSteps() { base.SetUpSteps(); + AddStep("resume player", () => Player.GameplayClockContainer.Start()); confirmClockRunning(true); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs index 4d701f56a9..8f767659c6 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerReferenceLeaking.cs @@ -10,7 +10,7 @@ using osu.Game.Storyboards; namespace osu.Game.Tests.Visual.Gameplay { - public class TestScenePlayerReferenceLeaking : AllPlayersTestScene + public class TestScenePlayerReferenceLeaking : TestSceneAllRulesetPlayers { private readonly WeakList workingWeakReferences = new WeakList(); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs index 36335bc54a..e82722e7a2 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplay.cs @@ -13,7 +13,7 @@ using osu.Game.Screens.Play; namespace osu.Game.Tests.Visual.Gameplay { [Description("Player instantiated with a replay.")] - public class TestSceneReplay : AllPlayersTestScene + public class TestSceneReplay : TestSceneAllRulesetPlayers { protected override Player CreatePlayer(Ruleset ruleset) { diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index fc06780431..189420dcef 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -79,12 +79,17 @@ namespace osu.Game.Tests.Visual.SongSelect private OsuConfigManager config; - [SetUp] - public virtual void SetUp() => Schedule(() => + [SetUpSteps] + public override void SetUpSteps() { - Ruleset.Value = new OsuRuleset().RulesetInfo; - manager?.Delete(manager.GetAllUsableBeatmapSets()); - }); + base.SetUpSteps(); + + AddStep("delete all beatmaps", () => + { + Ruleset.Value = new OsuRuleset().RulesetInfo; + manager?.Delete(manager.GetAllUsableBeatmapSets()); + }); + } [Test] public void TestSingleFilterOnEnter() @@ -120,9 +125,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen()); AddAssert("ensure selection changed", () => selected != Beatmap.Value); - - AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen()); - AddUntilStep("bindable lease returned", () => !Beatmap.Disabled); } [Test] @@ -148,9 +150,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen()); AddAssert("ensure selection didn't change", () => selected == Beatmap.Value); - - AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen()); - AddUntilStep("bindable lease returned", () => !Beatmap.Disabled); } [Test] @@ -180,9 +179,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen()); AddAssert("ensure selection changed", () => selected != Beatmap.Value); - - AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen()); - AddUntilStep("bindable lease returned", () => !Beatmap.Disabled); } [Test] @@ -213,9 +209,6 @@ namespace osu.Game.Tests.Visual.SongSelect AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen()); AddAssert("ensure selection didn't change", () => selected == Beatmap.Value); - - AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen()); - AddUntilStep("bindable lease returned", () => !Beatmap.Disabled); } [Test] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7228e22382..8a288f8299 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -39,6 +39,8 @@ namespace osu.Game.Screens.Play public override float BackgroundParallaxAmount => 0.1f; + public override bool DisallowExternalBeatmapRulesetChanges => true; + public override bool HideOverlaysOnEnter => true; public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs index 3ed65bee61..7c5ba7d30f 100644 --- a/osu.Game/Tests/Visual/PlayerTestScene.cs +++ b/osu.Game/Tests/Visual/PlayerTestScene.cs @@ -33,8 +33,10 @@ namespace osu.Game.Tests.Visual } [SetUpSteps] - public virtual void SetUpSteps() + public override void SetUpSteps() { + base.SetUpSteps(); + AddStep(ruleset.RulesetInfo.Name, loadPlayer); AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1); } diff --git a/osu.Game/Tests/Visual/ScreenTestScene.cs b/osu.Game/Tests/Visual/ScreenTestScene.cs index 707aa61283..e501aa33b3 100644 --- a/osu.Game/Tests/Visual/ScreenTestScene.cs +++ b/osu.Game/Tests/Visual/ScreenTestScene.cs @@ -3,6 +3,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Game.Screens; namespace osu.Game.Tests.Visual @@ -27,11 +28,24 @@ namespace osu.Game.Tests.Visual }); } - protected void LoadScreen(OsuScreen screen) + protected void LoadScreen(OsuScreen screen) => Stack.Push(screen); + + [SetUpSteps] + public virtual void SetUpSteps() => addExitAllScreensStep(); + + // pending framework update. + //[TearDownSteps] + //public void TearDownSteps() => addExitAllScreensStep(); + + private void addExitAllScreensStep() { - if (Stack.CurrentScreen != null) + AddUntilStep("exit all screens", () => + { + if (Stack.CurrentScreen == null) return true; + Stack.Exit(); - Stack.Push(screen); + return false; + }); } } } From e6783b622d2ab6ba693a956ce2bdebaec12d6e2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 14:56:42 +0900 Subject: [PATCH 0102/1142] Fix incorrectly build tests --- osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 4676f14655..bbb50c287b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -7,12 +7,10 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Graphics; using osu.Framework.IO.Stores; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Screens; using osu.Game.Screens.Play; using osu.Game.Skinning; using osu.Game.Tests.Visual; @@ -21,7 +19,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Tests { - public class TestSceneLegacyBeatmapSkin : OsuTestScene + public class TestSceneLegacyBeatmapSkin : ScreenTestScene { [Resolved] private AudioManager audio { get; set; } @@ -65,7 +63,8 @@ namespace osu.Game.Rulesets.Osu.Tests ExposedPlayer player; Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours); - Child = new OsuScreenStack(player = new ExposedPlayer(userHasCustomColours)) { RelativeSizeAxes = Axes.Both }; + + LoadScreen(player = new ExposedPlayer(userHasCustomColours)); return player; } From 97c3ce132bd7febeb1f90d7f533748ab9436236d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 15:01:37 +0900 Subject: [PATCH 0103/1142] Fix incorrect nUnit adapter version causing rider failures --- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 1d8c4708c1..9d4e016eae 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -4,7 +4,7 @@ - + From 4a444face115c69cb95f8df0e538602a2cb0d94d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 31 Jan 2020 09:46:35 +0300 Subject: [PATCH 0104/1142] Change ShowMoreButton hide logic --- osu.Game/Overlays/Comments/CommentsContainer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index d174c78666..8761b88b1e 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -181,10 +181,12 @@ namespace osu.Game.Overlays.Comments moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments; moreButton.IsLoading = false; } + else + { + moreButton.Hide(); + } commentCounter.Current.Value = response.Total; - - moreButton.FadeTo(response.HasMore ? 1 : 0); }, loadCancellation.Token); } From 3b5b799d60157ab47a7507ee3184365591d151c2 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 31 Jan 2020 09:51:56 +0300 Subject: [PATCH 0105/1142] Adjust height of ShowMore button --- osu.Game/Graphics/UserInterface/ShowMoreButton.cs | 5 +++-- osu.Game/Overlays/Comments/CommentsShowMoreButton.cs | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs index 4931a6aed6..c9cd9f1158 100644 --- a/osu.Game/Graphics/UserInterface/ShowMoreButton.cs +++ b/osu.Game/Graphics/UserInterface/ShowMoreButton.cs @@ -40,13 +40,14 @@ namespace osu.Game.Graphics.UserInterface public ShowMoreButton() { - AutoSizeAxes = Axes.Both; + Height = 30; + Width = 140; } protected override Drawable CreateContent() => new CircularContainer { Masking = true, - Size = new Vector2(140, 30), + RelativeSizeAxes = Axes.Both, Children = new Drawable[] { background = new Box diff --git a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs index ab65c9c63a..d2ff7ecb1f 100644 --- a/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs +++ b/osu.Game/Overlays/Comments/CommentsShowMoreButton.cs @@ -14,6 +14,8 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { + Height = 20; + IdleColour = colourProvider.Background2; HoverColour = colourProvider.Background1; ChevronIconColour = colourProvider.Foreground1; From ab7bbf38a8e768f0ddef1cdb902ed4b3576805f5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 16:14:55 +0900 Subject: [PATCH 0106/1142] Set default beatmap later in test initialisation --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 189420dcef..c01dee2959 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -72,8 +72,6 @@ namespace osu.Game.Tests.Visual.SongSelect // required to get bindables attached Add(music); - Beatmap.SetDefault(); - Dependencies.Cache(config = new OsuConfigManager(LocalStorage)); } @@ -88,6 +86,8 @@ namespace osu.Game.Tests.Visual.SongSelect { Ruleset.Value = new OsuRuleset().RulesetInfo; manager?.Delete(manager.GetAllUsableBeatmapSets()); + + Beatmap.SetDefault(); }); } From 2f61d3f5ad5f5697c75b8b5500246586b036c58e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 17:35:53 +0900 Subject: [PATCH 0107/1142] Fix song select remaining issue locally --- osu.Game/Screens/Select/SongSelect.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a16401a527..f9f015643d 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -345,8 +345,8 @@ namespace osu.Game.Screens.Select selectionChangedDebounce = null; } - if (performStartAction) - OnStart(); + if (performStartAction && OnStart()) + Carousel.AllowSelection = false; } /// @@ -500,6 +500,8 @@ namespace osu.Game.Screens.Select public override void OnResuming(IScreen last) { + Carousel.AllowSelection = true; + BeatmapDetails.Leaderboard.RefreshScores(); Beatmap.Value.Track.Looping = true; @@ -647,7 +649,6 @@ namespace osu.Game.Screens.Select decoupledRuleset.ValueChanged += r => Ruleset.Value = r.NewValue; decoupledRuleset.DisabledChanged += r => Ruleset.Disabled = r; - Beatmap.BindDisabledChanged(disabled => Carousel.AllowSelection = !disabled, true); Beatmap.BindValueChanged(workingBeatmapChanged); boundLocalBindables = true; From a547d2ed5c0004458911859e6a3b719d65931d03 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 18:37:16 +0900 Subject: [PATCH 0108/1142] Don't least at Player just yet --- osu.Game/Screens/Play/Player.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8a288f8299..7228e22382 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -39,8 +39,6 @@ namespace osu.Game.Screens.Play public override float BackgroundParallaxAmount => 0.1f; - public override bool DisallowExternalBeatmapRulesetChanges => true; - public override bool HideOverlaysOnEnter => true; public override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; From 19f516e710b657aacc124d433459bd0ce8fc96ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 19:10:44 +0900 Subject: [PATCH 0109/1142] Ensure OsuScreen level leases are taken out synchronously --- .../Background/TestSceneUserDimBackgrounds.cs | 8 ++-- .../Visual/Gameplay/TestScenePlayerLoader.cs | 6 ++- .../Visual/Gameplay/TestSceneResults.cs | 15 ++++++-- osu.Game.Tests/Visual/Menus/IntroTestScene.cs | 6 ++- .../Multiplayer/TestSceneMultiHeader.cs | 4 +- .../TestSceneScreenBreadcrumbControl.cs | 4 +- .../UserInterface/ScreenBreadcrumbControl.cs | 3 +- osu.Game/Screens/Multi/Multiplayer.cs | 4 +- osu.Game/Screens/OsuScreen.cs | 22 +++++++++-- osu.Game/Screens/OsuScreenStack.cs | 38 +++++++++++-------- osu.Game/Screens/Select/PlaySongSelect.cs | 5 +-- 11 files changed, 79 insertions(+), 36 deletions(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs index 589ec7e8aa..eff5bd710d 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs @@ -68,10 +68,10 @@ namespace osu.Game.Tests.Visual.Background [SetUp] public virtual void SetUp() => Schedule(() => { - Child = new OsuScreenStack(songSelect = new DummySongSelect()) - { - RelativeSizeAxes = Axes.Both - }; + var stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }; + Child = stack; + + stack.Push(songSelect = new DummySongSelect()); }); /// diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index ad5950d9fc..33ecbed62e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -207,9 +207,11 @@ namespace osu.Game.Tests.Visual.Gameplay { RelativeSizeAxes = Axes.Both; + OsuScreenStack stack; + InternalChildren = new Drawable[] { - new OsuScreenStack(screen) + stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both, }, @@ -224,6 +226,8 @@ namespace osu.Game.Tests.Visual.Gameplay Origin = Anchor.TopLeft, } }; + + stack.Push(screen); } } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs index 7790126db5..2b7a32ba17 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneResults.cs @@ -75,10 +75,16 @@ namespace osu.Game.Tests.Visual.Gameplay public void ResultsWithoutPlayer() { TestSoloResults screen = null; + OsuScreenStack stack; - AddStep("load results", () => Child = new OsuScreenStack(screen = createResultsScreen()) + AddStep("load results", () => { - RelativeSizeAxes = Axes.Both + Child = stack = new OsuScreenStack + { + RelativeSizeAxes = Axes.Both + }; + + stack.Push(screen = createResultsScreen()); }); AddUntilStep("wait for loaded", () => screen.IsLoaded); AddAssert("retry overlay not present", () => screen.RetryOverlay == null); @@ -102,11 +108,14 @@ namespace osu.Game.Tests.Visual.Gameplay public TestResultsContainer(IScreen screen) { RelativeSizeAxes = Axes.Both; + OsuScreenStack stack; - InternalChild = new OsuScreenStack(screen) + InternalChild = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both, }; + + stack.Push(screen); } } diff --git a/osu.Game.Tests/Visual/Menus/IntroTestScene.cs b/osu.Game.Tests/Visual/Menus/IntroTestScene.cs index d03d341ee4..5870ef9813 100644 --- a/osu.Game.Tests/Visual/Menus/IntroTestScene.cs +++ b/osu.Game.Tests/Visual/Menus/IntroTestScene.cs @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Menus protected IntroTestScene() { - Drawable introStack = null; + OsuScreenStack introStack = null; Children = new Drawable[] { @@ -57,10 +57,12 @@ namespace osu.Game.Tests.Visual.Menus introStack?.Expire(); - Add(introStack = new OsuScreenStack(CreateScreen()) + Add(introStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both, }); + + introStack.Push(CreateScreen()); }); } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiHeader.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiHeader.cs index 3f89f636b1..76ab402b72 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiHeader.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiHeader.cs @@ -16,7 +16,9 @@ namespace osu.Game.Tests.Visual.Multiplayer { int index = 0; - OsuScreenStack screenStack = new OsuScreenStack(new TestMultiplayerSubScreen(index)) { RelativeSizeAxes = Axes.Both }; + OsuScreenStack screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }; + + screenStack.Push(new TestMultiplayerSubScreen(index)); Children = new Drawable[] { diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs index 7386e0fa1f..77a7d819a9 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneScreenBreadcrumbControl.cs @@ -25,7 +25,9 @@ namespace osu.Game.Tests.Visual.UserInterface OsuSpriteText titleText; IScreen startScreen = new TestScreenOne(); - screenStack = new OsuScreenStack(startScreen) { RelativeSizeAxes = Axes.Both }; + + screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }; + screenStack.Push(startScreen); Children = new Drawable[] { diff --git a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs index 3e0a6c3265..e85525b2f8 100644 --- a/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs +++ b/osu.Game/Graphics/UserInterface/ScreenBreadcrumbControl.cs @@ -17,7 +17,8 @@ namespace osu.Game.Graphics.UserInterface stack.ScreenPushed += onPushed; stack.ScreenExited += onExited; - onPushed(null, stack.CurrentScreen); + if (stack.CurrentScreen != null) + onPushed(null, stack.CurrentScreen); Current.ValueChanged += current => current.NewValue.MakeCurrent(); } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 86d52ff791..9d6a459d14 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -96,7 +96,7 @@ namespace osu.Game.Screens.Multi { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = screenStack = new OsuScreenStack(loungeSubScreen = new LoungeSubScreen()) { RelativeSizeAxes = Axes.Both } + Child = screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both } }, new Header(screenStack), createButton = new HeaderButton @@ -120,6 +120,8 @@ namespace osu.Game.Screens.Multi } }; + screenStack.Push(loungeSubScreen = new LoungeSubScreen()); + screenStack.ScreenPushed += screenPushed; screenStack.ScreenExited += screenExited; } diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 6394fb8d23..61e94ae969 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using Microsoft.EntityFrameworkCore.Internal; using osu.Framework.Allocation; @@ -95,15 +96,30 @@ namespace osu.Game.Screens public Bindable> Mods { get; private set; } + private OsuScreenDependencies screenDependencies; + + internal void CreateLeasedDependencies(IReadOnlyDependencyContainer dependencies) => createDependencies(dependencies); + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) { - var screenDependencies = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, parent); + if (screenDependencies == null) + { + if (DisallowExternalBeatmapRulesetChanges) + throw new InvalidOperationException($"Screens that specify {nameof(DisallowExternalBeatmapRulesetChanges)} must be pushed immediately."); + + createDependencies(parent); + } + + return base.CreateChildDependencies(screenDependencies); + } + + private void createDependencies(IReadOnlyDependencyContainer dependencies) + { + screenDependencies = new OsuScreenDependencies(DisallowExternalBeatmapRulesetChanges, dependencies); Beatmap = screenDependencies.Beatmap; Ruleset = screenDependencies.Ruleset; Mods = screenDependencies.Mods; - - return base.CreateChildDependencies(screenDependencies); } protected BackgroundScreen Background => backgroundStack?.CurrentScreen as BackgroundScreen; diff --git a/osu.Game/Screens/OsuScreenStack.cs b/osu.Game/Screens/OsuScreenStack.cs index 0844e32d46..db577ea5e9 100644 --- a/osu.Game/Screens/OsuScreenStack.cs +++ b/osu.Game/Screens/OsuScreenStack.cs @@ -18,17 +18,6 @@ namespace osu.Game.Screens protected float ParallaxAmount => parallaxContainer.ParallaxAmount; public OsuScreenStack() - { - initializeStack(); - } - - public OsuScreenStack(IScreen baseScreen) - : base(baseScreen) - { - initializeStack(); - } - - private void initializeStack() { InternalChild = parallaxContainer = new ParallaxContainer { @@ -36,13 +25,32 @@ namespace osu.Game.Screens Child = backgroundScreenStack = new BackgroundScreenStack { RelativeSizeAxes = Axes.Both }, }; - ScreenPushed += onScreenChange; - ScreenExited += onScreenChange; + ScreenPushed += screenPushed; + ScreenExited += screenExited; } - private void onScreenChange(IScreen prev, IScreen next) + private void screenPushed(IScreen prev, IScreen next) { - parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; + if (LoadState < LoadState.Ready) + { + // dependencies must be present to stay in a sane state. + // this is generally only ever hit by test scenes. + Schedule(() => screenPushed(prev, next)); + return; + } + + // create dependencies synchronously to ensure leases are in a sane state. + ((OsuScreen)next).CreateLeasedDependencies((prev as OsuScreen)?.Dependencies ?? Dependencies); + + setParallax(next); } + + private void screenExited(IScreen prev, IScreen next) + { + setParallax(next); + } + + private void setParallax(IScreen next) => + parallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * ((IOsuScreen)next)?.BackgroundParallaxAmount ?? 1.0f; } } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 9368bac69f..347eae49f0 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -68,10 +68,7 @@ namespace osu.Game.Screens.Select SampleConfirm?.Play(); - LoadComponentAsync(player = new PlayerLoader(() => new Player()), l => - { - if (this.IsCurrentScreen()) this.Push(player); - }); + this.Push(player = new PlayerLoader(() => new Player())); return true; } From a66cdee5e98a849cfafdbbc8a955e7217a573e16 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 21:36:19 +0900 Subject: [PATCH 0110/1142] Fix missed issues --- osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs | 5 ++++- osu.Game/Screens/OsuScreenStack.cs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 4676f14655..c3742601c1 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -63,9 +63,12 @@ namespace osu.Game.Rulesets.Osu.Tests private ExposedPlayer loadBeatmap(bool userHasCustomColours, bool beatmapHasColours) { ExposedPlayer player; + OsuScreenStack stack; Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours); - Child = new OsuScreenStack(player = new ExposedPlayer(userHasCustomColours)) { RelativeSizeAxes = Axes.Both }; + Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both }; + + stack.Push(player = new ExposedPlayer(userHasCustomColours)); return player; } diff --git a/osu.Game/Screens/OsuScreenStack.cs b/osu.Game/Screens/OsuScreenStack.cs index db577ea5e9..a05933ef0e 100644 --- a/osu.Game/Screens/OsuScreenStack.cs +++ b/osu.Game/Screens/OsuScreenStack.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens [Cached] private BackgroundScreenStack backgroundScreenStack; - private ParallaxContainer parallaxContainer; + private readonly ParallaxContainer parallaxContainer; protected float ParallaxAmount => parallaxContainer.ParallaxAmount; From 3e15265a53df29d334d5aff48af57c073405c40c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 22:09:02 +0900 Subject: [PATCH 0111/1142] 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 5497a82a7a..e5a1ec2f4e 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 0ea558bbc7..b38b7ff9b1 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 a215bc65e8..6ab3c0f2d2 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From c4331f34d55772d6b6c9d04b638772724cd74ca8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 31 Jan 2020 22:09:39 +0900 Subject: [PATCH 0112/1142] Consume TearDownSteps --- osu.Game/Tests/Visual/ScreenTestScene.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Tests/Visual/ScreenTestScene.cs b/osu.Game/Tests/Visual/ScreenTestScene.cs index e501aa33b3..feca592049 100644 --- a/osu.Game/Tests/Visual/ScreenTestScene.cs +++ b/osu.Game/Tests/Visual/ScreenTestScene.cs @@ -33,9 +33,8 @@ namespace osu.Game.Tests.Visual [SetUpSteps] public virtual void SetUpSteps() => addExitAllScreensStep(); - // pending framework update. - //[TearDownSteps] - //public void TearDownSteps() => addExitAllScreensStep(); + [TearDownSteps] + public void TearDownSteps() => addExitAllScreensStep(); private void addExitAllScreensStep() { From e728d2be1779d280d5ee3a1492a0590acf463af6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 1 Feb 2020 01:19:04 +0900 Subject: [PATCH 0113/1142] Use ElementAtOrDefault --- osu.Game/Overlays/ChatOverlay.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 9e48ee5041..f2aef0995f 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -323,8 +323,7 @@ namespace osu.Game.Overlays { var channel = ChannelTabControl.Items .Where(tab => !(tab is ChannelSelectorTabItem.ChannelSelectorTabChannel)) - .Skip(index) - .FirstOrDefault(); + .ElementAtOrDefault(index); if (channel != null) ChannelTabControl.Current.Value = channel; } From 90caa612455425f97c892a81be2f37a46066e9f0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 1 Feb 2020 02:05:26 +0900 Subject: [PATCH 0114/1142] Reverse comparison for readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- .../Edit/Compose/Components/Timeline/TimelineTickDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index b565a42c5a..36ee976bf7 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline for (var i = 0; i < beatmap.ControlPointInfo.TimingPoints.Count; i++) { var point = beatmap.ControlPointInfo.TimingPoints[i]; - var until = beatmap.ControlPointInfo.TimingPoints.Count > i + 1 ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; + var until = i + 1 < beatmap.ControlPointInfo.TimingPoints.Count ? beatmap.ControlPointInfo.TimingPoints[i + 1].Time : working.Value.Track.Length; int beat = 0; From d94045e612cf0d4e1105078fdf66512bacdc5b09 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 1 Feb 2020 02:12:50 +0900 Subject: [PATCH 0115/1142] Fix remaining merge conflict --- osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index 7cf40b1209..bbb50c287b 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -61,7 +61,6 @@ namespace osu.Game.Rulesets.Osu.Tests private ExposedPlayer loadBeatmap(bool userHasCustomColours, bool beatmapHasColours) { ExposedPlayer player; - OsuScreenStack stack; Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours); From 9596030e1dadd5c0190c7868718bb090ae18b978 Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Fri, 31 Jan 2020 18:32:47 +0100 Subject: [PATCH 0116/1142] Make use of ElementAtOrDefault() when possible --- osu.Game/Overlays/ChatOverlay.cs | 2 +- osu.Game/Overlays/MusicController.cs | 2 +- osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 2c0fa49b5d..8b3edd60a1 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -321,7 +321,7 @@ namespace osu.Game.Overlays private void selectTab(int index) { - var channel = ChannelTabControl.Items.Skip(index).FirstOrDefault(); + var channel = ChannelTabControl.Items.ElementAtOrDefault(index); if (channel != null && !(channel is ChannelSelectorTabItem.ChannelSelectorTabChannel)) ChannelTabControl.Current.Value = channel; } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 19f06e99f1..7c7daf6eb9 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -196,7 +196,7 @@ namespace osu.Game.Overlays if (!instant) queuedDirection = TrackChangeDirection.Next; - var playable = BeatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? BeatmapSets.FirstOrDefault(); + var playable = BeatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).ElementAtOrDefault(1) ?? BeatmapSets.FirstOrDefault(); if (playable != null) { diff --git a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs index 8f2dbce6f7..422bf00c6d 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarRulesetSelector.cs @@ -99,7 +99,7 @@ namespace osu.Game.Overlays.Toolbar { int requested = e.Key - Key.Number1; - RulesetInfo found = Rulesets.AvailableRulesets.Skip(requested).FirstOrDefault(); + RulesetInfo found = Rulesets.AvailableRulesets.ElementAtOrDefault(requested); if (found != null) Current.Value = found; return true; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index ab8dccb9dd..5ac1d4ecc4 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -154,7 +154,7 @@ namespace osu.Game.Rulesets.Edit { if (e.Key >= Key.Number1 && e.Key <= Key.Number9) { - var item = toolboxCollection.Items.Skip(e.Key - Key.Number1).FirstOrDefault(); + var item = toolboxCollection.Items.ElementAtOrDefault(e.Key - Key.Number1); if (item != null) { From 6d30e425a1083e41a9a80285cf539584b45a2345 Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Fri, 31 Jan 2020 18:51:29 +0100 Subject: [PATCH 0117/1142] Revert change to avoid conflict with another PR --- osu.Game/Overlays/ChatOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index 8b3edd60a1..2c0fa49b5d 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -321,7 +321,7 @@ namespace osu.Game.Overlays private void selectTab(int index) { - var channel = ChannelTabControl.Items.ElementAtOrDefault(index); + var channel = ChannelTabControl.Items.Skip(index).FirstOrDefault(); if (channel != null && !(channel is ChannelSelectorTabItem.ChannelSelectorTabChannel)) ChannelTabControl.Current.Value = channel; } From a74d22d9e55a5fb76fcd4f55bc049ae4ee046b32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 1 Feb 2020 15:50:33 +0100 Subject: [PATCH 0118/1142] Extract beatmap stats test to separate scene --- .../SongSelect/TestSceneAdvancedStats.cs | 125 ++++++++++++++++++ .../SongSelect/TestSceneBeatmapDetails.cs | 28 ---- .../Screens/Select/Details/AdvancedStats.cs | 40 +++--- 3 files changed, 146 insertions(+), 47 deletions(-) create mode 100644 osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs new file mode 100644 index 0000000000..c08e974544 --- /dev/null +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs @@ -0,0 +1,125 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Select.Details; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.SongSelect +{ + [System.ComponentModel.Description("Advanced beatmap statistics display")] + public class TestSceneAdvancedStats : OsuTestScene + { + private TestAdvancedStats advancedStats; + + [Resolved] + private RulesetStore rulesets { get; set; } + + [Resolved] + private OsuColour colours { get; set; } + + [SetUp] + public void Setup() => Schedule(() => Child = advancedStats = new TestAdvancedStats + { + Width = 500 + }); + + private BeatmapInfo exampleBeatmapInfo => new BeatmapInfo + { + RulesetID = 0, + Ruleset = rulesets.AvailableRulesets.First(), + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 7.2f, + DrainRate = 1, + OverallDifficulty = 5.7f, + ApproachRate = 3.5f + }, + StarDifficulty = 4.5f + }; + + [Test] + public void TestNoMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("no mods selected", () => SelectedMods.Value = Array.Empty()); + + AddAssert("first bar text is Circle Size", () => advancedStats.ChildrenOfType().First().Text == "Circle Size"); + AddAssert("circle size bar is white", () => advancedStats.FirstValue.ModBar.AccentColour == Color4.White); + AddAssert("HP drain bar is white", () => advancedStats.HpDrain.ModBar.AccentColour == Color4.White); + AddAssert("accuracy bar is white", () => advancedStats.Accuracy.ModBar.AccentColour == Color4.White); + AddAssert("approach rate bar is white", () => advancedStats.ApproachRate.ModBar.AccentColour == Color4.White); + } + + [Test] + public void TestManiaFirstBarText() + { + AddStep("set beatmap", () => advancedStats.Beatmap = new BeatmapInfo + { + Ruleset = rulesets.GetRuleset(3), + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 5, + DrainRate = 4.3f, + OverallDifficulty = 4.5f, + ApproachRate = 3.1f + }, + StarDifficulty = 8 + }); + + AddAssert("first bar text is Key Count", () => advancedStats.ChildrenOfType().First().Text == "Key Count"); + } + + [Test] + public void TestEasyMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("select EZ mod", () => + { + var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); + SelectedMods.Value = new[] { ruleset.GetAllMods().OfType().Single() }; + }); + + AddAssert("circle size bar is blue", () => advancedStats.FirstValue.ModBar.AccentColour == colours.BlueDark); + AddAssert("HP drain bar is blue", () => advancedStats.HpDrain.ModBar.AccentColour == colours.BlueDark); + AddAssert("accuracy bar is blue", () => advancedStats.Accuracy.ModBar.AccentColour == colours.BlueDark); + AddAssert("approach rate bar is blue", () => advancedStats.ApproachRate.ModBar.AccentColour == colours.BlueDark); + } + + [Test] + public void TestHardRockMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("select HR mod", () => + { + var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); + SelectedMods.Value = new[] { ruleset.GetAllMods().OfType().Single() }; + }); + + AddAssert("circle size bar is red", () => advancedStats.FirstValue.ModBar.AccentColour == colours.Red); + AddAssert("HP drain bar is red", () => advancedStats.HpDrain.ModBar.AccentColour == colours.Red); + AddAssert("accuracy bar is red", () => advancedStats.Accuracy.ModBar.AccentColour == colours.Red); + AddAssert("approach rate bar is red", () => advancedStats.ApproachRate.ModBar.AccentColour == colours.Red); + } + + private class TestAdvancedStats : AdvancedStats + { + public new StatisticRow FirstValue => base.FirstValue; + public new StatisticRow HpDrain => base.HpDrain; + public new StatisticRow Accuracy => base.Accuracy; + public new StatisticRow ApproachRate => base.ApproachRate; + } + } +} diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs index 6aa5a76490..acf037198f 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapDetails.cs @@ -3,14 +3,8 @@ using System.Linq; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Testing; using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; using osu.Game.Screens.Select; namespace osu.Game.Tests.Visual.SongSelect @@ -180,27 +174,5 @@ namespace osu.Game.Tests.Visual.SongSelect OnlineBeatmapID = 162, }); } - - [Resolved] - private RulesetStore rulesets { get; set; } - - [Resolved] - private OsuColour colours { get; set; } - - [Test] - public void TestModAdjustments() - { - TestAllMetrics(); - - Ruleset ruleset = rulesets.AvailableRulesets.First().CreateInstance(); - - AddStep("with EZ mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModEasy) }); - - AddAssert("first bar coloured blue", () => details.ChildrenOfType().Skip(1).First().AccentColour == colours.BlueDark); - - AddStep("with HR mod", () => SelectedMods.Value = new[] { ruleset.GetAllMods().First(m => m is ModHardRock) }); - - AddAssert("first bar coloured red", () => details.ChildrenOfType().Skip(1).First().AccentColour == colours.Red); - } } } diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 56c400e869..81f2b8dc7b 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -26,7 +26,8 @@ namespace osu.Game.Screens.Select.Details [Resolved] private IBindable> mods { get; set; } - private readonly StatisticRow firstValue, hpDrain, accuracy, approachRate, starDifficulty; + protected readonly StatisticRow FirstValue, HpDrain, Accuracy, ApproachRate; + private readonly StatisticRow starDifficulty; private BeatmapInfo beatmap; @@ -52,10 +53,10 @@ namespace osu.Game.Screens.Select.Details Spacing = new Vector2(4f), Children = new[] { - firstValue = new StatisticRow(), //circle size/key amount - hpDrain = new StatisticRow { Title = "HP Drain" }, - accuracy = new StatisticRow { Title = "Accuracy" }, - approachRate = new StatisticRow { Title = "Approach Rate" }, + FirstValue = new StatisticRow(), //circle size/key amount + HpDrain = new StatisticRow { Title = "HP Drain" }, + Accuracy = new StatisticRow { Title = "Accuracy" }, + ApproachRate = new StatisticRow { Title = "Approach Rate" }, starDifficulty = new StatisticRow(10, true) { Title = "Star Difficulty" }, }, }; @@ -122,24 +123,24 @@ namespace osu.Game.Screens.Select.Details case 3: // Account for mania differences locally for now // Eventually this should be handled in a more modular way, allowing rulesets to return arbitrary difficulty attributes - firstValue.Title = "Key Count"; - firstValue.Value = (baseDifficulty?.CircleSize ?? 0, null); + FirstValue.Title = "Key Count"; + FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, null); break; default: - firstValue.Title = "Circle Size"; - firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); + FirstValue.Title = "Circle Size"; + FirstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); break; } starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null); - hpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate); - accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty); - approachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate); + HpDrain.Value = (baseDifficulty?.DrainRate ?? 0, adjustedDifficulty?.DrainRate); + Accuracy.Value = (baseDifficulty?.OverallDifficulty ?? 0, adjustedDifficulty?.OverallDifficulty); + ApproachRate.Value = (baseDifficulty?.ApproachRate ?? 0, adjustedDifficulty?.ApproachRate); } - private class StatisticRow : Container, IHasAccentColour + public class StatisticRow : Container, IHasAccentColour { private const float value_width = 25; private const float name_width = 70; @@ -147,7 +148,8 @@ namespace osu.Game.Screens.Select.Details private readonly float maxValue; private readonly bool forceDecimalPlaces; private readonly OsuSpriteText name, valueText; - private readonly Bar bar, modBar; + private readonly Bar bar; + public readonly Bar ModBar; [Resolved] private OsuColour colours { get; set; } @@ -173,14 +175,14 @@ namespace osu.Game.Screens.Select.Details bar.Length = value.baseValue / maxValue; valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##"); - modBar.Length = (value.adjustedValue ?? 0) / maxValue; + ModBar.Length = (value.adjustedValue ?? 0) / maxValue; if (value.adjustedValue > value.baseValue) - modBar.AccentColour = valueText.Colour = colours.Red; + ModBar.AccentColour = valueText.Colour = colours.Red; else if (value.adjustedValue < value.baseValue) - modBar.AccentColour = valueText.Colour = colours.BlueDark; + ModBar.AccentColour = valueText.Colour = colours.BlueDark; else - modBar.AccentColour = valueText.Colour = Color4.White; + ModBar.AccentColour = valueText.Colour = Color4.White; } } @@ -217,7 +219,7 @@ namespace osu.Game.Screens.Select.Details BackgroundColour = Color4.White.Opacity(0.5f), Padding = new MarginPadding { Left = name_width + 10, Right = value_width + 10 }, }, - modBar = new Bar + ModBar = new Bar { Origin = Anchor.CentreLeft, Anchor = Anchor.CentreLeft, From e90ae667b7e2481ad867fabae6df1e1969064012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 1 Feb 2020 16:08:24 +0100 Subject: [PATCH 0119/1142] Add failing tests --- .../SongSelect/TestSceneAdvancedStats.cs | 76 +++++++++++++++---- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs index c08e974544..3d3517ada4 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneAdvancedStats.cs @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.SongSelect BaseDifficulty = new BeatmapDifficulty { CircleSize = 7.2f, - DrainRate = 1, + DrainRate = 3, OverallDifficulty = 5.7f, ApproachRate = 3.5f }, @@ -55,10 +55,10 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep("no mods selected", () => SelectedMods.Value = Array.Empty()); AddAssert("first bar text is Circle Size", () => advancedStats.ChildrenOfType().First().Text == "Circle Size"); - AddAssert("circle size bar is white", () => advancedStats.FirstValue.ModBar.AccentColour == Color4.White); - AddAssert("HP drain bar is white", () => advancedStats.HpDrain.ModBar.AccentColour == Color4.White); - AddAssert("accuracy bar is white", () => advancedStats.Accuracy.ModBar.AccentColour == Color4.White); - AddAssert("approach rate bar is white", () => advancedStats.ApproachRate.ModBar.AccentColour == Color4.White); + AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue)); + AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain)); + AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy)); + AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate)); } [Test] @@ -91,10 +91,10 @@ namespace osu.Game.Tests.Visual.SongSelect SelectedMods.Value = new[] { ruleset.GetAllMods().OfType().Single() }; }); - AddAssert("circle size bar is blue", () => advancedStats.FirstValue.ModBar.AccentColour == colours.BlueDark); - AddAssert("HP drain bar is blue", () => advancedStats.HpDrain.ModBar.AccentColour == colours.BlueDark); - AddAssert("accuracy bar is blue", () => advancedStats.Accuracy.ModBar.AccentColour == colours.BlueDark); - AddAssert("approach rate bar is blue", () => advancedStats.ApproachRate.ModBar.AccentColour == colours.BlueDark); + AddAssert("circle size bar is blue", () => barIsBlue(advancedStats.FirstValue)); + AddAssert("HP drain bar is blue", () => barIsBlue(advancedStats.HpDrain)); + AddAssert("accuracy bar is blue", () => barIsBlue(advancedStats.Accuracy)); + AddAssert("approach rate bar is blue", () => barIsBlue(advancedStats.ApproachRate)); } [Test] @@ -108,12 +108,62 @@ namespace osu.Game.Tests.Visual.SongSelect SelectedMods.Value = new[] { ruleset.GetAllMods().OfType().Single() }; }); - AddAssert("circle size bar is red", () => advancedStats.FirstValue.ModBar.AccentColour == colours.Red); - AddAssert("HP drain bar is red", () => advancedStats.HpDrain.ModBar.AccentColour == colours.Red); - AddAssert("accuracy bar is red", () => advancedStats.Accuracy.ModBar.AccentColour == colours.Red); - AddAssert("approach rate bar is red", () => advancedStats.ApproachRate.ModBar.AccentColour == colours.Red); + AddAssert("circle size bar is red", () => barIsRed(advancedStats.FirstValue)); + AddAssert("HP drain bar is red", () => barIsRed(advancedStats.HpDrain)); + AddAssert("accuracy bar is red", () => barIsRed(advancedStats.Accuracy)); + AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate)); } + [Test] + public void TestUnchangedDifficultyAdjustMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("select unchanged Difficulty Adjust mod", () => + { + var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); + var difficultyAdjustMod = ruleset.GetAllMods().OfType().Single(); + difficultyAdjustMod.ReadFromDifficulty(advancedStats.Beatmap.BaseDifficulty); + SelectedMods.Value = new[] { difficultyAdjustMod }; + }); + + AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue)); + AddAssert("HP drain bar is white", () => barIsWhite(advancedStats.HpDrain)); + AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy)); + AddAssert("approach rate bar is white", () => barIsWhite(advancedStats.ApproachRate)); + } + + [Test] + public void TestChangedDifficultyAdjustMod() + { + AddStep("set beatmap", () => advancedStats.Beatmap = exampleBeatmapInfo); + + AddStep("select changed Difficulty Adjust mod", () => + { + var ruleset = advancedStats.Beatmap.Ruleset.CreateInstance(); + var difficultyAdjustMod = ruleset.GetAllMods().OfType().Single(); + var originalDifficulty = advancedStats.Beatmap.BaseDifficulty; + var adjustedDifficulty = new BeatmapDifficulty + { + CircleSize = originalDifficulty.CircleSize, + DrainRate = originalDifficulty.DrainRate - 0.5f, + OverallDifficulty = originalDifficulty.OverallDifficulty, + ApproachRate = originalDifficulty.ApproachRate + 2.2f, + }; + difficultyAdjustMod.ReadFromDifficulty(adjustedDifficulty); + SelectedMods.Value = new[] { difficultyAdjustMod }; + }); + + AddAssert("circle size bar is white", () => barIsWhite(advancedStats.FirstValue)); + AddAssert("drain rate bar is blue", () => barIsBlue(advancedStats.HpDrain)); + AddAssert("accuracy bar is white", () => barIsWhite(advancedStats.Accuracy)); + AddAssert("approach rate bar is red", () => barIsRed(advancedStats.ApproachRate)); + } + + private bool barIsWhite(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == Color4.White; + private bool barIsBlue(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.BlueDark; + private bool barIsRed(AdvancedStats.StatisticRow row) => row.ModBar.AccentColour == colours.Red; + private class TestAdvancedStats : AdvancedStats { public new StatisticRow FirstValue => base.FirstValue; From 0bfadfbbf1fbb713e10f252001285b43cbae6343 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 1 Feb 2020 16:16:15 +0100 Subject: [PATCH 0120/1142] Apply precision when comparing adjusted values In some cases, applying the Difficulty Adjust mod without actually changing any of the settings previously caused the bar in song select beatmap details to appear red/blue instead of staying white. This was caused by not accounting for floating-point imprecisions when determining bar colour in AdvancedStats. To resolve, first check equality with tolerance, and only then apply blue/red colours if that equality check does not hold. --- osu.Game/Screens/Select/Details/AdvancedStats.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 81f2b8dc7b..7ab91677a9 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -16,6 +16,7 @@ using System.Collections.Generic; using osu.Game.Rulesets.Mods; using System.Linq; using osu.Framework.Threading; +using osu.Framework.Utils; using osu.Game.Configuration; using osu.Game.Overlays.Settings; @@ -177,12 +178,12 @@ namespace osu.Game.Screens.Select.Details valueText.Text = (value.adjustedValue ?? value.baseValue).ToString(forceDecimalPlaces ? "0.00" : "0.##"); ModBar.Length = (value.adjustedValue ?? 0) / maxValue; - if (value.adjustedValue > value.baseValue) + if (Precision.AlmostEquals(value.baseValue, value.adjustedValue ?? value.baseValue, 0.05f)) + ModBar.AccentColour = valueText.Colour = Color4.White; + else if (value.adjustedValue > value.baseValue) ModBar.AccentColour = valueText.Colour = colours.Red; else if (value.adjustedValue < value.baseValue) ModBar.AccentColour = valueText.Colour = colours.BlueDark; - else - ModBar.AccentColour = valueText.Colour = Color4.White; } } From 9f4261111b3347719009e7ea21dff8c895791548 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sat, 1 Feb 2020 16:55:30 +0100 Subject: [PATCH 0121/1142] Match osu-stable behaviour and size --- .../Objects/Drawables/Pieces/SliderBall.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index ef7b077480..1fa27b6ff6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -24,6 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly Slider slider; public readonly Drawable FollowCircle; + public readonly Drawable InternalFollowCircle; private readonly DrawableSlider drawableSlider; public SliderBall(Slider slider, DrawableSlider drawableSlider = null) @@ -38,6 +39,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new[] { + InternalFollowCircle = new CircularContainer + { + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Alpha = 0 + }, FollowCircle = new FollowCircleContainer { Origin = Anchor.Centre, @@ -95,7 +103,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces tracking = value; - FollowCircle.ScaleTo(tracking ? 2f : 1, 300, Easing.OutQuint); + // Cursor input is checked against the internal circle, which scales instantly to match osu-stable behaviour + InternalFollowCircle.ScaleTo(tracking ? 2.4f : 1f); + FollowCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); } } @@ -149,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces // in valid time range Time.Current >= slider.StartTime && Time.Current < slider.EndTime && // in valid position range - lastScreenSpaceMousePosition.HasValue && FollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && + lastScreenSpaceMousePosition.HasValue && InternalFollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && // valid action (actions?.Any(isValidTrackingAction) ?? false); } From 2d42a83bb9bd718bac9e6ce5c5dce41632f6f455 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 1 Feb 2020 11:24:29 -0800 Subject: [PATCH 0122/1142] Fix mod select overlay overflowing toolbar at max ui scale --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 4 +-- osu.Game/Screens/Select/SongSelect.cs | 41 +++++++++++++++------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 38f5d54714..af772bc2fa 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -66,7 +66,6 @@ namespace osu.Game.Overlays.Mods Waves.ThirdWaveColour = OsuColour.FromHex(@"005774"); Waves.FourthWaveColour = OsuColour.FromHex(@"003a4e"); - Height = 510; Padding = new MarginPadding { Horizontal = -OsuScreen.HORIZONTAL_OVERFLOW_PADDING }; Children = new Drawable[] @@ -85,8 +84,7 @@ namespace osu.Game.Overlays.Mods new Triangles { TriangleScale = 5, - RelativeSizeAxes = Axes.X, - Height = Height, //set the height from the start to ensure correct triangle density. + RelativeSizeAxes = Axes.Both, ColourLight = new Color4(53, 66, 82, 255), ColourDark = new Color4(41, 54, 70, 255), }, diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f9f015643d..8647012ee7 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -221,23 +221,38 @@ namespace osu.Game.Screens.Select if (ShowFooter) { - AddRangeInternal(new[] + AddRangeInternal(new Drawable[] { - FooterPanels = new Container + new GridContainer // used for max width implementation { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Bottom = Footer.HEIGHT }, - Children = new Drawable[] + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] { - BeatmapOptions = new BeatmapOptionsOverlay(), - ModSelect = new ModSelectOverlay + new Dimension(), + new Dimension(GridSizeMode.Relative, 1f, maxSize: 560), + }, + Content = new[] + { + null, + new Drawable[] { - RelativeSizeAxes = Axes.X, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre, + FooterPanels = new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Bottom = Footer.HEIGHT }, + Children = new Drawable[] + { + BeatmapOptions = new BeatmapOptionsOverlay(), + ModSelect = new ModSelectOverlay + { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.BottomCentre, + Anchor = Anchor.BottomCentre, + } + } + } } } }, From 609ee260302563751370d7e47ad5939cb887e673 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 1 Feb 2020 11:41:41 -0800 Subject: [PATCH 0123/1142] Fix mod select overlay not showing up in test --- .../Visual/UserInterface/TestSceneModSelectOverlay.cs | 1 - osu.Game/Overlays/Mods/ModSelectOverlay.cs | 2 ++ osu.Game/Screens/Select/SongSelect.cs | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs index 12ee4ceb2e..dfc684d376 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs @@ -60,7 +60,6 @@ namespace osu.Game.Tests.Visual.UserInterface { modSelect = new TestModSelectOverlay { - RelativeSizeAxes = Axes.X, Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, }, diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index af772bc2fa..2868fe1d79 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -66,6 +66,8 @@ namespace osu.Game.Overlays.Mods Waves.ThirdWaveColour = OsuColour.FromHex(@"005774"); Waves.FourthWaveColour = OsuColour.FromHex(@"003a4e"); + RelativeSizeAxes = Axes.Both; + Padding = new MarginPadding { Horizontal = -OsuScreen.HORIZONTAL_OVERFLOW_PADDING }; Children = new Drawable[] diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8647012ee7..3f80c90b9d 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -247,7 +247,6 @@ namespace osu.Game.Screens.Select BeatmapOptions = new BeatmapOptionsOverlay(), ModSelect = new ModSelectOverlay { - RelativeSizeAxes = Axes.Both, Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, } From 583fee074fa2ef266f5595501646c7b383b1a0fa Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 1 Feb 2020 11:50:24 -0800 Subject: [PATCH 0124/1142] Fix mod select not showing up in mod settings test --- osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index e2ce2341e5..ba0970e123 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -74,7 +74,6 @@ namespace osu.Game.Tests.Visual.UserInterface Child = modSelect = new TestModSelectOverlay { - RelativeSizeAxes = Axes.X, Origin = Anchor.BottomCentre, Anchor = Anchor.BottomCentre, }; From e894acf53ca21b2d8eb8ce13c7850623b22e2e29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 1 Feb 2020 22:48:46 +0100 Subject: [PATCH 0125/1142] Make star filter range bindables BindableDoubles Due to using Bindables previously, song select's filter control would not apply tolerance when checking IsDefault, therefore wrongly hiding maps with star ratings above 10.1. --- osu.Game/Screens/Select/FilterControl.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index c851b201d7..6a03cfb68e 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -149,8 +149,8 @@ namespace osu.Game.Screens.Select private readonly IBindable ruleset = new Bindable(); private readonly Bindable showConverted = new Bindable(); - private readonly Bindable minimumStars = new Bindable(); - private readonly Bindable maximumStars = new Bindable(); + private readonly Bindable minimumStars = new BindableDouble(); + private readonly Bindable maximumStars = new BindableDouble(); public readonly Box Background; From 434c0d92e4ff952b57806b73609b30b327f029f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 1 Feb 2020 22:50:29 +0100 Subject: [PATCH 0126/1142] Use Bindable{Float,Double}s everywhere To avoid further floating-point comparison bugs, remove all usages of Bindable<{float,double}>, replacing them with their Bindable counterparts. --- .../Objects/Drawables/Connections/FollowPointConnection.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs | 2 +- .../Objects/Drawables/DrawableRepeatPoint.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 2 +- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs | 2 +- .../Visual/Background/TestSceneUserDimBackgrounds.cs | 4 ++-- osu.Game/Rulesets/Objects/HitObject.cs | 2 +- osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 4 ++-- osu.Game/Tests/Visual/ScrollingTestContainer.cs | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs index 6c4fbbac17..a5e89210f6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections /// /// The start time of . /// - public readonly Bindable StartTime = new Bindable(); + public readonly Bindable StartTime = new BindableDouble(); /// /// The which s will exit from. diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 3162f4b379..4ef63bb2a0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly IBindable positionBindable = new Bindable(); private readonly IBindable stackHeightBindable = new Bindable(); - private readonly IBindable scaleBindable = new Bindable(); + private readonly IBindable scaleBindable = new BindableFloat(); public OsuAction? HitAction => HitArea.HitAction; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs index 20b31c68f2..8fdcd060e7 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableRepeatPoint.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables InternalChild = scaleContainer = new ReverseArrowPiece(); } - private readonly IBindable scaleBindable = new Bindable(); + private readonly IBindable scaleBindable = new BindableFloat(); [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index cd3c572ba0..7403649184 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private readonly IBindable positionBindable = new Bindable(); private readonly IBindable stackHeightBindable = new Bindable(); - private readonly IBindable scaleBindable = new Bindable(); + private readonly IBindable scaleBindable = new BindableFloat(); public DrawableSlider(Slider s) : base(s) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index 9d4d9958a1..60b5c335d6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables }; } - private readonly IBindable scaleBindable = new Bindable(); + private readonly IBindable scaleBindable = new BindableFloat(); [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 0ba712a83f..15af141c99 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects public double Radius => OBJECT_RADIUS * Scale; - public readonly Bindable ScaleBindable = new Bindable(1); + public readonly Bindable ScaleBindable = new BindableFloat(1); public float Scale { diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index a463542e64..79b5d1b7f8 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor autoCursorScale = config.GetBindable(OsuSetting.AutoCursorSize); autoCursorScale.ValueChanged += _ => calculateScale(); - CursorScale = new Bindable(); + CursorScale = new BindableFloat(); CursorScale.ValueChanged += e => ActiveCursor.Scale = cursorTrail.Scale = new Vector2(e.NewValue); calculateScale(); diff --git a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs index ca3030db3e..abba444c73 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuResumeOverlay.cs @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.UI { Add(localCursorContainer = new OsuCursorContainer()); - localCursorScale = new Bindable(); + localCursorScale = new BindableFloat(); localCursorScale.BindTo(localCursorContainer.CursorScale); localCursorScale.BindValueChanged(scale => cursorScaleContainer.Scale = new Vector2(scale.NewValue), true); } diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs index 589ec7e8aa..29bcc7df9e 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs @@ -302,8 +302,8 @@ namespace osu.Game.Tests.Visual.Background } public readonly Bindable DimEnabled = new Bindable(); - public readonly Bindable DimLevel = new Bindable(); - public readonly Bindable BlurLevel = new Bindable(); + public readonly Bindable DimLevel = new BindableDouble(); + public readonly Bindable BlurLevel = new BindableDouble(); public new BeatmapCarousel Carousel => base.Carousel; diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index bd96441ebb..c09844e0c6 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Objects /// public event Action DefaultsApplied; - public readonly Bindable StartTimeBindable = new Bindable(); + public readonly Bindable StartTimeBindable = new BindableDouble(); /// /// The time at which the HitObject starts. diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 3ced9ee753..50fd127093 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Backgrounds /// /// The amount of blur to be applied in addition to user-specified blur. /// - public readonly Bindable BlurAmount = new Bindable(); + public readonly Bindable BlurAmount = new BindableFloat(); internal readonly IBindable IsBreakTime = new Bindable(); @@ -119,7 +119,7 @@ namespace osu.Game.Screens.Backgrounds /// /// Used in contexts where there can potentially be both user and screen-specified blurring occuring at the same time, such as in /// - public readonly Bindable BlurAmount = new Bindable(); + public readonly Bindable BlurAmount = new BindableFloat(); public Background Background { diff --git a/osu.Game/Tests/Visual/ScrollingTestContainer.cs b/osu.Game/Tests/Visual/ScrollingTestContainer.cs index bdad3d278c..161ebe7030 100644 --- a/osu.Game/Tests/Visual/ScrollingTestContainer.cs +++ b/osu.Game/Tests/Visual/ScrollingTestContainer.cs @@ -47,7 +47,7 @@ namespace osu.Game.Tests.Visual public readonly Bindable Direction = new Bindable(); IBindable IScrollingInfo.Direction => Direction; - public readonly Bindable TimeRange = new Bindable(1000) { Value = 1000 }; + public readonly Bindable TimeRange = new BindableDouble(1000) { Value = 1000 }; IBindable IScrollingInfo.TimeRange => TimeRange; public readonly TestScrollAlgorithm Algorithm = new TestScrollAlgorithm(); From 36116f8c45f06ffa0256f6e2ba53a67182a74753 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 2 Feb 2020 12:03:51 +0300 Subject: [PATCH 0127/1142] Refactor ruleset presentation --- .../TestSceneUserProfileRecentSection.cs | 16 ++++++++++ .../Requests/Responses/APIRecentActivity.cs | 31 +------------------ .../Sections/Recent/DrawableRecentActivity.cs | 26 ++++++++++++---- 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs index 532aaa9c92..06091f3c81 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileRecentSection.cs @@ -136,6 +136,22 @@ namespace osu.Game.Tests.Visual.Online Beatmap = dummyBeatmap, }, new APIRecentActivity + { + User = dummyUser, + Type = RecentActivityType.Rank, + Rank = 1, + Mode = "vitaru", + Beatmap = dummyBeatmap, + }, + new APIRecentActivity + { + User = dummyUser, + Type = RecentActivityType.Rank, + Rank = 1, + Mode = "fruits", + Beatmap = dummyBeatmap, + }, + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.RankLost, diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs index b416085217..8695d09570 100644 --- a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -41,37 +41,8 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty("count")] public int Count; - public string Mode; - [JsonProperty("mode")] - private string mode - { - set - { - switch (value) - { - default: - Mode = value; - return; - - case "osu": - Mode = "osu!"; - return; - - case "mania": - Mode = "osu!mania"; - return; - - case "taiko": - Mode = "osu!taiko"; - return; - - case "fruits": - Mode = "osu!catch"; - return; - } - } - } + public string Mode; [JsonProperty("beatmap")] public RecentActivityBeatmap Beatmap; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 3f8ab93abd..5a315b59b4 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.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.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,6 +13,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Online.Leaderboards; +using osu.Game.Rulesets; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -19,7 +21,11 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { private const int font_size = 14; - private IAPIProvider api; + [Resolved] + private IAPIProvider api { get; set; } + + [Resolved] + private RulesetStore rulesets { get; set; } private readonly APIRecentActivity activity; @@ -31,10 +37,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } [BackgroundDependencyLoader] - private void load(IAPIProvider api, OverlayColourProvider colourProvider) + private void load(OverlayColourProvider colourProvider) { - this.api = api; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; AddInternal(new GridContainer @@ -118,6 +122,16 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } + private string getRulesetName() + { + var shortName = activity.Mode; + + if (rulesets.AvailableRulesets.Select(r => r.ShortName).Contains(shortName)) + return rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName).Name; + + return shortName; + } + private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) @@ -185,14 +199,14 @@ namespace osu.Game.Overlays.Profile.Sections.Recent addUserLink(); addText($" achieved rank #{activity.Rank} on "); addBeatmapLink(); - addText($" ({activity.Mode})"); + addText($" ({getRulesetName()})"); break; case RecentActivityType.RankLost: addUserLink(); addText(" has lost first place on "); addBeatmapLink(); - addText($" ({activity.Mode})"); + addText($" ({getRulesetName()})"); break; case RecentActivityType.UserSupportAgain: From a70385f2b26058cec6da3d7ebb7d150cbe54967c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 2 Feb 2020 12:19:09 +0300 Subject: [PATCH 0128/1142] Simplify getRulesetName --- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 5a315b59b4..f538833eb0 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -126,10 +126,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { var shortName = activity.Mode; - if (rulesets.AvailableRulesets.Select(r => r.ShortName).Contains(shortName)) - return rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName).Name; - - return shortName; + return rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName)?.Name ?? shortName; } private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; From e2589b2dcb6cdaaef86485ce04484635c7d0ed92 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 11:24:28 +0100 Subject: [PATCH 0129/1142] Rename drawable --- .../Objects/Drawables/Pieces/SliderBall.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 1fa27b6ff6..4599044912 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly Slider slider; public readonly Drawable FollowCircle; - public readonly Drawable InternalFollowCircle; + public readonly Drawable TrackingArea; private readonly DrawableSlider drawableSlider; public SliderBall(Slider slider, DrawableSlider drawableSlider = null) @@ -39,7 +39,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new[] { - InternalFollowCircle = new CircularContainer + // This is separate from the visible followcircle to ensure consistent internal tracking area (needed to match osu-stable) + TrackingArea = new CircularContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -103,8 +104,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces tracking = value; - // Cursor input is checked against the internal circle, which scales instantly to match osu-stable behaviour - InternalFollowCircle.ScaleTo(tracking ? 2.4f : 1f); + // Tracking area is bigger than the visible followcircle and scales instantly to match osu-stable + TrackingArea.ScaleTo(tracking ? 2.4f : 1f); FollowCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); } @@ -159,7 +160,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces // in valid time range Time.Current >= slider.StartTime && Time.Current < slider.EndTime && // in valid position range - lastScreenSpaceMousePosition.HasValue && InternalFollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && + lastScreenSpaceMousePosition.HasValue && TrackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && // valid action (actions?.Any(isValidTrackingAction) ?? false); } From 52aae684116fbed2109b168dcb2a534da491fb88 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 17:52:34 +0700 Subject: [PATCH 0130/1142] Adjust profile scores to closer match osu-web --- .../Profile/Sections/Ranks/DrawableProfileScore.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 5196bef48d..13f4d9a3a5 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -23,7 +23,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks public class DrawableProfileScore : CompositeDrawable { private const int performance_width = 80; - private const int content_padding = 10; + private const int content_padding_left = 10; + private const int content_padding_right = 30; protected readonly ScoreInfo Score; @@ -51,7 +52,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = content_padding, Right = performance_width + content_padding }, + Padding = new MarginPadding { Left = content_padding_left, Right = performance_width + content_padding_right }, Children = new Drawable[] { new FillFlowContainer @@ -142,17 +143,21 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { new Box { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Both, - Size = new Vector2(1, 0.5f), + Size = new Vector2(1.06f, 0.5f), Colour = Color4.Black.Opacity(0.5f), Shear = new Vector2(-0.45f, 0), EdgeSmoothness = new Vector2(2, 0), }, new Box { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.Y, - Size = new Vector2(1, -0.5f), + Size = new Vector2(1.06f, -0.5f), Position = new Vector2(0, 1), Colour = Color4.Black.Opacity(0.5f), Shear = new Vector2(0.45f, 0), From abccf05155906d24c0b1757f89f3ac0b5f206a11 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 2 Feb 2020 14:46:50 +0300 Subject: [PATCH 0131/1142] Update visibility of each key counter instead of this container For isolating changing visibility of the key counter display based on config and internal values from just fading the container. --- osu.Game/Screens/Play/KeyCounterDisplay.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index 9c107f0293..5672042a98 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; @@ -100,7 +101,9 @@ namespace osu.Game.Screens.Play } } - private void updateVisibility() => this.FadeTo(Visible.Value || configVisibility.Value ? 1 : 0, duration); + private void updateVisibility() => + // Change visibility of all key counters internally to isolate from showing them by fading in this container. + Children.ForEach(k => k.FadeTo(Visible.Value || ConfigVisibility.Value ? 1 : 0, duration)); public override bool HandleNonPositionalInput => receptor == null; public override bool HandlePositionalInput => receptor == null; From 6a11c3a8f9edcdf04b386215d5601e6fba9ba2d3 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 2 Feb 2020 14:48:07 +0300 Subject: [PATCH 0132/1142] Expose ConfigVisibility bindable for testing purposes --- osu.Game/Screens/Play/KeyCounterDisplay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index 5672042a98..d7b4913d3c 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -21,7 +21,7 @@ namespace osu.Game.Screens.Play private const double key_fade_time = 80; public readonly Bindable Visible = new Bindable(true); - private readonly Bindable configVisibility = new Bindable(); + protected readonly Bindable ConfigVisibility = new Bindable(); public KeyCounterDisplay() { @@ -43,7 +43,7 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.KeyOverlay, configVisibility); + config.BindWith(OsuSetting.KeyOverlay, ConfigVisibility); } protected override void LoadComplete() @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); Visible.BindValueChanged(_ => updateVisibility()); - configVisibility.BindValueChanged(_ => updateVisibility(), true); + ConfigVisibility.BindValueChanged(_ => updateVisibility(), true); } private bool isCounting = true; From 6103674b5481055f2a34cb2f44d09889583793bb Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 2 Feb 2020 14:50:05 +0300 Subject: [PATCH 0133/1142] Add tests for changing HUD visibility on hidden key counter configuration --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 57 ++++++++++++++++++- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index ee58219cd3..e34e87d8df 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -2,18 +2,21 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; +using osuTK.Input; namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneHUDOverlay : ManualInputManagerTestScene { - private HUDOverlay hudOverlay; + private TestHUDOverlay hudOverlay; private Drawable hideTarget => hudOverlay.KeyCounter; // best way of checking hideTargets without exposing. @@ -28,6 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("showhud is set", () => hudOverlay.ShowHud.Value); AddAssert("hidetarget is visible", () => hideTarget.IsPresent); + AddAssert("key counters are visible", () => hudOverlay.KeyCounter.All(k => k.IsPresent)); AddAssert("pause button is visible", () => hudOverlay.HoldToQuit.IsPresent); } @@ -50,6 +54,9 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); AddAssert("pause button is still visible", () => hudOverlay.HoldToQuit.IsPresent); + + // Key counters should not be affected by this, only the key counter container will be hidden as checked above. + AddAssert("key counters not affected", () => hudOverlay.KeyCounter.All(k => k.IsPresent)); } [Test] @@ -68,14 +75,58 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("config unchanged", () => originalConfigValue == config.Get(OsuSetting.ShowInterface)); } - private void createNew(Action action = null) + [Test] + public void TestChangeHUDVisibilityOnHiddenKeyCounter() + { + createNew(); + + AddStep("set keycounter visible false", () => + { + hudOverlay.KeyCounter.ConfigVisibility.Value = false; + hudOverlay.KeyCounter.Visible.Value = false; + }); + + AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); + AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); + AddAssert("key counters hidden", () => hudOverlay.KeyCounter.All(k => !k.IsPresent)); + + AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true); + AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent); + AddAssert("key counters still hidden", () => hudOverlay.KeyCounter.All(k => !k.IsPresent)); + } + + private void createNew(Action action = null) { AddStep("create overlay", () => { - Child = hudOverlay = new HUDOverlay(null, null, null, Array.Empty()); + Child = hudOverlay = new TestHUDOverlay(); action?.Invoke(hudOverlay); }); } + + private class TestHUDOverlay : HUDOverlay + { + public new TestKeyCounterDisplay KeyCounter => (TestKeyCounterDisplay)base.KeyCounter; + + protected override KeyCounterDisplay CreateKeyCounter() => new TestKeyCounterDisplay + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Margin = new MarginPadding(10), + }; + + public TestHUDOverlay() + : base(null, null, null, Array.Empty()) + { + // Add any key just to display the key counter visually. + KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); + } + } + + private class TestKeyCounterDisplay : KeyCounterDisplay + { + public new Bindable ConfigVisibility => base.ConfigVisibility; + } } } From f7abfdb40e8fcea47b3ddfc8bb33550f9bc60ba7 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 14:33:48 +0100 Subject: [PATCH 0134/1142] Remove unnecessary parameter --- osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index 4599044912..a81ac3f4ff 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -44,8 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces { Origin = Anchor.Centre, Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Alpha = 0 + RelativeSizeAxes = Axes.Both }, FollowCircle = new FollowCircleContainer { From 35032e2ddd1b0d76bd1615c25dd17de7cd3cee10 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 14:34:06 +0100 Subject: [PATCH 0135/1142] Make variables private --- .../Objects/Drawables/Pieces/SliderBall.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index a81ac3f4ff..b89b0cafc4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -23,8 +23,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces public Func GetInitialHitAction; private readonly Slider slider; - public readonly Drawable FollowCircle; - public readonly Drawable TrackingArea; + private readonly Drawable followCircle; + private readonly Drawable trackingArea; private readonly DrawableSlider drawableSlider; public SliderBall(Slider slider, DrawableSlider drawableSlider = null) @@ -40,13 +40,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new[] { // This is separate from the visible followcircle to ensure consistent internal tracking area (needed to match osu-stable) - TrackingArea = new CircularContainer + trackingArea = new CircularContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, RelativeSizeAxes = Axes.Both }, - FollowCircle = new FollowCircleContainer + followCircle = new FollowCircleContainer { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -104,9 +104,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces tracking = value; // Tracking area is bigger than the visible followcircle and scales instantly to match osu-stable - TrackingArea.ScaleTo(tracking ? 2.4f : 1f); - FollowCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); - FollowCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); + trackingArea.ScaleTo(tracking ? 2.4f : 1f); + followCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); + followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); } } @@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces // in valid time range Time.Current >= slider.StartTime && Time.Current < slider.EndTime && // in valid position range - lastScreenSpaceMousePosition.HasValue && TrackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && + lastScreenSpaceMousePosition.HasValue && trackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && // valid action (actions?.Any(isValidTrackingAction) ?? false); } From 122fd63ac467912b80ffea3d9d1d90637ba47dcc Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:05:20 +0700 Subject: [PATCH 0136/1142] Inline single-use constants --- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 13f4d9a3a5..7400bed04e 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; @@ -23,8 +23,6 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks public class DrawableProfileScore : CompositeDrawable { private const int performance_width = 80; - private const int content_padding_left = 10; - private const int content_padding_right = 30; protected readonly ScoreInfo Score; @@ -52,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = content_padding_left, Right = performance_width + content_padding_right }, + Padding = new MarginPadding { Left = 10, Right = performance_width + 30 }, Children = new Drawable[] { new FillFlowContainer From a641069ec2b9ef3b7f47da143084facfecaaa719 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:07:23 +0700 Subject: [PATCH 0137/1142] Change profile score background colour --- osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs | 4 ++-- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index 717ec4fb1a..f65c909155 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs @@ -44,8 +44,8 @@ namespace osu.Game.Overlays.Profile.Sections [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - background.Colour = idleColour = colourProvider.Background4; - hoverColour = colourProvider.Background3; + background.Colour = idleColour = colourProvider.Background3; + hoverColour = colourProvider.Background2; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 7400bed04e..55ed80cc04 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; @@ -145,7 +145,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Both, Size = new Vector2(1.06f, 0.5f), - Colour = Color4.Black.Opacity(0.5f), + Colour = colourProvider.Background4, Shear = new Vector2(-0.45f, 0), EdgeSmoothness = new Vector2(2, 0), }, @@ -157,7 +157,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks RelativePositionAxes = Axes.Y, Size = new Vector2(1.06f, -0.5f), Position = new Vector2(0, 1), - Colour = Color4.Black.Opacity(0.5f), + Colour = colourProvider.Background4, Shear = new Vector2(0.45f, 0), EdgeSmoothness = new Vector2(2, 0), }, From 30a5835bdbc24abc82d09f8e6832d5aa9aaf37a5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 2 Feb 2020 23:07:39 +0900 Subject: [PATCH 0138/1142] Combine link flows and simplify new line addition --- .../Profile/Header/BottomHeaderContainer.cs | 80 ++++++++----------- 1 file changed, 34 insertions(+), 46 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 469f9caf4a..bca72666de 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -15,7 +15,6 @@ using osu.Game.Graphics.Containers; using osu.Game.Users; using osuTK; using osuTK.Graphics; -using static osu.Framework.Graphics.Containers.TextFlowContainer; namespace osu.Game.Overlays.Profile.Header { @@ -23,8 +22,7 @@ namespace osu.Game.Overlays.Profile.Header { public readonly Bindable User = new Bindable(); - private LinkFlowContainer topLinkContainer; - private LinkFlowContainer bottomLinkContainer; + private LinkFlowContainer linkContainer; private Color4 iconColour; @@ -45,26 +43,12 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4 }, - new FillFlowContainer + linkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, Spacing = new Vector2(0, 10), - Children = new Drawable[] - { - topLinkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - }, - bottomLinkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - } - } } }; @@ -73,44 +57,43 @@ namespace osu.Game.Overlays.Profile.Header private void updateDisplay(User user) { - topLinkContainer.Clear(); - bottomLinkContainer.Clear(); + linkContainer.Clear(); if (user == null) return; if (user.JoinDate.ToUniversalTime().Year < 2008) - topLinkContainer.AddText("Here since the beginning"); + linkContainer.AddText("Here since the beginning"); else { - topLinkContainer.AddText("Joined "); - topLinkContainer.AddText(new DrawableDate(user.JoinDate), embolden); + linkContainer.AddText("Joined "); + linkContainer.AddText(new DrawableDate(user.JoinDate), embolden); } - addSpacer(topLinkContainer); + addSpacer(linkContainer); if (user.IsOnline) { - topLinkContainer.AddText("Currently online"); - addSpacer(topLinkContainer); + linkContainer.AddText("Currently online"); + addSpacer(linkContainer); } else if (user.LastVisit.HasValue) { - topLinkContainer.AddText("Last seen "); - topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden); + linkContainer.AddText("Last seen "); + linkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden); - addSpacer(topLinkContainer); + addSpacer(linkContainer); } if (user.PlayStyles?.Length > 0) { - topLinkContainer.AddText("Plays with "); - topLinkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), embolden); + linkContainer.AddText("Plays with "); + linkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), embolden); - addSpacer(topLinkContainer); + addSpacer(linkContainer); } - topLinkContainer.AddText("Contributed "); - topLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: embolden); + linkContainer.AddText("Contributed "); + linkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: embolden); string websiteWithoutProtocol = user.Website; @@ -123,46 +106,51 @@ namespace osu.Game.Overlays.Profile.Header } } + requireNewLineOnAddInfo = true; + tryAddInfo(FontAwesome.Solid.MapMarker, user.Location); tryAddInfo(OsuIcon.Heart, user.Interests); tryAddInfo(FontAwesome.Solid.Suitcase, user.Occupation); - bottomLinkContainer.NewLine(); + + requireNewLineOnAddInfo = true; + if (!string.IsNullOrEmpty(user.Twitter)) tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); tryAddInfo(FontAwesome.Brands.Discord, user.Discord); tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); - - // Hide the container to prevent adding unnecessary padding if it has no children other than the NewLineContainer - if (bottomLinkContainer.Children.All(child => child is NewLineContainer)) - bottomLinkContainer.Hide(); - else - // this is needed if user gets changed without the whole header being reloaded - bottomLinkContainer.Show(); } private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); + private bool requireNewLineOnAddInfo; + private void tryAddInfo(IconUsage icon, string content, string link = null) { if (string.IsNullOrEmpty(content)) return; + if (requireNewLineOnAddInfo) + { + linkContainer.NewLine(); + requireNewLineOnAddInfo = false; + } + // newlines could be contained in API returned user content. content = content.Replace("\n", " "); - bottomLinkContainer.AddIcon(icon, text => + linkContainer.AddIcon(icon, text => { text.Font = text.Font.With(size: 10); text.Colour = iconColour; }); if (link != null) - bottomLinkContainer.AddLink(" " + content, link, creationParameters: embolden); + linkContainer.AddLink(" " + content, link, creationParameters: embolden); else - bottomLinkContainer.AddText(" " + content, embolden); + linkContainer.AddText(" " + content, embolden); - addSpacer(bottomLinkContainer); + addSpacer(linkContainer); } private void embolden(SpriteText text) => text.Font = text.Font.With(weight: FontWeight.Bold); From 79efcbd6f315c4cc6e6d723d09f544d75838dde7 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:08:16 +0700 Subject: [PATCH 0139/1142] Fix performance background width --- .../Sections/Ranks/DrawableProfileScore.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 55ed80cc04..07a85be041 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -1,10 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -16,14 +16,16 @@ using osu.Game.Online.Leaderboards; using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Sections.Ranks { public class DrawableProfileScore : CompositeDrawable { + private const int height = 40; private const int performance_width = 80; + private const float performance_background_shear = 0.45f; + protected readonly ScoreInfo Score; [Resolved] @@ -37,12 +39,14 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Score = score; RelativeSizeAxes = Axes.X; - Height = 40; + Height = height; } [BackgroundDependencyLoader] private void load() { + float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); + AddInternal(new ProfileItemContainer { Children = new Drawable[] @@ -143,22 +147,24 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(1.06f, 0.5f), + RelativeSizeAxes = Axes.Y, + Width = performance_background_width, + Height = 0.5f, Colour = colourProvider.Background4, - Shear = new Vector2(-0.45f, 0), + Shear = new Vector2(-performance_background_shear, 0), EdgeSmoothness = new Vector2(2, 0), }, new Box { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.Y, - Size = new Vector2(1.06f, -0.5f), + Width = performance_background_width, + Height = -0.5f, Position = new Vector2(0, 1), Colour = colourProvider.Background4, - Shear = new Vector2(0.45f, 0), + Shear = new Vector2(performance_background_shear, 0), EdgeSmoothness = new Vector2(2, 0), }, createDrawablePerformance().With(d => From aa13b605a4877458470173f33ddd0946b26a781a Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 21:34:35 +0700 Subject: [PATCH 0140/1142] Fix inconsistent local variable naming --- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 07a85be041..930f9b8a43 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [BackgroundDependencyLoader] private void load() { - float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); + float performanceBackgroundWidth = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); AddInternal(new ProfileItemContainer { @@ -148,7 +148,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, - Width = performance_background_width, + Width = performanceBackgroundWidth, Height = 0.5f, Colour = colourProvider.Background4, Shear = new Vector2(-performance_background_shear, 0), @@ -160,7 +160,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.Y, - Width = performance_background_width, + Width = performanceBackgroundWidth, Height = -0.5f, Position = new Vector2(0, 1), Colour = colourProvider.Background4, From 0a186fe7229380551c663cb828f299bb6634a5b3 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 22:37:58 +0700 Subject: [PATCH 0141/1142] Avoid calculating constants in load() --- .../Profile/Sections/Ranks/DrawableProfileScore.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 930f9b8a43..1905728442 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -25,6 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private const int performance_width = 80; private const float performance_background_shear = 0.45f; + private float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); protected readonly ScoreInfo Score; @@ -45,8 +46,6 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [BackgroundDependencyLoader] private void load() { - float performanceBackgroundWidth = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); - AddInternal(new ProfileItemContainer { Children = new Drawable[] @@ -148,7 +147,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, - Width = performanceBackgroundWidth, + Width = performance_background_width, Height = 0.5f, Colour = colourProvider.Background4, Shear = new Vector2(-performance_background_shear, 0), @@ -160,7 +159,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.TopRight, RelativeSizeAxes = Axes.Y, RelativePositionAxes = Axes.Y, - Width = performanceBackgroundWidth, + Width = performance_background_width, Height = -0.5f, Position = new Vector2(0, 1), Colour = colourProvider.Background4, From 28e340c4860b72a5a4ca6a35415a8af8d032d45f Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 2 Feb 2020 18:39:39 +0300 Subject: [PATCH 0142/1142] Inherit Container and fade the key flow instead of individual children --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 15 +++++++-------- osu.Game/Screens/Play/KeyCounterDisplay.cs | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index e34e87d8df..11064d0ffd 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -2,11 +2,10 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; @@ -31,7 +30,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("showhud is set", () => hudOverlay.ShowHud.Value); AddAssert("hidetarget is visible", () => hideTarget.IsPresent); - AddAssert("key counters are visible", () => hudOverlay.KeyCounter.All(k => k.IsPresent)); + AddAssert("key counter flow is visible", () => hudOverlay.KeyCounter.KeyFlow.IsPresent); AddAssert("pause button is visible", () => hudOverlay.HoldToQuit.IsPresent); } @@ -55,8 +54,8 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); AddAssert("pause button is still visible", () => hudOverlay.HoldToQuit.IsPresent); - // Key counters should not be affected by this, only the key counter container will be hidden as checked above. - AddAssert("key counters not affected", () => hudOverlay.KeyCounter.All(k => k.IsPresent)); + // Key counter flow container should not be affected by this, only the key counter display will be hidden as checked above. + AddAssert("key counter flow not affected", () => hudOverlay.KeyCounter.KeyFlow.IsPresent); } [Test] @@ -88,11 +87,11 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); - AddAssert("key counters hidden", () => hudOverlay.KeyCounter.All(k => !k.IsPresent)); + AddAssert("key counters hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true); AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent); - AddAssert("key counters still hidden", () => hudOverlay.KeyCounter.All(k => !k.IsPresent)); + AddAssert("key counters still hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); } private void createNew(Action action = null) @@ -126,7 +125,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class TestKeyCounterDisplay : KeyCounterDisplay { - public new Bindable ConfigVisibility => base.ConfigVisibility; + public new Container KeyFlow => base.KeyFlow; } } } diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index d7b4913d3c..b03f663371 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -5,7 +5,6 @@ using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input.Events; @@ -15,7 +14,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Play { - public class KeyCounterDisplay : FillFlowContainer + public class KeyCounterDisplay : Container { private const int duration = 100; private const double key_fade_time = 80; @@ -23,10 +22,19 @@ namespace osu.Game.Screens.Play public readonly Bindable Visible = new Bindable(true); protected readonly Bindable ConfigVisibility = new Bindable(); + protected readonly FillFlowContainer KeyFlow; + + protected override Container Content => KeyFlow; + public KeyCounterDisplay() { - Direction = FillDirection.Horizontal; AutoSizeAxes = Axes.Both; + + InternalChild = KeyFlow = new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + }; } public override void Add(KeyCounter key) @@ -102,8 +110,8 @@ namespace osu.Game.Screens.Play } private void updateVisibility() => - // Change visibility of all key counters internally to isolate from showing them by fading in this container. - Children.ForEach(k => k.FadeTo(Visible.Value || ConfigVisibility.Value ? 1 : 0, duration)); + // Isolate changing visibility of the key counters from fading this component. + KeyFlow.FadeTo(Visible.Value || alwaysShow.Value ? 1 : 0, duration); public override bool HandleNonPositionalInput => receptor == null; public override bool HandlePositionalInput => receptor == null; From 0f449d1b9945902bee4913488fec8bfe2a44bc45 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 2 Feb 2020 18:46:59 +0300 Subject: [PATCH 0143/1142] Set config value instead --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 11064d0ffd..7ce6153ba5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -77,11 +77,14 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestChangeHUDVisibilityOnHiddenKeyCounter() { + bool keyCounterVisibleValue = false; + createNew(); + AddStep("save keycounter visible value", () => keyCounterVisibleValue = config.Get(OsuSetting.KeyOverlay)); AddStep("set keycounter visible false", () => { - hudOverlay.KeyCounter.ConfigVisibility.Value = false; + config.Set(OsuSetting.KeyOverlay, false); hudOverlay.KeyCounter.Visible.Value = false; }); @@ -92,6 +95,8 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true); AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent); AddAssert("key counters still hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); + + AddStep("return value", () => config.Set(OsuSetting.KeyOverlay, keyCounterVisibleValue)); } private void createNew(Action action = null) @@ -125,7 +130,7 @@ namespace osu.Game.Tests.Visual.Gameplay private class TestKeyCounterDisplay : KeyCounterDisplay { - public new Container KeyFlow => base.KeyFlow; + public new FillFlowContainer KeyFlow => base.KeyFlow; } } } From 4cdf4b223c1c0141ca7627096386dba16d26655b Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sun, 2 Feb 2020 18:47:12 +0300 Subject: [PATCH 0144/1142] Rename to alwaysShow and add XMLDoc --- osu.Game/Screens/Play/KeyCounterDisplay.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index b03f663371..b5d8c99e67 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -19,8 +19,13 @@ namespace osu.Game.Screens.Play private const int duration = 100; private const double key_fade_time = 80; + /// + /// Whether to always show key counter regardless of . + /// This is bound to configuration setting bindable. + /// + private readonly Bindable alwaysShow = new Bindable(); + public readonly Bindable Visible = new Bindable(true); - protected readonly Bindable ConfigVisibility = new Bindable(); protected readonly FillFlowContainer KeyFlow; @@ -51,7 +56,7 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.KeyOverlay, ConfigVisibility); + config.BindWith(OsuSetting.KeyOverlay, alwaysShow); } protected override void LoadComplete() @@ -59,7 +64,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); Visible.BindValueChanged(_ => updateVisibility()); - ConfigVisibility.BindValueChanged(_ => updateVisibility(), true); + alwaysShow.BindValueChanged(_ => updateVisibility(), true); } private bool isCounting = true; From 1f53778d623244d17ac616943be992da7710f532 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 16:59:17 +0100 Subject: [PATCH 0145/1142] Add explanation to comment --- osu.Game/Overlays/Profile/Header/Components/RankGraph.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs index 83c6d80dae..ffc060b3f1 100644 --- a/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/Components/RankGraph.cs @@ -270,7 +270,8 @@ namespace osu.Game.Overlays.Profile.Header.Components [BackgroundDependencyLoader] private void load(OsuColour colours) { - // To match osu-web, background and text should both be coloured using OverlayColourProvider + // Temporary colour since it's currently impossible to change it without bugs (see https://github.com/ppy/osu-framework/issues/3231) + // If above is fixed, this should use OverlayColourProvider background.Colour = colours.Gray1; } From 7e162d9798d7e88fc27cdebe04bcdcc7dbdbd719 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 17:03:41 +0100 Subject: [PATCH 0146/1142] Fix failing test --- osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs index c70cc4ae4e..8f7e7498a9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankGraph.cs @@ -4,11 +4,13 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays; using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; using osuTK; @@ -24,6 +26,9 @@ namespace osu.Game.Tests.Visual.Online typeof(LineGraph) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Pink); + public TestSceneRankGraph() { RankGraph graph; From 878489651c456b6747960b6e724c7305400f71b3 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Sun, 2 Feb 2020 23:04:11 +0700 Subject: [PATCH 0147/1142] Make performance_background_width readonly --- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 1905728442..f55d469e22 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private const int performance_width = 80; private const float performance_background_shear = 0.45f; - private float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); + private readonly float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); protected readonly ScoreInfo Score; From 030d02594cc955a19fb1d2a4c2ccb3b8f8243d99 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 17:10:11 +0100 Subject: [PATCH 0148/1142] Allow non-italic DrawableDate --- osu.Game/Graphics/DrawableDate.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 925c7981e0..0224c77ee8 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -29,9 +29,9 @@ namespace osu.Game.Graphics } } - public DrawableDate(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE) + public DrawableDate(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE, bool italic = true) { - Font = OsuFont.GetFont(weight: FontWeight.Regular, size: textSize, italics: true); + Font = OsuFont.GetFont(weight: FontWeight.Regular, size: textSize, italics: italic); Date = date; } From d15942d1270a803947bb4dcf0811560d32efa71a Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 17:21:22 +0100 Subject: [PATCH 0149/1142] Revert containers merge and rework bottomLinkContainer visibility logic --- .../Profile/Header/BottomHeaderContainer.cs | 101 ++++++++++-------- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index bca72666de..065bef8329 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -22,7 +22,8 @@ namespace osu.Game.Overlays.Profile.Header { public readonly Bindable User = new Bindable(); - private LinkFlowContainer linkContainer; + private LinkFlowContainer topLinkContainer; + private LinkFlowContainer bottomLinkContainer; private Color4 iconColour; @@ -43,12 +44,26 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background4 }, - linkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) + new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + topLinkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + bottomLinkContainer = new LinkFlowContainer(text => text.Font = text.Font.With(size: 12)) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + } + } } }; @@ -57,43 +72,44 @@ namespace osu.Game.Overlays.Profile.Header private void updateDisplay(User user) { - linkContainer.Clear(); + topLinkContainer.Clear(); + bottomLinkContainer.Clear(); if (user == null) return; if (user.JoinDate.ToUniversalTime().Year < 2008) - linkContainer.AddText("Here since the beginning"); + topLinkContainer.AddText("Here since the beginning"); else { - linkContainer.AddText("Joined "); - linkContainer.AddText(new DrawableDate(user.JoinDate), embolden); + topLinkContainer.AddText("Joined "); + topLinkContainer.AddText(new DrawableDate(user.JoinDate), embolden); } - addSpacer(linkContainer); + addSpacer(topLinkContainer); if (user.IsOnline) { - linkContainer.AddText("Currently online"); - addSpacer(linkContainer); + topLinkContainer.AddText("Currently online"); + addSpacer(topLinkContainer); } else if (user.LastVisit.HasValue) { - linkContainer.AddText("Last seen "); - linkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden); + topLinkContainer.AddText("Last seen "); + topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden); - addSpacer(linkContainer); + addSpacer(topLinkContainer); } if (user.PlayStyles?.Length > 0) { - linkContainer.AddText("Plays with "); - linkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), embolden); + topLinkContainer.AddText("Plays with "); + topLinkContainer.AddText(string.Join(", ", user.PlayStyles.Select(style => style.GetDescription())), embolden); - addSpacer(linkContainer); + addSpacer(topLinkContainer); } - linkContainer.AddText("Contributed "); - linkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: embolden); + topLinkContainer.AddText("Contributed "); + topLinkContainer.AddLink($@"{user.PostCount:#,##0} forum posts", $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: embolden); string websiteWithoutProtocol = user.Website; @@ -106,51 +122,48 @@ namespace osu.Game.Overlays.Profile.Header } } - requireNewLineOnAddInfo = true; - - tryAddInfo(FontAwesome.Solid.MapMarker, user.Location); - tryAddInfo(OsuIcon.Heart, user.Interests); - tryAddInfo(FontAwesome.Solid.Suitcase, user.Occupation); - - requireNewLineOnAddInfo = true; + bool anyInfoAdded = false; + anyInfoAdded |= tryAddInfo(FontAwesome.Solid.MapMarker, user.Location); + anyInfoAdded |= tryAddInfo(OsuIcon.Heart, user.Interests); + anyInfoAdded |= tryAddInfo(FontAwesome.Solid.Suitcase, user.Occupation); + bottomLinkContainer.NewLine(); if (!string.IsNullOrEmpty(user.Twitter)) - tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); - tryAddInfo(FontAwesome.Brands.Discord, user.Discord); - tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); - tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); - tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); + anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); + anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Discord, user.Discord); + anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); + anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); + anyInfoAdded |= tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); + + // If no information was added to the bottomLinkContainer, hide it to avoid unwanted padding + if (anyInfoAdded) + bottomLinkContainer.Show(); + else + bottomLinkContainer.Hide(); } private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); - private bool requireNewLineOnAddInfo; - - private void tryAddInfo(IconUsage icon, string content, string link = null) + private bool tryAddInfo(IconUsage icon, string content, string link = null) { - if (string.IsNullOrEmpty(content)) return; - - if (requireNewLineOnAddInfo) - { - linkContainer.NewLine(); - requireNewLineOnAddInfo = false; - } + if (string.IsNullOrEmpty(content)) return false; // newlines could be contained in API returned user content. content = content.Replace("\n", " "); - linkContainer.AddIcon(icon, text => + bottomLinkContainer.AddIcon(icon, text => { text.Font = text.Font.With(size: 10); text.Colour = iconColour; }); if (link != null) - linkContainer.AddLink(" " + content, link, creationParameters: embolden); + bottomLinkContainer.AddLink(" " + content, link, creationParameters: embolden); else - linkContainer.AddText(" " + content, embolden); + bottomLinkContainer.AddText(" " + content, embolden); - addSpacer(linkContainer); + addSpacer(bottomLinkContainer); + return true; } private void embolden(SpriteText text) => text.Font = text.Font.With(weight: FontWeight.Bold); From 3cc1b811ef21a648eeda60c51aa751fdc6db3431 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 17:22:48 +0100 Subject: [PATCH 0150/1142] Make dates non-italic to match osu-web --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 065bef8329..3dcd65d64e 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -82,7 +82,7 @@ namespace osu.Game.Overlays.Profile.Header else { topLinkContainer.AddText("Joined "); - topLinkContainer.AddText(new DrawableDate(user.JoinDate), embolden); + topLinkContainer.AddText(new DrawableDate(user.JoinDate, italic: false), embolden); } addSpacer(topLinkContainer); @@ -95,7 +95,7 @@ namespace osu.Game.Overlays.Profile.Header else if (user.LastVisit.HasValue) { topLinkContainer.AddText("Last seen "); - topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value), embolden); + topLinkContainer.AddText(new DrawableDate(user.LastVisit.Value, italic: false), embolden); addSpacer(topLinkContainer); } From 72107c27c99cb568d8457dfe01f3ce2d271ffbc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 2 Feb 2020 17:39:58 +0100 Subject: [PATCH 0151/1142] Only add newline if necessary --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 3dcd65d64e..4643ca709b 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -127,7 +127,10 @@ namespace osu.Game.Overlays.Profile.Header anyInfoAdded |= tryAddInfo(FontAwesome.Solid.MapMarker, user.Location); anyInfoAdded |= tryAddInfo(OsuIcon.Heart, user.Interests); anyInfoAdded |= tryAddInfo(FontAwesome.Solid.Suitcase, user.Occupation); - bottomLinkContainer.NewLine(); + + if (anyInfoAdded) + bottomLinkContainer.NewLine(); + if (!string.IsNullOrEmpty(user.Twitter)) anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Discord, user.Discord); From c479d0efa48be274e36ffa55359bfff6716ab30d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 2 Feb 2020 17:41:42 +0100 Subject: [PATCH 0152/1142] Simplify show/hide logic --- osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs index 4643ca709b..c27b5f4b4a 100644 --- a/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BottomHeaderContainer.cs @@ -139,10 +139,7 @@ namespace osu.Game.Overlays.Profile.Header anyInfoAdded |= tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); // If no information was added to the bottomLinkContainer, hide it to avoid unwanted padding - if (anyInfoAdded) - bottomLinkContainer.Show(); - else - bottomLinkContainer.Hide(); + bottomLinkContainer.Alpha = anyInfoAdded ? 1 : 0; } private void addSpacer(OsuTextFlowContainer textFlow) => textFlow.AddArbitraryDrawable(new Container { Width = 15 }); From fd7fccbb62c50a7201d88218c4375f1cd984a648 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 19:16:54 +0100 Subject: [PATCH 0153/1142] Add tests --- .../TestSceneSliderInput.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index b6fc9821a4..675c9fd0e7 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -44,6 +44,7 @@ namespace osu.Game.Rulesets.Osu.Tests private const double time_during_slide_2 = 3000; private const double time_during_slide_3 = 3500; private const double time_during_slide_4 = 3800; + private const double time_slider_end = 4000; private List judgementResults; private bool allJudgedFired; @@ -284,6 +285,47 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("Tracking acquired", assertMidSliderJudgements); } + + /// + /// Scenario: + /// - Press a key on the slider head + /// - While holding the key, move cursor close to the edge of tracking area + /// - Keep the cursor on the edge of tracking area until the slider ends + /// Expected Result: + /// A passing test case will have the slider track the cursor throughout the whole test. + /// + [Test] + public void TestTrackingAreaEdge() + { + performTest(new List + { + new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + }); + AddAssert("Tracking kept", assertGreatJudge); + } + + /// + /// Scenario: + /// - Press a key on the slider head + /// - While holding the key, move cursor just outside the tracking area + /// - Keep the cursor just outside the tracking area until the slider ends + /// Expected Result: + /// A passing test case will have the slider drop the tracking on frame 2. + /// + [Test] + public void TestTrackingAreaOutsideEdge() + { + performTest(new List + { + new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.2f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.2f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + }); + AddAssert("Tracking dropped", assertMidSliderJudgementFail); + } + private bool assertGreatJudge() => judgementResults.Last().Type == HitResult.Great; private bool assertHeadMissTailTracked() => judgementResults[^2].Type == HitResult.Great && judgementResults.First().Type == HitResult.Miss; From c7f1d4a8a0874b6e59b58bbaccb10456966320b0 Mon Sep 17 00:00:00 2001 From: Tree Date: Sun, 2 Feb 2020 19:29:26 +0100 Subject: [PATCH 0154/1142] Remove unnecessary newline --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 675c9fd0e7..38dcc3b23e 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -285,7 +285,6 @@ namespace osu.Game.Rulesets.Osu.Tests AddAssert("Tracking acquired", assertMidSliderJudgements); } - /// /// Scenario: /// - Press a key on the slider head From 162a3713a33bbec70b4b4c3f260cf9167dc881ae Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 2 Feb 2020 21:25:35 +0100 Subject: [PATCH 0155/1142] Modify tests to avoid fails in CLI testing --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 675c9fd0e7..7dc81059eb 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -300,8 +300,8 @@ namespace osu.Game.Rulesets.Osu.Tests performTest(new List { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, - new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking kept", assertGreatJudge); } @@ -320,8 +320,8 @@ namespace osu.Game.Rulesets.Osu.Tests performTest(new List { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, - new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.2f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.2f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking dropped", assertMidSliderJudgementFail); } From edb4c0f7528dfee3d20290166d82ca375626c550 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 10:24:53 +0900 Subject: [PATCH 0156/1142] Add blank lines for conformity --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 4b18b961ad..eaa714d68a 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -302,6 +302,7 @@ namespace osu.Game.Rulesets.Osu.Tests new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); + AddAssert("Tracking kept", assertGreatJudge); } @@ -322,6 +323,7 @@ namespace osu.Game.Rulesets.Osu.Tests new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); + AddAssert("Tracking dropped", assertMidSliderJudgementFail); } From ff17c76a20180b5789f03b5b217b11aa315a8b42 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:26:12 +0700 Subject: [PATCH 0157/1142] Fix modifiers for performance_background_width --- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index f55d469e22..c9f787bb26 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -25,7 +25,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks private const int performance_width = 80; private const float performance_background_shear = 0.45f; - private readonly float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); + private static readonly float performance_background_width = performance_width + (height / 4f * MathF.Tan(performance_background_shear)); protected readonly ScoreInfo Score; From 2253ed4c0d13544ab4ef802c666acfd6a004bb87 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 10:29:40 +0900 Subject: [PATCH 0158/1142] Move path length to a constant --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index eaa714d68a..2ad2c544e5 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -300,7 +300,7 @@ namespace osu.Game.Rulesets.Osu.Tests { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking kept", assertGreatJudge); @@ -321,7 +321,7 @@ namespace osu.Game.Rulesets.Osu.Tests { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(25, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking dropped", assertMidSliderJudgementFail); @@ -337,6 +337,8 @@ namespace osu.Game.Rulesets.Osu.Tests private ScoreAccessibleReplayPlayer currentPlayer; + private const float slider_path_length = 25; + private void performTest(List frames) { AddStep("load player", () => @@ -352,8 +354,8 @@ namespace osu.Game.Rulesets.Osu.Tests Path = new SliderPath(PathType.PerfectCurve, new[] { Vector2.Zero, - new Vector2(25, 0), - }, 25), + new Vector2(slider_path_length, 0), + }, slider_path_length), } }, BeatmapInfo = From 9426f786e91adefae97c64397ed9356fc2125d8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 10:33:56 +0900 Subject: [PATCH 0159/1142] Use slightly closer values --- osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 2ad2c544e5..33d79d9cbc 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -300,7 +300,7 @@ namespace osu.Game.Rulesets.Osu.Tests { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking kept", assertGreatJudge); @@ -321,7 +321,7 @@ namespace osu.Game.Rulesets.Osu.Tests { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, - new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, + new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.201f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); AddAssert("Tracking dropped", assertMidSliderJudgementFail); From 84fcf45aaead75d4f43efe54b890760ed50c551a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 11:55:14 +0900 Subject: [PATCH 0160/1142] Make slider tracking match what is on screen --- .../TestSceneSliderInput.cs | 4 ++-- .../Objects/Drawables/Pieces/SliderBall.cs | 14 ++------------ 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs index 33d79d9cbc..94df239267 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderInput.cs @@ -299,7 +299,7 @@ namespace osu.Game.Rulesets.Osu.Tests performTest(new List { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, - new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.19f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 250 }, new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.199f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); @@ -320,7 +320,7 @@ namespace osu.Game.Rulesets.Osu.Tests performTest(new List { new OsuReplayFrame { Position = new Vector2(0, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start }, - new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 100 }, + new OsuReplayFrame { Position = new Vector2(0, OsuHitObject.OBJECT_RADIUS * 1.21f), Actions = { OsuAction.LeftButton }, Time = time_slider_start + 250 }, new OsuReplayFrame { Position = new Vector2(slider_path_length, OsuHitObject.OBJECT_RADIUS * 1.201f), Actions = { OsuAction.LeftButton }, Time = time_slider_end }, }); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs index b89b0cafc4..0dc5c9b4a0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBall.cs @@ -24,7 +24,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces private readonly Slider slider; private readonly Drawable followCircle; - private readonly Drawable trackingArea; private readonly DrawableSlider drawableSlider; public SliderBall(Slider slider, DrawableSlider drawableSlider = null) @@ -39,13 +38,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces Children = new[] { - // This is separate from the visible followcircle to ensure consistent internal tracking area (needed to match osu-stable) - trackingArea = new CircularContainer - { - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - RelativeSizeAxes = Axes.Both - }, followCircle = new FollowCircleContainer { Origin = Anchor.Centre, @@ -103,9 +95,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces tracking = value; - // Tracking area is bigger than the visible followcircle and scales instantly to match osu-stable - trackingArea.ScaleTo(tracking ? 2.4f : 1f); - followCircle.ScaleTo(tracking ? 2f : 1f, 300, Easing.OutQuint); + followCircle.ScaleTo(tracking ? 2.4f : 1f, 300, Easing.OutQuint); followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint); } } @@ -159,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces // in valid time range Time.Current >= slider.StartTime && Time.Current < slider.EndTime && // in valid position range - lastScreenSpaceMousePosition.HasValue && trackingArea.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && + lastScreenSpaceMousePosition.HasValue && followCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) && // valid action (actions?.Any(isValidTrackingAction) ?? false); } From 9680c0941fa1b751b1dd0a4ab48235e6b15081ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 12:46:11 +0900 Subject: [PATCH 0161/1142] Move private helper methods to botom of file --- .../Sections/Recent/DrawableRecentActivity.cs | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index f538833eb0..8782e82642 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -122,30 +122,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } - private string getRulesetName() - { - var shortName = activity.Mode; - - return rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == shortName)?.Name ?? shortName; - } - - private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; - - private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) - => OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true); - - private void addUserLink() - => content.AddLink(activity.User?.Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User?.Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold)); - - private void addBeatmapLink() - => content.AddLink(activity.Beatmap?.Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap?.Url), creationParameters: t => t.Font = getLinkFont()); - - private void addBeatmapsetLink() - => content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont()); - - private void addText(string text) - => content.AddText(text, t => t.Font = OsuFont.GetFont(size: font_size, weight: FontWeight.SemiBold)); - private void createMessage() { switch (activity.Type) @@ -227,5 +203,25 @@ namespace osu.Game.Overlays.Profile.Sections.Recent break; } } + + private string getRulesetName() => + rulesets.AvailableRulesets.FirstOrDefault(r => r.ShortName == activity.Mode)?.Name ?? activity.Mode; + + private void addUserLink() + => content.AddLink(activity.User?.Username, LinkAction.OpenUserProfile, getLinkArgument(activity.User?.Url), creationParameters: t => t.Font = getLinkFont(FontWeight.Bold)); + + private void addBeatmapLink() + => content.AddLink(activity.Beatmap?.Title, LinkAction.OpenBeatmap, getLinkArgument(activity.Beatmap?.Url), creationParameters: t => t.Font = getLinkFont()); + + private void addBeatmapsetLink() + => content.AddLink(activity.Beatmapset?.Title, LinkAction.OpenBeatmapSet, getLinkArgument(activity.Beatmapset?.Url), creationParameters: t => t.Font = getLinkFont()); + + private string getLinkArgument(string url) => MessageFormatter.GetLinkDetails($"{api.Endpoint}{url}").Argument; + + private FontUsage getLinkFont(FontWeight fontWeight = FontWeight.Regular) + => OsuFont.GetFont(size: font_size, weight: fontWeight, italics: true); + + private void addText(string text) + => content.AddText(text, t => t.Font = OsuFont.GetFont(size: font_size, weight: FontWeight.SemiBold)); } } From d9d8712360b3093c76bf0cb6f7f1f3922de45578 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 15:13:21 +0900 Subject: [PATCH 0162/1142] Refactor class layout for readability --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 5b53d9d1fa..f8a9d14f62 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -17,11 +17,6 @@ namespace osu.Game.Overlays { public class OverlayRulesetTabItem : TabItem { - protected readonly OsuSpriteText Text; - private readonly FillFlowContainer content; - - protected override Container Content => content; - private Color4 accentColour; protected virtual Color4 AccentColour @@ -30,13 +25,17 @@ namespace osu.Game.Overlays set { accentColour = value; - Text.FadeColour(value, 120, Easing.OutQuint); + text.FadeColour(value, 120, Easing.OutQuint); } } + protected override Container Content { get; } + [Resolved] private OverlayColourProvider colourProvider { get; set; } + private readonly OsuSpriteText text; + public OverlayRulesetTabItem(RulesetInfo value) : base(value) { @@ -44,12 +43,12 @@ namespace osu.Game.Overlays AddRangeInternal(new Drawable[] { - content = new FillFlowContainer + Content = new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(3, 0), - Child = Text = new OsuSpriteText + Child = text = new OsuSpriteText { Origin = Anchor.Centre, Anchor = Anchor.Centre, @@ -87,7 +86,7 @@ namespace osu.Game.Overlays private void updateState() { - Text.Font = Text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); + text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); AccentColour = IsHovered || Active.Value ? Color4.White : colourProvider.Highlight1; } } From 9183c78319bf3629d67e8c0346e0e5640ca83219 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 16:04:32 +0900 Subject: [PATCH 0163/1142] Fix crash on exiting song select with ctrl-enter autoplay --- .../SongSelect/TestScenePlaySongSelect.cs | 27 ++++++++++++++++++- osu.Game/Screens/Select/PlaySongSelect.cs | 4 +-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index c01dee2959..80192b9ebc 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -23,6 +23,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Taiko; +using osu.Game.Screens.Play; using osu.Game.Screens.Select; using osu.Game.Screens.Select.Carousel; using osu.Game.Screens.Select.Filter; @@ -77,7 +78,6 @@ namespace osu.Game.Tests.Visual.SongSelect private OsuConfigManager config; - [SetUpSteps] public override void SetUpSteps() { base.SetUpSteps(); @@ -426,6 +426,31 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("start not requested", () => !startRequested); } + [Test] + public void TestAutoplayViaCtrlEnter() + { + addRulesetImportStep(0); + + createSongSelect(); + + AddStep("press ctrl+enter", () => + { + InputManager.PressKey(Key.ControlLeft); + InputManager.PressKey(Key.Enter); + + InputManager.ReleaseKey(Key.ControlLeft); + InputManager.ReleaseKey(Key.Enter); + }); + + AddUntilStep("wait for player", () => Stack.CurrentScreen is PlayerLoader); + + AddAssert("autoplay enabled", () => songSelect.Mods.Value.FirstOrDefault() is ModAutoplay); + + AddUntilStep("wait for return to ss", () => songSelect.IsCurrentScreen()); + + AddAssert("mod disabled", () => songSelect.Mods.Value.Count == 0); + } + [Test] public void TestHideSetSelectsCorrectBeatmap() { diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 9368bac69f..18f13c5e1d 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -33,6 +33,8 @@ namespace osu.Game.Screens.Select public override void OnResuming(IScreen last) { + base.OnResuming(last); + player = null; if (removeAutoModOnResume) @@ -41,8 +43,6 @@ namespace osu.Game.Screens.Select ModSelect.DeselectTypes(new[] { autoType }, true); removeAutoModOnResume = false; } - - base.OnResuming(last); } protected override bool OnStart() From 81ab6d43b6cc0be470910f11d478f56d2e3c5032 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 11:09:46 +0300 Subject: [PATCH 0164/1142] Add ability to create ruleset selector in OverlayHeader --- .../UserInterface/TestSceneOverlayHeader.cs | 4 ++- osu.Game/Overlays/OverlayHeader.cs | 35 +++++++++++++++---- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs index c899ccb9eb..1cd68d1fdd 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneOverlayHeader.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.UserInterface addHeader("Orange OverlayHeader (no background)", new TestNoBackgroundHeader(), OverlayColourScheme.Orange); addHeader("Blue OverlayHeader", new TestNoControlHeader(), OverlayColourScheme.Blue); - addHeader("Green TabControlOverlayHeader (string)", new TestStringTabControlHeader(), OverlayColourScheme.Green); + addHeader("Green TabControlOverlayHeader (string) with ruleset selector", new TestStringTabControlHeader(), OverlayColourScheme.Green); addHeader("Pink TabControlOverlayHeader (enum)", new TestEnumTabControlHeader(), OverlayColourScheme.Pink); addHeader("Red BreadcrumbControlOverlayHeader (no background)", new TestBreadcrumbControlHeader(), OverlayColourScheme.Red); } @@ -116,6 +116,8 @@ namespace osu.Game.Tests.Visual.UserInterface protected override ScreenTitle CreateTitle() => new TestTitle(); + protected override Drawable CreateTitleContent() => new OverlayRulesetSelector(); + public TestStringTabControlHeader() { TabControl.AddItem("tab1"); diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index 5596f71dd0..36ac47bb87 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -50,14 +50,29 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.Both, Colour = Color4.Gray, }, - title = CreateTitle().With(title => + new Container { - title.Margin = new MarginPadding + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { + Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10, - Left = UserProfileOverlay.CONTENT_X_MARGIN - }; - }) + }, + Children = new[] + { + title = CreateTitle().With(title => + { + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + }), + CreateTitleContent().With(content => + { + content.Anchor = Anchor.CentreRight; + content.Origin = Anchor.CentreRight; + }) + } + } } }, } @@ -75,10 +90,16 @@ namespace osu.Game.Overlays } [NotNull] - protected virtual Drawable CreateContent() => Drawable.Empty(); + protected virtual Drawable CreateContent() => Empty(); [NotNull] - protected virtual Drawable CreateBackground() => Drawable.Empty(); + protected virtual Drawable CreateBackground() => Empty(); + + /// + /// Creates a on the opposite side of the . Used mostly to create . + /// + [NotNull] + protected virtual Drawable CreateTitleContent() => Empty(); protected abstract ScreenTitle CreateTitle(); } From 91aa66bcb29b6e5a43a5ef0f921fdf497c1c16a4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2020 08:16:18 +0000 Subject: [PATCH 0165/1142] Bump Sentry from 1.2.0 to 2.0.1 Bumps [Sentry](https://github.com/getsentry/sentry-dotnet) from 1.2.0 to 2.0.1. - [Release notes](https://github.com/getsentry/sentry-dotnet/releases) - [Commits](https://github.com/getsentry/sentry-dotnet/compare/1.2.0...2.0.1) 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 b38b7ff9b1..ce58be52ee 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + From ce6e97096cd3889b2807a22934736d6760a6ca56 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 11:44:31 +0300 Subject: [PATCH 0166/1142] Fix broken overlays oops --- osu.Game/Overlays/OverlayHeader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/OverlayHeader.cs b/osu.Game/Overlays/OverlayHeader.cs index 36ac47bb87..bedf8e5435 100644 --- a/osu.Game/Overlays/OverlayHeader.cs +++ b/osu.Game/Overlays/OverlayHeader.cs @@ -63,8 +63,8 @@ namespace osu.Game.Overlays { title = CreateTitle().With(title => { - Anchor = Anchor.CentreLeft; - Origin = Anchor.CentreLeft; + title.Anchor = Anchor.CentreLeft; + title.Origin = Anchor.CentreLeft; }), CreateTitleContent().With(content => { From 032c2c2afe281d1a68e86612096ff5a6dbd9bd75 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 14:16:26 +0300 Subject: [PATCH 0167/1142] Refactor BeatmapRulesetSelector --- .../Online/TestSceneBeatmapRulesetSelector.cs | 4 + .../BeatmapSet/BeatmapRulesetSelector.cs | 17 +- .../BeatmapSet/BeatmapRulesetTabItem.cs | 150 ++++++------------ osu.Game/Overlays/BeatmapSet/Header.cs | 6 +- osu.Game/Overlays/OverlayRulesetTabItem.cs | 16 +- 5 files changed, 65 insertions(+), 128 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapRulesetSelector.cs index 1f8df438fb..8b077c8de3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapRulesetSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapRulesetSelector.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics.UserInterface; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Overlays.BeatmapSet; using osu.Game.Rulesets; using System; @@ -21,6 +22,9 @@ namespace osu.Game.Tests.Visual.Online typeof(BeatmapRulesetTabItem), }; + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + private readonly TestRulesetSelector selector; public TestSceneBeatmapRulesetSelector() diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetSelector.cs b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetSelector.cs index a0bedc848e..005d21726b 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetSelector.cs @@ -2,17 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.UserInterface; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using osuTK; using System.Linq; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapRulesetSelector : RulesetSelector + public class BeatmapRulesetSelector : OverlayRulesetSelector { private readonly Bindable beatmapSet = new Bindable(); @@ -28,21 +25,9 @@ namespace osu.Game.Overlays.BeatmapSet } } - public BeatmapRulesetSelector() - { - AutoSizeAxes = Axes.Both; - } - protected override TabItem CreateTabItem(RulesetInfo value) => new BeatmapRulesetTabItem(value) { BeatmapSet = { BindTarget = beatmapSet } }; - - protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - }; } } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs index cdea49afe7..3e473df621 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs @@ -3,143 +3,87 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Events; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; -using osuTK; -using osuTK.Graphics; using System.Linq; namespace osu.Game.Overlays.BeatmapSet { - public class BeatmapRulesetTabItem : TabItem + public class BeatmapRulesetTabItem : OverlayRulesetTabItem { - private readonly OsuSpriteText name, count; - private readonly Box bar; - public readonly Bindable BeatmapSet = new Bindable(); public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + + private OsuSpriteText count; + private Container countContainer; + public BeatmapRulesetTabItem(RulesetInfo value) : base(value) { - AutoSizeAxes = Axes.Both; + } - FillFlowContainer nameContainer; - - Children = new Drawable[] + [BackgroundDependencyLoader] + private void load() + { + Content.Add(countContainer = new Container { - nameContainer = new FillFlowContainer + AutoSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Masking = true, + CornerRadius = 4f, + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Margin = new MarginPadding { Bottom = 7.5f }, - Spacing = new Vector2(2.5f), - Children = new Drawable[] + new Box { - name = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Text = value.Name, - Font = OsuFont.Default.With(size: 18), - }, - new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 4f, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), - }, - count = new OsuSpriteText - { - Alpha = 0, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Margin = new MarginPadding { Horizontal = 5f }, - Font = OsuFont.Default.With(weight: FontWeight.SemiBold), - } - } - } + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background6 + }, + count = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Margin = new MarginPadding { Horizontal = 5f }, + Font = OsuFont.Default.With(weight: FontWeight.SemiBold), + Colour = colourProvider.Foreground1, } - }, - bar = new Box - { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - RelativeSizeAxes = Axes.X, - }, - new HoverClickSounds(), - }; + } + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); BeatmapSet.BindValueChanged(setInfo => { var beatmapsCount = setInfo.NewValue?.Beatmaps.Count(b => b.Ruleset.Equals(Value)) ?? 0; count.Text = beatmapsCount.ToString(); - count.Alpha = beatmapsCount > 0 ? 1f : 0f; + countContainer.FadeTo(beatmapsCount > 0 ? 1 : 0); Enabled.Value = beatmapsCount > 0; }, true); - Enabled.BindValueChanged(v => nameContainer.Alpha = v.NewValue ? 1f : 0.5f, true); + Enabled.BindValueChanged(enabled => + { + if (enabled.NewValue) + { + UpdateState(); + return; + } + + AccentColour = colourProvider.Foreground1; + }, true); } - - [Resolved] - private OsuColour colour { get; set; } - - protected override void LoadComplete() - { - base.LoadComplete(); - - count.Colour = colour.Gray9; - bar.Colour = colour.Blue; - - updateState(); - } - - private void updateState() - { - var isHoveredOrActive = IsHovered || Active.Value; - - bar.ResizeHeightTo(isHoveredOrActive ? 4 : 0, 200, Easing.OutQuint); - - name.Colour = isHoveredOrActive ? colour.GrayE : colour.GrayC; - name.Font = name.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Regular); - } - - #region Hovering and activation logic - - protected override void OnActivated() => updateState(); - - protected override void OnDeactivated() => updateState(); - - protected override bool OnHover(HoverEvent e) - { - updateState(); - return false; - } - - protected override void OnHoverLost(HoverLostEvent e) => updateState(); - - #endregion } } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 7b42e7e459..c787df01ae 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -74,7 +74,7 @@ namespace osu.Game.Overlays.BeatmapSet new Container { RelativeSizeAxes = Axes.X, - Height = tabs_height, + AutoSizeAxes = Axes.Y, Children = new Drawable[] { tabsBg = new Box @@ -84,8 +84,8 @@ namespace osu.Game.Overlays.BeatmapSet RulesetSelector = new BeatmapRulesetSelector { Current = ruleset, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, } }, }, diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index f8a9d14f62..5e6ac57886 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -64,29 +64,33 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - updateState(); + UpdateState(); } protected override bool OnHover(HoverEvent e) { base.OnHover(e); - updateState(); + UpdateState(); return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - updateState(); + UpdateState(); } - protected override void OnActivated() => updateState(); + protected override void OnActivated() => UpdateState(); - protected override void OnDeactivated() => updateState(); + protected override void OnDeactivated() => UpdateState(); - private void updateState() + protected void UpdateState() { text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); + + if (!Enabled.Value) + return; + AccentColour = IsHovered || Active.Value ? Color4.White : colourProvider.Highlight1; } } From fa453bc3e158d3a604407d1a44fc1f09a5aed600 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 14:35:07 +0300 Subject: [PATCH 0168/1142] Refactor beatmap header --- .../Overlays/BeatmapSet/BeatmapSetHeader.cs | 34 +++ osu.Game/Overlays/BeatmapSet/Header.cs | 248 +++++++++--------- 2 files changed, 151 insertions(+), 131 deletions(-) create mode 100644 osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs new file mode 100644 index 0000000000..bf9f3ccc17 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -0,0 +1,34 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; + +namespace osu.Game.Overlays.BeatmapSet +{ + public class BeatmapSetHeader : OverlayHeader + { + public readonly Bindable Ruleset = new Bindable(); + public BeatmapRulesetSelector RulesetSelector; + + protected override ScreenTitle CreateTitle() => new BeatmapHeaderTitle(); + + protected override Drawable CreateTitleContent() => RulesetSelector = new BeatmapRulesetSelector + { + Current = Ruleset + }; + + private class BeatmapHeaderTitle : ScreenTitle + { + public BeatmapHeaderTitle() + { + Title = @"beatmap"; + Section = @"info"; + } + + protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog"); + } + } +} diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index c787df01ae..7c5c5a9d55 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -26,11 +26,9 @@ namespace osu.Game.Overlays.BeatmapSet public class Header : BeatmapDownloadTrackingComposite { private const float transition_duration = 200; - private const float tabs_height = 50; private const float buttons_height = 45; private const float buttons_spacing = 5; - private readonly Box tabsBg; private readonly UpdateableBeatmapSetCover cover; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; @@ -41,14 +39,13 @@ namespace osu.Game.Overlays.BeatmapSet public bool DownloadButtonsVisible => downloadButtonsContainer.Any(); - public readonly BeatmapRulesetSelector RulesetSelector; + public BeatmapRulesetSelector RulesetSelector => beatmapSetHeader.RulesetSelector; public readonly BeatmapPicker Picker; private readonly FavouriteButton favouriteButton; - private readonly FillFlowContainer fadeContent; - private readonly LoadingAnimation loading; + private readonly BeatmapSetHeader beatmapSetHeader; [Cached(typeof(IBindable))] private readonly Bindable ruleset = new Bindable(); @@ -69,154 +66,145 @@ namespace osu.Game.Overlays.BeatmapSet Offset = new Vector2(0f, 1f), }; - InternalChildren = new Drawable[] + InternalChild = new FillFlowContainer { - new Container + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + beatmapSetHeader = new BeatmapSetHeader { - tabsBg = new Box - { - RelativeSizeAxes = Axes.Both, - }, - RulesetSelector = new BeatmapRulesetSelector - { - Current = ruleset, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } + Ruleset = { BindTarget = ruleset }, }, - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Top = tabs_height }, - Children = new Drawable[] + new Container { - new Container + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + new Container { - cover = new UpdateableBeatmapSetCover + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Masking = true, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)), - }, - }, - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding - { - Top = 20, - Bottom = 30, - Left = BeatmapSetOverlay.X_PADDING, - Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, - }, - Children = new Drawable[] - { - fadeContent = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] + cover = new UpdateableBeatmapSetCover { - new Container + RelativeSizeAxes = Axes.Both, + Masking = true, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)), + }, + }, + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding + { + Top = 20, + Bottom = 30, + Left = BeatmapSetOverlay.X_PADDING, + Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, + }, + Children = new Drawable[] + { + fadeContent = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = Picker = new BeatmapPicker(), - }, - new FillFlowContainer - { - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] + new Container { - title = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 37, weight: FontWeight.Bold, italics: true) - }, - externalLink = new ExternalLinkButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Left = 3, Bottom = 4 }, //To better lineup with the font - }, - } - }, - artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 25, weight: FontWeight.SemiBold, italics: true) }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 20 }, - Child = author = new AuthorInfo(), - }, - beatmapAvailability = new BeatmapAvailability(), - new Container - { - RelativeSizeAxes = Axes.X, - Height = buttons_height, - Margin = new MarginPadding { Top = 10 }, - Children = new Drawable[] + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Child = Picker = new BeatmapPicker(), + }, + new FillFlowContainer { - favouriteButton = new FavouriteButton + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] { - BeatmapSet = { BindTarget = BeatmapSet } - }, - downloadButtonsContainer = new FillFlowContainer + title = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 37, weight: FontWeight.Bold, italics: true) + }, + externalLink = new ExternalLinkButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Left = 3, Bottom = 4 }, //To better lineup with the font + }, + } + }, + artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 25, weight: FontWeight.SemiBold, italics: true) }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Top = 20 }, + Child = author = new AuthorInfo(), + }, + beatmapAvailability = new BeatmapAvailability(), + new Container + { + RelativeSizeAxes = Axes.X, + Height = buttons_height, + Margin = new MarginPadding { Top = 10 }, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, - Spacing = new Vector2(buttons_spacing), + favouriteButton = new FavouriteButton + { + BeatmapSet = { BindTarget = BeatmapSet } + }, + downloadButtonsContainer = new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = buttons_height + buttons_spacing }, + Spacing = new Vector2(buttons_spacing), + }, }, }, }, }, - }, - } - }, - loading = new LoadingAnimation - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(1.5f), - }, - new FillFlowContainer - { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = BeatmapSetOverlay.TOP_PADDING, Right = BeatmapSetOverlay.X_PADDING }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(10), - Children = new Drawable[] + } + }, + loading = new LoadingAnimation { - onlineStatusPill = new BeatmapSetOnlineStatusPill + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Scale = new Vector2(1.5f), + }, + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = BeatmapSetOverlay.TOP_PADDING, Right = BeatmapSetOverlay.X_PADDING }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(10), + Children = new Drawable[] { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - TextSize = 14, - TextPadding = new MarginPadding { Horizontal = 25, Vertical = 8 } + onlineStatusPill = new BeatmapSetOnlineStatusPill + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + TextSize = 14, + TextPadding = new MarginPadding { Horizontal = 25, Vertical = 8 } + }, + Details = new Details(), }, - Details = new Details(), }, }, }, - }, + } }; Picker.Beatmap.ValueChanged += b => @@ -229,8 +217,6 @@ namespace osu.Game.Overlays.BeatmapSet [BackgroundDependencyLoader] private void load(OsuColour colours) { - tabsBg.Colour = colours.Gray3; - State.BindValueChanged(_ => updateDownloadButtons()); BeatmapSet.BindValueChanged(setInfo => From 2abcc6ad69c4c9c64ebb15f227ff77e3463c1f06 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 15:25:07 +0300 Subject: [PATCH 0169/1142] Simplify counter addition in BeatmapRulesetTabItem --- osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs index 3e473df621..df159977e6 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.BeatmapSet [BackgroundDependencyLoader] private void load() { - Content.Add(countContainer = new Container + Add(countContainer = new Container { AutoSizeAxes = Axes.Both, Anchor = Anchor.Centre, From 351cb8ac1a8c9e00c587b4fa8b0f3a3684d5a629 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 3 Feb 2020 15:47:52 +0300 Subject: [PATCH 0170/1142] Rename Visible to HasReplayLoaded and change default value Doesn't make sense to be true by default --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 18 ++++++++---------- osu.Game/Screens/Play/KeyCounterDisplay.cs | 8 ++++---- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 7ce6153ba5..5887cc2435 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -30,8 +30,8 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("showhud is set", () => hudOverlay.ShowHud.Value); AddAssert("hidetarget is visible", () => hideTarget.IsPresent); - AddAssert("key counter flow is visible", () => hudOverlay.KeyCounter.KeyFlow.IsPresent); AddAssert("pause button is visible", () => hudOverlay.HoldToQuit.IsPresent); + AddAssert("key counter flow is hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); } [Test] @@ -45,17 +45,19 @@ namespace osu.Game.Tests.Visual.Gameplay } [Test] - public void TestHideExternally() + public void TestChangeVisibilityExternally() { createNew(); AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); - AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); + AddAssert("key counter flow is hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); AddAssert("pause button is still visible", () => hudOverlay.HoldToQuit.IsPresent); - // Key counter flow container should not be affected by this, only the key counter display will be hidden as checked above. - AddAssert("key counter flow not affected", () => hudOverlay.KeyCounter.KeyFlow.IsPresent); + AddStep("set showhud false", () => hudOverlay.ShowHud.Value = true); + AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent); + AddAssert("key counter flow is still hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); + AddAssert("pause button is still visible", () => hudOverlay.HoldToQuit.IsPresent); } [Test] @@ -82,11 +84,7 @@ namespace osu.Game.Tests.Visual.Gameplay createNew(); AddStep("save keycounter visible value", () => keyCounterVisibleValue = config.Get(OsuSetting.KeyOverlay)); - AddStep("set keycounter visible false", () => - { - config.Set(OsuSetting.KeyOverlay, false); - hudOverlay.KeyCounter.Visible.Value = false; - }); + AddStep("set keycounter visible false", () => config.Set(OsuSetting.KeyOverlay, false)); AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index b5d8c99e67..4c4fcea879 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -20,12 +20,12 @@ namespace osu.Game.Screens.Play private const double key_fade_time = 80; /// - /// Whether to always show key counter regardless of . + /// Whether to always show key counter regardless of any other condition. /// This is bound to configuration setting bindable. /// private readonly Bindable alwaysShow = new Bindable(); - public readonly Bindable Visible = new Bindable(true); + public readonly Bindable HasReplayLoaded = new BindableBool(); protected readonly FillFlowContainer KeyFlow; @@ -63,7 +63,7 @@ namespace osu.Game.Screens.Play { base.LoadComplete(); - Visible.BindValueChanged(_ => updateVisibility()); + HasReplayLoaded.BindValueChanged(_ => updateVisibility()); alwaysShow.BindValueChanged(_ => updateVisibility(), true); } @@ -116,7 +116,7 @@ namespace osu.Game.Screens.Play private void updateVisibility() => // Isolate changing visibility of the key counters from fading this component. - KeyFlow.FadeTo(Visible.Value || alwaysShow.Value ? 1 : 0, duration); + KeyFlow.FadeTo(HasReplayLoaded.Value || alwaysShow.Value ? 1 : 0, duration); public override bool HandleNonPositionalInput => receptor == null; public override bool HandlePositionalInput => receptor == null; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7228e22382..02fc5f81d5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -219,7 +219,7 @@ namespace osu.Game.Screens.Play IsPaused = { BindTarget = GameplayClockContainer.IsPaused } }, PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } }, - KeyCounter = { Visible = { BindTarget = DrawableRuleset.HasReplayLoaded } }, + KeyCounter = { HasReplayLoaded = { BindTarget = DrawableRuleset.HasReplayLoaded } }, RequestSeek = GameplayClockContainer.Seek, Anchor = Anchor.Centre, Origin = Anchor.Centre From a365082a98283b3fef5f2d557a689e2bb4385a44 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 3 Feb 2020 22:18:07 +0900 Subject: [PATCH 0171/1142] Fix potential nullref in UserDimBackgrounds tests --- osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs index 41b13b50df..6d014ca1ca 100644 --- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs +++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs @@ -277,7 +277,7 @@ namespace osu.Game.Tests.Visual.Background private void setupUserSettings() { - AddUntilStep("Song select has selection", () => songSelect.Carousel.SelectedBeatmap != null); + AddUntilStep("Song select has selection", () => songSelect.Carousel?.SelectedBeatmap != null); AddStep("Set default user settings", () => { SelectedMods.Value = SelectedMods.Value.Concat(new[] { new OsuModNoFail() }).ToArray(); From 257b4052e89ed18030b24877fc656007a9dace54 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Mon, 3 Feb 2020 22:09:07 +0700 Subject: [PATCH 0172/1142] Add {ScoreInfo,UserStatistics}.Accuracy --- osu.Game/Scoring/ScoreInfo.cs | 3 +++ osu.Game/Users/UserStatistics.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index c37bab9086..8787785861 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -31,6 +31,9 @@ namespace osu.Game.Scoring [Column(TypeName = "DECIMAL(1,4)")] public double Accuracy { get; set; } + [JsonIgnore] + public string DisplayAccuracy => Accuracy == 1 ? "100%" : $"{Accuracy:P2}"; + [JsonProperty(@"pp")] public double? PP { get; set; } diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index 24f1f0b30e..9254eefb60 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -43,6 +43,9 @@ namespace osu.Game.Users [JsonProperty(@"hit_accuracy")] public decimal Accuracy; + [JsonIgnore] + public string DisplayAccuracy => $"{Accuracy:P2}"; + [JsonProperty(@"play_count")] public int PlayCount; From 9898a926b2afca3823e81895aa03f3859693a7d6 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Mon, 3 Feb 2020 22:11:36 +0700 Subject: [PATCH 0173/1142] Use ScoreInfo.DisplayAccuracy everywhere --- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 2 +- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 +- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 2 +- .../Screens/Multi/Match/Components/MatchLeaderboardScore.cs | 2 +- osu.Game/Screens/Ranking/Results.cs | 2 +- osu.Game/Screens/Select/LocalScoreDeleteDialog.cs | 3 +-- 7 files changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index c8b2f2327b..c9131883bb 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -277,7 +277,7 @@ namespace osu.Game.Online.Leaderboards protected virtual IEnumerable GetStatistics(ScoreInfo model) => new[] { new LeaderboardScoreStatistic(FontAwesome.Solid.Link, "Max Combo", model.MaxCombo.ToString()), - new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:0%}" : @"{0:0.00%}", model.Accuracy)) + new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", model.DisplayAccuracy) }; protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index f6723839b2..3a944882ab 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -116,7 +116,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new OsuSpriteText { Margin = new MarginPadding { Right = horizontal_inset }, - Text = $@"{score.Accuracy:P2}", + Text = score.DisplayAccuracy, Font = OsuFont.GetFont(size: text_size), Colour = score.Accuracy == 1 ? highAccuracyColour : Color4.White }, diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index b9664d7c2f..4f26e43fb2 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores set { totalScoreColumn.Text = $@"{value.TotalScore:N0}"; - accuracyColumn.Text = $@"{value.Accuracy:P2}"; + accuracyColumn.Text = value.DisplayAccuracy; maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; ppColumn.Text = $@"{value.PP:N0}"; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index c9f787bb26..0eee34a304 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -182,7 +182,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks protected OsuSpriteText CreateDrawableAccuracy() => new OsuSpriteText { - Text = $"{Score.Accuracy:0.00%}", + Text = Score.DisplayAccuracy, Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), Colour = colours.Yellow, }; diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs index bab9672d65..73a40d9579 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Multi.Match.Components protected override IEnumerable GetStatistics(ScoreInfo model) => new[] { - new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:0%}" : @"{0:0.00%}", model.Accuracy)), + new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", model.DisplayAccuracy), new LeaderboardScoreStatistic(FontAwesome.Solid.Sync, "Total Attempts", score.TotalAttempts.ToString()), new LeaderboardScoreStatistic(FontAwesome.Solid.Check, "Completed Beatmaps", score.CompletedBeatmaps.ToString()), }; diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index d063988b3f..05f1872be9 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -211,7 +211,7 @@ namespace osu.Game.Screens.Ranking { Anchor = Anchor.CentreLeft, Origin = Anchor.BottomCentre, - Text = $"{Score.Accuracy:P2}", + Text = Score.DisplayAccuracy, Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 40), RelativePositionAxes = Axes.X, X = 0.9f, diff --git a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs index 99e76124e8..085ea372c0 100644 --- a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs +++ b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs @@ -32,8 +32,7 @@ namespace osu.Game.Screens.Select BeatmapInfo beatmap = beatmapManager.QueryBeatmap(b => b.ID == score.BeatmapInfoID); Debug.Assert(beatmap != null); - string accuracy = string.Format(score.Accuracy == 1 ? "{0:0%}" : "{0:0.00%}", score.Accuracy); - BodyText = $"{score.User} ({accuracy}, {score.Rank})"; + BodyText = $"{score.User} ({score.DisplayAccuracy}, {score.Rank})"; Icon = FontAwesome.Regular.TrashAlt; HeaderText = "Confirm deletion of local score"; From 4dfdd98e8bda9e5c1f2c86351b1c0c2f23696ed8 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Mon, 3 Feb 2020 22:12:34 +0700 Subject: [PATCH 0174/1142] Use UserStatistics.DisplayAccuracy everywhere --- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 2 +- osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 19a24dd576..668de15c9e 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -178,7 +178,7 @@ namespace osu.Game.Overlays.Profile.Header if (user?.Statistics != null) { userStats.Add(new UserStatsLine("Ranked Score", user.Statistics.RankedScore.ToString("#,##0"))); - userStats.Add(new UserStatsLine("Hit Accuracy", Math.Round(user.Statistics.Accuracy, 2).ToString("#0.00'%'"))); + userStats.Add(new UserStatsLine("Hit Accuracy", user.Statistics.DisplayAccuracy)); userStats.Add(new UserStatsLine("Play Count", user.Statistics.PlayCount.ToString("#,##0"))); userStats.Add(new UserStatsLine("Total Score", user.Statistics.TotalScore.ToString("#,##0"))); userStats.Add(new UserStatsLine("Total Hits", user.Statistics.TotalHits.ToString("#,##0"))); diff --git a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs index 019a278771..351c4df6b7 100644 --- a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Rankings.Tables protected sealed override Drawable[] CreateAdditionalContent(UserStatistics item) => new[] { - new ColoredRowText { Text = $@"{item.Accuracy:F2}%", }, + new ColoredRowText { Text = item.DisplayAccuracy, }, new ColoredRowText { Text = $@"{item.PlayCount:N0}", }, }.Concat(CreateUniqueContent(item)).Concat(new[] { From 698408bb6d147cc977f1b445afeeaf5957151314 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Mon, 3 Feb 2020 22:36:38 +0700 Subject: [PATCH 0175/1142] Remove redundant using directive --- osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs index 668de15c9e..6ed4fc3187 100644 --- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs +++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; From 12574111e5375b56ebfae7af839b38d55be427d6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 19:44:10 +0300 Subject: [PATCH 0176/1142] Use ColourProvider colours --- .../Online/TestSceneRankingsSpotlightSelector.cs | 4 ++++ osu.Game/Overlays/Rankings/SpotlightSelector.cs | 14 +++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index 009fe7cc8c..e46c8a4a71 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays; using osu.Game.Overlays.Rankings; namespace osu.Game.Tests.Visual.Online @@ -21,6 +22,9 @@ namespace osu.Game.Tests.Visual.Online protected override bool UseOnlineAPI => true; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + [Resolved] private IAPIProvider api { get; set; } diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 4da3daa62a..e34c01113e 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -83,9 +83,9 @@ namespace osu.Game.Overlays.Rankings } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - background.Colour = colours.GreySeafoam; + background.Colour = colourProvider.Dark3; } protected override void LoadComplete() @@ -138,9 +138,9 @@ namespace osu.Game.Overlays.Rankings } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - valueText.Colour = colours.GreySeafoamLighter; + valueText.Colour = colourProvider.Content2; } } @@ -151,10 +151,10 @@ namespace osu.Game.Overlays.Rankings protected override DropdownMenu CreateMenu() => menu = base.CreateMenu().With(m => m.MaxHeight = 400); [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - menu.BackgroundColour = colours.Gray1; - AccentColour = colours.GreySeafoamDarker; + menu.BackgroundColour = colourProvider.Background5; + AccentColour = colourProvider.Background6; } } } From 51ed289c597407867c7096345ed89b8a53d09d95 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 3 Feb 2020 19:59:58 +0300 Subject: [PATCH 0177/1142] Revert namings and behaviour changes --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 18 ++++++++++-------- osu.Game/Screens/Play/KeyCounterDisplay.cs | 17 ++++++----------- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 5887cc2435..7ce6153ba5 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -30,8 +30,8 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("showhud is set", () => hudOverlay.ShowHud.Value); AddAssert("hidetarget is visible", () => hideTarget.IsPresent); + AddAssert("key counter flow is visible", () => hudOverlay.KeyCounter.KeyFlow.IsPresent); AddAssert("pause button is visible", () => hudOverlay.HoldToQuit.IsPresent); - AddAssert("key counter flow is hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); } [Test] @@ -45,19 +45,17 @@ namespace osu.Game.Tests.Visual.Gameplay } [Test] - public void TestChangeVisibilityExternally() + public void TestHideExternally() { createNew(); AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); + AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); - AddAssert("key counter flow is hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); AddAssert("pause button is still visible", () => hudOverlay.HoldToQuit.IsPresent); - AddStep("set showhud false", () => hudOverlay.ShowHud.Value = true); - AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent); - AddAssert("key counter flow is still hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); - AddAssert("pause button is still visible", () => hudOverlay.HoldToQuit.IsPresent); + // Key counter flow container should not be affected by this, only the key counter display will be hidden as checked above. + AddAssert("key counter flow not affected", () => hudOverlay.KeyCounter.KeyFlow.IsPresent); } [Test] @@ -84,7 +82,11 @@ namespace osu.Game.Tests.Visual.Gameplay createNew(); AddStep("save keycounter visible value", () => keyCounterVisibleValue = config.Get(OsuSetting.KeyOverlay)); - AddStep("set keycounter visible false", () => config.Set(OsuSetting.KeyOverlay, false)); + AddStep("set keycounter visible false", () => + { + config.Set(OsuSetting.KeyOverlay, false); + hudOverlay.KeyCounter.Visible.Value = false; + }); AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index 4c4fcea879..5584bdc359 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -19,13 +19,8 @@ namespace osu.Game.Screens.Play private const int duration = 100; private const double key_fade_time = 80; - /// - /// Whether to always show key counter regardless of any other condition. - /// This is bound to configuration setting bindable. - /// - private readonly Bindable alwaysShow = new Bindable(); - - public readonly Bindable HasReplayLoaded = new BindableBool(); + public readonly Bindable Visible = new Bindable(true); + private readonly Bindable configVisibility = new Bindable(); protected readonly FillFlowContainer KeyFlow; @@ -56,15 +51,15 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.KeyOverlay, alwaysShow); + config.BindWith(OsuSetting.KeyOverlay, configVisibility); } protected override void LoadComplete() { base.LoadComplete(); - HasReplayLoaded.BindValueChanged(_ => updateVisibility()); - alwaysShow.BindValueChanged(_ => updateVisibility(), true); + Visible.BindValueChanged(_ => updateVisibility()); + configVisibility.BindValueChanged(_ => updateVisibility(), true); } private bool isCounting = true; @@ -116,7 +111,7 @@ namespace osu.Game.Screens.Play private void updateVisibility() => // Isolate changing visibility of the key counters from fading this component. - KeyFlow.FadeTo(HasReplayLoaded.Value || alwaysShow.Value ? 1 : 0, duration); + KeyFlow.FadeTo(AlwaysVisible.Value || configVisibility.Value ? 1 : 0, duration); public override bool HandleNonPositionalInput => receptor == null; public override bool HandlePositionalInput => receptor == null; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 02fc5f81d5..7228e22382 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -219,7 +219,7 @@ namespace osu.Game.Screens.Play IsPaused = { BindTarget = GameplayClockContainer.IsPaused } }, PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } }, - KeyCounter = { HasReplayLoaded = { BindTarget = DrawableRuleset.HasReplayLoaded } }, + KeyCounter = { Visible = { BindTarget = DrawableRuleset.HasReplayLoaded } }, RequestSeek = GameplayClockContainer.Seek, Anchor = Anchor.Centre, Origin = Anchor.Centre From 4cd4055e7cb509d20e788ab261dd2dcb44519bfa Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 3 Feb 2020 20:00:43 +0300 Subject: [PATCH 0178/1142] Rename to AlwaysVisible and add XMLDoc --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +- osu.Game/Screens/Play/KeyCounterDisplay.cs | 9 +++++++-- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 7ce6153ba5..2bafcc1197 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("set keycounter visible false", () => { config.Set(OsuSetting.KeyOverlay, false); - hudOverlay.KeyCounter.Visible.Value = false; + hudOverlay.KeyCounter.AlwaysVisible.Value = false; }); AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); diff --git a/osu.Game/Screens/Play/KeyCounterDisplay.cs b/osu.Game/Screens/Play/KeyCounterDisplay.cs index 5584bdc359..2ed4afafd3 100644 --- a/osu.Game/Screens/Play/KeyCounterDisplay.cs +++ b/osu.Game/Screens/Play/KeyCounterDisplay.cs @@ -19,13 +19,18 @@ namespace osu.Game.Screens.Play private const int duration = 100; private const double key_fade_time = 80; - public readonly Bindable Visible = new Bindable(true); private readonly Bindable configVisibility = new Bindable(); protected readonly FillFlowContainer KeyFlow; protected override Container Content => KeyFlow; + /// + /// Whether the key counter should be visible regardless of the configuration value. + /// This is true by default, but can be changed. + /// + public readonly Bindable AlwaysVisible = new Bindable(true); + public KeyCounterDisplay() { AutoSizeAxes = Axes.Both; @@ -58,7 +63,7 @@ namespace osu.Game.Screens.Play { base.LoadComplete(); - Visible.BindValueChanged(_ => updateVisibility()); + AlwaysVisible.BindValueChanged(_ => updateVisibility()); configVisibility.BindValueChanged(_ => updateVisibility(), true); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7228e22382..aecd35f7dc 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -219,7 +219,7 @@ namespace osu.Game.Screens.Play IsPaused = { BindTarget = GameplayClockContainer.IsPaused } }, PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } }, - KeyCounter = { Visible = { BindTarget = DrawableRuleset.HasReplayLoaded } }, + KeyCounter = { AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded } }, RequestSeek = GameplayClockContainer.Seek, Anchor = Anchor.Centre, Origin = Anchor.Centre From b284170437d3174f27c07ec090f51201923f1ec5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 20:20:35 +0300 Subject: [PATCH 0179/1142] Basic implementation of new RankingsOverlayHeader --- .../Visual/Online/TestSceneRankingsHeader.cs | 18 ++++--- .../Overlays/Changelog/ChangelogHeader.cs | 18 +++---- osu.Game/Overlays/ChangelogOverlay.cs | 2 +- osu.Game/Overlays/News/NewsHeader.cs | 10 ++-- .../Rankings/RankingsOverlayHeader.cs | 48 +++++++++++++++++++ osu.Game/Overlays/TabControlOverlayHeader.cs | 9 +++- 6 files changed, 79 insertions(+), 26 deletions(-) create mode 100644 osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs index e708934bc3..ff2da39629 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs @@ -3,8 +3,9 @@ using System; using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Graphics; +using osu.Game.Overlays; using osu.Game.Overlays.Rankings; using osu.Game.Rulesets; using osu.Game.Users; @@ -15,24 +16,21 @@ namespace osu.Game.Tests.Visual.Online { public override IReadOnlyList RequiredTypes => new[] { - typeof(DismissableFlag), - typeof(HeaderTitle), - typeof(RankingsRulesetSelector), - typeof(RankingsScopeSelector), - typeof(RankingsHeader), + typeof(RankingsOverlayHeader), }; + [Cached] + private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneRankingsHeader() { var countryBindable = new Bindable(); var ruleset = new Bindable(); var scope = new Bindable(); - Add(new RankingsHeader + Add(new RankingsOverlayHeader { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scope = { BindTarget = scope }, + Current = { BindTarget = scope }, Country = { BindTarget = countryBindable }, Ruleset = { BindTarget = ruleset }, Spotlights = new[] diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 4165a180da..8663ec586b 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Changelog { public class ChangelogHeader : BreadcrumbControlOverlayHeader { - public readonly Bindable Current = new Bindable(); + public readonly Bindable Build = new Bindable(); public Action ListingSelected; @@ -25,18 +25,18 @@ namespace osu.Game.Overlays.Changelog public ChangelogHeader() { TabControl.AddItem(listing_string); - TabControl.Current.ValueChanged += e => + Current.ValueChanged += e => { if (e.NewValue == listing_string) ListingSelected?.Invoke(); }; - Current.ValueChanged += showBuild; + Build.ValueChanged += showBuild; Streams.Current.ValueChanged += e => { - if (e.NewValue?.LatestBuild != null && !e.NewValue.Equals(Current.Value?.UpdateStream)) - Current.Value = e.NewValue.LatestBuild; + if (e.NewValue?.LatestBuild != null && !e.NewValue.Equals(Build.Value?.UpdateStream)) + Build.Value = e.NewValue.LatestBuild; }; } @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Changelog if (e.NewValue != null) { TabControl.AddItem(e.NewValue.ToString()); - TabControl.Current.Value = e.NewValue.ToString(); + Current.Value = e.NewValue.ToString(); updateCurrentStream(); @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.Changelog } else { - TabControl.Current.Value = listing_string; + Current.Value = listing_string; Streams.Current.Value = null; title.Version = null; } @@ -86,10 +86,10 @@ namespace osu.Game.Overlays.Changelog private void updateCurrentStream() { - if (Current.Value == null) + if (Build.Value == null) return; - Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == Current.Value.UpdateStream.Name); + Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == Build.Value.UpdateStream.Name); } private class ChangelogHeaderTitle : ScreenTitle diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 90ba206077..6a8cb29d3e 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -78,7 +78,7 @@ namespace osu.Game.Overlays sampleBack = audio.Samples.Get(@"UI/generic-select-soft"); - Header.Current.BindTo(Current); + Header.Build.BindTo(Current); Current.BindValueChanged(e => { diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index b525ba7a82..b55e3ffba0 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.News private NewsHeaderTitle title; - public readonly Bindable Current = new Bindable(null); + public readonly Bindable Post = new Bindable(null); public Action ShowFrontPage; @@ -22,13 +22,13 @@ namespace osu.Game.Overlays.News { TabControl.AddItem(front_page_string); - TabControl.Current.ValueChanged += e => + Current.ValueChanged += e => { if (e.NewValue == front_page_string) ShowFrontPage?.Invoke(); }; - Current.ValueChanged += showPost; + Post.ValueChanged += showPost; } private void showPost(ValueChangedEvent e) @@ -39,13 +39,13 @@ namespace osu.Game.Overlays.News if (e.NewValue != null) { TabControl.AddItem(e.NewValue); - TabControl.Current.Value = e.NewValue; + Current.Value = e.NewValue; title.IsReadingPost = true; } else { - TabControl.Current.Value = front_page_string; + Current.Value = front_page_string; title.IsReadingPost = false; } } diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs new file mode 100644 index 0000000000..e4199ba56d --- /dev/null +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -0,0 +1,48 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Bindables; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets; +using osu.Game.Users; +using System.Collections.Generic; + +namespace osu.Game.Overlays.Rankings +{ + public class RankingsOverlayHeader : TabControlOverlayHeader + { + public readonly Bindable Ruleset = new Bindable(); + public readonly Bindable Country = new Bindable(); + + public IEnumerable Spotlights { get; set; } + + protected override ScreenTitle CreateTitle() => new RankingsTitle + { + Scope = { BindTarget = Current } + }; + + protected override Drawable CreateTitleContent() => new OverlayRulesetSelector + { + Current = Ruleset + }; + + private class RankingsTitle : ScreenTitle + { + public readonly Bindable Scope = new Bindable(); + + public RankingsTitle() + { + Title = "ranking"; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Scope.BindValueChanged(scope => Section = scope.NewValue.ToString().ToLowerInvariant(), true); + } + + protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/rankings"); + } + } +} diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index b410739b25..5c3881c4ee 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -3,6 +3,7 @@ using JetBrains.Annotations; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -19,6 +20,8 @@ namespace osu.Game.Overlays /// The type of item to be represented by tabs. public abstract class TabControlOverlayHeader : OverlayHeader { + public readonly Bindable Current = new Bindable(); + protected OsuTabControl TabControl; private readonly Box controlBackground; @@ -35,7 +38,11 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, }, - TabControl = CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }) + TabControl = CreateTabControl().With(control => + { + control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }; + control.Current = Current; + }) } }); } From 588a77484b65e07d5a5a1cc225dca96771b62eb8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 20:32:20 +0300 Subject: [PATCH 0180/1142] Add ContryFilter to new header --- .../Online/TestSceneRankingsCountryFilter.cs | 5 +++++ .../Visual/Online/TestSceneRankingsHeader.cs | 1 + osu.Game/Overlays/Rankings/CountryFilter.cs | 4 ++-- osu.Game/Overlays/Rankings/CountryPill.cs | 8 ++++---- .../Overlays/Rankings/RankingsOverlayHeader.cs | 14 ++++++++++++++ 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs index 7ac65181f9..79862deb16 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsCountryFilter.cs @@ -11,6 +11,8 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osuTK.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays; +using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.Online { @@ -22,6 +24,9 @@ namespace osu.Game.Tests.Visual.Online typeof(CountryPill) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneRankingsCountryFilter() { var countryBindable = new Bindable(); diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs index ff2da39629..9837ae251d 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs @@ -17,6 +17,7 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { typeof(RankingsOverlayHeader), + typeof(CountryFilter), }; [Cached] diff --git a/osu.Game/Overlays/Rankings/CountryFilter.cs b/osu.Game/Overlays/Rankings/CountryFilter.cs index 2b12457ccc..4bdefb06ef 100644 --- a/osu.Game/Overlays/Rankings/CountryFilter.cs +++ b/osu.Game/Overlays/Rankings/CountryFilter.cs @@ -76,9 +76,9 @@ namespace osu.Game.Overlays.Rankings } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - background.Colour = colours.GreySeafoam; + background.Colour = colourProvider.Dark3; } protected override void LoadComplete() diff --git a/osu.Game/Overlays/Rankings/CountryPill.cs b/osu.Game/Overlays/Rankings/CountryPill.cs index 410d316006..1b19bbd95e 100644 --- a/osu.Game/Overlays/Rankings/CountryPill.cs +++ b/osu.Game/Overlays/Rankings/CountryPill.cs @@ -100,9 +100,9 @@ namespace osu.Game.Overlays.Rankings } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - background.Colour = colours.GreySeafoamDarker; + background.Colour = colourProvider.Background5; } protected override void LoadComplete() @@ -154,9 +154,9 @@ namespace osu.Game.Overlays.Rankings } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - IdleColour = colours.GreySeafoamLighter; + IdleColour = colourProvider.Light2; HoverColour = Color4.White; } } diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index e4199ba56d..b3f96604ea 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -7,6 +7,7 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osu.Game.Users; using System.Collections.Generic; +using osu.Framework.Graphics.Containers; namespace osu.Game.Overlays.Rankings { @@ -27,6 +28,19 @@ namespace osu.Game.Overlays.Rankings Current = Ruleset }; + protected override Drawable CreateContent() => new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new CountryFilter + { + Current = Country + } + } + }; + private class RankingsTitle : ScreenTitle { public readonly Bindable Scope = new Bindable(); From dc1d0d0f32063952da5e149deb03193fbf284205 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 20:47:41 +0300 Subject: [PATCH 0181/1142] Add spotlights selector to new header --- .../Rankings/RankingsOverlayHeader.cs | 69 ++++++++++++++++++- 1 file changed, 67 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index b3f96604ea..f6d39c7df4 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -8,15 +8,22 @@ using osu.Game.Rulesets; using osu.Game.Users; using System.Collections.Generic; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Allocation; namespace osu.Game.Overlays.Rankings { public class RankingsOverlayHeader : TabControlOverlayHeader { public readonly Bindable Ruleset = new Bindable(); + public readonly Bindable Spotlight = new Bindable(); public readonly Bindable Country = new Bindable(); - public IEnumerable Spotlights { get; set; } + public IEnumerable Spotlights + { + get => spotlightsContainer.Spotlights; + set => spotlightsContainer.Spotlights = value; + } protected override ScreenTitle CreateTitle() => new RankingsTitle { @@ -28,19 +35,35 @@ namespace osu.Game.Overlays.Rankings Current = Ruleset }; - protected override Drawable CreateContent() => new Container + private SpotlightsContainer spotlightsContainer; + + protected override Drawable CreateContent() => new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, Children = new Drawable[] { new CountryFilter { Current = Country + }, + spotlightsContainer = new SpotlightsContainer + { + Spotlight = { BindTarget = Spotlight } } } }; + protected override void LoadComplete() + { + Current.BindValueChanged(onCurrentChanged, true); + base.LoadComplete(); + } + + private void onCurrentChanged(ValueChangedEvent scope) => + spotlightsContainer.FadeTo(scope.NewValue == RankingsScope.Spotlights ? 1 : 0, 200, Easing.OutQuint); + private class RankingsTitle : ScreenTitle { public readonly Bindable Scope = new Bindable(); @@ -58,5 +81,47 @@ namespace osu.Game.Overlays.Rankings protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/rankings"); } + + private class SpotlightsContainer : CompositeDrawable + { + public readonly Bindable Spotlight = new Bindable(); + + public IEnumerable Spotlights + { + get => dropdown.Items; + set => dropdown.Items = value; + } + + private readonly OsuDropdown dropdown; + private readonly Box background; + + public SpotlightsContainer() + { + Height = 100; + RelativeSizeAxes = Axes.X; + InternalChildren = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + dropdown = new OsuDropdown + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Width = 0.8f, + Current = Spotlight, + Y = 20, + } + }; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + background.Colour = colourProvider.Dark3; + } + } } } From 3b6ed3fb2756a9a61fff3c4174c03aed36aa5f69 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 20:53:30 +0300 Subject: [PATCH 0182/1142] Use new header in the RankingsOverlay --- osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs | 3 ++- osu.Game/Overlays/RankingsOverlay.cs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs index 568e36df4c..a769ebe4a9 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs @@ -25,7 +25,8 @@ namespace osu.Game.Tests.Visual.Online typeof(TableRowBackground), typeof(UserBasedTable), typeof(RankingsTable<>), - typeof(RankingsOverlay) + typeof(RankingsOverlay), + typeof(RankingsOverlayHeader) }; [Cached] diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 1ab18b8c15..4a463e431c 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -55,12 +55,13 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - new RankingsHeader + new RankingsOverlayHeader { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, + Depth = -float.MaxValue, Country = { BindTarget = Country }, - Scope = { BindTarget = Scope }, + Current = { BindTarget = Scope }, Ruleset = { BindTarget = ruleset } }, new Container From 2a802307e7b2b38e87765ea8eb3378c4329126cc Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 20:59:08 +0300 Subject: [PATCH 0183/1142] Delete unused components --- .../TestSceneRankingsDismissableFlag.cs | 66 --------- .../Visual/Online/TestSceneRankingsHeader.cs | 1 + .../Online/TestSceneRankingsHeaderTitle.cs | 55 -------- .../TestSceneRankingsRulesetSelector.cs | 41 ------ .../Online/TestSceneRankingsScopeSelector.cs | 54 -------- osu.Game/Overlays/Rankings/DismissableFlag.cs | 55 -------- osu.Game/Overlays/Rankings/HeaderTitle.cs | 91 ------------ osu.Game/Overlays/Rankings/RankingsHeader.cs | 129 ------------------ .../Rankings/RankingsOverlayHeader.cs | 8 ++ .../Rankings/RankingsRulesetSelector.cs | 56 -------- .../Rankings/RankingsScopeSelector.cs | 26 ---- 11 files changed, 9 insertions(+), 573 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Online/TestSceneRankingsDismissableFlag.cs delete mode 100644 osu.Game.Tests/Visual/Online/TestSceneRankingsHeaderTitle.cs delete mode 100644 osu.Game.Tests/Visual/Online/TestSceneRankingsRulesetSelector.cs delete mode 100644 osu.Game.Tests/Visual/Online/TestSceneRankingsScopeSelector.cs delete mode 100644 osu.Game/Overlays/Rankings/DismissableFlag.cs delete mode 100644 osu.Game/Overlays/Rankings/HeaderTitle.cs delete mode 100644 osu.Game/Overlays/Rankings/RankingsHeader.cs delete mode 100644 osu.Game/Overlays/Rankings/RankingsRulesetSelector.cs delete mode 100644 osu.Game/Overlays/Rankings/RankingsScopeSelector.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsDismissableFlag.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsDismissableFlag.cs deleted file mode 100644 index cd954cd6bd..0000000000 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsDismissableFlag.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Overlays.Rankings; -using osu.Game.Users; -using osuTK; - -namespace osu.Game.Tests.Visual.Online -{ - public class TestSceneRankingsDismissableFlag : OsuTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(DismissableFlag), - }; - - public TestSceneRankingsDismissableFlag() - { - DismissableFlag flag; - SpriteText text; - - var countryA = new Country - { - FlagName = "BY", - FullName = "Belarus" - }; - - var countryB = new Country - { - FlagName = "US", - FullName = "United States" - }; - - AddRange(new Drawable[] - { - flag = new DismissableFlag - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(30, 20), - Country = countryA, - }, - text = new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = "Invoked", - Font = OsuFont.GetFont(size: 30), - Alpha = 0, - } - }); - - flag.Action += () => text.FadeIn().Then().FadeOut(1000, Easing.OutQuint); - - AddStep("Trigger click", () => flag.Click()); - AddStep("Change to country 2", () => flag.Country = countryB); - AddStep("Change to country 1", () => flag.Country = countryA); - } - } -} diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs index 9837ae251d..898e461bde 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs @@ -18,6 +18,7 @@ namespace osu.Game.Tests.Visual.Online { typeof(RankingsOverlayHeader), typeof(CountryFilter), + typeof(CountryPill) }; [Cached] diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeaderTitle.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeaderTitle.cs deleted file mode 100644 index 0edf104da0..0000000000 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeaderTitle.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Game.Overlays.Rankings; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual.Online -{ - public class TestSceneRankingsHeaderTitle : OsuTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(DismissableFlag), - typeof(HeaderTitle), - }; - - public TestSceneRankingsHeaderTitle() - { - var countryBindable = new Bindable(); - var scope = new Bindable(); - - Add(new HeaderTitle - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Country = { BindTarget = countryBindable }, - Scope = { BindTarget = scope }, - }); - - var countryA = new Country - { - FlagName = "BY", - FullName = "Belarus" - }; - - var countryB = new Country - { - FlagName = "US", - FullName = "United States" - }; - - AddStep("Set country 1", () => countryBindable.Value = countryA); - AddStep("Set country 2", () => countryBindable.Value = countryB); - AddStep("Set null country", () => countryBindable.Value = null); - AddStep("Set scope to Performance", () => scope.Value = RankingsScope.Performance); - AddStep("Set scope to Spotlights", () => scope.Value = RankingsScope.Spotlights); - AddStep("Set scope to Score", () => scope.Value = RankingsScope.Score); - AddStep("Set scope to Country", () => scope.Value = RankingsScope.Country); - } - } -} diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsRulesetSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsRulesetSelector.cs deleted file mode 100644 index 84515bd3a4..0000000000 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsRulesetSelector.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using osu.Game.Overlays.Rankings; -using osu.Framework.Graphics; -using osu.Game.Rulesets; -using osu.Framework.Bindables; -using osu.Game.Rulesets.Osu; -using osu.Game.Rulesets.Mania; -using osu.Game.Rulesets.Taiko; -using osu.Game.Rulesets.Catch; - -namespace osu.Game.Tests.Visual.Online -{ - public class TestSceneRankingsRulesetSelector : OsuTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(RankingsRulesetSelector), - }; - - public TestSceneRankingsRulesetSelector() - { - var current = new Bindable(); - - Add(new RankingsRulesetSelector - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Current = { BindTarget = current } - }); - - AddStep("Select osu!", () => current.Value = new OsuRuleset().RulesetInfo); - AddStep("Select mania", () => current.Value = new ManiaRuleset().RulesetInfo); - AddStep("Select taiko", () => current.Value = new TaikoRuleset().RulesetInfo); - AddStep("Select catch", () => current.Value = new CatchRuleset().RulesetInfo); - } - } -} diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsScopeSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsScopeSelector.cs deleted file mode 100644 index 3693d6b5b4..0000000000 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsScopeSelector.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using osu.Framework.Graphics; -using osu.Framework.Bindables; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Allocation; -using osu.Game.Graphics; -using osu.Game.Overlays.Rankings; - -namespace osu.Game.Tests.Visual.Online -{ - public class TestSceneRankingsScopeSelector : OsuTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(RankingsScopeSelector), - }; - - private readonly Box background; - - public TestSceneRankingsScopeSelector() - { - var scope = new Bindable(); - - AddRange(new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both - }, - new RankingsScopeSelector - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Current = scope, - } - }); - - AddStep(@"Select country", () => scope.Value = RankingsScope.Country); - AddStep(@"Select performance", () => scope.Value = RankingsScope.Performance); - AddStep(@"Select score", () => scope.Value = RankingsScope.Score); - AddStep(@"Select spotlights", () => scope.Value = RankingsScope.Spotlights); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.GreySeafoam; - } - } -} diff --git a/osu.Game/Overlays/Rankings/DismissableFlag.cs b/osu.Game/Overlays/Rankings/DismissableFlag.cs deleted file mode 100644 index 7a55b0bba6..0000000000 --- a/osu.Game/Overlays/Rankings/DismissableFlag.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Framework.Graphics.Sprites; -using osu.Game.Users.Drawables; -using osuTK.Graphics; -using osuTK; -using osu.Framework.Input.Events; -using System; - -namespace osu.Game.Overlays.Rankings -{ - public class DismissableFlag : UpdateableFlag - { - private const int duration = 200; - - public Action Action; - - private readonly SpriteIcon hoverIcon; - - public DismissableFlag() - { - AddInternal(hoverIcon = new SpriteIcon - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Depth = -1, - Alpha = 0, - Size = new Vector2(10), - Icon = FontAwesome.Solid.Times, - }); - } - - protected override bool OnHover(HoverEvent e) - { - hoverIcon.FadeIn(duration, Easing.OutQuint); - this.FadeColour(Color4.Gray, duration, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - base.OnHoverLost(e); - hoverIcon.FadeOut(duration, Easing.OutQuint); - this.FadeColour(Color4.White, duration, Easing.OutQuint); - } - - protected override bool OnClick(ClickEvent e) - { - Action?.Invoke(); - return true; - } - } -} diff --git a/osu.Game/Overlays/Rankings/HeaderTitle.cs b/osu.Game/Overlays/Rankings/HeaderTitle.cs deleted file mode 100644 index b08a2a3900..0000000000 --- a/osu.Game/Overlays/Rankings/HeaderTitle.cs +++ /dev/null @@ -1,91 +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.Bindables; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Game.Users; -using osu.Framework.Graphics; -using osuTK; -using osu.Game.Graphics; -using osu.Framework.Allocation; -using osu.Game.Graphics.Sprites; - -namespace osu.Game.Overlays.Rankings -{ - public class HeaderTitle : CompositeDrawable - { - private const int spacing = 10; - private const int flag_margin = 5; - private const int text_size = 40; - - public readonly Bindable Scope = new Bindable(); - public readonly Bindable Country = new Bindable(); - - private readonly SpriteText scopeText; - private readonly DismissableFlag flag; - - public HeaderTitle() - { - AutoSizeAxes = Axes.Both; - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(spacing, 0), - Children = new Drawable[] - { - flag = new DismissableFlag - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Margin = new MarginPadding { Bottom = flag_margin }, - Size = new Vector2(30, 20), - }, - scopeText = new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Light) - }, - new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Light), - Text = @"Ranking" - } - } - }; - - flag.Action += () => Country.Value = null; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - scopeText.Colour = colours.Lime; - } - - protected override void LoadComplete() - { - Scope.BindValueChanged(onScopeChanged, true); - Country.BindValueChanged(onCountryChanged, true); - base.LoadComplete(); - } - - private void onScopeChanged(ValueChangedEvent scope) => scopeText.Text = scope.NewValue.ToString(); - - private void onCountryChanged(ValueChangedEvent country) - { - if (country.NewValue == null) - { - flag.Hide(); - return; - } - - flag.Country = country.NewValue; - flag.Show(); - } - } -} diff --git a/osu.Game/Overlays/Rankings/RankingsHeader.cs b/osu.Game/Overlays/Rankings/RankingsHeader.cs deleted file mode 100644 index 6aa3e75df9..0000000000 --- a/osu.Game/Overlays/Rankings/RankingsHeader.cs +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Game.Rulesets; -using osu.Game.Users; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Graphics.Textures; -using osuTK; -using osu.Game.Graphics.UserInterface; -using System.Collections.Generic; - -namespace osu.Game.Overlays.Rankings -{ - public class RankingsHeader : CompositeDrawable - { - private const int content_height = 250; - - public IEnumerable Spotlights - { - get => dropdown.Items; - set => dropdown.Items = value; - } - - public readonly Bindable Scope = new Bindable(); - public readonly Bindable Ruleset = new Bindable(); - public readonly Bindable Country = new Bindable(); - public readonly Bindable Spotlight = new Bindable(); - - private readonly OsuDropdown dropdown; - - public RankingsHeader() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - - AddInternal(new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new RankingsRulesetSelector - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Current = Ruleset - }, - new Container - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Height = content_height, - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Child = new HeaderBackground(), - }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - new RankingsScopeSelector - { - Margin = new MarginPadding { Top = 10 }, - Current = Scope - }, - new HeaderTitle - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Margin = new MarginPadding { Top = 10 }, - Scope = { BindTarget = Scope }, - Country = { BindTarget = Country }, - }, - dropdown = new OsuDropdown - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Width = 0.8f, - Current = Spotlight, - } - } - }, - } - } - } - }); - } - - protected override void LoadComplete() - { - Scope.BindValueChanged(onScopeChanged, true); - base.LoadComplete(); - } - - private void onScopeChanged(ValueChangedEvent scope) => - dropdown.FadeTo(scope.NewValue == RankingsScope.Spotlights ? 1 : 0, 200, Easing.OutQuint); - - private class HeaderBackground : Sprite - { - public HeaderBackground() - { - Anchor = Anchor.Centre; - Origin = Anchor.Centre; - RelativeSizeAxes = Axes.Both; - FillMode = FillMode.Fill; - } - - [BackgroundDependencyLoader] - private void load(TextureStore textures) - { - Texture = textures.Get(@"Headers/rankings"); - } - } - } -} diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index f6d39c7df4..94afe4e5a5 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -124,4 +124,12 @@ namespace osu.Game.Overlays.Rankings } } } + + public enum RankingsScope + { + Performance, + Spotlights, + Score, + Country + } } diff --git a/osu.Game/Overlays/Rankings/RankingsRulesetSelector.cs b/osu.Game/Overlays/Rankings/RankingsRulesetSelector.cs deleted file mode 100644 index 3d25e3995a..0000000000 --- a/osu.Game/Overlays/Rankings/RankingsRulesetSelector.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; -using osu.Game.Rulesets; -using osuTK; -using System.Linq; - -namespace osu.Game.Overlays.Rankings -{ - public class RankingsRulesetSelector : PageTabControl - { - protected override TabItem CreateTabItem(RulesetInfo value) => new RankingsTabItem(value); - - protected override Dropdown CreateDropdown() => null; - - public RankingsRulesetSelector() - { - AutoSizeAxes = Axes.X; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours, RulesetStore rulesets) - { - foreach (var r in rulesets.AvailableRulesets) - AddItem(r); - - AccentColour = colours.Lime; - - SelectTab(TabContainer.FirstOrDefault()); - } - - protected override TabFillFlowContainer CreateTabFlow() => new TabFillFlowContainer - { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(20, 0), - }; - - private class RankingsTabItem : PageTabItem - { - public RankingsTabItem(RulesetInfo value) - : base(value) - { - } - - protected override string CreateText() => $"{Value.Name}"; - } - } -} diff --git a/osu.Game/Overlays/Rankings/RankingsScopeSelector.cs b/osu.Game/Overlays/Rankings/RankingsScopeSelector.cs deleted file mode 100644 index 2095bcc61c..0000000000 --- a/osu.Game/Overlays/Rankings/RankingsScopeSelector.cs +++ /dev/null @@ -1,26 +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.Game.Graphics.UserInterface; -using osu.Framework.Allocation; -using osuTK.Graphics; - -namespace osu.Game.Overlays.Rankings -{ - public class RankingsScopeSelector : GradientLineTabControl - { - [BackgroundDependencyLoader] - private void load() - { - AccentColour = LineColour = Color4.Black; - } - } - - public enum RankingsScope - { - Performance, - Spotlights, - Score, - Country - } -} From f7cbb8c1f7c202e9c4b14cae9357a883d6cb4708 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 21:05:11 +0300 Subject: [PATCH 0184/1142] Recolour RankingsOverlay background --- osu.Game/Overlays/RankingsOverlay.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 4a463e431c..84470d9caa 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -6,7 +6,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Overlays.Rankings; using osu.Game.Users; using osu.Game.Rulesets; @@ -27,6 +26,7 @@ namespace osu.Game.Overlays private readonly BasicScrollContainer scrollFlow; private readonly Container tableContainer; private readonly DimmedLoadingLayer loading; + private readonly Box background; private APIRequest lastRequest; private CancellationTokenSource cancellationToken; @@ -39,10 +39,9 @@ namespace osu.Game.Overlays { Children = new Drawable[] { - new Box + background = new Box { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.1f), + RelativeSizeAxes = Axes.Both }, scrollFlow = new BasicScrollContainer { @@ -87,6 +86,12 @@ namespace osu.Game.Overlays }; } + [BackgroundDependencyLoader] + private void load() + { + background.Colour = ColourProvider.Background5; + } + protected override void LoadComplete() { Country.BindValueChanged(_ => From 824ee8a8882dacbb18269894739dbedbe2524512 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 21:22:37 +0300 Subject: [PATCH 0185/1142] Recolour rankings tables --- .../Visual/Online/TestSceneRankingsTables.cs | 4 ++++ osu.Game/Overlays/Rankings/Tables/RankingsTable.cs | 14 +++++++------- .../Overlays/Rankings/Tables/TableRowBackground.cs | 7 +++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs index 93da2a439e..ab174f303e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs @@ -16,6 +16,7 @@ using osu.Game.Rulesets.Mania; using osu.Game.Rulesets.Taiko; using osu.Game.Rulesets.Catch; using osu.Framework.Allocation; +using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { @@ -36,6 +37,9 @@ namespace osu.Game.Tests.Visual.Online [Resolved] private IAPIProvider api { get; set; } + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + private readonly BasicScrollContainer scrollFlow; private readonly DimmedLoadingLayer loading; private CancellationTokenSource cancellationToken; diff --git a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs index f947c5585c..943897581e 100644 --- a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Rankings.Tables { public abstract class RankingsTable : TableContainer { - protected const int TEXT_SIZE = 14; + protected const int TEXT_SIZE = 12; private const float horizontal_inset = 20; private const float row_height = 25; private const int items_per_page = 50; @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.Rankings.Tables private static TableColumn[] mainHeaders => new[] { - new TableColumn(string.Empty, Anchor.Centre, new Dimension(GridSizeMode.Absolute, 50)), // place + new TableColumn(string.Empty, Anchor.Centre, new Dimension(GridSizeMode.Absolute, 40)), // place new TableColumn(string.Empty, Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed)), // flag and username (country name) }; @@ -77,7 +77,7 @@ namespace osu.Game.Overlays.Rankings.Tables private OsuSpriteText createIndexDrawable(int index) => new OsuSpriteText { Text = $"#{index + 1}", - Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: TEXT_SIZE, weight: FontWeight.SemiBold) }; private FillFlowContainer createMainContent(TModel item) => new FillFlowContainer @@ -112,10 +112,10 @@ namespace osu.Game.Overlays.Rankings.Tables } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { if (Text != highlighted) - Colour = colours.GreySeafoamLighter; + Colour = colourProvider.Foreground1; } } @@ -131,9 +131,9 @@ namespace osu.Game.Overlays.Rankings.Tables protected class ColoredRowText : RowText { [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - Colour = colours.GreySeafoamLighter; + Colour = colourProvider.Foreground1; } } } diff --git a/osu.Game/Overlays/Rankings/Tables/TableRowBackground.cs b/osu.Game/Overlays/Rankings/Tables/TableRowBackground.cs index 04e1c22dae..fe87a8b3d4 100644 --- a/osu.Game/Overlays/Rankings/Tables/TableRowBackground.cs +++ b/osu.Game/Overlays/Rankings/Tables/TableRowBackground.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; -using osu.Game.Graphics; using osuTK.Graphics; namespace osu.Game.Overlays.Rankings.Tables @@ -35,10 +34,10 @@ namespace osu.Game.Overlays.Rankings.Tables } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - background.Colour = idleColour = colours.GreySeafoam; - hoverColour = colours.GreySeafoamLight; + background.Colour = idleColour = colourProvider.Background4; + hoverColour = colourProvider.Background3; } protected override bool OnHover(HoverEvent e) From 4abd9cb89ae3fc3c5bf13a633a35a622a67656c5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 21:45:10 +0300 Subject: [PATCH 0186/1142] Move Enabled/Disabled state logic to the OverlayRulesetTabItem --- .../BeatmapSet/BeatmapRulesetTabItem.cs | 13 ---------- osu.Game/Overlays/OverlayRulesetTabItem.cs | 26 +++++++++---------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs index df159977e6..cb258edced 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapRulesetTabItem.cs @@ -18,8 +18,6 @@ namespace osu.Game.Overlays.BeatmapSet { public readonly Bindable BeatmapSet = new Bindable(); - public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; - [Resolved] private OverlayColourProvider colourProvider { get; set; } @@ -73,17 +71,6 @@ namespace osu.Game.Overlays.BeatmapSet Enabled.Value = beatmapsCount > 0; }, true); - - Enabled.BindValueChanged(enabled => - { - if (enabled.NewValue) - { - UpdateState(); - return; - } - - AccentColour = colourProvider.Foreground1; - }, true); } } } diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 5e6ac57886..1f0beffe78 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -17,6 +17,8 @@ namespace osu.Game.Overlays { public class OverlayRulesetTabItem : TabItem { + public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; + private Color4 accentColour; protected virtual Color4 AccentColour @@ -61,37 +63,35 @@ namespace osu.Game.Overlays Enabled.Value = true; } - [BackgroundDependencyLoader] - private void load() + protected override void LoadComplete() { - UpdateState(); + base.LoadComplete(); + Enabled.BindValueChanged(_ => updateState(), true); } protected override bool OnHover(HoverEvent e) { base.OnHover(e); - UpdateState(); + updateState(); return true; } protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - UpdateState(); + updateState(); } - protected override void OnActivated() => UpdateState(); + protected override void OnActivated() => updateState(); - protected override void OnDeactivated() => UpdateState(); + protected override void OnDeactivated() => updateState(); - protected void UpdateState() + private void updateState() { text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - - if (!Enabled.Value) - return; - - AccentColour = IsHovered || Active.Value ? Color4.White : colourProvider.Highlight1; + AccentColour = IsHovered || Active.Value ? Color4.White : getStateColour(); } + + private Color4 getStateColour() => Enabled.Value ? colourProvider.Highlight1 : colourProvider.Foreground1; } } From e42b95974a9d9b9071faabde678d28754bde8d99 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 21:49:21 +0300 Subject: [PATCH 0187/1142] Fix failing test scene --- osu.Game/Overlays/NewsOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index 6dde300556..71c205ff63 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -60,7 +60,7 @@ namespace osu.Game.Overlays }, }; - header.Current.BindTo(Current); + header.Post.BindTo(Current); Current.TriggerChange(); } From 26a9d60437d706ab993354d4a39630548a3d5c38 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 3 Feb 2020 23:17:10 +0300 Subject: [PATCH 0188/1142] Avoid exposing whenever possible --- .../Visual/Gameplay/TestSceneHUDOverlay.cs | 45 ++++++------------- 1 file changed, 13 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index 2bafcc1197..b7d4c0be21 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -15,9 +15,11 @@ namespace osu.Game.Tests.Visual.Gameplay { public class TestSceneHUDOverlay : ManualInputManagerTestScene { - private TestHUDOverlay hudOverlay; + private HUDOverlay hudOverlay; - private Drawable hideTarget => hudOverlay.KeyCounter; // best way of checking hideTargets without exposing. + // best way to check without exposing. + private Drawable hideTarget => hudOverlay.KeyCounter; + private FillFlowContainer keyCounterFlow => (FillFlowContainer)hudOverlay.KeyCounter.Child.Parent; [Resolved] private OsuConfigManager config { get; set; } @@ -30,7 +32,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("showhud is set", () => hudOverlay.ShowHud.Value); AddAssert("hidetarget is visible", () => hideTarget.IsPresent); - AddAssert("key counter flow is visible", () => hudOverlay.KeyCounter.KeyFlow.IsPresent); + AddAssert("key counter flow is visible", () => keyCounterFlow.IsPresent); AddAssert("pause button is visible", () => hudOverlay.HoldToQuit.IsPresent); } @@ -55,7 +57,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddAssert("pause button is still visible", () => hudOverlay.HoldToQuit.IsPresent); // Key counter flow container should not be affected by this, only the key counter display will be hidden as checked above. - AddAssert("key counter flow not affected", () => hudOverlay.KeyCounter.KeyFlow.IsPresent); + AddAssert("key counter flow not affected", () => keyCounterFlow.IsPresent); } [Test] @@ -90,47 +92,26 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("set showhud false", () => hudOverlay.ShowHud.Value = false); AddUntilStep("hidetarget is hidden", () => !hideTarget.IsPresent); - AddAssert("key counters hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); + AddAssert("key counters hidden", () => !keyCounterFlow.IsPresent); AddStep("set showhud true", () => hudOverlay.ShowHud.Value = true); AddUntilStep("hidetarget is visible", () => hideTarget.IsPresent); - AddAssert("key counters still hidden", () => !hudOverlay.KeyCounter.KeyFlow.IsPresent); + AddAssert("key counters still hidden", () => !keyCounterFlow.IsPresent); AddStep("return value", () => config.Set(OsuSetting.KeyOverlay, keyCounterVisibleValue)); } - private void createNew(Action action = null) + private void createNew(Action action = null) { AddStep("create overlay", () => { - Child = hudOverlay = new TestHUDOverlay(); + Child = hudOverlay = new HUDOverlay(null, null, null, Array.Empty()); + + // Add any key just to display the key counter visually. + hudOverlay.KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); action?.Invoke(hudOverlay); }); } - - private class TestHUDOverlay : HUDOverlay - { - public new TestKeyCounterDisplay KeyCounter => (TestKeyCounterDisplay)base.KeyCounter; - - protected override KeyCounterDisplay CreateKeyCounter() => new TestKeyCounterDisplay - { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Margin = new MarginPadding(10), - }; - - public TestHUDOverlay() - : base(null, null, null, Array.Empty()) - { - // Add any key just to display the key counter visually. - KeyCounter.Add(new KeyCounterKeyboard(Key.Space)); - } - } - - private class TestKeyCounterDisplay : KeyCounterDisplay - { - public new FillFlowContainer KeyFlow => base.KeyFlow; - } } } From 0ccbffde8d9b7d114eb9d88e6ee2a1441f4fd35a Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 3 Feb 2020 23:43:04 +0300 Subject: [PATCH 0189/1142] Use ChildrenOfType instead --- osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs index b7d4c0be21..fc03dc6ed3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs @@ -2,10 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; @@ -19,7 +21,7 @@ namespace osu.Game.Tests.Visual.Gameplay // best way to check without exposing. private Drawable hideTarget => hudOverlay.KeyCounter; - private FillFlowContainer keyCounterFlow => (FillFlowContainer)hudOverlay.KeyCounter.Child.Parent; + private FillFlowContainer keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().First(); [Resolved] private OsuConfigManager config { get; set; } From fe078c244d2d0e11fd449355cefd9ed6f2233c1e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 00:43:04 +0300 Subject: [PATCH 0190/1142] Expose TabControlOverlayHeader.Current value --- osu.Game/Overlays/Changelog/ChangelogHeader.cs | 18 +++++++++--------- osu.Game/Overlays/ChangelogOverlay.cs | 2 +- osu.Game/Overlays/News/NewsHeader.cs | 10 +++++----- osu.Game/Overlays/NewsOverlay.cs | 2 +- osu.Game/Overlays/TabControlOverlayHeader.cs | 17 +++++++++++++++-- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Changelog/ChangelogHeader.cs b/osu.Game/Overlays/Changelog/ChangelogHeader.cs index 4165a180da..8663ec586b 100644 --- a/osu.Game/Overlays/Changelog/ChangelogHeader.cs +++ b/osu.Game/Overlays/Changelog/ChangelogHeader.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.Changelog { public class ChangelogHeader : BreadcrumbControlOverlayHeader { - public readonly Bindable Current = new Bindable(); + public readonly Bindable Build = new Bindable(); public Action ListingSelected; @@ -25,18 +25,18 @@ namespace osu.Game.Overlays.Changelog public ChangelogHeader() { TabControl.AddItem(listing_string); - TabControl.Current.ValueChanged += e => + Current.ValueChanged += e => { if (e.NewValue == listing_string) ListingSelected?.Invoke(); }; - Current.ValueChanged += showBuild; + Build.ValueChanged += showBuild; Streams.Current.ValueChanged += e => { - if (e.NewValue?.LatestBuild != null && !e.NewValue.Equals(Current.Value?.UpdateStream)) - Current.Value = e.NewValue.LatestBuild; + if (e.NewValue?.LatestBuild != null && !e.NewValue.Equals(Build.Value?.UpdateStream)) + Build.Value = e.NewValue.LatestBuild; }; } @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.Changelog if (e.NewValue != null) { TabControl.AddItem(e.NewValue.ToString()); - TabControl.Current.Value = e.NewValue.ToString(); + Current.Value = e.NewValue.ToString(); updateCurrentStream(); @@ -58,7 +58,7 @@ namespace osu.Game.Overlays.Changelog } else { - TabControl.Current.Value = listing_string; + Current.Value = listing_string; Streams.Current.Value = null; title.Version = null; } @@ -86,10 +86,10 @@ namespace osu.Game.Overlays.Changelog private void updateCurrentStream() { - if (Current.Value == null) + if (Build.Value == null) return; - Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == Current.Value.UpdateStream.Name); + Streams.Current.Value = Streams.Items.FirstOrDefault(s => s.Name == Build.Value.UpdateStream.Name); } private class ChangelogHeaderTitle : ScreenTitle diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs index 90ba206077..6a8cb29d3e 100644 --- a/osu.Game/Overlays/ChangelogOverlay.cs +++ b/osu.Game/Overlays/ChangelogOverlay.cs @@ -78,7 +78,7 @@ namespace osu.Game.Overlays sampleBack = audio.Samples.Get(@"UI/generic-select-soft"); - Header.Current.BindTo(Current); + Header.Build.BindTo(Current); Current.BindValueChanged(e => { diff --git a/osu.Game/Overlays/News/NewsHeader.cs b/osu.Game/Overlays/News/NewsHeader.cs index b525ba7a82..b55e3ffba0 100644 --- a/osu.Game/Overlays/News/NewsHeader.cs +++ b/osu.Game/Overlays/News/NewsHeader.cs @@ -14,7 +14,7 @@ namespace osu.Game.Overlays.News private NewsHeaderTitle title; - public readonly Bindable Current = new Bindable(null); + public readonly Bindable Post = new Bindable(null); public Action ShowFrontPage; @@ -22,13 +22,13 @@ namespace osu.Game.Overlays.News { TabControl.AddItem(front_page_string); - TabControl.Current.ValueChanged += e => + Current.ValueChanged += e => { if (e.NewValue == front_page_string) ShowFrontPage?.Invoke(); }; - Current.ValueChanged += showPost; + Post.ValueChanged += showPost; } private void showPost(ValueChangedEvent e) @@ -39,13 +39,13 @@ namespace osu.Game.Overlays.News if (e.NewValue != null) { TabControl.AddItem(e.NewValue); - TabControl.Current.Value = e.NewValue; + Current.Value = e.NewValue; title.IsReadingPost = true; } else { - TabControl.Current.Value = front_page_string; + Current.Value = front_page_string; title.IsReadingPost = false; } } diff --git a/osu.Game/Overlays/NewsOverlay.cs b/osu.Game/Overlays/NewsOverlay.cs index 6dde300556..71c205ff63 100644 --- a/osu.Game/Overlays/NewsOverlay.cs +++ b/osu.Game/Overlays/NewsOverlay.cs @@ -60,7 +60,7 @@ namespace osu.Game.Overlays }, }; - header.Current.BindTo(Current); + header.Post.BindTo(Current); Current.TriggerChange(); } diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index b410739b25..dff5a17bd8 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -3,6 +3,7 @@ using JetBrains.Annotations; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -17,10 +18,18 @@ namespace osu.Game.Overlays /// An overlay header which contains a . /// /// The type of item to be represented by tabs. - public abstract class TabControlOverlayHeader : OverlayHeader + public abstract class TabControlOverlayHeader : OverlayHeader, IHasCurrentValue { protected OsuTabControl TabControl; + private readonly BindableWithCurrent current = new BindableWithCurrent(); + + public Bindable Current + { + get => current.Current; + set => current.Current = value; + } + private readonly Box controlBackground; protected TabControlOverlayHeader() @@ -35,7 +44,11 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Both, }, - TabControl = CreateTabControl().With(control => control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }) + TabControl = CreateTabControl().With(control => + { + control.Margin = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN }; + control.Current = current; + }) } }); } From 5950ba3656914e9c667ebd6764ca55905935745a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 00:55:41 +0300 Subject: [PATCH 0191/1142] Change the order of colour check --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 1f0beffe78..67c458cc5c 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -89,9 +89,9 @@ namespace osu.Game.Overlays private void updateState() { text.Font = text.Font.With(weight: Active.Value ? FontWeight.Bold : FontWeight.Medium); - AccentColour = IsHovered || Active.Value ? Color4.White : getStateColour(); + AccentColour = Enabled.Value ? getActiveColour() : colourProvider.Foreground1; } - private Color4 getStateColour() => Enabled.Value ? colourProvider.Highlight1 : colourProvider.Foreground1; + private Color4 getActiveColour() => IsHovered || Active.Value ? Color4.White : colourProvider.Highlight1; } } From 22e3150f685a6916f0ddc2d689023cb32361598e Mon Sep 17 00:00:00 2001 From: Joehu Date: Mon, 3 Feb 2020 17:21:06 -0800 Subject: [PATCH 0192/1142] Fix comment and remove magic numbers --- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 2 ++ osu.Game/Screens/Select/SongSelect.cs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 2868fe1d79..0813e57dae 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -30,6 +30,8 @@ namespace osu.Game.Overlays.Mods { public class ModSelectOverlay : WaveOverlayContainer { + public const float HEIGHT = 510; + protected readonly TriangleButton DeselectAllButton; protected readonly TriangleButton CustomiseButton; protected readonly TriangleButton CloseButton; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 3f80c90b9d..a5dce9a065 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -223,13 +223,13 @@ namespace osu.Game.Screens.Select { AddRangeInternal(new Drawable[] { - new GridContainer // used for max width implementation + new GridContainer // used for max height implementation { RelativeSizeAxes = Axes.Both, RowDimensions = new[] { new Dimension(), - new Dimension(GridSizeMode.Relative, 1f, maxSize: 560), + new Dimension(GridSizeMode.Relative, 1f, maxSize: ModSelectOverlay.HEIGHT + Footer.HEIGHT), }, Content = new[] { From ddf9317bec9113ac89ac3ad7fc12d356d5cc070c Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 08:25:01 +0700 Subject: [PATCH 0193/1142] Replace `:P2` with `:0.00%` --- osu.Game/Scoring/ScoreInfo.cs | 2 +- osu.Game/Users/UserStatistics.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 8787785861..8dc5137818 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -32,7 +32,7 @@ namespace osu.Game.Scoring public double Accuracy { get; set; } [JsonIgnore] - public string DisplayAccuracy => Accuracy == 1 ? "100%" : $"{Accuracy:P2}"; + public string DisplayAccuracy => Accuracy == 1 ? "100%" : $"{Accuracy:0.00%}"; [JsonProperty(@"pp")] public double? PP { get; set; } diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index 9254eefb60..0f692dd60d 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -44,7 +44,7 @@ namespace osu.Game.Users public decimal Accuracy; [JsonIgnore] - public string DisplayAccuracy => $"{Accuracy:P2}"; + public string DisplayAccuracy => $"{Accuracy:0.00%}"; [JsonProperty(@"play_count")] public int PlayCount; From 68b3dc01df65551e900bc3762a18c371a841b33d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Feb 2020 12:53:57 +0900 Subject: [PATCH 0194/1142] Move property override below ctor --- osu.Game/Overlays/OverlayRulesetTabItem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/OverlayRulesetTabItem.cs b/osu.Game/Overlays/OverlayRulesetTabItem.cs index 67c458cc5c..9b4dd5ba1e 100644 --- a/osu.Game/Overlays/OverlayRulesetTabItem.cs +++ b/osu.Game/Overlays/OverlayRulesetTabItem.cs @@ -17,8 +17,6 @@ namespace osu.Game.Overlays { public class OverlayRulesetTabItem : TabItem { - public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; - private Color4 accentColour; protected virtual Color4 AccentColour @@ -69,6 +67,8 @@ namespace osu.Game.Overlays Enabled.BindValueChanged(_ => updateState(), true); } + public override bool PropagatePositionalInputSubTree => Enabled.Value && !Active.Value && base.PropagatePositionalInputSubTree; + protected override bool OnHover(HoverEvent e) { base.OnHover(e); From bc9b499de010fc6f311908db0745d928c153caaf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Feb 2020 12:55:09 +0900 Subject: [PATCH 0195/1142] Make selector only privately-settable --- osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs index bf9f3ccc17..e5e3e276d5 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapSetHeader.cs @@ -11,7 +11,8 @@ namespace osu.Game.Overlays.BeatmapSet public class BeatmapSetHeader : OverlayHeader { public readonly Bindable Ruleset = new Bindable(); - public BeatmapRulesetSelector RulesetSelector; + + public BeatmapRulesetSelector RulesetSelector { get; private set; } protected override ScreenTitle CreateTitle() => new BeatmapHeaderTitle(); From a8ce50fadd588f0f6b8aa5b3c6c4624272335fc1 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 11:17:23 +0700 Subject: [PATCH 0196/1142] Add FormatUtils.FormatAccuracy and usages --- osu.Game/Scoring/ScoreInfo.cs | 3 ++- osu.Game/Users/UserStatistics.cs | 3 ++- osu.Game/Utils/FormatUtils.cs | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Utils/FormatUtils.cs diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index 8dc5137818..bed9104cad 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Users; +using osu.Game.Utils; namespace osu.Game.Scoring { @@ -32,7 +33,7 @@ namespace osu.Game.Scoring public double Accuracy { get; set; } [JsonIgnore] - public string DisplayAccuracy => Accuracy == 1 ? "100%" : $"{Accuracy:0.00%}"; + public string DisplayAccuracy => Accuracy.FormatAccuracy(); [JsonProperty(@"pp")] public double? PP { get; set; } diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index 0f692dd60d..129c128977 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -5,6 +5,7 @@ using System; using Newtonsoft.Json; using osu.Game.Scoring; using static osu.Game.Users.User; +using osu.Game.Utils; namespace osu.Game.Users { @@ -44,7 +45,7 @@ namespace osu.Game.Users public decimal Accuracy; [JsonIgnore] - public string DisplayAccuracy => $"{Accuracy:0.00%}"; + public string DisplayAccuracy => Accuracy.FormatAccuracy(); [JsonProperty(@"play_count")] public int PlayCount; diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs new file mode 100644 index 0000000000..f966c09a67 --- /dev/null +++ b/osu.Game/Utils/FormatUtils.cs @@ -0,0 +1,21 @@ +namespace osu.Game.Utils +{ + public static class FormatUtils + { + /// + /// Turns the provided accuracy into a percentage with 2 decimal places. + /// Omits all decimal places when equals 1d. + /// + /// The accuracy to be formatted + /// formatted accuracy in percentage + public static string FormatAccuracy(this double accuracy) => accuracy == 1 ? "100%" : $"{accuracy:0.00%}"; + + /// + /// Turns the provided accuracy into a percentage with 2 decimal places. + /// Omits all decimal places when equals 100m. + /// + /// The accuracy to be formatted + /// formatted accuracy in percentage + public static string FormatAccuracy(this decimal accuracy) => accuracy == 100 ? "100%" : $"{accuracy:0.00}%"; + } +} \ No newline at end of file From 14db81384295ec7e97d9b3bc749fefe01d982da8 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 11:18:19 +0700 Subject: [PATCH 0197/1142] Add licence header --- osu.Game/Utils/FormatUtils.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index f966c09a67..7ff0c4f657 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -1,3 +1,6 @@ +// 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.Utils { public static class FormatUtils From 2bbd12e39a235b10b0c7c3b781e5ca9ddbe5413d Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 11:36:22 +0700 Subject: [PATCH 0198/1142] Fix code formatting --- osu.Game/Users/UserStatistics.cs | 2 +- osu.Game/Utils/FormatUtils.cs | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index 129c128977..e5e77821ab 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -4,8 +4,8 @@ using System; using Newtonsoft.Json; using osu.Game.Scoring; -using static osu.Game.Users.User; using osu.Game.Utils; +using static osu.Game.Users.User; namespace osu.Game.Users { diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index 7ff0c4f657..b3758b3375 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -3,22 +3,22 @@ namespace osu.Game.Utils { - public static class FormatUtils - { - /// + public static class FormatUtils + { + /// /// Turns the provided accuracy into a percentage with 2 decimal places. - /// Omits all decimal places when equals 1d. + /// Omits all decimal places when equals 1d. /// /// The accuracy to be formatted /// formatted accuracy in percentage - public static string FormatAccuracy(this double accuracy) => accuracy == 1 ? "100%" : $"{accuracy:0.00%}"; + public static string FormatAccuracy(this double accuracy) => accuracy == 1 ? "100%" : $"{accuracy:0.00%}"; - /// + /// /// Turns the provided accuracy into a percentage with 2 decimal places. - /// Omits all decimal places when equals 100m. + /// Omits all decimal places when equals 100m. /// /// The accuracy to be formatted /// formatted accuracy in percentage - public static string FormatAccuracy(this decimal accuracy) => accuracy == 100 ? "100%" : $"{accuracy:0.00}%"; - } -} \ No newline at end of file + public static string FormatAccuracy(this decimal accuracy) => accuracy == 100 ? "100%" : $"{accuracy:0.00}%"; + } +} From b6cfb987f327304cfee25efbf4134866794e6925 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 4 Feb 2020 17:00:36 +0900 Subject: [PATCH 0199/1142] Make drag handles not pop into existence --- osu.Game/Overlays/Music/PlaylistItem.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 4ce67c2d66..0f68df737e 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -66,6 +66,7 @@ namespace osu.Game.Overlays.Music Origin = Anchor.CentreLeft, Size = new Vector2(12), Colour = colours.Gray5, + AlwaysPresent = true, Alpha = 0 }, text = new OsuTextFlowContainer From c3bd6c3f7f5aba82e19273a05971e052d28656de Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 11:21:21 +0300 Subject: [PATCH 0200/1142] Remove no longer used field --- osu.Game/Overlays/TabControlOverlayHeader.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/TabControlOverlayHeader.cs b/osu.Game/Overlays/TabControlOverlayHeader.cs index d729b9fa9f..b199a2a0cf 100644 --- a/osu.Game/Overlays/TabControlOverlayHeader.cs +++ b/osu.Game/Overlays/TabControlOverlayHeader.cs @@ -20,8 +20,6 @@ namespace osu.Game.Overlays /// The type of item to be represented by tabs. public abstract class TabControlOverlayHeader : OverlayHeader, IHasCurrentValue { - public readonly Bindable Current = new Bindable(); - protected OsuTabControl TabControl; private readonly BindableWithCurrent current = new BindableWithCurrent(); From 873eda3bb544520239667d5dd79d236261985b86 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 14:00:18 +0300 Subject: [PATCH 0201/1142] Recolour info section --- osu.Game/Overlays/BeatmapSet/Info.cs | 25 ++++++++------------- osu.Game/Overlays/BeatmapSet/SuccessRate.cs | 7 +++--- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 16d6236051..d7392b31e1 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -24,6 +24,7 @@ namespace osu.Game.Overlays.BeatmapSet private const float spacing = 20; private readonly Box successRateBackground; + private readonly Box background; private readonly SuccessRate successRate; public readonly Bindable BeatmapSet = new Bindable(); @@ -50,10 +51,9 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { - new Box + background = new Box { - RelativeSizeAxes = Axes.Both, - Colour = Color4.White, + RelativeSizeAxes = Axes.Both }, new Container { @@ -126,14 +126,14 @@ namespace osu.Game.Overlays.BeatmapSet } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - successRateBackground.Colour = colours.GrayE; + successRateBackground.Colour = colourProvider.Background4; + background.Colour = colourProvider.Background5; } private class MetadataSection : FillFlowContainer { - private readonly OsuSpriteText header; private readonly TextFlowContainer textFlow; public string Text @@ -148,7 +148,7 @@ namespace osu.Game.Overlays.BeatmapSet this.FadeIn(transition_duration); textFlow.Clear(); - textFlow.AddText(value, s => s.Font = s.Font.With(size: 14)); + textFlow.AddText(value, s => s.Font = s.Font.With(size: 12)); } } @@ -160,11 +160,10 @@ namespace osu.Game.Overlays.BeatmapSet InternalChildren = new Drawable[] { - header = new OsuSpriteText + new OsuSpriteText { Text = title, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold), - Shadow = false, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Black), Margin = new MarginPadding { Top = 20 }, }, textFlow = new OsuTextFlowContainer @@ -174,12 +173,6 @@ namespace osu.Game.Overlays.BeatmapSet }, }; } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - header.Colour = textFlow.Colour = colours.Gray5; - } } } } diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs index cd81013c30..1dcc847760 100644 --- a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.BeatmapSet protected readonly FailRetryGraph Graph; private readonly FillFlowContainer header; - private readonly OsuSpriteText successRateLabel, successPercent, graphLabel; + private readonly OsuSpriteText successPercent; private readonly Bar successRate; private readonly Container percentContainer; @@ -60,7 +60,7 @@ namespace osu.Game.Overlays.BeatmapSet Direction = FillDirection.Vertical, Children = new Drawable[] { - successRateLabel = new OsuSpriteText + new OsuSpriteText { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -85,7 +85,7 @@ namespace osu.Game.Overlays.BeatmapSet Font = OsuFont.GetFont(size: 13), }, }, - graphLabel = new OsuSpriteText + new OsuSpriteText { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -107,7 +107,6 @@ namespace osu.Game.Overlays.BeatmapSet [BackgroundDependencyLoader] private void load(OsuColour colours) { - successRateLabel.Colour = successPercent.Colour = graphLabel.Colour = colours.Gray5; successRate.AccentColour = colours.Green; successRate.BackgroundColour = colours.GrayD; From 0e54e0e092dd01ca70338b26da74c685a687eec4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 14:17:22 +0300 Subject: [PATCH 0202/1142] Recolour DrawableTopScore --- .../BeatmapSet/Scores/DrawableTopScore.cs | 28 ++----------------- .../Scores/TopScoreStatisticsSection.cs | 25 ++++++++--------- .../BeatmapSet/Scores/TopScoreUserSection.cs | 19 ++++--------- 3 files changed, 20 insertions(+), 52 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index d263483046..e12c977430 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -7,8 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Events; -using osu.Game.Graphics; using osu.Game.Scoring; using osuTK; using osuTK.Graphics; @@ -17,11 +15,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { public class DrawableTopScore : CompositeDrawable { - private const float fade_duration = 100; - - private Color4 backgroundIdleColour; - private Color4 backgroundHoveredColour; - private readonly Box background; public DrawableTopScore(ScoreInfo score, int position = 1) @@ -30,7 +23,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores AutoSizeAxes = Axes.Y; Masking = true; - CornerRadius = 10; + CornerRadius = 5; EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, @@ -84,24 +77,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - backgroundIdleColour = colours.Gray3; - backgroundHoveredColour = colours.Gray4; - - background.Colour = backgroundIdleColour; - } - - protected override bool OnHover(HoverEvent e) - { - background.FadeColour(backgroundHoveredColour, fade_duration, Easing.OutQuint); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - background.FadeColour(backgroundIdleColour, fade_duration, Easing.OutQuint); - base.OnHoverLost(e); + background.Colour = colourProvider.Background4; } private class AutoSizingGrid : GridContainer diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 4f26e43fb2..9f6e60a547 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -24,8 +24,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private const float margin = 10; - private readonly FontUsage smallFont = OsuFont.GetFont(size: 20); - private readonly FontUsage largeFont = OsuFont.GetFont(size: 25); + private readonly FontUsage smallFont = OsuFont.GetFont(size: 16); + private readonly FontUsage largeFont = OsuFont.GetFont(size: 22); private readonly TextColumn totalScoreColumn; private readonly TextColumn accuracyColumn; @@ -109,6 +109,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private class InfoColumn : CompositeDrawable { private readonly Box separator; + private readonly OsuSpriteText text; public InfoColumn(string title, Drawable content) { @@ -121,9 +122,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(0, 2), Children = new[] { - new OsuSpriteText + text = new OsuSpriteText { - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black), + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Black), Text = title.ToUpper() }, separator = new Box @@ -137,9 +138,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - separator.Colour = colours.Gray5; + separator.Colour = text.Colour = colourProvider.Foreground1; } } @@ -189,15 +190,11 @@ namespace osu.Game.Overlays.BeatmapSet.Scores set { modsContainer.Clear(); - - foreach (Mod mod in value) + modsContainer.Children = value.Select(mod => new ModIcon(mod) { - modsContainer.Add(new ModIcon(mod) - { - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.3f), - }); - } + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.25f), + }).ToList(); } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 38a909411a..afffdd04c4 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -51,13 +50,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 24, weight: FontWeight.Bold, italics: true) + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) }, rank = new UpdateableRank(ScoreRank.D) { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(40), + Size = new Vector2(28), FillMode = FillMode.Fit, }, } @@ -66,7 +65,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(80), + Size = new Vector2(70), Masking = true, CornerRadius = 5, EdgeEffect = new EdgeEffectParameters @@ -87,7 +86,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(0, 3), Children = new Drawable[] { - usernameText = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold, italics: true)) + usernameText = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)) { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, @@ -97,13 +96,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) }, flag = new UpdateableFlag { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Size = new Vector2(20, 13), + Size = new Vector2(19, 13), ShowPlaceholderOnNull = false, }, } @@ -112,12 +111,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }; } - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - rankText.Colour = colours.Yellow; - } - public int ScorePosition { set => rankText.Text = $"#{value}"; From f30cdab025fc4ef4409a0a395589fa2a97c8929c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 14:35:04 +0300 Subject: [PATCH 0203/1142] Update Scores section --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 10 ++++++++-- .../BeatmapSet/Scores/ScoreTableRowBackground.cs | 6 +++--- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 5 ++--- .../BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- .../Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 3a944882ab..7a17412722 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private const float horizontal_inset = 20; private const float row_height = 25; - private const int text_size = 14; + private const int text_size = 12; private readonly FillFlowContainer backgroundFlow; @@ -190,7 +190,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public HeaderText(string text) { Text = text.ToUpper(); - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Black); + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold); + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Colour = colourProvider.Foreground1; } } } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs index 724a7f8b55..14ea3e6b38 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs @@ -48,18 +48,18 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } [BackgroundDependencyLoader] - private void load(OsuColour colours, IAPIProvider api) + private void load(OsuColour colours, OverlayColourProvider colourProvider, IAPIProvider api) { var isOwnScore = api.LocalUser.Value.Id == score.UserID; if (isOwnScore) background.Colour = colours.GreenDarker; else if (index % 2 == 0) - background.Colour = colours.Gray3; + background.Colour = colourProvider.Background4; else background.Alpha = 0; - hoveredBackground.Colour = isOwnScore ? colours.GreenDark : colours.Gray4; + hoveredBackground.Colour = isOwnScore ? colours.GreenDark : colourProvider.Background3; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 0378d364b8..0a3b5d9457 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osuTK; using System.Linq; @@ -179,9 +178,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - background.Colour = colours.Gray2; + background.Colour = colourProvider.Background5; user.BindTo(api.LocalUser); } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 9f6e60a547..7d410d0d34 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -130,7 +130,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores separator = new Box { RelativeSizeAxes = Axes.X, - Height = 2 + Height = 1 }, content } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index afffdd04c4..72a7efd777 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -50,7 +50,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold) }, rank = new UpdateableRank(ScoreRank.D) { From cff619b0e406823df149704560f7154f210fb0c5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 14:46:22 +0300 Subject: [PATCH 0204/1142] Adjust overlay layout --- osu.Game/Overlays/BeatmapSetOverlay.cs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index e4e928df18..f747cfff16 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Beatmaps; -using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; using osu.Game.Overlays.BeatmapSet; @@ -33,6 +32,8 @@ namespace osu.Game.Overlays // receive input outside our bounds so we can trigger a close event on ourselves. public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; + private readonly Box background; + public BeatmapSetOverlay() : base(OverlayColourScheme.Blue) { @@ -41,10 +42,9 @@ namespace osu.Game.Overlays Children = new Drawable[] { - new Box + background = new Box { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.2f) + RelativeSizeAxes = Axes.Both }, scroll = new OsuScrollContainer { @@ -55,10 +55,20 @@ namespace osu.Game.Overlays RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), Children = new Drawable[] { - Header = new Header(), - info = new Info(), + new ReverseChildIDFillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + Header = new Header(), + info = new Info() + } + }, new ScoresContainer { Beatmap = { BindTarget = Header.Picker.Beatmap } @@ -83,6 +93,8 @@ namespace osu.Game.Overlays private void load(RulesetStore rulesets) { this.rulesets = rulesets; + + background.Colour = ColourProvider.Background6; } protected override void PopOutComplete() From 5f63ef3bc139d9245046d6bac4d64f5246e231e4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 14:52:26 +0300 Subject: [PATCH 0205/1142] Fix crashing test --- osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs index 1b136d9e41..3c959e05c1 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs @@ -3,11 +3,13 @@ using System; using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Utils; using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays; using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Scoring; @@ -27,6 +29,9 @@ namespace osu.Game.Tests.Visual.Online typeof(ScoreTableRowBackground), }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + public TestSceneScoresContainer() { TestScoresContainer scoresContainer; From 3571c2b6172c70abb46586ffb801eb45f68df6fe Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 19:41:44 +0700 Subject: [PATCH 0206/1142] Rearrange children in TopScoreStatisticsSection --- .../Scores/TopScoreStatisticsSection.cs | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 7d410d0d34..5abff41cc1 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -44,9 +44,24 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Spacing = new Vector2(10, 0), + Direction = FillDirection.Vertical, + Spacing = new Vector2(10, 8), Children = new Drawable[] { + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(margin, 0), + Children = new Drawable[] + { + totalScoreColumn = new TextColumn("total score", largeFont), + accuracyColumn = new TextColumn("accuracy", largeFont), + maxComboColumn = new TextColumn("max combo", largeFont) + } + }, new FillFlowContainer { Anchor = Anchor.TopRight, @@ -66,20 +81,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores modsColumn = new ModsInfoColumn(), } }, - new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(margin, 0), - Children = new Drawable[] - { - totalScoreColumn = new TextColumn("total score", largeFont), - accuracyColumn = new TextColumn("accuracy", largeFont), - maxComboColumn = new TextColumn("max combo", largeFont) - } - }, } }; } From c12fc67887781b4c13c824e689f6bc09194fd6e3 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 19:42:37 +0700 Subject: [PATCH 0207/1142] Change InfoColumn title font weight --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 5abff41cc1..928d6be800 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -125,7 +125,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { text = new OsuSpriteText { - Font = OsuFont.GetFont(size: 10, weight: FontWeight.Black), + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), Text = title.ToUpper() }, separator = new Box From 4f312ae6bca082e476bfac9b32d83fb2694850f8 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 19:43:14 +0700 Subject: [PATCH 0208/1142] Adjust InfoColumn spacing --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 928d6be800..88aac732d7 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -120,7 +120,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 2), + Spacing = new Vector2(0, 1), Children = new[] { text = new OsuSpriteText From 8f9917238e3303860659442aa7ac373cbdae04bf Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 19:45:08 +0700 Subject: [PATCH 0209/1142] Add optional minimum width to InfoColumn --- .../BeatmapSet/Scores/TopScoreStatisticsSection.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 88aac732d7..b456a35480 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -23,6 +23,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public class TopScoreStatisticsSection : CompositeDrawable { private const float margin = 10; + private const float statistics_column_min_width = 50; private readonly FontUsage smallFont = OsuFont.GetFont(size: 16); private readonly FontUsage largeFont = OsuFont.GetFont(size: 22); @@ -112,7 +113,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly Box separator; private readonly OsuSpriteText text; - public InfoColumn(string title, Drawable content) + public InfoColumn(string title, Drawable content, float? minWidth = null) { AutoSizeAxes = Axes.Both; @@ -130,7 +131,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }, separator = new Box { - RelativeSizeAxes = Axes.X, + RelativeSizeAxes = minWidth == null ? Axes.X : Axes.None, + Width = minWidth ?? 1f, Height = 1 }, content @@ -149,13 +151,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private readonly SpriteText text; - public TextColumn(string title, FontUsage font) - : this(title, new OsuSpriteText { Font = font }) + public TextColumn(string title, FontUsage font, float? minWidth = null) + : this(title, new OsuSpriteText { Font = font }, minWidth) { } - private TextColumn(string title, SpriteText text) - : base(title, text) + private TextColumn(string title, SpriteText text, float? minWidth = null) + : base(title, text, minWidth) { this.text = text; } From 556a4e64cb705c8a413fe7acd14446b3fedb29b8 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 19:46:14 +0700 Subject: [PATCH 0210/1142] Use minimum width on statistics columns --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index b456a35480..d11a74617a 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -103,7 +103,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - private TextColumn createStatisticsColumn(HitResult hitResult, int count) => new TextColumn(hitResult.GetDescription(), smallFont) + private TextColumn createStatisticsColumn(HitResult hitResult, int count) => new TextColumn(hitResult.GetDescription(), smallFont, statistics_column_min_width) { Text = count.ToString() }; From a8faee91d8404989469e7606a85296d371065b64 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 19:54:57 +0700 Subject: [PATCH 0211/1142] Use minWidth on pp column --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index d11a74617a..fc50a528e9 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -78,7 +78,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Direction = FillDirection.Horizontal, Spacing = new Vector2(margin, 0), }, - ppColumn = new TextColumn("pp", smallFont), + ppColumn = new TextColumn("pp", smallFont, statistics_column_min_width), modsColumn = new ModsInfoColumn(), } }, From 5030b66092ff9e28c006c5ee025bf5881c65997d Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 19:59:11 +0700 Subject: [PATCH 0212/1142] Adjust width of statistics columns --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index fc50a528e9..54ead4ebf4 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public class TopScoreStatisticsSection : CompositeDrawable { private const float margin = 10; - private const float statistics_column_min_width = 50; + private const float statistics_column_min_width = 40; private readonly FontUsage smallFont = OsuFont.GetFont(size: 16); private readonly FontUsage largeFont = OsuFont.GetFont(size: 22); From 37992e99f9785f27540be781d76ce04bbf190568 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 16:04:06 +0300 Subject: [PATCH 0213/1142] API implementation --- .../Requests/GetSpotlightRankingsRequest.cs | 30 +++++++++++++++++++ .../Requests/GetSpotlightRankingsResponse.cs | 22 ++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 osu.Game/Online/API/Requests/GetSpotlightRankingsRequest.cs create mode 100644 osu.Game/Online/API/Requests/GetSpotlightRankingsResponse.cs diff --git a/osu.Game/Online/API/Requests/GetSpotlightRankingsRequest.cs b/osu.Game/Online/API/Requests/GetSpotlightRankingsRequest.cs new file mode 100644 index 0000000000..a279db134f --- /dev/null +++ b/osu.Game/Online/API/Requests/GetSpotlightRankingsRequest.cs @@ -0,0 +1,30 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.IO.Network; +using osu.Game.Rulesets; + +namespace osu.Game.Online.API.Requests +{ + public class GetSpotlightRankingsRequest : GetRankingsRequest + { + private readonly int spotlight; + + public GetSpotlightRankingsRequest(RulesetInfo ruleset, int spotlight) + : base(ruleset, 1) + { + this.spotlight = spotlight; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + req.AddParameter("spotlight", spotlight.ToString()); + + return req; + } + + protected override string TargetPostfix() => "charts"; + } +} diff --git a/osu.Game/Online/API/Requests/GetSpotlightRankingsResponse.cs b/osu.Game/Online/API/Requests/GetSpotlightRankingsResponse.cs new file mode 100644 index 0000000000..2259314a9f --- /dev/null +++ b/osu.Game/Online/API/Requests/GetSpotlightRankingsResponse.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 System.Collections.Generic; +using Newtonsoft.Json; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests +{ + public class GetSpotlightRankingsResponse + { + [JsonProperty("ranking")] + public List Users; + + [JsonProperty("spotlight")] + public APISpotlight Spotlight; + + [JsonProperty("beatmapsets")] + public List BeatmapSets; + } +} From f889f2435bc83cebb783c37a31d49319fac505d8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 16:20:15 +0300 Subject: [PATCH 0214/1142] Add test step to TestSceneRankingsTable --- .../Visual/Online/TestSceneRankingsTables.cs | 15 +++++++++++++++ .../Overlays/Rankings/Tables/UserBasedTable.cs | 4 ++-- osu.Game/Users/UserStatistics.cs | 8 ++++---- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs index ab174f303e..19ca63208e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs @@ -68,6 +68,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Mania scores", () => createScoreTable(new ManiaRuleset().RulesetInfo)); AddStep("Taiko country scores", () => createCountryTable(new TaikoRuleset().RulesetInfo)); AddStep("Catch US performance page 10", () => createPerformanceTable(new CatchRuleset().RulesetInfo, "US", 10)); + AddStep("Osu 271 spotlight table", () => createSpotlightTable(new OsuRuleset().RulesetInfo, 271)); } private void createCountryTable(RulesetInfo ruleset, int page = 1) @@ -112,6 +113,20 @@ namespace osu.Game.Tests.Visual.Online api.Queue(request); } + private void createSpotlightTable(RulesetInfo ruleset, int spotlight) + { + onLoadStarted(); + + request = new GetSpotlightRankingsRequest(ruleset, spotlight); + ((GetSpotlightRankingsRequest)request).Success += rankings => Schedule(() => + { + var table = new ScoresTable(1, rankings.Users); + loadTable(table); + }); + + api.Queue(request); + } + private void onLoadStarted() { loading.Show(); diff --git a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs index 351c4df6b7..e1395479f2 100644 --- a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs @@ -44,8 +44,8 @@ namespace osu.Game.Overlays.Rankings.Tables new ColoredRowText { Text = $@"{item.PlayCount:N0}", }, }.Concat(CreateUniqueContent(item)).Concat(new[] { - new ColoredRowText { Text = $@"{item.GradesCount.SS + item.GradesCount.SSPlus:N0}", }, - new ColoredRowText { Text = $@"{item.GradesCount.S + item.GradesCount.SPlus:N0}", }, + new ColoredRowText { Text = $@"{item.GradesCount.SS + (item.GradesCount.SSPlus ?? 0):N0}", }, + new ColoredRowText { Text = $@"{item.GradesCount.S + (item.GradesCount.SPlus ?? 0):N0}", }, new ColoredRowText { Text = $@"{item.GradesCount.A:N0}", } }).ToArray(); diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index e5e77821ab..8ce26074a8 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -30,7 +30,7 @@ namespace osu.Game.Users public decimal? PP; [JsonProperty(@"pp_rank")] // the API sometimes only returns this value in condensed user responses - private int rank + private int? rank { set => Ranks.Global = value; } @@ -71,13 +71,13 @@ namespace osu.Game.Users public struct Grades { [JsonProperty(@"ssh")] - public int SSPlus; + public int? SSPlus; [JsonProperty(@"ss")] public int SS; [JsonProperty(@"sh")] - public int SPlus; + public int? SPlus; [JsonProperty(@"s")] public int S; @@ -85,7 +85,7 @@ namespace osu.Game.Users [JsonProperty(@"a")] public int A; - public int this[ScoreRank rank] + public int? this[ScoreRank rank] { get { From f112760b0027030f8c1e62683529624d04e9e8fd Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 21:55:04 +0700 Subject: [PATCH 0215/1142] Revert column separator height to 2 --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 54ead4ebf4..c3a929dd4a 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = minWidth == null ? Axes.X : Axes.None, Width = minWidth ?? 1f, - Height = 1 + Height = 2 }, content } From 1c16ab1813393f0652a8ea257e51540f34b77817 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 21:55:20 +0700 Subject: [PATCH 0216/1142] Use better colours --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index c3a929dd4a..ec87b04947 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -143,7 +143,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - separator.Colour = text.Colour = colourProvider.Foreground1; + text.Colour = colourProvider.Foreground1; + separator.Colour = colourProvider.Background3; } } From bd815cd81b003f5fe95250cab209e09b759492b3 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 21:55:48 +0700 Subject: [PATCH 0217/1142] Use minWidth on more columns to further match web --- .../BeatmapSet/Scores/TopScoreStatisticsSection.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index ec87b04947..8386c82572 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -23,7 +23,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public class TopScoreStatisticsSection : CompositeDrawable { private const float margin = 10; - private const float statistics_column_min_width = 40; + private const float top_columns_min_width = 64; + private const float bottom_columns_min_width = 45; private readonly FontUsage smallFont = OsuFont.GetFont(size: 16); private readonly FontUsage largeFont = OsuFont.GetFont(size: 22); @@ -58,9 +59,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Spacing = new Vector2(margin, 0), Children = new Drawable[] { - totalScoreColumn = new TextColumn("total score", largeFont), - accuracyColumn = new TextColumn("accuracy", largeFont), - maxComboColumn = new TextColumn("max combo", largeFont) + totalScoreColumn = new TextColumn("total score", largeFont, top_columns_min_width), + accuracyColumn = new TextColumn("accuracy", largeFont, top_columns_min_width), + maxComboColumn = new TextColumn("max combo", largeFont, top_columns_min_width) } }, new FillFlowContainer @@ -78,7 +79,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Direction = FillDirection.Horizontal, Spacing = new Vector2(margin, 0), }, - ppColumn = new TextColumn("pp", smallFont, statistics_column_min_width), + ppColumn = new TextColumn("pp", smallFont, bottom_columns_min_width), modsColumn = new ModsInfoColumn(), } }, @@ -103,7 +104,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } - private TextColumn createStatisticsColumn(HitResult hitResult, int count) => new TextColumn(hitResult.GetDescription(), smallFont, statistics_column_min_width) + private TextColumn createStatisticsColumn(HitResult hitResult, int count) => new TextColumn(hitResult.GetDescription(), smallFont, bottom_columns_min_width) { Text = count.ToString() }; From 0cba1a357f68f90b81fb2828aa2265ae7a328c1d Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 21:56:22 +0700 Subject: [PATCH 0218/1142] Adjust padding on DrawableTopScore --- osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index e12c977430..bb85b4a37b 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -42,7 +42,12 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(10), + Padding = new MarginPadding + { + Vertical = 10, + Left = 10, + Right = 25, + }, Children = new Drawable[] { new AutoSizingGrid From 833bb28dcfcddd529959a60b0f4ea2b1a25d4688 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 4 Feb 2020 22:38:25 +0700 Subject: [PATCH 0219/1142] Adjust separator position between top and bottom content --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 8386c82572..171aae06d3 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -134,7 +134,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = minWidth == null ? Axes.X : Axes.None, Width = minWidth ?? 1f, - Height = 2 + Height = 2, + Margin = new MarginPadding { Top = 2 } }, content } From b28a1d38a6b66f0c678bfb1150a29dcdf82a2cfe Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 17:09:18 +0100 Subject: [PATCH 0220/1142] Simplify GradientLine and fix colour changing --- .../UserInterface/GradientLineTabControl.cs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/GradientLineTabControl.cs b/osu.Game/Graphics/UserInterface/GradientLineTabControl.cs index baca57ea89..1d67c4e033 100644 --- a/osu.Game/Graphics/UserInterface/GradientLineTabControl.cs +++ b/osu.Game/Graphics/UserInterface/GradientLineTabControl.cs @@ -49,14 +49,7 @@ namespace osu.Game.Graphics.UserInterface public GradientLine() { RelativeSizeAxes = Axes.X; - Size = new Vector2(0.8f, 1.5f); - - ColumnDimensions = new[] - { - new Dimension(), - new Dimension(mode: GridSizeMode.Relative, size: 0.4f), - new Dimension(), - }; + Size = new Vector2(0.8f, 1f); Content = new[] { @@ -65,16 +58,12 @@ namespace osu.Game.Graphics.UserInterface new Box { RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientHorizontal(Color4.Transparent, Color4.White) + Colour = ColourInfo.GradientHorizontal(Color4.Transparent, Colour) }, new Box { RelativeSizeAxes = Axes.Both, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientHorizontal(Color4.White, Color4.Transparent) + Colour = ColourInfo.GradientHorizontal(Colour, Color4.Transparent) }, } }; From 9bc45d21f13e2a048d991e9144cf773e2592389b Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 17:11:28 +0100 Subject: [PATCH 0221/1142] Recolour LeaderboardScopeSelector --- osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index e2a725ec46..20a3b09db4 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -26,10 +26,10 @@ namespace osu.Game.Overlays.BeatmapSet } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { - AccentColour = colours.Blue; - LineColour = Color4.Gray; + AccentColour = colourProvider.Highlight1; + LineColour = colourProvider.Background1; } private class ScopeSelectorTabItem : PageTabItem From 5e369534b6a6d949c526a0fea2b802cf7b2d540c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 19:15:23 +0300 Subject: [PATCH 0222/1142] Allow guests to view comments --- osu.Game/Overlays/Comments/CommentsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 8761b88b1e..15443ace88 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -148,7 +148,7 @@ namespace osu.Game.Overlays.Comments loadCancellation?.Cancel(); request = new GetCommentsRequest(type, id.Value, Sort.Value, currentPage++); request.Success += onSuccess; - api.Queue(request); + api.PerformAsync(request); } private void clearComments() From a84068448a2e40ffd81e94a8bacd42e4981c8403 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 19:19:49 +0300 Subject: [PATCH 0223/1142] refetch comments on user change --- osu.Game/Overlays/Comments/CommentsContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 15443ace88..3d68f453b7 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -113,6 +113,7 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { + api.LocalUser.BindValueChanged(_ => refetchComments()); Sort.BindValueChanged(_ => refetchComments(), true); base.LoadComplete(); } From 4ea9efd92e8a1f87ec905ac8ec387d335d1862a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 4 Feb 2020 17:56:06 +0100 Subject: [PATCH 0224/1142] Enforce column ordering --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 171aae06d3..8a17fef367 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -99,7 +99,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; ppColumn.Text = $@"{value.PP:N0}"; - statisticsColumns.ChildrenEnumerable = value.Statistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); + statisticsColumns.ChildrenEnumerable = value.Statistics + .OrderByDescending(pair => pair.Key) + .Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); modsColumn.Mods = value.Mods; } } From 5eb1619e24ca180b99de8b762a30b9986dc4da75 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 18:02:49 +0100 Subject: [PATCH 0225/1142] Adjust title / artist font weight --- osu.Game/Overlays/BeatmapSet/Header.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 7c5c5a9d55..b62a5d46f0 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; @@ -134,7 +134,7 @@ namespace osu.Game.Overlays.BeatmapSet { title = new OsuSpriteText { - Font = OsuFont.GetFont(size: 37, weight: FontWeight.Bold, italics: true) + Font = OsuFont.GetFont(size: 37, weight: FontWeight.SemiBold, italics: true) }, externalLink = new ExternalLinkButton { @@ -144,7 +144,7 @@ namespace osu.Game.Overlays.BeatmapSet }, } }, - artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 25, weight: FontWeight.SemiBold, italics: true) }, + artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 25, weight: FontWeight.Medium, italics: true) }, new Container { RelativeSizeAxes = Axes.X, From a9cfade2f4a2af83c94b81132ff66a1cfa867dab Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 21:02:10 +0300 Subject: [PATCH 0226/1142] Adjust null handling --- osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs | 7 ++++--- osu.Game/Users/UserStatistics.cs | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs index e1395479f2..0e77d7d764 100644 --- a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Users; +using osu.Game.Scoring; namespace osu.Game.Overlays.Rankings.Tables { @@ -44,9 +45,9 @@ namespace osu.Game.Overlays.Rankings.Tables new ColoredRowText { Text = $@"{item.PlayCount:N0}", }, }.Concat(CreateUniqueContent(item)).Concat(new[] { - new ColoredRowText { Text = $@"{item.GradesCount.SS + (item.GradesCount.SSPlus ?? 0):N0}", }, - new ColoredRowText { Text = $@"{item.GradesCount.S + (item.GradesCount.SPlus ?? 0):N0}", }, - new ColoredRowText { Text = $@"{item.GradesCount.A:N0}", } + new ColoredRowText { Text = $@"{item.GradesCount[ScoreRank.XH] + item.GradesCount[ScoreRank.X]:N0}", }, + new ColoredRowText { Text = $@"{item.GradesCount[ScoreRank.SH] + item.GradesCount[ScoreRank.S]:N0}", }, + new ColoredRowText { Text = $@"{item.GradesCount[ScoreRank.A]:N0}", } }).ToArray(); protected abstract TableColumn[] CreateUniqueHeaders(); diff --git a/osu.Game/Users/UserStatistics.cs b/osu.Game/Users/UserStatistics.cs index 8ce26074a8..8b7699d0ad 100644 --- a/osu.Game/Users/UserStatistics.cs +++ b/osu.Game/Users/UserStatistics.cs @@ -85,20 +85,20 @@ namespace osu.Game.Users [JsonProperty(@"a")] public int A; - public int? this[ScoreRank rank] + public int this[ScoreRank rank] { get { switch (rank) { case ScoreRank.XH: - return SSPlus; + return SSPlus ?? 0; case ScoreRank.X: return SS; case ScoreRank.SH: - return SPlus; + return SPlus ?? 0; case ScoreRank.S: return S; From f8ad9476efd7727945ee9b38f324555180d1e908 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 4 Feb 2020 21:03:17 +0300 Subject: [PATCH 0227/1142] Adjust test step name --- osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs index 19ca63208e..656402e713 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsTables.cs @@ -68,7 +68,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("Mania scores", () => createScoreTable(new ManiaRuleset().RulesetInfo)); AddStep("Taiko country scores", () => createCountryTable(new TaikoRuleset().RulesetInfo)); AddStep("Catch US performance page 10", () => createPerformanceTable(new CatchRuleset().RulesetInfo, "US", 10)); - AddStep("Osu 271 spotlight table", () => createSpotlightTable(new OsuRuleset().RulesetInfo, 271)); + AddStep("Osu spotlight table (chart 271)", () => createSpotlightTable(new OsuRuleset().RulesetInfo, 271)); } private void createCountryTable(RulesetInfo ruleset, int page = 1) From 5b881568db688d501f8464963ac85d87b751981a Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 19:15:02 +0100 Subject: [PATCH 0228/1142] Adjust header gradient colours --- osu.Game/Overlays/BeatmapSet/Header.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index b62a5d46f0..5cfbd2ef83 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -93,10 +93,9 @@ namespace osu.Game.Overlays.BeatmapSet RelativeSizeAxes = Axes.Both, Masking = true, }, - new Box + coverGradient = new Box { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.3f), Color4.Black.Opacity(0.8f)), + RelativeSizeAxes = Axes.Both }, }, }, @@ -215,8 +214,10 @@ namespace osu.Game.Overlays.BeatmapSet } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OverlayColourProvider colourProvider) { + coverGradient.Colour = ColourInfo.GradientVertical(colourProvider.Background6.Opacity(0.3f), colourProvider.Background6.Opacity(0.8f)); + State.BindValueChanged(_ => updateDownloadButtons()); BeatmapSet.BindValueChanged(setInfo => From b6301f6537753fa7ad6597dbb8b7a2135cdb2e7a Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 19:52:32 +0100 Subject: [PATCH 0229/1142] Adjust PreviewButton alpha and animation --- osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs index 8c884e0950..80b287f6c6 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons { private const float transition_duration = 500; - private readonly Box bg, progress; + private readonly Box background, progress; private readonly PlayButton playButton; private PreviewTrack preview => playButton.Preview; @@ -40,10 +40,11 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons Children = new Drawable[] { - bg = new Box + background = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.25f), + Colour = Color4.Black, + Alpha = 0.5f }, new Container { @@ -91,13 +92,13 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons protected override bool OnHover(HoverEvent e) { - bg.FadeColour(Color4.Black.Opacity(0.5f), 100); + background.FadeTo(0.75f, 80); return base.OnHover(e); } protected override void OnHoverLost(HoverLostEvent e) { - bg.FadeColour(Color4.Black.Opacity(0.25f), 100); + background.FadeTo(0.5f, 80); base.OnHoverLost(e); } } From a366a92d4c93001a0af58566ff68448d20f88e96 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 19:54:51 +0100 Subject: [PATCH 0230/1142] Use alpha instead of colour opacity --- osu.Game/Overlays/BeatmapSet/Details.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index d76f6a43db..627f3d04c9 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -119,7 +118,8 @@ namespace osu.Game.Overlays.BeatmapSet new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), + Colour = Color4.Black, + Alpha = 0.5f }, content = new Container { From 86283cc422654e7babbb54a67cab8f8ccc8dc151 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 19:55:19 +0100 Subject: [PATCH 0231/1142] Recolour SuccessRate background --- osu.Game/Overlays/BeatmapSet/SuccessRate.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs index 1dcc847760..dac750dacf 100644 --- a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs @@ -105,10 +105,10 @@ namespace osu.Game.Overlays.BeatmapSet } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, OverlayColourProvider colourProvider) { successRate.AccentColour = colours.Green; - successRate.BackgroundColour = colours.GrayD; + successRate.BackgroundColour = colourProvider.Background6; updateDisplay(); } From d0eb4e44719b20621362dc721cedfc18f17ab051 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 20:08:54 +0100 Subject: [PATCH 0232/1142] Add necessary variable --- osu.Game/Overlays/BeatmapSet/Header.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 5cfbd2ef83..f2d1077844 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -30,6 +30,7 @@ namespace osu.Game.Overlays.BeatmapSet private const float buttons_spacing = 5; private readonly UpdateableBeatmapSetCover cover; + private readonly Box coverGradient; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; private readonly FillFlowContainer downloadButtonsContainer; From 2cc1255035d5f84aad41dd5cc21a38db0a837229 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 20:09:52 +0100 Subject: [PATCH 0233/1142] Adjust online status pill font and padding --- osu.Game/Overlays/BeatmapSet/Header.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index f2d1077844..dccebe5bad 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -196,8 +196,8 @@ namespace osu.Game.Overlays.BeatmapSet { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - TextSize = 14, - TextPadding = new MarginPadding { Horizontal = 25, Vertical = 8 } + TextSize = 17, + TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 } }, Details = new Details(), }, From 268bb73ac668f927f936b5c72798fc6cdf5fc270 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 20:14:50 +0100 Subject: [PATCH 0234/1142] Adjust header padding --- osu.Game/Overlays/BeatmapSet/Header.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index dccebe5bad..c620ae2bca 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -106,8 +106,7 @@ namespace osu.Game.Overlays.BeatmapSet AutoSizeAxes = Axes.Y, Padding = new MarginPadding { - Top = 20, - Bottom = 30, + Vertical = BeatmapSetOverlay.Y_PADDING, Left = BeatmapSetOverlay.X_PADDING, Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH, }, @@ -187,7 +186,7 @@ namespace osu.Game.Overlays.BeatmapSet Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight, AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = BeatmapSetOverlay.TOP_PADDING, Right = BeatmapSetOverlay.X_PADDING }, + Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = BeatmapSetOverlay.X_PADDING }, Direction = FillDirection.Vertical, Spacing = new Vector2(10), Children = new Drawable[] From cbfb90983bfe8b146bcf1df5883c6b7b06a109d6 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 20:17:27 +0100 Subject: [PATCH 0235/1142] Rename variable --- osu.Game/Overlays/BeatmapSetOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index f747cfff16..7624351e41 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays public class BeatmapSetOverlay : FullscreenOverlay { public const float X_PADDING = 40; - public const float TOP_PADDING = 25; + public const float Y_PADDING = 25; public const float RIGHT_WIDTH = 275; protected readonly Header Header; From 85fb4b4a18eb79ccd7b65786a3f99f83b67838f7 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:00:00 +0100 Subject: [PATCH 0236/1142] Recolour DetailBox --- osu.Game/Overlays/BeatmapSet/Details.cs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index 627f3d04c9..d24ad58a74 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; @@ -106,6 +106,8 @@ namespace osu.Game.Overlays.BeatmapSet private class DetailBox : Container { private readonly Container content; + private readonly Box background; + protected override Container Content => content; public DetailBox() @@ -115,10 +117,9 @@ namespace osu.Game.Overlays.BeatmapSet InternalChildren = new Drawable[] { - new Box + background = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, Alpha = 0.5f }, content = new Container @@ -129,6 +130,12 @@ namespace osu.Game.Overlays.BeatmapSet }, }; } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + background.Colour = colourProvider.Background6; + } } } } From 88e79dfa78031b474fdb1ba341a4c8acb9c4ae13 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:00:27 +0100 Subject: [PATCH 0237/1142] Hide ratings if beatmap has no leaderboard --- osu.Game/Overlays/BeatmapSet/Details.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index d24ad58a74..85341e6f1c 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; @@ -20,6 +20,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly PreviewButton preview; private readonly BasicStats basic; private readonly AdvancedStats advanced; + private readonly DetailBox ratingBox; private BeatmapSetInfo beatmapSet; @@ -53,6 +54,7 @@ namespace osu.Game.Overlays.BeatmapSet private void updateDisplay() { Ratings.Metrics = BeatmapSet?.Metrics; + ratingBox.Alpha = (BeatmapSet?.OnlineInfo?.Status ?? 0) > 0 ? 1 : 0; } public Details() @@ -85,7 +87,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Vertical = 7.5f }, }, }, - new DetailBox + ratingBox = new DetailBox { Child = Ratings = new UserRatings { From 48beb9fd6d45688911e18f08f81137bde53b03ee Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:01:02 +0100 Subject: [PATCH 0238/1142] Recolour PreviewButton --- osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs index 80b287f6c6..5ce283d0d8 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs @@ -43,7 +43,6 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons background = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, Alpha = 0.5f }, new Container @@ -72,9 +71,10 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, OverlayColourProvider colourProvider) { progress.Colour = colours.Yellow; + background.Colour = colourProvider.Background6; } protected override void Update() From 3ef6027d5718a11bd2a4ef8154c949d2911452f5 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:02:02 +0100 Subject: [PATCH 0239/1142] Show placeholder instead of success rate when beatmap unranked --- osu.Game/Overlays/BeatmapSet/Info.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index d7392b31e1..516eee43ce 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -26,6 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Box successRateBackground; private readonly Box background; private readonly SuccessRate successRate; + private readonly OsuSpriteText unrankedPlaceholder; public readonly Bindable BeatmapSet = new Bindable(); @@ -110,6 +111,14 @@ namespace osu.Game.Overlays.BeatmapSet RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = 20, Horizontal = 15 }, }, + unrankedPlaceholder = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Alpha = 0, + Text = "Unranked beatmap", + Font = OsuFont.GetFont(size: 13) + }, }, }, }, @@ -122,6 +131,9 @@ namespace osu.Game.Overlays.BeatmapSet tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? string.Empty; language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? string.Empty; + var setHasLeaderboard = (b.NewValue?.OnlineInfo?.Status ?? 0) > 0; + successRate.Alpha = setHasLeaderboard ? 1 : 0; + unrankedPlaceholder.Alpha = setHasLeaderboard ? 0 : 1; }; } From 54580858499cb36326ef0a8beade69f5c568702c Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:11:35 +0100 Subject: [PATCH 0240/1142] Adjust TopScoreUserSection font and spacing --- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 72a7efd777..1923c5a48f 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -96,13 +96,14 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: 10) }, flag = new UpdateableFlag { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Size = new Vector2(19, 13), + Margin = new MarginPadding { Top = 2 }, // makes spacing look more even ShowPlaceholderOnNull = false, }, } From d23e4a1fa1cc649a7242b356298c081474ccdc35 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:27:51 +0100 Subject: [PATCH 0241/1142] Change scoreboard text size --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 7a17412722..c124f7b262 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private const float horizontal_inset = 20; private const float row_height = 25; - private const int text_size = 12; + private const int text_size = 14; private readonly FillFlowContainer backgroundFlow; From 979589704534c0592bb249b9f42084aadb929e77 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:28:31 +0100 Subject: [PATCH 0242/1142] Enforce correct column order in ScoreTable --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index c124f7b262..7820323171 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; @@ -65,6 +65,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores for (int i = 0; i < value.Count; i++) backgroundFlow.Add(new ScoreTableRowBackground(i, value[i])); + // Ensure correct column order + foreach (ScoreInfo score in value) + score.Statistics = score.Statistics.OrderByDescending(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value); + Columns = createHeaders(value[0]); Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); } From 82914b5d6e6f852f9d21ab65277b3889f3d19468 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:41:33 +0100 Subject: [PATCH 0243/1142] Adjust ScoreTable spacing --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 7820323171..f04477d911 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -81,9 +81,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new TableColumn("rank", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)), new TableColumn("", Anchor.Centre, new Dimension(GridSizeMode.Absolute, 70)), // grade new TableColumn("score", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), - new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), + new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 60, maxSize: 70)), new TableColumn("player", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 150)), - new TableColumn("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 90)) + new TableColumn("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 110)) }; foreach (var statistic in score.Statistics) @@ -194,7 +194,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public HeaderText(string text) { Text = text.ToUpper(); - Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold); + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold); } [BackgroundDependencyLoader] From d7af96a2e51817fbffa8d872d500f25081cc628b Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:42:01 +0100 Subject: [PATCH 0244/1142] Adjust corner radius --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs index 14ea3e6b38..83271efe09 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativeSizeAxes = Axes.X; Height = 25; - CornerRadius = 3; + CornerRadius = 5; Masking = true; InternalChildren = new Drawable[] From 86c0b509835eae73a680c72f41bb6bc59124c9fd Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:45:45 +0100 Subject: [PATCH 0245/1142] Adjust font once again for readibility --- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 1923c5a48f..9913493617 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -96,14 +96,14 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 10) + Font = OsuFont.GetFont(size: 12) }, flag = new UpdateableFlag { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Size = new Vector2(19, 13), - Margin = new MarginPadding { Top = 2 }, // makes spacing look more even + Margin = new MarginPadding { Top = 3 }, // makes spacing look more even ShowPlaceholderOnNull = false, }, } From c1b8445b006fd22243a4235a7da14c458220b53f Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 21:53:23 +0100 Subject: [PATCH 0246/1142] Add spacing to match osu-web Note: due to osu-web using flex to even out the spacing and me not being able to implement the same behaviour here, I added a static margin to separate the title from the diffname above. This looks better than the previous state in most cases, the only scenario where this differs somehow visibly from web is on mapsets with large numbers of difficulties. --- osu.Game/Overlays/BeatmapSet/Header.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index c620ae2bca..9f79b92cb6 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -129,6 +129,7 @@ namespace osu.Game.Overlays.BeatmapSet { Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 15 }, Children = new Drawable[] { title = new OsuSpriteText From ae467538d3bf0ff1b3483ba201d8f19d7b7f46c9 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Tue, 4 Feb 2020 22:39:51 +0100 Subject: [PATCH 0247/1142] Fix tests --- .../Online/TestSceneBeatmapSetOverlayDetails.cs | 11 ++++++++++- .../Online/TestSceneBeatmapSetOverlaySuccessRate.cs | 5 +++++ .../Online/TestSceneLeaderboardScopeSelector.cs | 5 +++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs index 990e0a166b..dea1e710b5 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlayDetails.cs @@ -5,9 +5,11 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Overlays.BeatmapSet; using osu.Game.Screens.Select.Details; @@ -22,6 +24,9 @@ namespace osu.Game.Tests.Visual.Online private RatingsExposingDetails details; + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + [SetUp] public void Setup() => Schedule(() => { @@ -55,8 +60,12 @@ namespace osu.Game.Tests.Visual.Online { Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(), Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(), - } + }, } + }, + OnlineInfo = new BeatmapSetOnlineInfo + { + Status = BeatmapSetOnlineStatus.Ranked } }; } diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs index 2b572c1f6c..03003daf81 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlaySuccessRate.cs @@ -5,11 +5,13 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Overlays; using osu.Game.Overlays.BeatmapSet; using osu.Game.Screens.Select.Details; using osuTK; @@ -26,6 +28,9 @@ namespace osu.Game.Tests.Visual.Online private GraphExposingSuccessRate successRate; + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + [SetUp] public void Setup() => Schedule(() => { diff --git a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs index cc3b2ac68b..f9a7bc99c3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneLeaderboardScopeSelector.cs @@ -7,11 +7,16 @@ using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Bindables; using osu.Game.Screens.Select.Leaderboards; +using osu.Framework.Allocation; +using osu.Game.Overlays; namespace osu.Game.Tests.Visual.Online { public class TestSceneLeaderboardScopeSelector : OsuTestScene { + [Cached] + private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + public override IReadOnlyList RequiredTypes => new[] { typeof(LeaderboardScopeSelector), From b606408667e842dd0326bf071fa551a2e1de7452 Mon Sep 17 00:00:00 2001 From: Tree Date: Tue, 4 Feb 2020 23:02:28 +0100 Subject: [PATCH 0248/1142] Remove space --- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 9913493617..00171e1170 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -103,7 +103,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Size = new Vector2(19, 13), - Margin = new MarginPadding { Top = 3 }, // makes spacing look more even + Margin = new MarginPadding { Top = 3 }, // makes spacing look more even ShowPlaceholderOnNull = false, }, } From 23d1d3fdf11bb9cf23e416cd0478dd8ba8ab4644 Mon Sep 17 00:00:00 2001 From: Tree Date: Tue, 4 Feb 2020 23:09:10 +0100 Subject: [PATCH 0249/1142] Convert field to local variable --- osu.Game/Overlays/BeatmapSet/Info.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 516eee43ce..a71409a05f 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -26,7 +26,6 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Box successRateBackground; private readonly Box background; private readonly SuccessRate successRate; - private readonly OsuSpriteText unrankedPlaceholder; public readonly Bindable BeatmapSet = new Bindable(); @@ -39,6 +38,8 @@ namespace osu.Game.Overlays.BeatmapSet public Info() { MetadataSection source, tags, genre, language; + OsuSpriteText unrankedPlaceholder; + RelativeSizeAxes = Axes.X; Height = 220; Masking = true; From c2a80119ca4cf9c65755abecfc9000dd234cc446 Mon Sep 17 00:00:00 2001 From: Tree Date: Tue, 4 Feb 2020 23:23:57 +0100 Subject: [PATCH 0250/1142] Remove using directives --- osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs index 5ce283d0d8..7eae05e4a9 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs @@ -3,7 +3,6 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -14,7 +13,6 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays.Direct; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet.Buttons { From 447f31ccfc21f96f3795c6e4f121e3a1f82aded0 Mon Sep 17 00:00:00 2001 From: Tree Date: Tue, 4 Feb 2020 23:25:21 +0100 Subject: [PATCH 0251/1142] Remove using directive --- osu.Game/Overlays/BeatmapSet/Details.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index 85341e6f1c..bd13b4371e 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -9,7 +9,6 @@ using osu.Game.Beatmaps; using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Screens.Select.Details; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { From 9347c3f535e9820ed461ea5c11b62fd9d9a8d7a4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 11:13:32 +0300 Subject: [PATCH 0252/1142] Add trigger user change test --- .../Visual/Online/TestSceneCommentsContainer.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 9c526c4f81..33acc75fa8 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics; using osu.Game.Overlays.Comments; using osu.Game.Overlays; using osu.Framework.Allocation; +using osu.Game.Online.API; namespace osu.Game.Tests.Visual.Online { @@ -34,21 +35,26 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); + private CommentsContainer comments; + private readonly BasicScrollContainer scroll; + public TestSceneCommentsContainer() { - BasicScrollContainer scroll; - CommentsContainer comments; - Add(scroll = new BasicScrollContainer { RelativeSizeAxes = Axes.Both, Child = comments = new CommentsContainer() }); + } + [BackgroundDependencyLoader] + private void load(IAPIProvider api) + { AddStep("Big Black comments", () => comments.ShowComments(CommentableType.Beatmapset, 41823)); AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); + AddStep("Trigger user change", api.LocalUser.TriggerChange); AddStep("Idle state", () => { scroll.Clear(); From a3fd952f74bf6693a576f3db4b8261e399db037c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 11:21:23 +0300 Subject: [PATCH 0253/1142] Use new SpotlightSelector in RankingsHeader --- .../Visual/Online/TestSceneRankingsHeader.cs | 13 ++-- .../Rankings/RankingsOverlayHeader.cs | 61 +++---------------- osu.Game/Overlays/Rankings/Spotlight.cs | 18 ------ 3 files changed, 16 insertions(+), 76 deletions(-) delete mode 100644 osu.Game/Overlays/Rankings/Spotlight.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs index 898e461bde..bc0ae3d264 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Rankings; using osu.Game.Rulesets; @@ -37,20 +38,20 @@ namespace osu.Game.Tests.Visual.Online Ruleset = { BindTarget = ruleset }, Spotlights = new[] { - new Spotlight + new APISpotlight { Id = 1, - Text = "Spotlight 1" + Name = "Spotlight 1" }, - new Spotlight + new APISpotlight { Id = 2, - Text = "Spotlight 2" + Name = "Spotlight 2" }, - new Spotlight + new APISpotlight { Id = 3, - Text = "Spotlight 3" + Name = "Spotlight 3" } } }); diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 94afe4e5a5..41722034b6 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -8,21 +8,20 @@ using osu.Game.Rulesets; using osu.Game.Users; using System.Collections.Generic; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Allocation; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Rankings { public class RankingsOverlayHeader : TabControlOverlayHeader { public readonly Bindable Ruleset = new Bindable(); - public readonly Bindable Spotlight = new Bindable(); + public readonly Bindable Spotlight = new Bindable(); public readonly Bindable Country = new Bindable(); - public IEnumerable Spotlights + public IEnumerable Spotlights { - get => spotlightsContainer.Spotlights; - set => spotlightsContainer.Spotlights = value; + get => spotlightSelector.Spotlights; + set => spotlightSelector.Spotlights = value; } protected override ScreenTitle CreateTitle() => new RankingsTitle @@ -35,7 +34,7 @@ namespace osu.Game.Overlays.Rankings Current = Ruleset }; - private SpotlightsContainer spotlightsContainer; + private SpotlightSelector spotlightSelector; protected override Drawable CreateContent() => new FillFlowContainer { @@ -48,9 +47,9 @@ namespace osu.Game.Overlays.Rankings { Current = Country }, - spotlightsContainer = new SpotlightsContainer + spotlightSelector = new SpotlightSelector { - Spotlight = { BindTarget = Spotlight } + Current = { BindTarget = Spotlight } } } }; @@ -62,7 +61,7 @@ namespace osu.Game.Overlays.Rankings } private void onCurrentChanged(ValueChangedEvent scope) => - spotlightsContainer.FadeTo(scope.NewValue == RankingsScope.Spotlights ? 1 : 0, 200, Easing.OutQuint); + spotlightSelector.FadeTo(scope.NewValue == RankingsScope.Spotlights ? 1 : 0, 200, Easing.OutQuint); private class RankingsTitle : ScreenTitle { @@ -81,48 +80,6 @@ namespace osu.Game.Overlays.Rankings protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/rankings"); } - - private class SpotlightsContainer : CompositeDrawable - { - public readonly Bindable Spotlight = new Bindable(); - - public IEnumerable Spotlights - { - get => dropdown.Items; - set => dropdown.Items = value; - } - - private readonly OsuDropdown dropdown; - private readonly Box background; - - public SpotlightsContainer() - { - Height = 100; - RelativeSizeAxes = Axes.X; - InternalChildren = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - }, - dropdown = new OsuDropdown - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Width = 0.8f, - Current = Spotlight, - Y = 20, - } - }; - } - - [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) - { - background.Colour = colourProvider.Dark3; - } - } } public enum RankingsScope diff --git a/osu.Game/Overlays/Rankings/Spotlight.cs b/osu.Game/Overlays/Rankings/Spotlight.cs deleted file mode 100644 index e956b4f449..0000000000 --- a/osu.Game/Overlays/Rankings/Spotlight.cs +++ /dev/null @@ -1,18 +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 Newtonsoft.Json; - -namespace osu.Game.Overlays.Rankings -{ - public class Spotlight - { - [JsonProperty("id")] - public int Id; - - [JsonProperty("text")] - public string Text; - - public override string ToString() => Text; - } -} From 63c595ed974ef224e7e350599ceafffa202320d0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 17:16:15 +0900 Subject: [PATCH 0254/1142] Make EditorBeatmap a component and move UpdateHitObject to it --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 20 ++-------------- osu.Game/Screens/Edit/Editor.cs | 6 ++--- osu.Game/Screens/Edit/EditorBeatmap.cs | 26 ++++++++++++++++++++- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 5ac1d4ecc4..0014360d24 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Framework.Logging; -using osu.Framework.Threading; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -50,8 +49,6 @@ namespace osu.Game.Rulesets.Edit [Resolved] private IBeatSnapProvider beatSnapProvider { get; set; } - private IBeatmapProcessor beatmapProcessor; - private DrawableEditRulesetWrapper drawableRulesetWrapper; private ComposeBlueprintContainer blueprintContainer; private Container distanceSnapGridContainer; @@ -71,8 +68,6 @@ namespace osu.Game.Rulesets.Edit [BackgroundDependencyLoader] private void load(IFrameBasedClock framedClock) { - beatmapProcessor = Ruleset.CreateBeatmapProcessor(EditorBeatmap.PlayableBeatmap); - EditorBeatmap.HitObjectAdded += addHitObject; EditorBeatmap.HitObjectRemoved += removeHitObject; EditorBeatmap.StartTimeChanged += UpdateHitObject; @@ -240,19 +235,6 @@ namespace osu.Game.Rulesets.Edit lastGridUpdateTime = EditorClock.CurrentTime; } - private ScheduledDelegate scheduledUpdate; - - public override void UpdateHitObject(HitObject hitObject) - { - scheduledUpdate?.Cancel(); - scheduledUpdate = Schedule(() => - { - beatmapProcessor?.PreProcess(); - hitObject?.ApplyDefaults(EditorBeatmap.ControlPointInfo, EditorBeatmap.BeatmapInfo.BaseDifficulty); - beatmapProcessor?.PostProcess(); - }); - } - private void addHitObject(HitObject hitObject) => UpdateHitObject(hitObject); private void removeHitObject(HitObject hitObject) => UpdateHitObject(null); @@ -309,6 +291,8 @@ namespace osu.Game.Rulesets.Edit public override float GetSnappedDistanceFromDistance(double referenceTime, float distance) => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(DistanceToDuration(referenceTime, distance), referenceTime)); + public override void UpdateHitObject(HitObject hitObject) => EditorBeatmap.UpdateHitObject(hitObject); + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 8c7270d3a2..9a60edadc4 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -81,7 +81,7 @@ namespace osu.Game.Screens.Edit clock.ChangeSource(sourceClock); playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); - editorBeatmap = new EditorBeatmap(playableBeatmap, beatDivisor); + AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap, beatDivisor)); dependencies.CacheAs(clock); dependencies.CacheAs(clock); @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Edit fileMenuItems.Add(new EditorMenuItem("Exit", MenuItemType.Standard, this.Exit)); - InternalChild = new OsuContextMenuContainer + AddInternal(new OsuContextMenuContainer { RelativeSizeAxes = Axes.Both, Children = new[] @@ -189,7 +189,7 @@ namespace osu.Game.Screens.Edit } }, } - }; + }); menuBar.Mode.ValueChanged += onModeChanged; diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 6edd62fa67..ba008e32e8 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -5,6 +5,8 @@ using System; using System.Collections; using System.Collections.Generic; using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; @@ -13,7 +15,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Screens.Edit { - public class EditorBeatmap : IBeatmap, IBeatSnapProvider + public class EditorBeatmap : Component, IBeatmap, IBeatSnapProvider { /// /// Invoked when a is added to this . @@ -36,17 +38,39 @@ namespace osu.Game.Screens.Edit private readonly BindableBeatDivisor beatDivisor; + private readonly IBeatmapProcessor beatmapProcessor; + private readonly Dictionary> startTimeBindables = new Dictionary>(); public EditorBeatmap(IBeatmap playableBeatmap, BindableBeatDivisor beatDivisor = null) { PlayableBeatmap = playableBeatmap; + this.beatDivisor = beatDivisor; + beatmapProcessor = playableBeatmap.BeatmapInfo.Ruleset?.CreateInstance().CreateBeatmapProcessor(PlayableBeatmap); + foreach (var obj in HitObjects) trackStartTime(obj); } + private ScheduledDelegate scheduledUpdate; + + /// + /// Updates a , invoking and re-processing the beatmap. + /// + /// The to update. + public void UpdateHitObject(HitObject hitObject) + { + scheduledUpdate?.Cancel(); + scheduledUpdate = Scheduler.AddDelayed(() => + { + beatmapProcessor?.PreProcess(); + hitObject?.ApplyDefaults(ControlPointInfo, BeatmapInfo.BaseDifficulty); + beatmapProcessor?.PostProcess(); + }, 0); + } + public BeatmapInfo BeatmapInfo { get => PlayableBeatmap.BeatmapInfo; From 96986bf5fcf03e56acbf8926346665ef1fea42f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 17:32:33 +0900 Subject: [PATCH 0255/1142] Remove beat divisor from ctor and use DI instead --- ...tSceneHitObjectComposerDistanceSnapping.cs | 22 +++++++++++++++++-- .../Visual/Editor/TimelineTestScene.cs | 3 ++- osu.Game/Screens/Edit/Editor.cs | 6 ++--- osu.Game/Screens/Edit/EditorBeatmap.cs | 8 +++---- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs index 5a4e76d586..3cb5909ba9 100644 --- a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs @@ -3,6 +3,8 @@ using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Edit; @@ -23,15 +25,31 @@ namespace osu.Game.Tests.Editor [Cached(typeof(IBeatSnapProvider))] private readonly EditorBeatmap editorBeatmap; + protected override Container Content { get; } + public TestSceneHitObjectComposerDistanceSnapping() { - editorBeatmap = new EditorBeatmap(new OsuBeatmap(), BeatDivisor); + base.Content.Add(new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + editorBeatmap = new EditorBeatmap(new OsuBeatmap()), + Content = new Container + { + RelativeSizeAxes = Axes.Both, + } + }, + }); } [SetUp] public void Setup() => Schedule(() => { - Child = composer = new TestHitObjectComposer(); + Children = new Drawable[] + { + composer = new TestHitObjectComposer() + }; BeatDivisor.Value = 1; diff --git a/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs index b5e526d3c2..40c0fedc9e 100644 --- a/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs @@ -38,13 +38,14 @@ namespace osu.Game.Tests.Visual.Editor { Beatmap.Value = new WaveformTestBeatmap(audio); - var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap, BeatDivisor); + var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap); Dependencies.Cache(editorBeatmap); Dependencies.CacheAs(editorBeatmap); AddRange(new Drawable[] { + editorBeatmap, new FillFlowContainer { AutoSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 9a60edadc4..3bec4b8f6f 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -80,15 +80,15 @@ namespace osu.Game.Screens.Edit clock = new EditorClock(Beatmap.Value, beatDivisor) { IsCoupled = false }; clock.ChangeSource(sourceClock); - playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); - AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap, beatDivisor)); - dependencies.CacheAs(clock); dependencies.CacheAs(clock); // todo: remove caching of this and consume via editorBeatmap? dependencies.Cache(beatDivisor); + playableBeatmap = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); + AddInternal(editorBeatmap = new EditorBeatmap(playableBeatmap)); + dependencies.CacheAs(editorBeatmap); EditorMenuBar menuBar; diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index ba008e32e8..cacb539891 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -4,6 +4,7 @@ using System; using System.Collections; using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Threading; @@ -36,18 +37,17 @@ namespace osu.Game.Screens.Edit public readonly IBeatmap PlayableBeatmap; - private readonly BindableBeatDivisor beatDivisor; + [Resolved] + private BindableBeatDivisor beatDivisor { get; set; } private readonly IBeatmapProcessor beatmapProcessor; private readonly Dictionary> startTimeBindables = new Dictionary>(); - public EditorBeatmap(IBeatmap playableBeatmap, BindableBeatDivisor beatDivisor = null) + public EditorBeatmap(IBeatmap playableBeatmap) { PlayableBeatmap = playableBeatmap; - this.beatDivisor = beatDivisor; - beatmapProcessor = playableBeatmap.BeatmapInfo.Ruleset?.CreateInstance().CreateBeatmapProcessor(PlayableBeatmap); foreach (var obj in HitObjects) From dffc58c5fae9e18fc96af3b8128ce3a7b2d06226 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 4 Feb 2020 12:23:02 +0900 Subject: [PATCH 0256/1142] Add blueprint type to timeline test --- .../Editor/TestSceneTimelineBlueprintContainer.cs | 13 +++++++++++++ .../Visual/Editor/TestSceneTimingScreen.cs | 7 ++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs index 3c75fd5310..4d8f877575 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.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; +using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Screens.Edit.Compose.Components.Timeline; @@ -10,6 +12,17 @@ namespace osu.Game.Tests.Visual.Editor [TestFixture] public class TestSceneTimelineBlueprintContainer : TimelineTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(TimelineHitObjectBlueprint), + }; + public override Drawable CreateTestComponent() => new TimelineBlueprintContainer(); + + protected override void LoadComplete() + { + base.LoadComplete(); + Clock.Seek(10000); + } } } diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimingScreen.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimingScreen.cs index adfed9a299..ae09a7fa47 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneTimingScreen.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneTimingScreen.cs @@ -27,7 +27,12 @@ namespace osu.Game.Tests.Visual.Editor }; [Cached(typeof(EditorBeatmap))] - private readonly EditorBeatmap editorBeatmap = new EditorBeatmap(new OsuBeatmap()); + private readonly EditorBeatmap editorBeatmap; + + public TestSceneTimingScreen() + { + editorBeatmap = new EditorBeatmap(new OsuBeatmap()); + } [BackgroundDependencyLoader] private void load() From cd6902a312480e53a7f49d1fa264ef158750d4cd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 17:12:26 +0900 Subject: [PATCH 0257/1142] Make EndTime and RepeatCount settable --- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 6 +++++- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 6 +++++- osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 6 +++++- osu.Game.Rulesets.Osu/Objects/Slider.cs | 9 +++++++-- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 6 +++++- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 6 +++++- osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 7 ++++++- osu.Game/Rulesets/Objects/Types/IHasEndTime.cs | 5 ++++- osu.Game/Rulesets/Objects/Types/IHasRepeats.cs | 2 +- 9 files changed, 43 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index 267e6d12c7..0c754412e5 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -36,7 +36,11 @@ namespace osu.Game.Rulesets.Catch.Objects } } - public double EndTime => StartTime + Duration; + public double EndTime + { + get => StartTime + Duration; + set => Duration = value - StartTime; + } public double Duration { get; set; } } diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index a4ed966abb..4d68bf592c 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -110,7 +110,11 @@ namespace osu.Game.Rulesets.Catch.Objects } } - public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; + public double EndTime + { + get => StartTime + this.SpanCount() * Path.Distance / Velocity; + set => throw new System.NotImplementedException(); + } public float EndX => X + this.CurvePositionAt(1).X / CatchPlayfield.BASE_WIDTH; diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index bdba813eed..86d3d2b2b0 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -15,7 +15,11 @@ namespace osu.Game.Rulesets.Mania.Objects /// public class HoldNote : ManiaHitObject, IHasEndTime { - public double EndTime => StartTime + Duration; + public double EndTime + { + get => StartTime + Duration; + set => Duration = value - StartTime; + } private double duration; diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index fe65ab78d1..bab7e6dbee 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -18,7 +18,12 @@ namespace osu.Game.Rulesets.Osu.Objects { public class Slider : OsuHitObject, IHasCurve { - public double EndTime => StartTime + this.SpanCount() * Path.Distance / Velocity; + public double EndTime + { + get => StartTime + this.SpanCount() * Path.Distance / Velocity; + set => throw new System.NotImplementedException(); + } + public double Duration => EndTime - StartTime; private readonly Cached endPositionCache = new Cached(); @@ -81,7 +86,7 @@ namespace osu.Game.Rulesets.Osu.Objects set { repeatCount = value; - endPositionCache.Invalidate(); + updateNestedPositions(); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 8956ca9c19..aacd78f176 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -18,7 +18,11 @@ namespace osu.Game.Rulesets.Taiko.Objects /// private const float base_distance = 100; - public double EndTime => StartTime + Duration; + public double EndTime + { + get => StartTime + Duration; + set => Duration = value - StartTime; + } public double Duration { get; set; } diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index e60984596d..2f06066a16 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -11,7 +11,11 @@ namespace osu.Game.Rulesets.Taiko.Objects { public class Swell : TaikoHitObject, IHasEndTime { - public double EndTime => StartTime + Duration; + public double EndTime + { + get => StartTime + Duration; + set => Duration = value - StartTime; + } public double Duration { get; set; } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 8d523022d6..b5cd9be245 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -26,7 +26,12 @@ namespace osu.Game.Rulesets.Objects.Legacy public List> NodeSamples { get; set; } public int RepeatCount { get; set; } - public double EndTime => StartTime + this.SpanCount() * Distance / Velocity; + public double EndTime + { + get => StartTime + this.SpanCount() * Distance / Velocity; + set => throw new System.NotImplementedException(); + } + public double Duration => EndTime - StartTime; public double Velocity = 1; diff --git a/osu.Game/Rulesets/Objects/Types/IHasEndTime.cs b/osu.Game/Rulesets/Objects/Types/IHasEndTime.cs index 516f1002a4..bc7103c60d 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasEndTime.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasEndTime.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 Newtonsoft.Json; + namespace osu.Game.Rulesets.Objects.Types { /// @@ -11,7 +13,8 @@ namespace osu.Game.Rulesets.Objects.Types /// /// The time at which the HitObject ends. /// - double EndTime { get; } + [JsonIgnore] + double EndTime { get; set; } /// /// The duration of the HitObject. diff --git a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs index b22752e902..256b1f3963 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Objects.Types /// /// The amount of times the HitObject repeats. /// - int RepeatCount { get; } + int RepeatCount { get; set; } /// /// The samples to be played when each node of the is hit.
From fa65e3a5bb51db63dc33f74189607e5d8dcb0487 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 12:09:32 +0300 Subject: [PATCH 0258/1142] Make spotlight selector work --- osu.Game/Overlays/RankingsOverlay.cs | 32 +++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 84470d9caa..36f5a3155a 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -14,6 +14,8 @@ using osu.Game.Online.API; using System.Threading; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Rankings.Tables; +using osu.Game.Online.API.Requests.Responses; +using System.Linq; namespace osu.Game.Overlays { @@ -22,11 +24,13 @@ namespace osu.Game.Overlays protected readonly Bindable Country = new Bindable(); protected readonly Bindable Scope = new Bindable(); private readonly Bindable ruleset = new Bindable(); + private readonly Bindable spotlight = new Bindable(); private readonly BasicScrollContainer scrollFlow; private readonly Container tableContainer; private readonly DimmedLoadingLayer loading; private readonly Box background; + private readonly RankingsOverlayHeader header; private APIRequest lastRequest; private CancellationTokenSource cancellationToken; @@ -54,14 +58,15 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - new RankingsOverlayHeader + header = new RankingsOverlayHeader { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Depth = -float.MaxValue, Country = { BindTarget = Country }, Current = { BindTarget = Scope }, - Ruleset = { BindTarget = ruleset } + Ruleset = { BindTarget = ruleset }, + Spotlight = { BindTarget = spotlight } }, new Container { @@ -109,11 +114,19 @@ namespace osu.Game.Overlays if (Scope.Value != RankingsScope.Performance) Country.Value = null; + if (Scope.Value == RankingsScope.Spotlights && !header.Spotlights.Any()) + { + getSpotlights(); + return; + } + Scheduler.AddOnce(loadNewContent); }, true); ruleset.BindValueChanged(_ => Scheduler.AddOnce(loadNewContent), true); + spotlight.BindValueChanged(_ => Scheduler.AddOnce(loadNewContent), true); + base.LoadComplete(); } @@ -127,6 +140,14 @@ namespace osu.Game.Overlays Country.Value = requested; } + private void getSpotlights() + { + loading.Show(); + var request = new GetSpotlightsRequest(); + request.Success += response => header.Spotlights = response.Spotlights; + api.Queue(request); + } + private void loadNewContent() { loading.Show(); @@ -145,7 +166,6 @@ namespace osu.Game.Overlays request.Success += () => loadTable(createTableFromResponse(request)); request.Failure += _ => loadTable(null); - api.Queue(request); } @@ -161,6 +181,9 @@ namespace osu.Game.Overlays case RankingsScope.Score: return new GetUserRankingsRequest(ruleset.Value, UserRankingsType.Score); + + case RankingsScope.Spotlights: + return new GetSpotlightRankingsRequest(ruleset.Value, header.Spotlight.Value.Id); } return null; @@ -184,6 +207,9 @@ namespace osu.Game.Overlays case GetCountryRankingsRequest countryRequest: return new CountriesTable(1, countryRequest.Result.Countries); + + case GetSpotlightRankingsRequest spotlightRequest: + return new ScoresTable(1, spotlightRequest.Result.Users); } return null; From 2b0b789980a0c7a099bc4ae88a5cf11a2229b70e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 12:14:24 +0300 Subject: [PATCH 0259/1142] Naming adjustments --- osu.Game/Overlays/RankingsOverlay.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 36f5a3155a..39f106a24e 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays private readonly Bindable spotlight = new Bindable(); private readonly BasicScrollContainer scrollFlow; - private readonly Container tableContainer; + private readonly Container contentContainer; private readonly DimmedLoadingLayer loading; private readonly Box background; private readonly RankingsOverlayHeader header; @@ -74,7 +74,7 @@ namespace osu.Game.Overlays AutoSizeAxes = Axes.Y, Children = new Drawable[] { - tableContainer = new Container + contentContainer = new Container { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -160,12 +160,12 @@ namespace osu.Game.Overlays if (request == null) { - loadTable(null); + loadContent(null); return; } - request.Success += () => loadTable(createTableFromResponse(request)); - request.Failure += _ => loadTable(null); + request.Success += () => loadContent(createContentFromResponse(request)); + request.Failure += _ => loadContent(null); api.Queue(request); } @@ -189,7 +189,7 @@ namespace osu.Game.Overlays return null; } - private Drawable createTableFromResponse(APIRequest request) + private Drawable createContentFromResponse(APIRequest request) { switch (request) { @@ -215,21 +215,21 @@ namespace osu.Game.Overlays return null; } - private void loadTable(Drawable table) + private void loadContent(Drawable content) { scrollFlow.ScrollToStart(); - if (table == null) + if (content == null) { - tableContainer.Clear(); + contentContainer.Clear(); loading.Hide(); return; } - LoadComponentAsync(table, t => + LoadComponentAsync(content, t => { loading.Hide(); - tableContainer.Child = table; + contentContainer.Child = content; }, (cancellationToken = new CancellationTokenSource()).Token); } } From b83ee6dabf45a4baf1ceebd4204ad56affe1245b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 12:22:42 +0300 Subject: [PATCH 0260/1142] Show beatmap panels for selected spotlight --- osu.Game/Overlays/RankingsOverlay.cs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 39f106a24e..2a4bc28b18 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -16,6 +16,8 @@ using osu.Game.Online.API.Requests; using osu.Game.Overlays.Rankings.Tables; using osu.Game.Online.API.Requests.Responses; using System.Linq; +using osuTK; +using osu.Game.Overlays.Direct; namespace osu.Game.Overlays { @@ -38,6 +40,9 @@ namespace osu.Game.Overlays [Resolved] private IAPIProvider api { get; set; } + [Resolved] + private RulesetStore rulesets { get; set; } + public RankingsOverlay() : base(OverlayColourScheme.Green) { @@ -209,7 +214,28 @@ namespace osu.Game.Overlays return new CountriesTable(1, countryRequest.Result.Countries); case GetSpotlightRankingsRequest spotlightRequest: - return new ScoresTable(1, spotlightRequest.Result.Users); + return new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + new ScoresTable(1, spotlightRequest.Result.Users), + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Spacing = new Vector2(10), + Children = spotlightRequest.Result.BeatmapSets.Select(b => new DirectGridPanel(b.ToBeatmapSet(rulesets)) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }).ToList() + } + } + }; } return null; From d04cc0123df7c7c7d3a476a03a27f93dd79257f4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 17:16:37 +0900 Subject: [PATCH 0261/1142] Initial implementation of timeline blueprint dragbars --- .../Compose/Components/Timeline/Timeline.cs | 13 ++- .../Timeline/TimelineHitObjectBlueprint.cs | 99 ++++++++++++++----- 2 files changed, 85 insertions(+), 27 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index a33040f400..0475e68e42 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -179,11 +179,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private IBeatSnapProvider beatSnapProvider { get; set; } - public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) - { - var targetTime = (position.X / Content.DrawWidth) * track.Length; - return (position, beatSnapProvider.SnapTime(targetTime)); - } + public double GetTimeFromScreenSpacePosition(Vector2 position) + => getTimeFromPosition(Content.ToLocalSpace(position)); + + public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) => + (position, beatSnapProvider.SnapTime(getTimeFromPosition(position))); + + private double getTimeFromPosition(Vector2 localPosition) => + (localPosition.X / Content.DrawWidth) * track.Length; public float GetBeatSnapDistanceAt(double referenceTime) => throw new NotImplementedException(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 2ed5471444..2ac35534f4 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -2,11 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using JetBrains.Annotations; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -24,7 +26,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [UsedImplicitly] private readonly Bindable startTime; - public const float THICKNESS = 3; + public const float THICKNESS = 5; private const float circle_size = 16; @@ -44,25 +46,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - if (hitObject is IHasEndTime) - { - AddInternal(extensionBar = new Container - { - CornerRadius = 2, - Masking = true, - Size = new Vector2(1, THICKNESS), - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.X, - Colour = Color4.Black, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - } - }); - } - AddInternal(circle = new Circle { Size = new Vector2(circle_size), @@ -74,6 +57,78 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline BorderColour = Color4.Black, BorderThickness = THICKNESS, }); + + if (hitObject is IHasEndTime) + { + AddRangeInternal(new Drawable[] + { + extensionBar = new Container + { + CornerRadius = 2, + Masking = true, + Size = new Vector2(1, THICKNESS), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.X, + Child = new Box + { + RelativeSizeAxes = Axes.Both, + } + }, + new DragBar(hitObject), + }); + } + } + + public class DragBar : CompositeDrawable + { + private readonly HitObject hitObject; + + [Resolved] + private Timeline timeline { get; set; } + + public DragBar(HitObject hitObject) + { + this.hitObject = hitObject; + + CornerRadius = 2; + Masking = true; + Size = new Vector2(THICKNESS, 1.5f); + Anchor = Anchor.CentreRight; + Origin = Anchor.CentreRight; + RelativePositionAxes = Axes.X; + RelativeSizeAxes = Axes.Y; + InternalChild = new Box + { + RelativeSizeAxes = Axes.Both, + }; + } + + protected override bool OnDragStart(DragStartEvent e) => true; + + [Resolved] + private EditorBeatmap beatmap { get; set; } + + protected override void OnDrag(DragEvent e) + { + base.OnDrag(e); + + var time = timeline.GetTimeFromScreenSpacePosition(e.ScreenSpaceMousePosition); + + switch (hitObject) + { + case IHasRepeats repeatHitObject: + repeatHitObject.RepeatCount = (int)((time - hitObject.StartTime) / (repeatHitObject.Duration / repeatHitObject.RepeatCount)); + break; + + case IHasEndTime endTimeHitObject: + endTimeHitObject.EndTime = time; + break; + } + + beatmap.UpdateHitObject(hitObject); + } } protected override void Update() @@ -88,14 +143,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { circle.BorderColour = Color4.Orange; if (extensionBar != null) - extensionBar.Colour = Color4.Orange; + extensionBar.BorderColour = Color4.Orange; } protected override void OnDeselected() { circle.BorderColour = Color4.Black; if (extensionBar != null) - extensionBar.Colour = Color4.Black; + extensionBar.BorderColour = Color4.Black; } public override Quad SelectionQuad From 09273d1da97a5b2ffe75fc9185a0c43161fdcb7c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 18:14:44 +0900 Subject: [PATCH 0262/1142] Fix test scene not correctly building a playable beatmap --- .../Visual/Editor/TimelineTestScene.cs | 5 ++-- osu.Game.Tests/WaveformTestBeatmap.cs | 27 ++++++++++++++----- osu.Game/Tests/Beatmaps/TestBeatmap.cs | 4 ++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs index 40c0fedc9e..7081eb3af5 100644 --- a/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs @@ -13,7 +13,6 @@ using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Objects; using osu.Game.Screens.Edit; using osu.Game.Screens.Edit.Compose.Components.Timeline; using osuTK; @@ -38,7 +37,9 @@ namespace osu.Game.Tests.Visual.Editor { Beatmap.Value = new WaveformTestBeatmap(audio); - var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap); + var playable = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset); + + var editorBeatmap = new EditorBeatmap(playable); Dependencies.Cache(editorBeatmap); Dependencies.CacheAs(editorBeatmap); diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs index b7d7bb1ee1..df6394ed34 100644 --- a/osu.Game.Tests/WaveformTestBeatmap.cs +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -11,6 +11,8 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.IO; using osu.Game.IO.Archives; +using osu.Game.Rulesets.Catch; +using osu.Game.Tests.Beatmaps; using osu.Game.Tests.Resources; namespace osu.Game.Tests @@ -20,11 +22,18 @@ namespace osu.Game.Tests ///
public class WaveformTestBeatmap : WorkingBeatmap { + private readonly Beatmap beatmap; private readonly ITrackStore trackStore; public WaveformTestBeatmap(AudioManager audioManager) - : base(new BeatmapInfo(), audioManager) + : this(audioManager, new WaveformBeatmap()) { + } + + public WaveformTestBeatmap(AudioManager audioManager, Beatmap beatmap) + : base(beatmap.BeatmapInfo, audioManager) + { + this.beatmap = beatmap; trackStore = audioManager.GetTrackStore(getZipReader()); } @@ -34,11 +43,11 @@ namespace osu.Game.Tests trackStore?.Dispose(); } - private Stream getStream() => TestResources.GetTestBeatmapStream(); + private static Stream getStream() => TestResources.GetTestBeatmapStream(); - private ZipArchiveReader getZipReader() => new ZipArchiveReader(getStream()); + private static ZipArchiveReader getZipReader() => new ZipArchiveReader(getStream()); - protected override IBeatmap GetBeatmap() => createTestBeatmap(); + protected override IBeatmap GetBeatmap() => beatmap; protected override Texture GetBackground() => null; @@ -57,10 +66,16 @@ namespace osu.Game.Tests } } - private Beatmap createTestBeatmap() + private class WaveformBeatmap : TestBeatmap { - using (var reader = getZipReader()) + public WaveformBeatmap() + : base(new CatchRuleset().RulesetInfo) { + } + + protected override Beatmap CreateBeatmap() + { + using (var reader = getZipReader()) using (var beatmapStream = reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu")))) using (var beatmapReader = new LineBufferedReader(beatmapStream)) return Decoder.GetDecoder(beatmapReader).Decode(beatmapReader); diff --git a/osu.Game/Tests/Beatmaps/TestBeatmap.cs b/osu.Game/Tests/Beatmaps/TestBeatmap.cs index d6f92ba086..96e3c037a3 100644 --- a/osu.Game/Tests/Beatmaps/TestBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestBeatmap.cs @@ -15,7 +15,7 @@ namespace osu.Game.Tests.Beatmaps { public TestBeatmap(RulesetInfo ruleset) { - var baseBeatmap = createTestBeatmap(); + var baseBeatmap = CreateBeatmap(); BeatmapInfo = baseBeatmap.BeatmapInfo; ControlPointInfo = baseBeatmap.ControlPointInfo; @@ -37,6 +37,8 @@ namespace osu.Game.Tests.Beatmaps }; } + protected virtual Beatmap CreateBeatmap() => createTestBeatmap(); + private static Beatmap createTestBeatmap() { using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(test_beatmap_data))) From d56accaef1ab193f33d214a16e53a56a8e22be49 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 15:32:51 +0900 Subject: [PATCH 0263/1142] Disallow negative / zero repeat counts (and fix off-by-one) --- .../Components/Timeline/TimelineHitObjectBlueprint.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 2ac35534f4..b2da1577d0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -119,7 +119,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline switch (hitObject) { case IHasRepeats repeatHitObject: - repeatHitObject.RepeatCount = (int)((time - hitObject.StartTime) / (repeatHitObject.Duration / repeatHitObject.RepeatCount)); + // find the number of repeats which can fit in the requested time. + var lengthOfOneRepeat = repeatHitObject.Duration / (repeatHitObject.RepeatCount + 1); + var proposedCount = (int)((time - hitObject.StartTime) / lengthOfOneRepeat) - 1; + + if (proposedCount == repeatHitObject.RepeatCount || proposedCount < 0) + return; + + repeatHitObject.RepeatCount = proposedCount; break; case IHasEndTime endTimeHitObject: From cef45afbc85eb24bad74f44d1e8d4c8d16913b86 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 15:33:04 +0900 Subject: [PATCH 0264/1142] Add a simple hover state --- .../Timeline/TimelineHitObjectBlueprint.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index b2da1577d0..8a6dd40bde 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -23,6 +23,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private readonly Container extensionBar; + protected override bool ShouldBeConsideredForInput(Drawable child) => true; + [UsedImplicitly] private readonly Bindable startTime; @@ -105,6 +107,45 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline }; } + protected override bool OnHover(HoverEvent e) + { + updateState(); + + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + updateState(); + base.OnHoverLost(e); + } + + private bool hasMouseDown; + + protected override bool OnMouseDown(MouseDownEvent e) + { + hasMouseDown = true; + updateState(); + return true; + } + + protected override void OnMouseUp(MouseUpEvent e) + { + hasMouseDown = false; + updateState(); + base.OnMouseUp(e); + } + + private void updateState() + { + if (IsHovered || hasMouseDown) + Colour = Color4.Orange; + else + { + Colour = Color4.White; + } + } + protected override bool OnDragStart(DragStartEvent e) => true; [Resolved] From 3d42973764434fbfe5359996e9edb270a56c759d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 15:58:35 +0900 Subject: [PATCH 0265/1142] Allow scrolling via drag while dragging a hold note handle --- .../Timeline/TimelineBlueprintContainer.cs | 40 ++++++++++++------- .../Timeline/TimelineHitObjectBlueprint.cs | 16 +++++++- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index 3b9cb1df24..9f3d776e5c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -49,20 +49,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override void OnDrag(DragEvent e) { - if (timeline != null) - { - var timelineQuad = timeline.ScreenSpaceDrawQuad; - var mouseX = e.ScreenSpaceMousePosition.X; - - // scroll if in a drag and dragging outside visible extents - if (mouseX > timelineQuad.TopRight.X) - timeline.ScrollBy((float)((mouseX - timelineQuad.TopRight.X) / 10 * Clock.ElapsedFrameTime)); - else if (mouseX < timelineQuad.TopLeft.X) - timeline.ScrollBy((float)((mouseX - timelineQuad.TopLeft.X) / 10 * Clock.ElapsedFrameTime)); - } + handleScrollViaDrag(e); base.OnDrag(e); - lastDragEvent = e; } protected override void OnDragEnd(DragEndEvent e) @@ -74,7 +63,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override void Update() { // trigger every frame so drags continue to update selection while playback is scrolling the timeline. - if (IsDragged) + if (lastDragEvent != null) OnDrag(lastDragEvent); base.Update(); @@ -82,10 +71,33 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override SelectionHandler CreateSelectionHandler() => new TimelineSelectionHandler(); - protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => new TimelineHitObjectBlueprint(hitObject); + protected override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) => new TimelineHitObjectBlueprint(hitObject) + { + OnDragHandled = handleScrollViaDrag + }; protected override DragBox CreateDragBox(Action performSelect) => new TimelineDragBox(performSelect); + private void handleScrollViaDrag(DragEvent e) + { + lastDragEvent = e; + + if (lastDragEvent == null) + return; + + if (timeline != null) + { + var timelineQuad = timeline.ScreenSpaceDrawQuad; + var mouseX = e.ScreenSpaceMousePosition.X; + + // scroll if in a drag and dragging outside visible extents + if (mouseX > timelineQuad.TopRight.X) + timeline.ScrollBy((float)((mouseX - timelineQuad.TopRight.X) / 10 * Clock.ElapsedFrameTime)); + else if (mouseX < timelineQuad.TopLeft.X) + timeline.ScrollBy((float)((mouseX - timelineQuad.TopLeft.X) / 10 * Clock.ElapsedFrameTime)); + } + } + internal class TimelineSelectionHandler : SelectionHandler { // for now we always allow movement. snapping is provided by the Timeline's "distance" snap implementation diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 8a6dd40bde..3de1cd3a4c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -28,6 +29,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [UsedImplicitly] private readonly Bindable startTime; + public Action OnDragHandled; + public const float THICKNESS = 5; private const float circle_size = 16; @@ -78,7 +81,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline RelativeSizeAxes = Axes.Both, } }, - new DragBar(hitObject), + new DragBar(hitObject) { OnDragHandled = e => OnDragHandled?.Invoke(e) } }); } } @@ -90,6 +93,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private Timeline timeline { get; set; } + public Action OnDragHandled; + public DragBar(HitObject hitObject) { this.hitObject = hitObject; @@ -155,6 +160,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { base.OnDrag(e); + OnDragHandled?.Invoke(e); + var time = timeline.GetTimeFromScreenSpacePosition(e.ScreenSpaceMousePosition); switch (hitObject) @@ -177,6 +184,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline beatmap.UpdateHitObject(hitObject); } + + protected override void OnDragEnd(DragEndEvent e) + { + base.OnDragEnd(e); + + OnDragHandled?.Invoke(null); + } } protected override void Update() From 98ab1f986272e89c0d092ec5cd01b726b74a4998 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 16:35:07 +0900 Subject: [PATCH 0266/1142] Fix negative spinners --- .../Components/Timeline/TimelineHitObjectBlueprint.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 3de1cd3a4c..5a15cb42fa 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -156,6 +156,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private EditorBeatmap beatmap { get; set; } + [Resolved] + private IBeatSnapProvider beatSnapProvider { get; set; } + protected override void OnDrag(DragEvent e) { base.OnDrag(e); @@ -178,7 +181,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline break; case IHasEndTime endTimeHitObject: - endTimeHitObject.EndTime = time; + var snappedTime = beatSnapProvider.SnapTime(time); + + if (endTimeHitObject.EndTime == snappedTime || snappedTime <= hitObject.StartTime) + return; + + endTimeHitObject.EndTime = snappedTime; break; } From cb30f463fb670d801a54044c6326f7b96e8a73ac Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 12:48:29 +0300 Subject: [PATCH 0267/1142] Update spotlight info based on selected one --- .../API/Requests/Responses/APISpotlight.cs | 3 +++ .../Rankings/RankingsOverlayHeader.cs | 10 +++++----- .../Overlays/Rankings/SpotlightSelector.cs | 19 +++++++++---------- osu.Game/Overlays/RankingsOverlay.cs | 10 +++++++--- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs index 3a002e57b2..4f63ebe3df 100644 --- a/osu.Game/Online/API/Requests/Responses/APISpotlight.cs +++ b/osu.Game/Online/API/Requests/Responses/APISpotlight.cs @@ -26,6 +26,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"end_date")] public DateTimeOffset EndDate; + [JsonProperty(@"participant_count")] + public int? Participants; + public override string ToString() => Name; } } diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 41722034b6..5c78879b26 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -20,8 +20,8 @@ namespace osu.Game.Overlays.Rankings public IEnumerable Spotlights { - get => spotlightSelector.Spotlights; - set => spotlightSelector.Spotlights = value; + get => SpotlightSelector.Spotlights; + set => SpotlightSelector.Spotlights = value; } protected override ScreenTitle CreateTitle() => new RankingsTitle @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Rankings Current = Ruleset }; - private SpotlightSelector spotlightSelector; + public SpotlightSelector SpotlightSelector; protected override Drawable CreateContent() => new FillFlowContainer { @@ -47,7 +47,7 @@ namespace osu.Game.Overlays.Rankings { Current = Country }, - spotlightSelector = new SpotlightSelector + SpotlightSelector = new SpotlightSelector { Current = { BindTarget = Spotlight } } @@ -61,7 +61,7 @@ namespace osu.Game.Overlays.Rankings } private void onCurrentChanged(ValueChangedEvent scope) => - spotlightSelector.FadeTo(scope.NewValue == RankingsScope.Spotlights ? 1 : 0, 200, Easing.OutQuint); + SpotlightSelector.FadeTo(scope.NewValue == RankingsScope.Spotlights ? 1 : 0, 200, Easing.OutQuint); private class RankingsTitle : ScreenTitle { diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index e34c01113e..bd2b7d9b21 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -38,6 +38,8 @@ namespace osu.Game.Overlays.Rankings private readonly InfoColumn startDateColumn; private readonly InfoColumn endDateColumn; + private readonly InfoColumn mapCountColumn; + private readonly InfoColumn participantsColumn; public SpotlightSelector() { @@ -75,6 +77,8 @@ namespace osu.Game.Overlays.Rankings { startDateColumn = new InfoColumn(@"Start Date"), endDateColumn = new InfoColumn(@"End Date"), + mapCountColumn = new InfoColumn(@"Map Count"), + participantsColumn = new InfoColumn(@"Participants") } } } @@ -88,17 +92,12 @@ namespace osu.Game.Overlays.Rankings background.Colour = colourProvider.Dark3; } - protected override void LoadComplete() + public void ShowInfo(APISpotlight spotlight, int mapCount) { - base.LoadComplete(); - - Current.BindValueChanged(onCurrentChanged); - } - - private void onCurrentChanged(ValueChangedEvent spotlight) - { - startDateColumn.Value = dateToString(spotlight.NewValue.StartDate); - endDateColumn.Value = dateToString(spotlight.NewValue.EndDate); + startDateColumn.Value = dateToString(spotlight.StartDate); + endDateColumn.Value = dateToString(spotlight.EndDate); + mapCountColumn.Value = mapCount.ToString(); + participantsColumn.Value = spotlight.Participants?.ToString("N0"); } private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 2a4bc28b18..ba0cc29d6d 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -36,6 +36,7 @@ namespace osu.Game.Overlays private APIRequest lastRequest; private CancellationTokenSource cancellationToken; + private GetSpotlightsRequest spotlightsRequest; [Resolved] private IAPIProvider api { get; set; } @@ -115,6 +116,8 @@ namespace osu.Game.Overlays Scope.BindValueChanged(_ => { + spotlightsRequest?.Cancel(); + // country filtering is only valid for performance scope. if (Scope.Value != RankingsScope.Performance) Country.Value = null; @@ -148,9 +151,9 @@ namespace osu.Game.Overlays private void getSpotlights() { loading.Show(); - var request = new GetSpotlightsRequest(); - request.Success += response => header.Spotlights = response.Spotlights; - api.Queue(request); + spotlightsRequest = new GetSpotlightsRequest(); + spotlightsRequest.Success += response => header.Spotlights = response.Spotlights; + api.Queue(spotlightsRequest); } private void loadNewContent() @@ -214,6 +217,7 @@ namespace osu.Game.Overlays return new CountriesTable(1, countryRequest.Result.Countries); case GetSpotlightRankingsRequest spotlightRequest: + header.SpotlightSelector.ShowInfo(spotlightRequest.Result.Spotlight, spotlightRequest.Result.BeatmapSets.Count); return new FillFlowContainer { AutoSizeAxes = Axes.Y, From 6708e271acd04336255c8c3aefa3e3ea8c2f17e7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 13:01:50 +0300 Subject: [PATCH 0268/1142] Adjust SpotlightSelector animations --- .../Rankings/RankingsOverlayHeader.cs | 2 +- .../Overlays/Rankings/SpotlightSelector.cs | 89 ++++++++++++------- 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 5c78879b26..538ae112b5 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -61,7 +61,7 @@ namespace osu.Game.Overlays.Rankings } private void onCurrentChanged(ValueChangedEvent scope) => - SpotlightSelector.FadeTo(scope.NewValue == RankingsScope.Spotlights ? 1 : 0, 200, Easing.OutQuint); + SpotlightSelector.State.Value = scope.NewValue == RankingsScope.Spotlights ? Visibility.Visible : Visibility.Hidden; private class RankingsTitle : ScreenTitle { diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index bd2b7d9b21..8af6c0bb3b 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -17,8 +17,11 @@ using osu.Framework.Graphics.UserInterface; namespace osu.Game.Overlays.Rankings { - public class SpotlightSelector : CompositeDrawable, IHasCurrentValue + public class SpotlightSelector : VisibilityContainer, IHasCurrentValue { + private const int height = 100; + private const int duration = 200; + private readonly Box background; private readonly SpotlightsDropdown dropdown; @@ -36,54 +39,60 @@ namespace osu.Game.Overlays.Rankings set => dropdown.Items = value; } + protected override bool StartHidden => true; + private readonly InfoColumn startDateColumn; private readonly InfoColumn endDateColumn; private readonly InfoColumn mapCountColumn; private readonly InfoColumn participantsColumn; + private readonly Container content; public SpotlightSelector() { RelativeSizeAxes = Axes.X; - Height = 100; - - InternalChildren = new Drawable[] + Add(content = new Container { - background = new Box + Height = height, + RelativeSizeAxes = Axes.X, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, - Children = new Drawable[] + background = new Box { - dropdown = new SpotlightsDropdown + RelativeSizeAxes = Axes.Both, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Children = new Drawable[] { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Current = Current, - Depth = -float.MaxValue - }, - new FillFlowContainer - { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(15, 0), - Children = new Drawable[] + dropdown = new SpotlightsDropdown { - startDateColumn = new InfoColumn(@"Start Date"), - endDateColumn = new InfoColumn(@"End Date"), - mapCountColumn = new InfoColumn(@"Map Count"), - participantsColumn = new InfoColumn(@"Participants") + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Current = Current, + Depth = -float.MaxValue + }, + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(15, 0), + Children = new Drawable[] + { + startDateColumn = new InfoColumn(@"Start Date"), + endDateColumn = new InfoColumn(@"End Date"), + mapCountColumn = new InfoColumn(@"Map Count"), + participantsColumn = new InfoColumn(@"Participants") + } } } - } - }, - }; + }, + } + }); } [BackgroundDependencyLoader] @@ -100,6 +109,18 @@ namespace osu.Game.Overlays.Rankings participantsColumn.Value = spotlight.Participants?.ToString("N0"); } + protected override void PopIn() + { + this.ResizeHeightTo(height, duration, Easing.OutQuint); + content.FadeIn(duration, Easing.OutQuint); + } + + protected override void PopOut() + { + this.ResizeHeightTo(0, duration, Easing.OutQuint); + content.FadeOut(duration, Easing.OutQuint); + } + private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); private class InfoColumn : FillFlowContainer From 00e010a06151a085636dcdfa5fbae2167470780e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 13:11:02 +0300 Subject: [PATCH 0269/1142] Add visibility test for SpotlightSelector --- .../Visual/Online/TestSceneRankingsSpotlightSelector.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index e46c8a4a71..f27ab1e775 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -35,6 +35,12 @@ namespace osu.Game.Tests.Visual.Online Add(selector = new SpotlightSelector()); } + [Test] + public void TestVisibility() + { + AddStep("Toggle Visibility", selector.ToggleVisibility); + } + [Test] public void TestLocalSpotlights() { From f5edad16e67d3a9151dd0118f11d5b48bf4c2e91 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 5 Feb 2020 19:43:13 +0900 Subject: [PATCH 0270/1142] Improve visuals --- .../Timeline/TimelineHitObjectBlueprint.cs | 184 ++++++++++++------ 1 file changed, 125 insertions(+), 59 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 5a15cb42fa..b46a373818 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -2,14 +2,17 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -22,8 +25,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { private readonly Circle circle; - private readonly Container extensionBar; - protected override bool ShouldBeConsideredForInput(Drawable child) => true; [UsedImplicitly] @@ -31,11 +32,20 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public Action OnDragHandled; - public const float THICKNESS = 5; + private readonly DragBar dragBar; + + private readonly List shadowComponents = new List(); + + private const float thickness = 5; + + private const float shadow_radius = 5; private const float circle_size = 16; - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => base.ReceivePositionalInputAt(screenSpacePos) || circle.ReceivePositionalInputAt(screenSpacePos); + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + base.ReceivePositionalInputAt(screenSpacePos) || + circle.ReceivePositionalInputAt(screenSpacePos) || + dragBar?.ReceivePositionalInputAt(screenSpacePos) == true; public TimelineHitObjectBlueprint(HitObject hitObject) : base(hitObject) @@ -51,7 +61,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - AddInternal(circle = new Circle + circle = new Circle { Size = new Vector2(circle_size), Anchor = Anchor.CentreLeft, @@ -59,34 +69,126 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline RelativePositionAxes = Axes.X, AlwaysPresent = true, Colour = Color4.White, - BorderColour = Color4.Black, - BorderThickness = THICKNESS, - }); + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = shadow_radius, + Colour = Color4.Black + }, + }; + + shadowComponents.Add(circle); if (hitObject is IHasEndTime) { + DragBar dragBarUnderlay; + Container extensionBar; + AddRangeInternal(new Drawable[] { extensionBar = new Container { - CornerRadius = 2, Masking = true, - Size = new Vector2(1, THICKNESS), + Size = new Vector2(1, thickness), Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, RelativePositionAxes = Axes.X, RelativeSizeAxes = Axes.X, + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = shadow_radius, + Colour = Color4.Black + }, Child = new Box { RelativeSizeAxes = Axes.Both, } }, - new DragBar(hitObject) { OnDragHandled = e => OnDragHandled?.Invoke(e) } + circle, + // only used for drawing the shadow + dragBarUnderlay = new DragBar(null), + // cover up the shadow on the join + new Box + { + Height = thickness, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + }, + dragBar = new DragBar(hitObject) { OnDragHandled = e => OnDragHandled?.Invoke(e) }, }); + + shadowComponents.Add(dragBarUnderlay); + shadowComponents.Add(extensionBar); + } + else + { + AddInternal(circle); + } + + updateShadows(); + } + + protected override void Update() + { + base.Update(); + + // no bindable so we perform this every update + Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); + } + + protected override void OnSelected() + { + updateShadows(); + } + + private void updateShadows() + { + foreach (var s in shadowComponents) + { + if (State == SelectionState.Selected) + { + s.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = shadow_radius / 2, + Colour = Color4.Orange, + }; + } + else + { + s.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Radius = shadow_radius, + Colour = State == SelectionState.Selected ? Color4.Orange : Color4.Black + }; + } } } - public class DragBar : CompositeDrawable + protected override void OnDeselected() + { + updateShadows(); + } + + public override Quad SelectionQuad + { + get + { + // correctly include the circle in the selection quad region, as it is usually outside the blueprint itself. + var leftQuad = circle.ScreenSpaceDrawQuad; + var rightQuad = dragBar?.ScreenSpaceDrawQuad ?? ScreenSpaceDrawQuad; + + return new Quad(leftQuad.TopLeft, Vector2.ComponentMax(rightQuad.TopRight, leftQuad.TopRight), + leftQuad.BottomLeft, Vector2.ComponentMax(rightQuad.BottomRight, leftQuad.BottomRight)); + } + } + + public override Vector2 SelectionPoint => ScreenSpaceDrawQuad.TopLeft; + + public class DragBar : Container { private readonly HitObject hitObject; @@ -95,20 +197,26 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public Action OnDragHandled; + public override bool HandlePositionalInput => hitObject != null; + public DragBar(HitObject hitObject) { this.hitObject = hitObject; CornerRadius = 2; Masking = true; - Size = new Vector2(THICKNESS, 1.5f); + Size = new Vector2(5, 1); Anchor = Anchor.CentreRight; - Origin = Anchor.CentreRight; + Origin = Anchor.Centre; RelativePositionAxes = Axes.X; RelativeSizeAxes = Axes.Y; - InternalChild = new Box + + InternalChildren = new Drawable[] { - RelativeSizeAxes = Axes.Both, + new Box + { + RelativeSizeAxes = Axes.Both, + } }; } @@ -143,12 +251,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private void updateState() { - if (IsHovered || hasMouseDown) - Colour = Color4.Orange; - else - { - Colour = Color4.White; - } + Colour = IsHovered || hasMouseDown ? Color4.OrangeRed : Color4.White; } protected override bool OnDragStart(DragStartEvent e) => true; @@ -200,42 +303,5 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline OnDragHandled?.Invoke(null); } } - - protected override void Update() - { - base.Update(); - - // no bindable so we perform this every update - Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); - } - - protected override void OnSelected() - { - circle.BorderColour = Color4.Orange; - if (extensionBar != null) - extensionBar.BorderColour = Color4.Orange; - } - - protected override void OnDeselected() - { - circle.BorderColour = Color4.Black; - if (extensionBar != null) - extensionBar.BorderColour = Color4.Black; - } - - public override Quad SelectionQuad - { - get - { - // correctly include the circle in the selection quad region, as it is usually outside the blueprint itself. - var circleQuad = circle.ScreenSpaceDrawQuad; - var actualQuad = ScreenSpaceDrawQuad; - - return new Quad(circleQuad.TopLeft, Vector2.ComponentMax(actualQuad.TopRight, circleQuad.TopRight), - circleQuad.BottomLeft, Vector2.ComponentMax(actualQuad.BottomRight, circleQuad.BottomRight)); - } - } - - public override Vector2 SelectionPoint => ScreenSpaceDrawQuad.TopLeft; } } From f4ee281dd6474552d935bda91234daf6c575d5ba Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 5 Feb 2020 16:15:55 +0100 Subject: [PATCH 0271/1142] Add optional decimal place --- osu.Game/Overlays/BeatmapSet/SuccessRate.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs index dac750dacf..15216b6e69 100644 --- a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs @@ -42,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapSet int playCount = beatmap?.OnlineInfo?.PlayCount ?? 0; var rate = playCount != 0 ? (float)passCount / playCount : 0; - successPercent.Text = rate.ToString("0%"); + successPercent.Text = rate.ToString("0.#%"); successRate.Length = rate; percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic); From 76037e4ffddab6a219219b8a909209dcb06a002f Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 5 Feb 2020 16:31:14 +0100 Subject: [PATCH 0272/1142] Recolour ranked status pill --- .../Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs | 9 ++++++++- osu.Game/Overlays/BeatmapSet/Header.cs | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs index 351e5df17a..f6e03d40ff 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetOnlineStatusPill.cs @@ -13,6 +13,7 @@ namespace osu.Game.Beatmaps.Drawables public class BeatmapSetOnlineStatusPill : CircularContainer { private readonly OsuSpriteText statusText; + private readonly Box background; private BeatmapSetOnlineStatus status; @@ -43,6 +44,12 @@ namespace osu.Game.Beatmaps.Drawables set => statusText.Padding = value; } + public Color4 BackgroundColour + { + get => background.Colour; + set => background.Colour = value; + } + public BeatmapSetOnlineStatusPill() { AutoSizeAxes = Axes.Both; @@ -50,7 +57,7 @@ namespace osu.Game.Beatmaps.Drawables Children = new Drawable[] { - new Box + background = new Box { RelativeSizeAxes = Axes.Both, Colour = Color4.Black, diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 9f79b92cb6..1b111ced1f 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -218,6 +218,7 @@ namespace osu.Game.Overlays.BeatmapSet private void load(OverlayColourProvider colourProvider) { coverGradient.Colour = ColourInfo.GradientVertical(colourProvider.Background6.Opacity(0.3f), colourProvider.Background6.Opacity(0.8f)); + onlineStatusPill.BackgroundColour = colourProvider.Background6; State.BindValueChanged(_ => updateDownloadButtons()); From e1e1c1a11af6a8397b43d250d0fba0edcb0268b2 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 5 Feb 2020 16:34:39 +0100 Subject: [PATCH 0273/1142] Match osu-web display accuracy Decided to change this only locally instead of modifying FormatAccuracy which would affect everywhere else in the game as well. --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index f04477d911..9c71cabfa6 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -120,7 +120,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new OsuSpriteText { Margin = new MarginPadding { Right = horizontal_inset }, - Text = score.DisplayAccuracy, + Text = $@"{score.Accuracy:0.00%}", Font = OsuFont.GetFont(size: text_size), Colour = score.Accuracy == 1 ? highAccuracyColour : Color4.White }, From fa3934ddb474b605b3147a364f43ce968984f7b5 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 5 Feb 2020 17:16:20 +0100 Subject: [PATCH 0274/1142] Match osu-web button description --- osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs index e0360c6312..5ed15cecd5 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs @@ -150,7 +150,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons }, new OsuSpriteText { - Text = BeatmapSet.Value.OnlineInfo.HasVideo && noVideo ? "without Video" : string.Empty, + Text = BeatmapSet.Value.OnlineInfo.HasVideo ? (noVideo ? "without Video" : "with Video") : string.Empty, Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold) }, }; From e79ba9a1299fc54728d9762af30e5e38a02f0e4b Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 5 Feb 2020 17:41:57 +0100 Subject: [PATCH 0275/1142] Add alwaysShowDecimals param to FormatAccuracy This allows us to specify whether we want it to show decimal places if accuracy is 100%. --- osu.Game/Utils/FormatUtils.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index b3758b3375..f0b8b470f1 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -7,18 +7,18 @@ namespace osu.Game.Utils { /// /// Turns the provided accuracy into a percentage with 2 decimal places. - /// Omits all decimal places when equals 1d. /// /// The accuracy to be formatted + /// Whether to show decimal places if equals 1d /// formatted accuracy in percentage - public static string FormatAccuracy(this double accuracy) => accuracy == 1 ? "100%" : $"{accuracy:0.00%}"; + public static string FormatAccuracy(this double accuracy, bool alwaysShowDecimals = false) => accuracy == 1 && !alwaysShowDecimals ? "100%" : $"{accuracy:0.00%}"; /// /// Turns the provided accuracy into a percentage with 2 decimal places. - /// Omits all decimal places when equals 100m. /// /// The accuracy to be formatted + /// Whether to show decimal places if equals 100m /// formatted accuracy in percentage - public static string FormatAccuracy(this decimal accuracy) => accuracy == 100 ? "100%" : $"{accuracy:0.00}%"; + public static string FormatAccuracy(this decimal accuracy, bool alwaysShowDecimals = false) => accuracy == 100 && !alwaysShowDecimals ? "100%" : $"{accuracy:0.00}%"; } } From 63df6b8da6255116b7c6fe25df8c5d09fe797cc3 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 5 Feb 2020 17:42:14 +0100 Subject: [PATCH 0276/1142] Change accuracy formatting method --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 9c71cabfa6..4d5bd84090 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -16,6 +16,7 @@ using osu.Game.Scoring; using osu.Game.Users.Drawables; using osuTK; using osuTK.Graphics; +using osu.Game.Utils; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -120,7 +121,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new OsuSpriteText { Margin = new MarginPadding { Right = horizontal_inset }, - Text = $@"{score.Accuracy:0.00%}", + Text = score.Accuracy.FormatAccuracy(alwaysShowDecimals: true), Font = OsuFont.GetFont(size: text_size), Colour = score.Accuracy == 1 ? highAccuracyColour : Color4.White }, From c93d2c7f00240ec8126732e801c66389f041457b Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 5 Feb 2020 18:26:01 +0100 Subject: [PATCH 0277/1142] Adjust loading container corner radius --- osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 0a3b5d9457..8560232209 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -164,7 +164,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { RelativeSizeAxes = Axes.Both, Masking = true, - CornerRadius = 10, + CornerRadius = 5, Child = loading = new DimmedLoadingLayer(iconScale: 0.8f) { Alpha = 0, From 24e8a2bd6920cae69a957c807c60648bd9c7ea86 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 22:59:01 +0300 Subject: [PATCH 0278/1142] Make SpotlightSelector.ShowInfo use the full rankings response --- osu.Game/Overlays/Rankings/SpotlightSelector.cs | 11 ++++++----- osu.Game/Overlays/RankingsOverlay.cs | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 8af6c0bb3b..8bf75b2357 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -14,6 +14,7 @@ using osuTK; using System; using System.Collections.Generic; using osu.Framework.Graphics.UserInterface; +using osu.Game.Online.API.Requests; namespace osu.Game.Overlays.Rankings { @@ -101,12 +102,12 @@ namespace osu.Game.Overlays.Rankings background.Colour = colourProvider.Dark3; } - public void ShowInfo(APISpotlight spotlight, int mapCount) + public void ShowInfo(GetSpotlightRankingsResponse response) { - startDateColumn.Value = dateToString(spotlight.StartDate); - endDateColumn.Value = dateToString(spotlight.EndDate); - mapCountColumn.Value = mapCount.ToString(); - participantsColumn.Value = spotlight.Participants?.ToString("N0"); + startDateColumn.Value = dateToString(response.Spotlight.StartDate); + endDateColumn.Value = dateToString(response.Spotlight.EndDate); + mapCountColumn.Value = response.BeatmapSets.Count.ToString(); + participantsColumn.Value = response.Spotlight.Participants?.ToString("N0"); } protected override void PopIn() diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index ba0cc29d6d..99e81eef15 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -217,7 +217,7 @@ namespace osu.Game.Overlays return new CountriesTable(1, countryRequest.Result.Countries); case GetSpotlightRankingsRequest spotlightRequest: - header.SpotlightSelector.ShowInfo(spotlightRequest.Result.Spotlight, spotlightRequest.Result.BeatmapSets.Count); + header.SpotlightSelector.ShowInfo(spotlightRequest.Result); return new FillFlowContainer { AutoSizeAxes = Axes.Y, From 4dd25b42aeee0fb158dcdb05ab128733332842f5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 23:00:42 +0300 Subject: [PATCH 0279/1142] Move spotlightsRequest to another place --- osu.Game/Overlays/RankingsOverlay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 99e81eef15..084c8b6e5a 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -36,7 +36,6 @@ namespace osu.Game.Overlays private APIRequest lastRequest; private CancellationTokenSource cancellationToken; - private GetSpotlightsRequest spotlightsRequest; [Resolved] private IAPIProvider api { get; set; } @@ -148,6 +147,8 @@ namespace osu.Game.Overlays Country.Value = requested; } + private GetSpotlightsRequest spotlightsRequest; + private void getSpotlights() { loading.Show(); From 7757a3a30bb7cfe33c0def5fe4489cddf7949796 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 5 Feb 2020 23:06:13 +0300 Subject: [PATCH 0280/1142] Move spotlight layout to it's own method --- osu.Game/Overlays/RankingsOverlay.cs | 52 ++++++++++++++++------------ 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 084c8b6e5a..4fc94420a4 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -218,34 +218,40 @@ namespace osu.Game.Overlays return new CountriesTable(1, countryRequest.Result.Countries); case GetSpotlightRankingsRequest spotlightRequest: - header.SpotlightSelector.ShowInfo(spotlightRequest.Result); - return new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - new ScoresTable(1, spotlightRequest.Result.Users), - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Spacing = new Vector2(10), - Children = spotlightRequest.Result.BeatmapSets.Select(b => new DirectGridPanel(b.ToBeatmapSet(rulesets)) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }).ToList() - } - } - }; + return getSpotlightContent(spotlightRequest.Result); } return null; } + private Drawable getSpotlightContent(GetSpotlightRankingsResponse response) + { + header.SpotlightSelector.ShowInfo(response); + + return new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + new ScoresTable(1, response.Users), + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Spacing = new Vector2(10), + Children = response.BeatmapSets.Select(b => new DirectGridPanel(b.ToBeatmapSet(rulesets)) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }).ToList() + } + } + }; + } + private void loadContent(Drawable content) { scrollFlow.ScrollToStart(); From 00edc7e66fd527d87f7ec2a80751544e863aec12 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 12:12:52 +0900 Subject: [PATCH 0281/1142] Fix RoomsContainer test scene not displaying --- .../Multi/Lounge/Components/RoomsContainer.cs | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 607b081653..6ef0f6b6db 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -47,22 +47,13 @@ namespace osu.Game.Screens.Multi.Lounge.Components }; } - [BackgroundDependencyLoader] - private void load() - { - rooms.BindTo(roomManager.Rooms); - - rooms.ItemsAdded += addRooms; - rooms.ItemsRemoved += removeRooms; - - roomManager.RoomsUpdated += updateSorting; - - addRooms(rooms); - } - protected override void LoadComplete() { - filter?.BindValueChanged(f => Filter(f.NewValue), true); + rooms.ItemsAdded += addRooms; + rooms.ItemsRemoved += removeRooms; + roomManager.RoomsUpdated += updateSorting; + + rooms.BindTo(roomManager.Rooms); } public void Filter(FilterCriteria criteria) @@ -94,8 +85,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components foreach (var r in rooms) roomFlow.Add(new DrawableRoom(r) { Action = () => selectRoom(r) }); - if (filter != null) - Filter(filter.Value); + Filter(filter?.Value); } private void removeRooms(IEnumerable rooms) From 7f0a134bc8c55ec7dac0dac6daf4c5e48ef6936c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 12:17:05 +0900 Subject: [PATCH 0282/1142] Bring test scene structure up-to-date --- .../Multiplayer/TestSceneLoungeRoomsContainer.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index eb4dc909df..cb873fc3eb 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -27,11 +28,11 @@ namespace osu.Game.Tests.Visual.Multiplayer [Cached(Type = typeof(IRoomManager))] private TestRoomManager roomManager = new TestRoomManager(); + private RoomsContainer container; + [BackgroundDependencyLoader] private void load() { - RoomsContainer container; - Child = container = new RoomsContainer { Anchor = Anchor.Centre, @@ -39,9 +40,18 @@ namespace osu.Game.Tests.Visual.Multiplayer Width = 0.5f, JoinRequested = joinRequested }; + } + + public override void SetUpSteps() + { + base.SetUpSteps(); AddStep("clear rooms", () => roomManager.Rooms.Clear()); + } + [Test] + public void TestBasicListChanges() + { AddStep("add rooms", () => { for (int i = 0; i < 3; i++) From 50c4e34c92091616053871ae652e11f10a7800e5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 11:56:09 +0900 Subject: [PATCH 0283/1142] Add ruleset to multiplayer filter criteria --- osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs | 8 +++++++- .../Screens/Multi/Lounge/Components/FilterCriteria.cs | 3 +++ .../Screens/Multi/Lounge/Components/RoomsContainer.cs | 3 +++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index 29d41132a7..9f93afec9d 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Overlays.SearchableList; +using osu.Game.Rulesets; using osuTK.Graphics; namespace osu.Game.Screens.Multi.Lounge.Components @@ -22,6 +23,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components [Resolved(CanBeNull = true)] private Bindable filter { get; set; } + [Resolved] + private IBindable ruleset { get; set; } + public FilterControl() { DisplayStyleControl.Hide(); @@ -38,6 +42,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components { base.LoadComplete(); + ruleset.BindValueChanged(_ => updateFilter()); Search.Current.BindValueChanged(_ => scheduleUpdateFilter()); Tabs.Current.BindValueChanged(_ => updateFilter(), true); } @@ -58,7 +63,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components { SearchString = Search.Current.Value ?? string.Empty, PrimaryFilter = Tabs.Current.Value, - SecondaryFilter = DisplayStyleControl.Dropdown.Current.Value + SecondaryFilter = DisplayStyleControl.Dropdown.Current.Value, + Ruleset = ruleset.Value }; } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs index 666bc44a8d..26d445e151 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterCriteria.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 osu.Game.Rulesets; + namespace osu.Game.Screens.Multi.Lounge.Components { public class FilterCriteria @@ -8,5 +10,6 @@ namespace osu.Game.Screens.Multi.Lounge.Components public string SearchString; public PrimaryFilter PrimaryFilter; public SecondaryFilter SecondaryFilter; + public RulesetInfo Ruleset; } } diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 6ef0f6b6db..f5e0e2bbee 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -65,6 +65,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components else { bool matchingFilter = true; + + matchingFilter &= r.Room.Playlist.Any(i => i.Ruleset.Equals(criteria.Ruleset)); + matchingFilter &= r.FilterTerms.Any(term => term.IndexOf(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase) >= 0); switch (criteria.SecondaryFilter) From 304a071e39578def381a4edc9b5c6638d2c9f613 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 11:56:20 +0900 Subject: [PATCH 0284/1142] Remove leasing at a Multiplayer screen level --- osu.Game/Screens/Multi/Multiplayer.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 9d6a459d14..72bf5a37e8 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -32,8 +32,6 @@ namespace osu.Game.Screens.Multi { public override bool CursorVisible => (screenStack.CurrentScreen as IMultiplayerSubScreen)?.CursorVisible ?? true; - public override bool DisallowExternalBeatmapRulesetChanges => true; - private readonly MultiplayerWaveContainer waves; private readonly OsuButton createButton; @@ -277,11 +275,7 @@ namespace osu.Game.Screens.Multi private void updateTrack(ValueChangedEvent _ = null) { - bool isMatch = screenStack.CurrentScreen is MatchSubScreen; - - Beatmap.Disabled = isMatch; - - if (isMatch) + if (screenStack.CurrentScreen is MatchSubScreen) { var track = Beatmap.Value?.Track; From a79d6ff27a68b6a9dd5b3abc901451b30dab3bd5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 11:59:33 +0900 Subject: [PATCH 0285/1142] Change transition to better handle mass filter cases --- osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs index f6cbe300f3..d45dac1ae6 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/DrawableRoom.cs @@ -75,8 +75,13 @@ namespace osu.Game.Screens.Multi.Lounge.Components { matchingFilter = value; - if (IsLoaded) - this.FadeTo(MatchingFilter ? 1 : 0, 200); + if (!IsLoaded) + return; + + if (matchingFilter) + this.FadeIn(200); + else + Hide(); } } From 1dc7fc4a33aee7e68dcc25789892d49cb69caa2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 12:26:14 +0900 Subject: [PATCH 0286/1142] Fix case where playlist is empty --- osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index f5e0e2bbee..a5881cc2f7 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -66,7 +66,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components { bool matchingFilter = true; - matchingFilter &= r.Room.Playlist.Any(i => i.Ruleset.Equals(criteria.Ruleset)); + matchingFilter &= r.Room.Playlist.Count == 0 || r.Room.Playlist.Any(i => i.Ruleset.Equals(criteria.Ruleset)); matchingFilter &= r.FilterTerms.Any(term => term.IndexOf(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase) >= 0); From d32bb79e5a7bb3a78bc670f35cf074a6c2a656a4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 12:26:08 +0900 Subject: [PATCH 0287/1142] Add simple filtering test --- .../TestSceneLoungeRoomsContainer.cs | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index cb873fc3eb..8bc780f4e0 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -51,10 +51,42 @@ namespace osu.Game.Tests.Visual.Multiplayer [Test] public void TestBasicListChanges() + { + addRooms(3); + + AddAssert("has 3 rooms", () => container.Rooms.Count == 3); + AddStep("remove first room", () => roomManager.Rooms.Remove(roomManager.Rooms.FirstOrDefault())); + AddAssert("has 2 rooms", () => container.Rooms.Count == 2); + AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0)); + + AddStep("select first room", () => container.Rooms.First().Action?.Invoke()); + AddAssert("first room selected", () => Room == roomManager.Rooms.First()); + + AddStep("join first room", () => container.Rooms.First().Action?.Invoke()); + AddAssert("first room joined", () => roomManager.Rooms.First().Status.Value is JoinedRoomStatus); + } + + [Test] + public void TestStringFiltering() + { + addRooms(4); + + AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4); + + AddStep("filter one room", () => container.Filter(new FilterCriteria { SearchString = "1" })); + + AddUntilStep("1 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 1); + + AddStep("remove filter", () => container.Filter(null)); + + AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4); + } + + private void addRooms(int count) { AddStep("add rooms", () => { - for (int i = 0; i < 3; i++) + for (int i = 0; i < count; i++) { roomManager.Rooms.Add(new Room { @@ -65,17 +97,6 @@ namespace osu.Game.Tests.Visual.Multiplayer }); } }); - - AddAssert("has 2 rooms", () => container.Rooms.Count == 3); - AddStep("remove first room", () => roomManager.Rooms.Remove(roomManager.Rooms.FirstOrDefault())); - AddAssert("has 2 rooms", () => container.Rooms.Count == 2); - AddAssert("first room removed", () => container.Rooms.All(r => r.Room.RoomID.Value != 0)); - - AddStep("select first room", () => container.Rooms.First().Action?.Invoke()); - AddAssert("first room selected", () => Room == roomManager.Rooms.First()); - - AddStep("join first room", () => container.Rooms.First().Action?.Invoke()); - AddAssert("first room joined", () => roomManager.Rooms.First().Status.Value is JoinedRoomStatus); } private void joinRequested(Room room) => room.Status.Value = new JoinedRoomStatus(); From 061b8c389fa12112f17071e5044de143f187a999 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 13:02:38 +0900 Subject: [PATCH 0288/1142] Fix null search string causing an exception --- osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index a5881cc2f7..88cc348000 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -68,7 +68,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components matchingFilter &= r.Room.Playlist.Count == 0 || r.Room.Playlist.Any(i => i.Ruleset.Equals(criteria.Ruleset)); - matchingFilter &= r.FilterTerms.Any(term => term.IndexOf(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase) >= 0); + if (!string.IsNullOrEmpty(criteria.SearchString)) + matchingFilter &= r.FilterTerms.Any(term => term.IndexOf(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase) >= 0); switch (criteria.SecondaryFilter) { From 43b22e3b63d9480e0a20b8f83ff3420577f575bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 13:03:15 +0900 Subject: [PATCH 0289/1142] Add a ruleset filtering test --- .../TestSceneLoungeRoomsContainer.cs | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index 8bc780f4e0..af02f1e514 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -8,8 +8,12 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Osu; using osu.Game.Screens.Multi; using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Users; @@ -82,19 +86,48 @@ namespace osu.Game.Tests.Visual.Multiplayer AddUntilStep("4 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 4); } - private void addRooms(int count) + [Test] + public void TestRulesetFiltering() + { + addRooms(2, new OsuRuleset().RulesetInfo); + addRooms(3, new CatchRuleset().RulesetInfo); + + AddUntilStep("5 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 5); + + AddStep("filter osu! rooms", () => container.Filter(new FilterCriteria { Ruleset = new OsuRuleset().RulesetInfo })); + + AddUntilStep("2 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 2); + + AddStep("filter catch rooms", () => container.Filter(new FilterCriteria { Ruleset = new CatchRuleset().RulesetInfo })); + + AddUntilStep("3 rooms visible", () => container.Rooms.Count(r => r.IsPresent) == 3); + } + + private void addRooms(int count, RulesetInfo ruleset = null) { AddStep("add rooms", () => { for (int i = 0; i < count; i++) { - roomManager.Rooms.Add(new Room + var room = new Room { RoomID = { Value = i }, Name = { Value = $"Room {i}" }, Host = { Value = new User { Username = "Host" } }, EndDate = { Value = DateTimeOffset.Now + TimeSpan.FromSeconds(10) } - }); + }; + + if (ruleset != null) + room.Playlist.Add(new PlaylistItem + { + Ruleset = ruleset, + Beatmap = new BeatmapInfo + { + Metadata = new BeatmapMetadata() + } + }); + + roomManager.Rooms.Add(room); } }); } From 49ec1d4a9938e02f07b24a1167e08efd391612d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 13:04:29 +0900 Subject: [PATCH 0290/1142] Fix braces style --- .../Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index af02f1e514..fe14a1ff0a 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -118,6 +118,7 @@ namespace osu.Game.Tests.Visual.Multiplayer }; if (ruleset != null) + { room.Playlist.Add(new PlaylistItem { Ruleset = ruleset, @@ -126,6 +127,7 @@ namespace osu.Game.Tests.Visual.Multiplayer Metadata = new BeatmapMetadata() } }); + } roomManager.Rooms.Add(room); } From daf5fa9da4ade1124f75a250e0c1c8964372fe16 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 13:16:32 +0900 Subject: [PATCH 0291/1142] Throw NotSupportedException instead --- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +- osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 4d68bf592c..b014b32305 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.Catch.Objects public double EndTime { get => StartTime + this.SpanCount() * Path.Distance / Velocity; - set => throw new System.NotImplementedException(); + set => throw new System.NotSupportedException($"Adjust via {nameof(RepeatCount)} instead"); // can be implemented if/when needed. } public float EndX => X + this.CurvePositionAt(1).X / CatchPlayfield.BASE_WIDTH; diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index bab7e6dbee..95fb6d9d48 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Objects public double EndTime { get => StartTime + this.SpanCount() * Path.Distance / Velocity; - set => throw new System.NotImplementedException(); + set => throw new System.NotSupportedException($"Adjust via {nameof(RepeatCount)} instead"); // can be implemented if/when needed. } public double Duration => EndTime - StartTime; diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index b5cd9be245..53cdf457c4 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public double EndTime { get => StartTime + this.SpanCount() * Distance / Velocity; - set => throw new System.NotImplementedException(); + set => throw new System.NotSupportedException($"Adjust via {nameof(RepeatCount)} instead"); // can be implemented if/when needed. } public double Duration => EndTime - StartTime; From e548a4b8ddba4b6c90dfdab0935715a5da008341 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 13:36:49 +0900 Subject: [PATCH 0292/1142] Fix missing bind causing regression in filter --- osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 88cc348000..e306706be9 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -54,6 +54,8 @@ namespace osu.Game.Screens.Multi.Lounge.Components roomManager.RoomsUpdated += updateSorting; rooms.BindTo(roomManager.Rooms); + + filter.BindValueChanged(criteria => Filter(criteria.NewValue)); } public void Filter(FilterCriteria criteria) From 114fd967c190988dab88aca1fc0f3eea0bcf9627 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 13:47:34 +0900 Subject: [PATCH 0293/1142] Revert "Remove leasing at a Multiplayer screen level" This reverts commit 304a071e39578def381a4edc9b5c6638d2c9f613. --- osu.Game/Screens/Multi/Multiplayer.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 72bf5a37e8..9d6a459d14 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -32,6 +32,8 @@ namespace osu.Game.Screens.Multi { public override bool CursorVisible => (screenStack.CurrentScreen as IMultiplayerSubScreen)?.CursorVisible ?? true; + public override bool DisallowExternalBeatmapRulesetChanges => true; + private readonly MultiplayerWaveContainer waves; private readonly OsuButton createButton; @@ -275,7 +277,11 @@ namespace osu.Game.Screens.Multi private void updateTrack(ValueChangedEvent _ = null) { - if (screenStack.CurrentScreen is MatchSubScreen) + bool isMatch = screenStack.CurrentScreen is MatchSubScreen; + + Beatmap.Disabled = isMatch; + + if (isMatch) { var track = Beatmap.Value?.Track; From 81cadb787569559fe22e058c59b8f456443136bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 14:22:01 +0900 Subject: [PATCH 0294/1142] Simplify the way multiple subscreens handle their disable states via a custom stack --- .../Screens/Multi/Lounge/LoungeSubScreen.cs | 24 ++++++++++++------- osu.Game/Screens/Multi/Multiplayer.cs | 10 ++++---- .../Multi/MultiplayerSubScreenStack.cs | 24 +++++++++++++++++++ osu.Game/Screens/OsuScreenStack.cs | 6 ++--- osu.Game/Screens/Select/MatchSongSelect.cs | 13 ---------- 5 files changed, 47 insertions(+), 30 deletions(-) create mode 100644 osu.Game/Screens/Multi/MultiplayerSubScreenStack.cs diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index 0a48f761cf..3709b85fcb 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -91,6 +91,22 @@ namespace osu.Game.Screens.Multi.Lounge public override void OnEntering(IScreen last) { base.OnEntering(last); + + onReturning(); + } + + public override void OnResuming(IScreen last) + { + base.OnResuming(last); + + if (currentRoom.Value?.RoomID.Value == null) + currentRoom.Value = new Room(); + + onReturning(); + } + + private void onReturning() + { Filter.Search.HoldFocus = true; } @@ -106,14 +122,6 @@ namespace osu.Game.Screens.Multi.Lounge Filter.Search.HoldFocus = false; } - public override void OnResuming(IScreen last) - { - base.OnResuming(last); - - if (currentRoom.Value?.RoomID.Value == null) - currentRoom.Value = new Room(); - } - private void joinRequested(Room room) { processingOverlay.Show(); diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 9d6a459d14..2277157134 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -32,6 +32,8 @@ namespace osu.Game.Screens.Multi { public override bool CursorVisible => (screenStack.CurrentScreen as IMultiplayerSubScreen)?.CursorVisible ?? true; + // this is required due to PlayerLoader eventually being pushed to the main stack + // while leases may be taken out by a subscreen. public override bool DisallowExternalBeatmapRulesetChanges => true; private readonly MultiplayerWaveContainer waves; @@ -96,7 +98,7 @@ namespace osu.Game.Screens.Multi { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = screenStack = new OsuScreenStack { RelativeSizeAxes = Axes.Both } + Child = screenStack = new MultiplayerSubScreenStack { RelativeSizeAxes = Axes.Both } }, new Header(screenStack), createButton = new HeaderButton @@ -277,11 +279,7 @@ namespace osu.Game.Screens.Multi private void updateTrack(ValueChangedEvent _ = null) { - bool isMatch = screenStack.CurrentScreen is MatchSubScreen; - - Beatmap.Disabled = isMatch; - - if (isMatch) + if (screenStack.CurrentScreen is MatchSubScreen) { var track = Beatmap.Value?.Track; diff --git a/osu.Game/Screens/Multi/MultiplayerSubScreenStack.cs b/osu.Game/Screens/Multi/MultiplayerSubScreenStack.cs new file mode 100644 index 0000000000..3b0ed0dba1 --- /dev/null +++ b/osu.Game/Screens/Multi/MultiplayerSubScreenStack.cs @@ -0,0 +1,24 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Screens; + +namespace osu.Game.Screens.Multi +{ + public class MultiplayerSubScreenStack : OsuScreenStack + { + protected override void ScreenChanged(IScreen prev, IScreen next) + { + base.ScreenChanged(prev, next); + + // because this is a screen stack within a screen stack, let's manually handle disabled changes to simplify things. + var osuScreen = ((OsuScreen)next); + + bool disallowChanges = osuScreen.DisallowExternalBeatmapRulesetChanges; + + osuScreen.Beatmap.Disabled = disallowChanges; + osuScreen.Ruleset.Disabled = disallowChanges; + osuScreen.Mods.Disabled = disallowChanges; + } + } +} diff --git a/osu.Game/Screens/OsuScreenStack.cs b/osu.Game/Screens/OsuScreenStack.cs index a05933ef0e..e2a0414df7 100644 --- a/osu.Game/Screens/OsuScreenStack.cs +++ b/osu.Game/Screens/OsuScreenStack.cs @@ -26,7 +26,7 @@ namespace osu.Game.Screens }; ScreenPushed += screenPushed; - ScreenExited += screenExited; + ScreenExited += ScreenChanged; } private void screenPushed(IScreen prev, IScreen next) @@ -42,10 +42,10 @@ namespace osu.Game.Screens // create dependencies synchronously to ensure leases are in a sane state. ((OsuScreen)next).CreateLeasedDependencies((prev as OsuScreen)?.Dependencies ?? Dependencies); - setParallax(next); + ScreenChanged(prev, next); } - private void screenExited(IScreen prev, IScreen next) + protected virtual void ScreenChanged(IScreen prev, IScreen next) { setParallax(next); } diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index a78477c771..6ba4157797 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -65,20 +65,7 @@ namespace osu.Game.Screens.Select Mods.Value = CurrentItem.Value.RequiredMods?.ToArray() ?? Array.Empty(); } - Beatmap.Disabled = true; - Ruleset.Disabled = true; - Mods.Disabled = true; - return false; } - - public override void OnEntering(IScreen last) - { - base.OnEntering(last); - - Beatmap.Disabled = false; - Ruleset.Disabled = false; - Mods.Disabled = false; - } } } From fd71a53717bf57782cb2e0f8379e4379ea7b191d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 14:28:09 +0900 Subject: [PATCH 0295/1142] Fix test regression --- osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index e306706be9..063957d816 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components rooms.BindTo(roomManager.Rooms); - filter.BindValueChanged(criteria => Filter(criteria.NewValue)); + filter?.BindValueChanged(criteria => Filter(criteria.NewValue)); } public void Filter(FilterCriteria criteria) From c138e3907e13543a95a86a25021d5f35b56af285 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Feb 2020 14:35:45 +0900 Subject: [PATCH 0296/1142] Move methods below ctor --- .../Timeline/TimelineHitObjectBlueprint.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index b46a373818..5225a4299e 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -25,8 +25,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { private readonly Circle circle; - protected override bool ShouldBeConsideredForInput(Drawable child) => true; - [UsedImplicitly] private readonly Bindable startTime; @@ -42,11 +40,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private const float circle_size = 16; - public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => - base.ReceivePositionalInputAt(screenSpacePos) || - circle.ReceivePositionalInputAt(screenSpacePos) || - dragBar?.ReceivePositionalInputAt(screenSpacePos) == true; - public TimelineHitObjectBlueprint(HitObject hitObject) : base(hitObject) { @@ -138,6 +131,13 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Width = (float)(HitObject.GetEndTime() - HitObject.StartTime); } + protected override bool ShouldBeConsideredForInput(Drawable child) => true; + + public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => + base.ReceivePositionalInputAt(screenSpacePos) || + circle.ReceivePositionalInputAt(screenSpacePos) || + dragBar?.ReceivePositionalInputAt(screenSpacePos) == true; + protected override void OnSelected() { updateShadows(); From 6ae0efa40d350521d28720fccd050ce7502fb8e3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 6 Feb 2020 14:47:43 +0900 Subject: [PATCH 0297/1142] Fix adjustment not working when dragged before object --- .../Components/Timeline/TimelineHitObjectBlueprint.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs index 5225a4299e..8f12c2f0ed 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineHitObjectBlueprint.cs @@ -275,18 +275,18 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline case IHasRepeats repeatHitObject: // find the number of repeats which can fit in the requested time. var lengthOfOneRepeat = repeatHitObject.Duration / (repeatHitObject.RepeatCount + 1); - var proposedCount = (int)((time - hitObject.StartTime) / lengthOfOneRepeat) - 1; + var proposedCount = Math.Max(0, (int)((time - hitObject.StartTime) / lengthOfOneRepeat) - 1); - if (proposedCount == repeatHitObject.RepeatCount || proposedCount < 0) + if (proposedCount == repeatHitObject.RepeatCount) return; repeatHitObject.RepeatCount = proposedCount; break; case IHasEndTime endTimeHitObject: - var snappedTime = beatSnapProvider.SnapTime(time); + var snappedTime = Math.Max(hitObject.StartTime, beatSnapProvider.SnapTime(time)); - if (endTimeHitObject.EndTime == snappedTime || snappedTime <= hitObject.StartTime) + if (endTimeHitObject.EndTime == snappedTime) return; endTimeHitObject.EndTime = snappedTime; From 6b67b601e9033f6d48d813561fd602be25863bef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 17:35:13 +0900 Subject: [PATCH 0298/1142] 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 e5a1ec2f4e..702591231b 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 ce58be52ee..81f59a4993 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 6ab3c0f2d2..8e359970a1 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From 48350638a247faea83506b24b2eb5bd4b5a48803 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 18:38:00 +0900 Subject: [PATCH 0299/1142] Hide drag handles of all playlist items not currently being dragged --- osu.Game/Overlays/Music/Playlist.cs | 6 ++++++ osu.Game/Overlays/Music/PlaylistItem.cs | 20 +++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index 8744a6db8b..1ba568443d 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -18,6 +18,11 @@ namespace osu.Game.Overlays.Music public readonly Bindable SelectedSet = new Bindable(); + /// + /// Whether any item is currently being dragged. Used to hide other items' drag handles. + /// + private readonly BindableBool playlistDragActive = new BindableBool(); + public new MarginPadding Padding { get => base.Padding; @@ -31,6 +36,7 @@ namespace osu.Game.Overlays.Music protected override RearrangeableListItem CreateDrawable(BeatmapSetInfo item) => new PlaylistItem(item) { SelectedSet = { BindTarget = SelectedSet }, + PlaylistDragActive = { BindTarget = playlistDragActive }, RequestSelection = set => RequestSelection?.Invoke(set) }; diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 0f68df737e..0569261867 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -23,7 +23,10 @@ namespace osu.Game.Overlays.Music { private const float fade_duration = 100; + public BindableBool PlaylistDragActive = new BindableBool(); + public readonly Bindable SelectedSet = new Bindable(); + public Action RequestSelection; private PlaylistItemHandle handle; @@ -122,11 +125,26 @@ namespace osu.Game.Overlays.Music return true; } + protected override bool OnDragStart(DragStartEvent e) + { + if (!base.OnDragStart(e)) + return false; + + PlaylistDragActive.Value = true; + return true; + } + + protected override void OnDragEnd(DragEndEvent e) + { + PlaylistDragActive.Value = false; + base.OnDragEnd(e); + } + protected override bool IsDraggableAt(Vector2 screenSpacePos) => handle.HandlingDrag; protected override bool OnHover(HoverEvent e) { - handle.UpdateHoverState(true); + handle.UpdateHoverState(IsDragged || !PlaylistDragActive.Value); return base.OnHover(e); } From 1613198834e3b32bda05096704a0f47c3ddddb5c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 6 Feb 2020 19:43:33 +0900 Subject: [PATCH 0300/1142] Set a sane default keyboard step for mod settings --- osu.Game/Configuration/SettingSourceAttribute.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index f859dccc80..a3788e4582 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -45,7 +45,8 @@ namespace osu.Game.Configuration yield return new SettingsSlider { LabelText = attr.Label, - Bindable = bNumber + Bindable = bNumber, + KeyboardStep = 0.1f, }; break; @@ -54,7 +55,8 @@ namespace osu.Game.Configuration yield return new SettingsSlider { LabelText = attr.Label, - Bindable = bNumber + Bindable = bNumber, + KeyboardStep = 0.1f, }; break; From 5946ad7d809f7e7500ecc1a18d1f5310d47b635a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 6 Feb 2020 16:54:02 +0300 Subject: [PATCH 0301/1142] Fix possible memory leak and better user change test support --- .../Online/TestSceneCommentsContainer.cs | 24 ++++++++++--------- .../Overlays/Comments/CommentsContainer.cs | 7 +++++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs index 33acc75fa8..2a43ba3f99 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsContainer.cs @@ -10,7 +10,8 @@ using osu.Framework.Graphics; using osu.Game.Overlays.Comments; using osu.Game.Overlays; using osu.Framework.Allocation; -using osu.Game.Online.API; +using osu.Framework.Bindables; +using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { @@ -35,31 +36,32 @@ namespace osu.Game.Tests.Visual.Online [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple); - private CommentsContainer comments; - private readonly BasicScrollContainer scroll; - public TestSceneCommentsContainer() { + BasicScrollContainer scroll; + TestCommentsContainer comments; + Add(scroll = new BasicScrollContainer { RelativeSizeAxes = Axes.Both, - Child = comments = new CommentsContainer() + Child = comments = new TestCommentsContainer() }); - } - [BackgroundDependencyLoader] - private void load(IAPIProvider api) - { AddStep("Big Black comments", () => comments.ShowComments(CommentableType.Beatmapset, 41823)); AddStep("Airman comments", () => comments.ShowComments(CommentableType.Beatmapset, 24313)); AddStep("Lazer build comments", () => comments.ShowComments(CommentableType.Build, 4772)); AddStep("News comments", () => comments.ShowComments(CommentableType.NewsPost, 715)); - AddStep("Trigger user change", api.LocalUser.TriggerChange); + AddStep("Trigger user change", comments.User.TriggerChange); AddStep("Idle state", () => { scroll.Clear(); - scroll.Add(comments = new CommentsContainer()); + scroll.Add(comments = new TestCommentsContainer()); }); } + + private class TestCommentsContainer : CommentsContainer + { + public new Bindable User => base.User; + } } } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 3d68f453b7..33a6be0d7a 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -12,6 +12,7 @@ using osu.Game.Online.API.Requests.Responses; using System.Threading; using System.Linq; using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Game.Users; namespace osu.Game.Overlays.Comments { @@ -23,6 +24,8 @@ namespace osu.Game.Overlays.Comments public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); + protected readonly Bindable User = new Bindable(); + [Resolved] private IAPIProvider api { get; set; } @@ -109,11 +112,13 @@ namespace osu.Game.Overlays.Comments } } }); + + User.BindTo(api.LocalUser); } protected override void LoadComplete() { - api.LocalUser.BindValueChanged(_ => refetchComments()); + User.BindValueChanged(_ => refetchComments()); Sort.BindValueChanged(_ => refetchComments(), true); base.LoadComplete(); } From c09af0052bf3f2e1a2e4809b12aeeb166f0501af Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Thu, 6 Feb 2020 20:21:47 +0100 Subject: [PATCH 0302/1142] Revert accuracy display and column sorting changes --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 7 +------ osu.Game/Utils/FormatUtils.cs | 8 ++++---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 4d5bd84090..2310b2a0f5 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -16,7 +16,6 @@ using osu.Game.Scoring; using osu.Game.Users.Drawables; using osuTK; using osuTK.Graphics; -using osu.Game.Utils; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -66,10 +65,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores for (int i = 0; i < value.Count; i++) backgroundFlow.Add(new ScoreTableRowBackground(i, value[i])); - // Ensure correct column order - foreach (ScoreInfo score in value) - score.Statistics = score.Statistics.OrderByDescending(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value); - Columns = createHeaders(value[0]); Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); } @@ -121,7 +116,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new OsuSpriteText { Margin = new MarginPadding { Right = horizontal_inset }, - Text = score.Accuracy.FormatAccuracy(alwaysShowDecimals: true), + Text = score.DisplayAccuracy, Font = OsuFont.GetFont(size: text_size), Colour = score.Accuracy == 1 ? highAccuracyColour : Color4.White }, diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index f0b8b470f1..b3758b3375 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -7,18 +7,18 @@ namespace osu.Game.Utils { /// /// Turns the provided accuracy into a percentage with 2 decimal places. + /// Omits all decimal places when equals 1d. /// /// The accuracy to be formatted - /// Whether to show decimal places if equals 1d /// formatted accuracy in percentage - public static string FormatAccuracy(this double accuracy, bool alwaysShowDecimals = false) => accuracy == 1 && !alwaysShowDecimals ? "100%" : $"{accuracy:0.00%}"; + public static string FormatAccuracy(this double accuracy) => accuracy == 1 ? "100%" : $"{accuracy:0.00%}"; /// /// Turns the provided accuracy into a percentage with 2 decimal places. + /// Omits all decimal places when equals 100m. /// /// The accuracy to be formatted - /// Whether to show decimal places if equals 100m /// formatted accuracy in percentage - public static string FormatAccuracy(this decimal accuracy, bool alwaysShowDecimals = false) => accuracy == 100 && !alwaysShowDecimals ? "100%" : $"{accuracy:0.00}%"; + public static string FormatAccuracy(this decimal accuracy) => accuracy == 100 ? "100%" : $"{accuracy:0.00}%"; } } From 83b2b63d2c0bbb4d92e785777191331c0ef5ff2c Mon Sep 17 00:00:00 2001 From: Roman Kapustin Date: Thu, 6 Feb 2020 23:02:03 +0300 Subject: [PATCH 0303/1142] Make ScreenshotManager a Drawable --- osu.Game/Graphics/ScreenshotManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index 3ad36577b5..dc681102ce 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -9,7 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; -using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Platform; @@ -22,7 +22,7 @@ using SixLabors.ImageSharp; namespace osu.Game.Graphics { - public class ScreenshotManager : Container, IKeyBindingHandler, IHandleGlobalKeyboardInput + public class ScreenshotManager : Drawable, IKeyBindingHandler, IHandleGlobalKeyboardInput { private readonly BindableBool cursorVisibility = new BindableBool(true); From 4495192c25ba78891aec846caedbbebe3fc48792 Mon Sep 17 00:00:00 2001 From: UselessToucan Date: Thu, 6 Feb 2020 23:22:30 +0300 Subject: [PATCH 0304/1142] Make ScreenshotManager a Component Co-Authored-By: Salman Ahmed --- osu.Game/Graphics/ScreenshotManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index dc681102ce..e21545688b 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -22,7 +22,7 @@ using SixLabors.ImageSharp; namespace osu.Game.Graphics { - public class ScreenshotManager : Drawable, IKeyBindingHandler, IHandleGlobalKeyboardInput + public class ScreenshotManager : Component, IKeyBindingHandler, IHandleGlobalKeyboardInput { private readonly BindableBool cursorVisibility = new BindableBool(true); From ecde641729da944bd819136b6fb9080012222339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 5 Feb 2020 21:52:36 +0100 Subject: [PATCH 0305/1142] Randomise colours in scrolling test scene Switch to using randomised colours in TestSceneScrollingHitObjects to better distinguish individual hit objects. --- .../Visual/Gameplay/TestSceneScrollingHitObjects.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs index 8629522dc2..da5a83e194 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Threading; +using osu.Framework.Utils; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; @@ -19,6 +20,7 @@ using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; using osuTK; +using osuTK.Graphics; namespace osu.Game.Tests.Visual.Gameplay { @@ -236,7 +238,11 @@ namespace osu.Game.Tests.Visual.Gameplay AutoSizeAxes = Axes.Both; - AddInternal(new Box { Size = new Vector2(75) }); + AddInternal(new Box + { + Size = new Vector2(75), + Colour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1) + }); } } } From 12469469ad14bd48de4721832ede56b972028b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 5 Feb 2020 22:56:44 +0100 Subject: [PATCH 0306/1142] Add reproduction test steps for lifetime bug Modify TestSceneScrollingHitObjects to contain a test case that serves as a reproduction for a visual bug in which using the overlapping scroll algorithm results in an incorrect origin adjustment for lifetime. --- .../Gameplay/TestSceneScrollingHitObjects.cs | 88 ++++++++++++------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs index da5a83e194..d03716db2e 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneScrollingHitObjects.cs @@ -32,7 +32,8 @@ namespace osu.Game.Tests.Visual.Gameplay [Cached(typeof(IReadOnlyList))] private IReadOnlyList mods { get; set; } = Array.Empty(); - private const int spawn_interval = 5000; + private const int time_range = 5000; + private const int spawn_rate = time_range / 10; private readonly ScrollingTestContainer[] scrollContainers = new ScrollingTestContainer[4]; private readonly TestPlayfield[] playfields = new TestPlayfield[4]; @@ -52,13 +53,13 @@ namespace osu.Game.Tests.Visual.Gameplay { RelativeSizeAxes = Axes.Both, Child = playfields[0] = new TestPlayfield(), - TimeRange = spawn_interval + TimeRange = time_range }, scrollContainers[1] = new ScrollingTestContainer(ScrollingDirection.Down) { RelativeSizeAxes = Axes.Both, Child = playfields[1] = new TestPlayfield(), - TimeRange = spawn_interval + TimeRange = time_range }, }, new Drawable[] @@ -67,13 +68,13 @@ namespace osu.Game.Tests.Visual.Gameplay { RelativeSizeAxes = Axes.Both, Child = playfields[2] = new TestPlayfield(), - TimeRange = spawn_interval + TimeRange = time_range }, scrollContainers[3] = new ScrollingTestContainer(ScrollingDirection.Right) { RelativeSizeAxes = Axes.Both, Child = playfields[3] = new TestPlayfield(), - TimeRange = spawn_interval + TimeRange = time_range } } } @@ -86,31 +87,55 @@ namespace osu.Game.Tests.Visual.Gameplay { scrollContainers.ForEach(c => c.ControlPoints.Add(new MultiplierControlPoint(0))); - for (int i = 0; i <= spawn_interval; i += 1000) + for (int i = spawn_rate / 2; i <= time_range; i += spawn_rate) addHitObject(Time.Current + i); hitObjectSpawnDelegate?.Cancel(); - hitObjectSpawnDelegate = Scheduler.AddDelayed(() => addHitObject(Time.Current + spawn_interval), 1000, true); + hitObjectSpawnDelegate = Scheduler.AddDelayed(() => addHitObject(Time.Current + time_range), spawn_rate, true); } + private IList testControlPoints => new List + { + new MultiplierControlPoint(time_range) { DifficultyPoint = { SpeedMultiplier = 1.25 } }, + new MultiplierControlPoint(1.5 * time_range) { DifficultyPoint = { SpeedMultiplier = 1 } }, + new MultiplierControlPoint(2 * time_range) { DifficultyPoint = { SpeedMultiplier = 1.5 } } + }; + [Test] public void TestScrollAlgorithms() { - AddStep("Constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant)); - AddStep("Overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping)); - AddStep("Sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential)); + AddStep("constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant)); + AddStep("overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping)); + AddStep("sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential)); - AddSliderStep("Time range", 100, 10000, spawn_interval, v => scrollContainers.Where(c => c != null).ForEach(c => c.TimeRange = v)); - AddStep("Add control point", () => addControlPoint(Time.Current + spawn_interval)); + AddSliderStep("time range", 100, 10000, time_range, v => scrollContainers.Where(c => c != null).ForEach(c => c.TimeRange = v)); + + AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current)); } [Test] - public void TestScrollLifetime() + public void TestConstantScrollLifetime() { - AddStep("Set constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant)); + AddStep("set constant scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Constant)); // scroll container time range must be less than the rate of spawning hitobjects // otherwise the hitobjects will spawn already partly visible on screen and look wrong - AddStep("Set time range", () => scrollContainers.ForEach(c => c.TimeRange = spawn_interval / 2.0)); + AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0)); + } + + [Test] + public void TestSequentialScrollLifetime() + { + AddStep("set sequential scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Sequential)); + AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0)); + AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current)); + } + + [Test] + public void TestOverlappingScrollLifetime() + { + AddStep("set overlapping scroll", () => setScrollAlgorithm(ScrollVisualisationMethod.Overlapping)); + AddStep("set time range", () => scrollContainers.ForEach(c => c.TimeRange = time_range / 2.0)); + AddStep("add control points", () => addControlPoints(testControlPoints, Time.Current)); } private void addHitObject(double time) @@ -124,28 +149,27 @@ namespace osu.Game.Tests.Visual.Gameplay }); } - private void addControlPoint(double time) + private TestDrawableControlPoint createDrawablePoint(TestPlayfield playfield, double t) { - scrollContainers.ForEach(c => + var obj = new TestDrawableControlPoint(playfield.Direction, t); + setAnchor(obj, playfield); + return obj; + } + + private void addControlPoints(IList controlPoints, double sequenceStartTime) + { + controlPoints.ForEach(point => point.StartTime += sequenceStartTime); + + scrollContainers.ForEach(container => { - c.ControlPoints.Add(new MultiplierControlPoint(time) { DifficultyPoint = { SpeedMultiplier = 3 } }); - c.ControlPoints.Add(new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } }); - c.ControlPoints.Add(new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } }); + container.ControlPoints.AddRange(controlPoints); }); - playfields.ForEach(p => + foreach (var playfield in playfields) { - TestDrawableControlPoint createDrawablePoint(double t) - { - var obj = new TestDrawableControlPoint(p.Direction, t); - setAnchor(obj, p); - return obj; - } - - p.Add(createDrawablePoint(time)); - p.Add(createDrawablePoint(time + 2000)); - p.Add(createDrawablePoint(time + 3000)); - }); + foreach (var controlPoint in controlPoints) + playfield.Add(createDrawablePoint(playfield, controlPoint.StartTime)); + } } private void setAnchor(DrawableHitObject obj, TestPlayfield playfield) From 5fde4f2c0cda1c48a130fb4771eac1230ff5ba45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 6 Feb 2020 22:46:31 +0100 Subject: [PATCH 0307/1142] Fix lifetime calculation in overlapping algorithm Changes to lifetime calculation in scrolling rulesets introduced in #7367, which aimed to account for the distance between hit objects' origin and its edge entering the scrolling area, fixed some issues with hitobjects appearing abruptly, but also regressed some other scenarios. Upon investigation, the regression was localised to the overlapping scroll algorithm. The reason for this was two-fold: * The previous code used TimeAt() to calculate the time of travel from the hit object's edge to its origin. For other algorithms, that time can be accurately reconstructed, because they don't have periods of time where there are multiple hit objects scrolling at different velocities. That invariant does not hold for the overlapping algorithm, therefore it is possible for different values to be technically correct for TimeAt(). However, the only value that matters for the adjustment is the one that's indicated by the control point that applies to the hit object origin, which can be uniquely identified. * Additionally, the offset returned (even if correct) was applied externally to the hit object's start time and passed to GetDisplayStartTime(). In the overlapping algorithm, the choice of control point used in GetDisplayStartTime() is important, since the value of the speed multiplier is read within. Externally rewinding the hit object's start time meant that in some cases the speed multiplier of the *previous* control point is applied, which led to hit objects appearing too late if the scrolling rate decreased. Because of the above, modify GetDisplayStartTime() to take the offset into account in all algorithms, and apply the adjustment correctly inside of them. The constant and sequential algorithms needed no adjustment from the previous logic, since: * the constant algorithm disregarded control points, and * the sequential algorithm would effectively rewind to time = 0, calculate the absolute distance from time = 0 to the hit object start, apply the origin offset *to the absolute distance*, and then convert back to time, applying all control points in sequence. Due to this it was impossible for control points to get mixed up while calculating. As for the overlapping algorithm, the high-level logic is as follows: * The distance that the origin has to travel is the length of the scroll plus the distance from the origin to the object edge. * The above distance divided by the scroll length gives the relative scroll lengths that the object has to travel. * As one relative scroll length takes one time range, the relative travel length multiplied by the time range gives the absolute travel time of the object origin. * Finally, the control point multiplier applicable at origin time is applied to the whole travel time. Correctness of the above is demonstrated by visual tests added before and headless unit tests of the algorithms themselves. The sequential scroll algorithm was not covered by unit tests, and remains uncovered due to floating-point inaccuracies that should be addressed separately. --- .../ScrollAlgorithms/ConstantScrollTest.cs | 19 ++++++++--- .../ScrollAlgorithms/OverlappingScrollTest.cs | 19 ++++++++--- .../Algorithms/ConstantScrollAlgorithm.cs | 6 +++- .../Scrolling/Algorithms/IScrollAlgorithm.cs | 32 +++++++++++++++---- .../Algorithms/OverlappingScrollAlgorithm.cs | 7 ++-- .../Algorithms/SequentialScrollAlgorithm.cs | 6 +++- .../Scrolling/ScrollingHitObjectContainer.cs | 3 +- .../Tests/Visual/ScrollingTestContainer.cs | 4 +-- 8 files changed, 71 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/ScrollAlgorithms/ConstantScrollTest.cs b/osu.Game.Tests/ScrollAlgorithms/ConstantScrollTest.cs index d7f709dc03..a6e8622b6f 100644 --- a/osu.Game.Tests/ScrollAlgorithms/ConstantScrollTest.cs +++ b/osu.Game.Tests/ScrollAlgorithms/ConstantScrollTest.cs @@ -18,12 +18,21 @@ namespace osu.Game.Tests.ScrollAlgorithms } [Test] - public void TestDisplayStartTime() + public void TestPointDisplayStartTime() { - Assert.AreEqual(-8000, algorithm.GetDisplayStartTime(2000, 10000)); - Assert.AreEqual(-3000, algorithm.GetDisplayStartTime(2000, 5000)); - Assert.AreEqual(2000, algorithm.GetDisplayStartTime(7000, 5000)); - Assert.AreEqual(7000, algorithm.GetDisplayStartTime(17000, 10000)); + Assert.AreEqual(-8000, algorithm.GetDisplayStartTime(2000, 0, 10000, 1)); + Assert.AreEqual(-3000, algorithm.GetDisplayStartTime(2000, 0, 5000, 1)); + Assert.AreEqual(2000, algorithm.GetDisplayStartTime(7000, 0, 5000, 1)); + Assert.AreEqual(7000, algorithm.GetDisplayStartTime(17000, 0, 10000, 1)); + } + + [Test] + public void TestObjectDisplayStartTime() + { + Assert.AreEqual(900, algorithm.GetDisplayStartTime(2000, 50, 1000, 500)); // 2000 - (1 + 50 / 500) * 1000 + Assert.AreEqual(8900, algorithm.GetDisplayStartTime(10000, 50, 1000, 500)); // 10000 - (1 + 50 / 500) * 1000 + Assert.AreEqual(13500, algorithm.GetDisplayStartTime(15000, 250, 1000, 500)); // 15000 - (1 + 250 / 500) * 1000 + Assert.AreEqual(19000, algorithm.GetDisplayStartTime(25000, 100, 5000, 500)); // 25000 - (1 + 100 / 500) * 5000 } [Test] diff --git a/osu.Game.Tests/ScrollAlgorithms/OverlappingScrollTest.cs b/osu.Game.Tests/ScrollAlgorithms/OverlappingScrollTest.cs index 106aa88be3..1429d22c1a 100644 --- a/osu.Game.Tests/ScrollAlgorithms/OverlappingScrollTest.cs +++ b/osu.Game.Tests/ScrollAlgorithms/OverlappingScrollTest.cs @@ -27,11 +27,22 @@ namespace osu.Game.Tests.ScrollAlgorithms } [Test] - public void TestDisplayStartTime() + public void TestPointDisplayStartTime() { - Assert.AreEqual(1000, algorithm.GetDisplayStartTime(2000, 1000)); // Like constant - Assert.AreEqual(10000, algorithm.GetDisplayStartTime(10500, 1000)); // 10500 - (1000 * 0.5) - Assert.AreEqual(20000, algorithm.GetDisplayStartTime(22000, 1000)); // 23000 - (1000 / 0.5) + Assert.AreEqual(1000, algorithm.GetDisplayStartTime(2000, 0, 1000, 1)); // Like constant + Assert.AreEqual(10000, algorithm.GetDisplayStartTime(10500, 0, 1000, 1)); // 10500 - (1000 * 0.5) + Assert.AreEqual(20000, algorithm.GetDisplayStartTime(22000, 0, 1000, 1)); // 23000 - (1000 / 0.5) + } + + [Test] + public void TestObjectDisplayStartTime() + { + Assert.AreEqual(900, algorithm.GetDisplayStartTime(2000, 50, 1000, 500)); // 2000 - (1 + 50 / 500) * 1000 / 1 + Assert.AreEqual(9450, algorithm.GetDisplayStartTime(10000, 50, 1000, 500)); // 10000 - (1 + 50 / 500) * 1000 / 2 + Assert.AreEqual(14250, algorithm.GetDisplayStartTime(15000, 250, 1000, 500)); // 15000 - (1 + 250 / 500) * 1000 / 2 + Assert.AreEqual(16500, algorithm.GetDisplayStartTime(18000, 250, 2000, 500)); // 18000 - (1 + 250 / 500) * 2000 / 2 + Assert.AreEqual(17800, algorithm.GetDisplayStartTime(20000, 50, 1000, 500)); // 20000 - (1 + 50 / 500) * 1000 / 0.5 + Assert.AreEqual(19800, algorithm.GetDisplayStartTime(22000, 50, 1000, 500)); // 22000 - (1 + 50 / 500) * 1000 / 0.5 } [Test] diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs index 75ea3efdf2..0d4283e319 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/ConstantScrollAlgorithm.cs @@ -5,7 +5,11 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms { public class ConstantScrollAlgorithm : IScrollAlgorithm { - public double GetDisplayStartTime(double time, double timeRange) => time - timeRange; + public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength) + { + var adjustedTime = TimeAt(-offset, originTime, timeRange, scrollLength); + return adjustedTime - timeRange; + } public float GetLength(double startTime, double endTime, double timeRange, float scrollLength) { diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs index 5f053975c7..c394a05bcc 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollAlgorithm.cs @@ -6,15 +6,33 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms public interface IScrollAlgorithm { /// - /// Given a point in time, computes the time at which it enters the time range. + /// Given a point in time associated with an object's origin + /// and the spatial distance between the edge and the origin of the object along the scrolling axis, + /// computes the time at which the object initially enters the time range. /// - /// - /// E.g. For a constant time range of 5000ms, the time at which t=7000ms enters the time range is 2000ms. - /// - /// The point in time. + /// + /// Let's assume the following parameters: + /// + /// = 7000ms, + /// = 100px, + /// = 5000ms, + /// = 1000px + /// + /// and a constant scrolling rate. + /// To arrive at the end of the scrolling container, the object's origin has to cover + /// 1000 + 100 = 1100px + /// so that the edge starts at the end of the scrolling container. + /// One scroll length of 1000px covers 5000ms of time, so the time required to cover 1100px is equal to + /// 5000 * (1100 / 1000) = 5500ms, + /// and therefore the object should start being visible at + /// 7000 - 5500 = 1500ms. + /// + /// The time point at which the object origin should enter the time range. + /// The spatial distance between the object's edge and its origin along the scrolling axis. /// The amount of visible time. - /// The time at which enters . - double GetDisplayStartTime(double time, double timeRange); + /// The absolute spatial length through . + /// The time at which the object should enter the time range. + double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength); /// /// Computes the spatial length within a start and end time. diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs index fe22a86fad..7b827e0c63 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/OverlappingScrollAlgorithm.cs @@ -20,11 +20,12 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms searchPoint = new MultiplierControlPoint(); } - public double GetDisplayStartTime(double time, double timeRange) + public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength) { + var controlPoint = controlPointAt(originTime); // The total amount of time that the hitobject will remain visible within the timeRange, which decreases as the speed multiplier increases - double visibleDuration = timeRange / controlPointAt(time).Multiplier; - return time - visibleDuration; + double visibleDuration = (scrollLength + offset) * timeRange / controlPoint.Multiplier / scrollLength; + return originTime - visibleDuration; } public float GetLength(double startTime, double endTime, double timeRange, float scrollLength) diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs index 3c9a205412..41f9ebdb82 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/SequentialScrollAlgorithm.cs @@ -20,7 +20,11 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms positionCache = new Dictionary(); } - public double GetDisplayStartTime(double time, double timeRange) => time - timeRange - 1000; + public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength) + { + double adjustedTime = TimeAt(-offset, originTime, timeRange, scrollLength); + return adjustedTime - timeRange - 1000; + } public float GetLength(double startTime, double endTime, double timeRange, float scrollLength) { diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 04b4374fc4..83a7f7289f 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -133,8 +133,7 @@ namespace osu.Game.Rulesets.UI.Scrolling break; } - var adjustedStartTime = scrollingInfo.Algorithm.TimeAt(-originAdjustment, hitObject.HitObject.StartTime, timeRange.Value, scrollLength); - return scrollingInfo.Algorithm.GetDisplayStartTime(adjustedStartTime, timeRange.Value); + return scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, originAdjustment, timeRange.Value, scrollLength); } // Cant use AddOnce() since the delegate is re-constructed every invocation diff --git a/osu.Game/Tests/Visual/ScrollingTestContainer.cs b/osu.Game/Tests/Visual/ScrollingTestContainer.cs index 161ebe7030..18326a78ad 100644 --- a/osu.Game/Tests/Visual/ScrollingTestContainer.cs +++ b/osu.Game/Tests/Visual/ScrollingTestContainer.cs @@ -86,8 +86,8 @@ namespace osu.Game.Tests.Visual } } - public double GetDisplayStartTime(double time, double timeRange) - => implementation.GetDisplayStartTime(time, timeRange); + public double GetDisplayStartTime(double originTime, float offset, double timeRange, float scrollLength) + => implementation.GetDisplayStartTime(originTime, offset, timeRange, scrollLength); public float GetLength(double startTime, double endTime, double timeRange, float scrollLength) => implementation.GetLength(startTime, endTime, timeRange, scrollLength); From 7460018cd3775394d3eca84e282bb0b165633b41 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 14:58:07 +0900 Subject: [PATCH 0308/1142] Move combo colours to GlobalSkinColours --- .../TestSceneLegacyBeatmapSkin.cs | 2 +- .../Gameplay/TestSceneHitObjectAccentColour.cs | 4 ++-- .../Skins/TestSceneSkinConfigurationLookup.cs | 6 +++--- .../Objects/Drawables/DrawableHitObject.cs | 2 +- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- osu.Game/Screens/Menu/MenuSideFlashes.cs | 2 +- osu.Game/Skinning/DefaultSkin.cs | 4 ++-- .../{GlobalSkinColour.cs => GlobalSkinColours.cs} | 3 ++- osu.Game/Skinning/GlobalSkinConfiguration.cs | 1 - osu.Game/Skinning/LegacySkin.cs | 15 +++++++++------ 10 files changed, 22 insertions(+), 19 deletions(-) rename osu.Game/Skinning/{GlobalSkinColour.cs => GlobalSkinColours.cs} (79%) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs index bbb50c287b..3ff37c4147 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs @@ -89,7 +89,7 @@ namespace osu.Game.Rulesets.Osu.Tests public IReadOnlyList UsableComboColours => GameplayClockContainer.ChildrenOfType() .First() - .GetConfig>(GlobalSkinConfiguration.ComboColours)?.Value; + .GetConfig>(GlobalSkinColours.ComboColours)?.Value; } private class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index c6d1f9da29..17dc27543d 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -126,10 +126,10 @@ namespace osu.Game.Tests.Gameplay { switch (lookup) { - case GlobalSkinConfiguration global: + case GlobalSkinColours global: switch (global) { - case GlobalSkinConfiguration.ComboColours: + case GlobalSkinColours.ComboColours: return SkinUtils.As(new Bindable>(ComboColours)); } diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs index ed54cc982d..35313ee858 100644 --- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs +++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs @@ -95,7 +95,7 @@ namespace osu.Game.Tests.Skins [Test] public void TestGlobalLookup() { - AddAssert("Check combo colours", () => requester.GetConfig>(GlobalSkinConfiguration.ComboColours)?.Value?.Count > 0); + AddAssert("Check combo colours", () => requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.Count > 0); } [Test] @@ -121,7 +121,7 @@ namespace osu.Game.Tests.Skins public void TestEmptyComboColours() { AddAssert("Check retrieved combo colours is skin default colours", () => - requester.GetConfig>(GlobalSkinConfiguration.ComboColours)?.Value?.SequenceEqual(SkinConfiguration.DefaultComboColours) ?? false); + requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.SequenceEqual(SkinConfiguration.DefaultComboColours) ?? false); } [Test] @@ -136,7 +136,7 @@ namespace osu.Game.Tests.Skins AddStep("Disallow default colours fallback in source2", () => source2.Configuration.AllowDefaultComboColoursFallback = false); AddAssert("Check retrieved combo colours from source1", () => - requester.GetConfig>(GlobalSkinConfiguration.ComboColours)?.Value?.SequenceEqual(source1.Configuration.ComboColours) ?? false); + requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.SequenceEqual(source1.Configuration.ComboColours) ?? false); } [Test] diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 4ac30fe7fb..e391157b5b 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -349,7 +349,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { if (HitObject is IHasComboInformation combo) { - var comboColours = CurrentSkin.GetConfig>(GlobalSkinConfiguration.ComboColours)?.Value; + var comboColours = CurrentSkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; AccentColour.Value = comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White; } } diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 8fc07f5989..06ca161fed 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -123,7 +123,7 @@ namespace osu.Game.Screens.Menu Color4 defaultColour = Color4.White.Opacity(0.2f); if (user.Value?.IsSupporter ?? false) - AccentColour = skin.Value.GetConfig(GlobalSkinColour.MenuGlow)?.Value ?? defaultColour; + AccentColour = skin.Value.GetConfig(GlobalSkinColours.MenuGlow)?.Value ?? defaultColour; else AccentColour = defaultColour; } diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index 3a88cda4ef..321381ac8d 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -112,7 +112,7 @@ namespace osu.Game.Screens.Menu Color4 baseColour = colours.Blue; if (user.Value?.IsSupporter ?? false) - baseColour = skin.Value.GetConfig(GlobalSkinColour.MenuGlow)?.Value ?? baseColour; + baseColour = skin.Value.GetConfig(GlobalSkinColours.MenuGlow)?.Value ?? baseColour; // linear colour looks better in this case, so let's use it for now. Color4 gradientDark = baseColour.Opacity(0).ToLinear(); diff --git a/osu.Game/Skinning/DefaultSkin.cs b/osu.Game/Skinning/DefaultSkin.cs index 2a065ea3d7..6b4af21b37 100644 --- a/osu.Game/Skinning/DefaultSkin.cs +++ b/osu.Game/Skinning/DefaultSkin.cs @@ -31,10 +31,10 @@ namespace osu.Game.Skinning { // todo: this code is pulled from LegacySkin and should not exist. // will likely change based on how databased storage of skin configuration goes. - case GlobalSkinConfiguration global: + case GlobalSkinColours global: switch (global) { - case GlobalSkinConfiguration.ComboColours: + case GlobalSkinColours.ComboColours: return SkinUtils.As(new Bindable>(Configuration.ComboColours)); } diff --git a/osu.Game/Skinning/GlobalSkinColour.cs b/osu.Game/Skinning/GlobalSkinColours.cs similarity index 79% rename from osu.Game/Skinning/GlobalSkinColour.cs rename to osu.Game/Skinning/GlobalSkinColours.cs index d039be98ce..f889371b98 100644 --- a/osu.Game/Skinning/GlobalSkinColour.cs +++ b/osu.Game/Skinning/GlobalSkinColours.cs @@ -3,8 +3,9 @@ namespace osu.Game.Skinning { - public enum GlobalSkinColour + public enum GlobalSkinColours { + ComboColours, MenuGlow } } diff --git a/osu.Game/Skinning/GlobalSkinConfiguration.cs b/osu.Game/Skinning/GlobalSkinConfiguration.cs index 66dc9a9395..0532e64546 100644 --- a/osu.Game/Skinning/GlobalSkinConfiguration.cs +++ b/osu.Game/Skinning/GlobalSkinConfiguration.cs @@ -5,6 +5,5 @@ namespace osu.Game.Skinning { public enum GlobalSkinConfiguration { - ComboColours } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 671d37fda4..609fb79d9a 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -68,22 +69,22 @@ namespace osu.Game.Skinning { switch (lookup) { - case GlobalSkinConfiguration global: - switch (global) + case GlobalSkinColours colour: + switch (colour) { - case GlobalSkinConfiguration.ComboColours: + case GlobalSkinColours.ComboColours: var comboColours = Configuration.ComboColours; if (comboColours != null) return SkinUtils.As(new Bindable>(comboColours)); break; + + default: + return SkinUtils.As(getCustomColour(colour.ToString())); } break; - case GlobalSkinColour colour: - return SkinUtils.As(getCustomColour(colour.ToString())); - case LegacySkinConfiguration.LegacySetting legacy: switch (legacy) { @@ -100,6 +101,8 @@ namespace osu.Game.Skinning return SkinUtils.As(getCustomColour(customColour.Lookup.ToString())); default: + // handles lookups like GlobalSkinConfiguration + try { if (Configuration.ConfigDictionary.TryGetValue(lookup.ToString(), out var val)) From 544685be4863631b47df94f19d4f6307cb014d71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 14:58:29 +0900 Subject: [PATCH 0309/1142] Add support for reading skin frame rate from configuration file --- .../Skinning/OsuLegacySkinTransformer.cs | 9 ++- osu.Game/Skinning/GlobalSkinConfiguration.cs | 1 + osu.Game/Skinning/LegacySkinExtensions.cs | 72 +++++++++++-------- 3 files changed, 51 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs index 266b619334..d6c3f443eb 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuLegacySkinTransformer.cs @@ -46,17 +46,20 @@ namespace osu.Game.Rulesets.Osu.Skinning switch (osuComponent.Component) { case OsuSkinComponents.FollowPoint: - return this.GetAnimation(component.LookupName, true, false); + return this.GetAnimation(component.LookupName, true, false, true); case OsuSkinComponents.SliderFollowCircle: - var followCircle = this.GetAnimation("sliderfollowcircle", true, true); + var followCircle = this.GetAnimation("sliderfollowcircle", true, true, true); if (followCircle != null) // follow circles are 2x the hitcircle resolution in legacy skins (since they are scaled down from >1x followCircle.Scale *= 0.5f; return followCircle; case OsuSkinComponents.SliderBall: - var sliderBallContent = this.GetAnimation("sliderb", true, true, ""); + var sliderBallContent = this.GetAnimation("sliderb", true, true, animationSeparator: ""); + + // todo: slider ball has a custom frame delay based on velocity + // Math.Max((150 / Velocity) * GameBase.SIXTY_FRAME_TIME, GameBase.SIXTY_FRAME_TIME); if (sliderBallContent != null) { diff --git a/osu.Game/Skinning/GlobalSkinConfiguration.cs b/osu.Game/Skinning/GlobalSkinConfiguration.cs index 0532e64546..8774fe5a97 100644 --- a/osu.Game/Skinning/GlobalSkinConfiguration.cs +++ b/osu.Game/Skinning/GlobalSkinConfiguration.cs @@ -5,5 +5,6 @@ namespace osu.Game.Skinning { public enum GlobalSkinConfiguration { + AnimationFramerate } } diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index c758b699ed..fa4de21eec 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.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.Generic; +using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Sprites; @@ -10,48 +12,62 @@ namespace osu.Game.Skinning { public static class LegacySkinExtensions { - public static Drawable GetAnimation(this ISkin source, string componentName, bool animatable, bool looping, string animationSeparator = "-") + public static Drawable GetAnimation(this ISkin source, string componentName, bool animatable, bool looping, bool applyConfigFrameRate = false, string animationSeparator = "-") { - const double default_frame_time = 1000 / 60d; - Texture texture; - Texture getFrameTexture(int frame) => source.GetTexture($"{componentName}{animationSeparator}{frame}"); - - TextureAnimation animation = null; - if (animatable) { - for (int i = 0; true; i++) + var textures = getTextures().ToArray(); + + if (textures.Length > 0) { - if ((texture = getFrameTexture(i)) == null) - break; - - if (animation == null) + var animation = new TextureAnimation { - animation = new TextureAnimation - { - DefaultFrameLength = default_frame_time, - Repeat = looping - }; - } + DefaultFrameLength = getFrameLength(source, applyConfigFrameRate, textures), + Repeat = looping, + }; - animation.AddFrame(texture); + foreach (var t in textures) + animation.AddFrame(t); + + return animation; } } - if (animation != null) - return animation; - + // if an animation was not allowed or not found, fall back to a sprite retrieval. if ((texture = source.GetTexture(componentName)) != null) - { - return new Sprite - { - Texture = texture - }; - } + return new Sprite { Texture = texture }; return null; + + IEnumerable getTextures() + { + for (int i = 0; true; i++) + { + if ((texture = source.GetTexture($"{componentName}{animationSeparator}{i}")) == null) + break; + + yield return texture; + } + } + } + + private const double default_frame_time = 1000 / 60d; + + private static double getFrameLength(ISkin source, bool applyConfigFrameRate, Texture[] textures) + { + if (applyConfigFrameRate) + { + var iniRate = source.GetConfig(GlobalSkinConfiguration.AnimationFramerate); + + if (iniRate != null) + return 1000f / iniRate.Value; + + return 1000f / textures.Length; + } + + return default_frame_time; } } } From 9181bb41c621c217c187535e9d899a7d8a76258d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 15:11:09 +0900 Subject: [PATCH 0310/1142] Remove unused using --- osu.Game/Skinning/LegacySkin.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 609fb79d9a..94611317d5 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Collections.Generic; using System.IO; using System.Linq; From c392ba6a7e35c7a6546cb21168ea9241264158e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 15:46:10 +0900 Subject: [PATCH 0311/1142] 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 702591231b..25bde037db 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 81f59a4993..21c9eab4c6 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 8e359970a1..3ed25360c5 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From f63bf0637305ecdd866dfa9667a8dfa6442c80c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 16:09:54 +0900 Subject: [PATCH 0312/1142] Fix incorrect distance snap grid being displayed when in selection mode --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 0014360d24..afe5d2b93b 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -174,7 +174,7 @@ namespace osu.Game.Rulesets.Edit { base.Update(); - if (EditorClock.CurrentTime != lastGridUpdateTime && blueprintContainer.CurrentTool != null) + if (EditorClock.CurrentTime != lastGridUpdateTime && !(blueprintContainer.CurrentTool is SelectTool)) showGridFor(Enumerable.Empty()); } @@ -328,7 +328,7 @@ namespace osu.Game.Rulesets.Edit /// Creates the applicable for a selection. /// /// The selection. - /// The for . + /// The for . If empty, a grid is returned for the current poitn in time. [CanBeNull] protected virtual DistanceSnapGrid CreateDistanceSnapGrid([NotNull] IEnumerable selectedHitObjects) => null; From 3aa18abd99b492cd6b01aa1d777ed5559134dbe9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 16:22:59 +0900 Subject: [PATCH 0313/1142] Fix typo in xmldoc Co-Authored-By: Tree --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index afe5d2b93b..6c81d70190 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -328,7 +328,7 @@ namespace osu.Game.Rulesets.Edit /// Creates the applicable for a selection. ///
/// The selection. - /// The for . If empty, a grid is returned for the current poitn in time. + /// The for . If empty, a grid is returned for the current point in time. [CanBeNull] protected virtual DistanceSnapGrid CreateDistanceSnapGrid([NotNull] IEnumerable selectedHitObjects) => null; From 9997ae17bc17dc45cd790e151c416786a727f6e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 16:42:56 +0900 Subject: [PATCH 0314/1142] Fix editor test scene exiting after loading --- osu.Game/Tests/Visual/EditorTestScene.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Visual/EditorTestScene.cs b/osu.Game/Tests/Visual/EditorTestScene.cs index 75bbb3e110..80bc3bdb87 100644 --- a/osu.Game/Tests/Visual/EditorTestScene.cs +++ b/osu.Game/Tests/Visual/EditorTestScene.cs @@ -24,8 +24,13 @@ namespace osu.Game.Tests.Visual private void load() { Beatmap.Value = CreateWorkingBeatmap(ruleset.RulesetInfo); + } - LoadScreen(new Editor()); + public override void SetUpSteps() + { + base.SetUpSteps(); + + AddStep("Load editor", () => LoadScreen(new Editor())); } } } From 89901523159eaa8cbc01f473cb7e6142fed6a8ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 16:43:50 +0900 Subject: [PATCH 0315/1142] Fix duration snapping still being incorrect --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 0014360d24..1312122cf4 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -289,7 +289,11 @@ namespace osu.Game.Rulesets.Edit => beatSnapProvider.SnapTime(referenceTime + DistanceToDuration(referenceTime, distance), referenceTime) - referenceTime; public override float GetSnappedDistanceFromDistance(double referenceTime, float distance) - => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(DistanceToDuration(referenceTime, distance), referenceTime)); + { + var snappedEndTime = beatSnapProvider.SnapTime(referenceTime + DistanceToDuration(referenceTime, distance), referenceTime); + + return DurationToDistance(referenceTime, snappedEndTime - referenceTime); + } public override void UpdateHitObject(HitObject hitObject) => EditorBeatmap.UpdateHitObject(hitObject); From b7996f91fc0849f767a9251be2763f81fdca8e60 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 17:51:38 +0900 Subject: [PATCH 0316/1142] Update the windows platform offset to match stable --- osu.Game/Screens/Play/GameplayClockContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/GameplayClockContainer.cs b/osu.Game/Screens/Play/GameplayClockContainer.cs index 9f46fddc5e..1c061c215b 100644 --- a/osu.Game/Screens/Play/GameplayClockContainer.cs +++ b/osu.Game/Screens/Play/GameplayClockContainer.cs @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Play // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. // This only seems to be required on windows. We need to eventually figure out why, with a bit of luck. - platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; + platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 15 : 0 }; // the final usable gameplay clock with user-set offsets applied. userOffsetClock = new FramedOffsetClock(platformOffsetClock); From e31d69c7497b666aec2b3f982cd4d18a10df1e89 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 18:02:48 +0900 Subject: [PATCH 0317/1142] Add commit status to EndPlacement; call BeginPlacement on initial movement --- .../Edit/Blueprints/ManiaPlacementBlueprint.cs | 2 +- .../Blueprints/HitCircles/HitCirclePlacementBlueprint.cs | 3 ++- .../Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs | 3 ++- .../Blueprints/Spinners/SpinnerPlacementBlueprint.cs | 2 +- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 9 ++++++--- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 5 +++-- .../Edit/Compose/Components/ComposeBlueprintContainer.cs | 2 ++ osu.Game/Screens/Edit/Compose/IPlacementHandler.cs | 3 ++- osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs | 5 +++-- 9 files changed, 22 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs index 7a3b42914e..362d6d40a8 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints protected override void OnMouseUp(MouseUpEvent e) { - EndPlacement(); + EndPlacement(true); base.OnMouseUp(e); } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs index bb47c7e464..407f5f540e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs @@ -30,12 +30,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles protected override bool OnClick(ClickEvent e) { - EndPlacement(); + EndPlacement(true); return true; } public override void UpdatePosition(Vector2 screenSpacePosition) { + BeginPlacement(); HitObject.Position = ToLocalSpace(screenSpacePosition); } } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index 90512849d4..75d05b9b6c 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -68,6 +68,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders switch (state) { case PlacementState.Initial: + BeginPlacement(); HitObject.Position = ToLocalSpace(screenSpacePosition); break; @@ -132,7 +133,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void endCurve() { updateSlider(); - EndPlacement(); + EndPlacement(true); } protected override void Update() diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs index 5525b8936e..8dc3cb0855 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners if (isPlacingEnd) { HitObject.EndTime = EditorClock.CurrentTime; - EndPlacement(); + EndPlacement(true); } else { diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index e181e1f431..e3f2fa915a 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -254,11 +254,14 @@ namespace osu.Game.Rulesets.Edit hitObject.StartTime = GetSnappedPosition(distanceSnapGrid.ToLocalSpace(inputManager.CurrentState.Mouse.Position), hitObject.StartTime).time; } - public void EndPlacement(HitObject hitObject) + public void EndPlacement(HitObject hitObject, bool commit) { - EditorBeatmap.Add(hitObject); + if (commit) + { + EditorBeatmap.Add(hitObject); - adjustableClock.Seek(hitObject.StartTime); + adjustableClock.Seek(hitObject.StartTime); + } showGridFor(Enumerable.Empty()); } diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 07283d2245..24fa96e1c5 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -103,11 +103,12 @@ namespace osu.Game.Rulesets.Edit /// Signals that the placement of has finished. /// This will destroy this , and add the to the . ///
- protected void EndPlacement() + /// Whether the object should be committed. + public void EndPlacement(bool commit) { if (!PlacementBegun) BeginPlacement(); - placementHandler.EndPlacement(HitObject); + placementHandler.EndPlacement(HitObject, commit); } /// diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 3c41dead5d..b257688568 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -63,6 +63,8 @@ namespace osu.Game.Screens.Edit.Compose.Components private void refreshTool() { placementBlueprintContainer.Clear(); + + currentPlacement?.EndPlacement(false); currentPlacement = null; var blueprint = CurrentTool?.CreatePlacementBlueprint(); diff --git a/osu.Game/Screens/Edit/Compose/IPlacementHandler.cs b/osu.Game/Screens/Edit/Compose/IPlacementHandler.cs index 47a4277430..aefcbc6542 100644 --- a/osu.Game/Screens/Edit/Compose/IPlacementHandler.cs +++ b/osu.Game/Screens/Edit/Compose/IPlacementHandler.cs @@ -17,7 +17,8 @@ namespace osu.Game.Screens.Edit.Compose /// Notifies that a placement has finished. /// /// The that has been placed. - void EndPlacement(HitObject hitObject); + /// Whether the object should be committed. + void EndPlacement(HitObject hitObject, bool commit); /// /// Deletes a . diff --git a/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs b/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs index 0688620b8e..ce95dfa62f 100644 --- a/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs +++ b/osu.Game/Tests/Visual/PlacementBlueprintTestScene.cs @@ -53,9 +53,10 @@ namespace osu.Game.Tests.Visual { } - public void EndPlacement(HitObject hitObject) + public void EndPlacement(HitObject hitObject, bool commit) { - AddHitObject(CreateHitObject(hitObject)); + if (commit) + AddHitObject(CreateHitObject(hitObject)); Remove(currentBlueprint); Add(currentBlueprint = CreateBlueprint()); From e08437c5dc34ec3bec18e81d5556e83c1fb56727 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 18:03:14 +0900 Subject: [PATCH 0318/1142] Track placement object in EditorBeatmap --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 ++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index e3f2fa915a..d946b2eb7f 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -250,12 +250,16 @@ namespace osu.Game.Rulesets.Edit public void BeginPlacement(HitObject hitObject) { + EditorBeatmap.PlacementObject.Value = hitObject; + if (distanceSnapGrid != null) hitObject.StartTime = GetSnappedPosition(distanceSnapGrid.ToLocalSpace(inputManager.CurrentState.Mouse.Position), hitObject.StartTime).time; } public void EndPlacement(HitObject hitObject, bool commit) { + EditorBeatmap.PlacementObject.Value = null; + if (commit) { EditorBeatmap.Add(hitObject); diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index cacb539891..e1f3ddf191 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -33,7 +33,15 @@ namespace osu.Game.Screens.Edit /// public event Action StartTimeChanged; - public BindableList SelectedHitObjects { get; } = new BindableList(); + /// + /// All currently selected s. + /// + public readonly BindableList SelectedHitObjects = new BindableList(); + + /// + /// The current placement + /// + public readonly Bindable PlacementObject = new Bindable(); public readonly IBeatmap PlayableBeatmap; From 56a091674b31fbe80d9ff08b704cfe8cd2fd7850 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 18:04:10 +0900 Subject: [PATCH 0319/1142] Add placement display to timeline --- .../Compose/Components/BlueprintContainer.cs | 24 +++++++------- .../Timeline/TimelineBlueprintContainer.cs | 31 +++++++++++++++++++ 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 675b2b648d..55b2b801e7 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected DragBox DragBox { get; private set; } - private Container selectionBlueprints; + protected Container SelectionBlueprints; private SelectionHandler selectionHandler; @@ -62,7 +62,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { DragBox = CreateDragBox(select), selectionHandler, - selectionBlueprints = CreateSelectionBlueprintContainer(), + SelectionBlueprints = CreateSelectionBlueprintContainer(), DragBox.CreateProxy().With(p => p.Depth = float.MinValue) }); @@ -73,7 +73,7 @@ namespace osu.Game.Screens.Edit.Compose.Components selectedHitObjects.ItemsAdded += objects => { foreach (var o in objects) - selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select(); + SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select(); SelectionChanged?.Invoke(selectedHitObjects); }; @@ -81,7 +81,7 @@ namespace osu.Game.Screens.Edit.Compose.Components selectedHitObjects.ItemsRemoved += objects => { foreach (var o in objects) - selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect(); + SelectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect(); SelectionChanged?.Invoke(selectedHitObjects); }; @@ -230,7 +230,7 @@ namespace osu.Game.Screens.Edit.Compose.Components private void removeBlueprintFor(HitObject hitObject) { - var blueprint = selectionBlueprints.SingleOrDefault(m => m.HitObject == hitObject); + var blueprint = SelectionBlueprints.SingleOrDefault(m => m.HitObject == hitObject); if (blueprint == null) return; @@ -239,7 +239,7 @@ namespace osu.Game.Screens.Edit.Compose.Components blueprint.Selected -= onBlueprintSelected; blueprint.Deselected -= onBlueprintDeselected; - selectionBlueprints.Remove(blueprint); + SelectionBlueprints.Remove(blueprint); } protected virtual void AddBlueprintFor(HitObject hitObject) @@ -251,7 +251,7 @@ namespace osu.Game.Screens.Edit.Compose.Components blueprint.Selected += onBlueprintSelected; blueprint.Deselected += onBlueprintDeselected; - selectionBlueprints.Add(blueprint); + SelectionBlueprints.Add(blueprint); } #endregion @@ -278,7 +278,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (!allowDeselection && selectionHandler.SelectedBlueprints.Any(s => s.IsHovered)) return; - foreach (SelectionBlueprint blueprint in selectionBlueprints.AliveChildren) + foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren) { if (blueprint.IsHovered) { @@ -308,7 +308,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// The rectangle to perform a selection on in screen-space coordinates. private void select(RectangleF rect) { - foreach (var blueprint in selectionBlueprints) + foreach (var blueprint in SelectionBlueprints) { if (blueprint.IsAlive && blueprint.IsPresent && rect.Contains(blueprint.SelectionPoint)) blueprint.Select(); @@ -322,7 +322,7 @@ namespace osu.Game.Screens.Edit.Compose.Components ///
private void selectAll() { - selectionBlueprints.ToList().ForEach(m => m.Select()); + SelectionBlueprints.ToList().ForEach(m => m.Select()); selectionHandler.UpdateVisibility(); } @@ -334,14 +334,14 @@ namespace osu.Game.Screens.Edit.Compose.Components private void onBlueprintSelected(SelectionBlueprint blueprint) { selectionHandler.HandleSelected(blueprint); - selectionBlueprints.ChangeChildDepth(blueprint, 1); + SelectionBlueprints.ChangeChildDepth(blueprint, 1); beatmap.SelectedHitObjects.Add(blueprint.HitObject); } private void onBlueprintDeselected(SelectionBlueprint blueprint) { selectionHandler.HandleDeselected(blueprint); - selectionBlueprints.ChangeChildDepth(blueprint, 0); + SelectionBlueprints.ChangeChildDepth(blueprint, 0); beatmap.SelectedHitObjects.Remove(blueprint.HitObject); } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs index 9f3d776e5c..84328466c3 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; @@ -21,8 +22,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved(CanBeNull = true)] private Timeline timeline { get; set; } + [Resolved] + private EditorBeatmap beatmap { get; set; } + private DragEvent lastDragEvent; + private Bindable placement; + + private SelectionBlueprint placementBlueprint; + public TimelineBlueprintContainer() { RelativeSizeAxes = Axes.Both; @@ -43,6 +51,29 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { base.LoadComplete(); DragBox.Alpha = 0; + + placement = beatmap.PlacementObject.GetBoundCopy(); + placement.ValueChanged += placementChanged; + } + + private void placementChanged(ValueChangedEvent obj) + { + if (obj.NewValue == null) + { + if (placementBlueprint != null) + { + SelectionBlueprints.Remove(placementBlueprint); + placementBlueprint = null; + } + } + else + { + placementBlueprint = CreateBlueprintFor(obj.NewValue); + + placementBlueprint.Colour = Color4.MediumPurple; + + SelectionBlueprints.Add(placementBlueprint); + } } protected override Container CreateSelectionBlueprintContainer() => new TimelineSelectionBlueprintContainer { RelativeSizeAxes = Axes.Both }; From 881d192af3ecdc9cc9f950bd4e607b70bb3c969d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 7 Feb 2020 12:07:16 +0300 Subject: [PATCH 0320/1142] Fix crash when selecting spotlight tab with not-null country --- osu.Game/Overlays/RankingsOverlay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index 4fc94420a4..a0aeff082e 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -110,7 +110,8 @@ namespace osu.Game.Overlays if (Country.Value != null) Scope.Value = RankingsScope.Performance; - Scheduler.AddOnce(loadNewContent); + if (Scope.Value != RankingsScope.Spotlights) + Scheduler.AddOnce(loadNewContent); }, true); Scope.BindValueChanged(_ => From 2082948f9a4f1ee2573e4217b78068f561da0766 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 18:23:59 +0900 Subject: [PATCH 0321/1142] Make editor screens display below timeline --- .../Screens/Edit/EditorScreenWithTimeline.cs | 86 +++++++++---------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs index 7ee1005add..e9ff0b5598 100644 --- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs +++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs @@ -18,6 +18,8 @@ namespace osu.Game.Screens.Edit private const float vertical_margins = 10; private const float horizontal_margins = 20; + private const float timeline_height = 110; + private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor(); private Container timelineContainer; @@ -32,65 +34,57 @@ namespace osu.Game.Screens.Edit Children = new Drawable[] { - new GridContainer + mainContent = new Container { + Name = "Main content", RelativeSizeAxes = Axes.Both, - Content = new[] + Padding = new MarginPadding { - new Drawable[] + Horizontal = horizontal_margins, + Top = vertical_margins + timeline_height, + Bottom = vertical_margins + }, + }, + new Container + { + Name = "Timeline", + RelativeSizeAxes = Axes.X, + Height = timeline_height, + Children = new Drawable[] + { + new Box { - new Container + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.5f) + }, + new Container + { + Name = "Timeline content", + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = horizontal_margins, Vertical = vertical_margins }, + Child = new GridContainer { - Name = "Timeline", RelativeSizeAxes = Axes.Both, - Children = new Drawable[] + Content = new[] { - new Box + new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f) - }, - new Container - { - Name = "Timeline content", - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = horizontal_margins, Vertical = vertical_margins }, - Child = new GridContainer + timelineContainer = new Container { RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - timelineContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Right = 5 }, - }, - new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } - }, - }, - ColumnDimensions = new[] - { - new Dimension(), - new Dimension(GridSizeMode.Absolute, 90), - } + Padding = new MarginPadding { Right = 5 }, }, - } + new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } + }, + }, + ColumnDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.Absolute, 90), } - } - }, - new Drawable[] - { - mainContent = new Container - { - Name = "Main content", - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = horizontal_margins, Vertical = vertical_margins }, - } + }, } - }, - RowDimensions = new[] { new Dimension(GridSizeMode.Absolute, 110) } + } }, }; From 6297606baaec8865d2201647746bb379c0e37ac9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 19:08:37 +0900 Subject: [PATCH 0322/1142] Make sMake spinner's EndTime correct on construction --- osu.Game.Rulesets.Osu/Objects/Spinner.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs index 2441a1449d..0b8d03d118 100644 --- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs @@ -13,8 +13,13 @@ namespace osu.Game.Rulesets.Osu.Objects { public class Spinner : OsuHitObject, IHasEndTime { - public double EndTime { get; set; } - public double Duration => EndTime - StartTime; + public double EndTime + { + get => StartTime + Duration; + set => Duration = value - StartTime; + } + + public double Duration { get; set; } /// /// Number of spins required to finish the spinner without miss. From a6531bf73e06504636f38d336aa397669cc41069 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 19:08:49 +0900 Subject: [PATCH 0323/1142] Don't show distance snap grid for spinners (for now) --- osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs | 6 ++++++ osu.Game/Rulesets/Edit/HitObjectComposer.cs | 11 ++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index b01488e7c2..cdf78a5902 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -36,6 +36,9 @@ namespace osu.Game.Rulesets.Osu.Edit protected override DistanceSnapGrid CreateDistanceSnapGrid(IEnumerable selectedHitObjects) { + if (BlueprintContainer.CurrentTool is SpinnerCompositionTool) + return null; + var objects = selectedHitObjects.ToList(); if (objects.Count == 0) @@ -89,6 +92,9 @@ namespace osu.Game.Rulesets.Osu.Edit targetIndex++; } + if (sourceObject is Spinner) + return null; + return new OsuDistanceSnapGrid((OsuHitObject)sourceObject, (OsuHitObject)targetObject); } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index e181e1f431..7b7c154191 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -49,8 +49,9 @@ namespace osu.Game.Rulesets.Edit [Resolved] private IBeatSnapProvider beatSnapProvider { get; set; } + protected ComposeBlueprintContainer BlueprintContainer; + private DrawableEditRulesetWrapper drawableRulesetWrapper; - private ComposeBlueprintContainer blueprintContainer; private Container distanceSnapGridContainer; private DistanceSnapGrid distanceSnapGrid; private readonly List layerContainers = new List(); @@ -94,7 +95,7 @@ namespace osu.Game.Rulesets.Edit new EditorPlayfieldBorder { RelativeSizeAxes = Axes.Both } }); - var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChild(blueprintContainer = CreateBlueprintContainer()); + var layerAboveRuleset = drawableRulesetWrapper.CreatePlayfieldAdjustmentContainer().WithChild(BlueprintContainer = CreateBlueprintContainer()); layerContainers.Add(layerBelowRuleset); layerContainers.Add(layerAboveRuleset); @@ -142,7 +143,7 @@ namespace osu.Game.Rulesets.Edit setSelectTool(); - blueprintContainer.SelectionChanged += selectionChanged; + BlueprintContainer.SelectionChanged += selectionChanged; } protected override bool OnKeyDown(KeyDownEvent e) @@ -174,7 +175,7 @@ namespace osu.Game.Rulesets.Edit { base.Update(); - if (EditorClock.CurrentTime != lastGridUpdateTime && !(blueprintContainer.CurrentTool is SelectTool)) + if (EditorClock.CurrentTime != lastGridUpdateTime && !(BlueprintContainer.CurrentTool is SelectTool)) showGridFor(Enumerable.Empty()); } @@ -210,7 +211,7 @@ namespace osu.Game.Rulesets.Edit private void toolSelected(HitObjectCompositionTool tool) { - blueprintContainer.CurrentTool = tool; + BlueprintContainer.CurrentTool = tool; if (tool is SelectTool) distanceSnapGridContainer.Hide(); From 830afe52096961bde1f33201f63e376c654811ce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 19:09:47 +0900 Subject: [PATCH 0324/1142] Make spinner blueprint update values more frequently. Also handle right-click --- .../Spinners/SpinnerPlacementBlueprint.cs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs index 5525b8936e..6d881d5f71 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs @@ -1,13 +1,14 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Graphics; +using System; using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.UI; using osuTK; +using osuTK.Input; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners { @@ -29,22 +30,29 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners { base.Update(); + if (isPlacingEnd) + HitObject.EndTime = Math.Max(HitObject.StartTime, EditorClock.CurrentTime); + piece.UpdateFrom(HitObject); } - protected override bool OnClick(ClickEvent e) + protected override bool OnMouseDown(MouseDownEvent e) { if (isPlacingEnd) { + if (e.Button != MouseButton.Right) + return false; + HitObject.EndTime = EditorClock.CurrentTime; EndPlacement(); } else { - isPlacingEnd = true; - piece.FadeTo(1f, 150, Easing.OutQuint); + if (e.Button != MouseButton.Left) + return false; BeginPlacement(); + isPlacingEnd = true; } return true; From 2e50e56d7c63ab3484bbe0612e94a8edc29315ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 7 Feb 2020 19:12:09 +0900 Subject: [PATCH 0325/1142] Seek to previous object endtime after successful placement --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index d946b2eb7f..df3a1384bb 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -264,7 +264,7 @@ namespace osu.Game.Rulesets.Edit { EditorBeatmap.Add(hitObject); - adjustableClock.Seek(hitObject.StartTime); + adjustableClock.Seek(hitObject.GetEndTime()); } showGridFor(Enumerable.Empty()); From 2d1afb66fb2d9c86b7bae7b930ee65710fe5508b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 7 Feb 2020 16:21:47 +0300 Subject: [PATCH 0326/1142] Add history counts to user api --- osu.Game/Users/User.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 5d0ffd5a67..c573fdd089 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -203,6 +203,21 @@ namespace osu.Game.Users public int ID; } + [JsonProperty("monthly_playcounts")] + public UserHistoryCount[] MonthlyPlaycounts; + + [JsonProperty("replays_watched_counts")] + public UserHistoryCount[] ReplaysWatchedCounts; + + public class UserHistoryCount + { + [JsonProperty("start_date")] + public DateTime Date; + + [JsonProperty("count")] + public long Count; + } + public override string ToString() => Username; /// From 678eb8ec3128a3ef0dd839b852041c72bd0947ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 Feb 2020 00:12:23 +0900 Subject: [PATCH 0327/1142] Reduce accessibility to set Co-Authored-By: Dan Balasescu --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 7b7c154191..f6c73d5e4c 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Edit [Resolved] private IBeatSnapProvider beatSnapProvider { get; set; } - protected ComposeBlueprintContainer BlueprintContainer; + protected ComposeBlueprintContainer BlueprintContainer { get; private set; } private DrawableEditRulesetWrapper drawableRulesetWrapper; private Container distanceSnapGridContainer; From 51edd8827772898e6e5ece224e4507cdeb182dac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 8 Feb 2020 00:28:52 +0900 Subject: [PATCH 0328/1142] Add back fade --- .../Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs index 6d881d5f71..48c1ce11e0 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Graphics; using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners.Components; @@ -52,6 +53,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners return false; BeginPlacement(); + piece.FadeTo(1f, 150, Easing.OutQuint); + isPlacingEnd = true; } From 7395f01919a6710fda4127676b6482e06d882676 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Fri, 7 Feb 2020 20:28:02 +0100 Subject: [PATCH 0329/1142] Use osu-web font sizes --- osu.Game/Overlays/BeatmapSet/Header.cs | 2 +- osu.Game/Overlays/BeatmapSet/Info.cs | 2 +- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 4 ++-- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 1b111ced1f..ab7b2d82ed 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -196,7 +196,7 @@ namespace osu.Game.Overlays.BeatmapSet { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - TextSize = 17, + TextSize = 14, TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 } }, Details = new Details(), diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index a71409a05f..0a5415124e 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -118,7 +118,7 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.Centre, Alpha = 0, Text = "Unranked beatmap", - Font = OsuFont.GetFont(size: 13) + Font = OsuFont.GetFont(size: 12) }, }, }, diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 2310b2a0f5..7f55aecaf0 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private const float horizontal_inset = 20; private const float row_height = 25; - private const int text_size = 14; + private const int text_size = 12; private readonly FillFlowContainer backgroundFlow; @@ -190,7 +190,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public HeaderText(string text) { Text = text.ToUpper(); - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold); + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold); } [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 00171e1170..8a368aa535 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -96,7 +96,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12) + Font = OsuFont.GetFont(size: 10) }, flag = new UpdateableFlag { From 59cf2037d062b7af68e7ea912a5a5715d1016d5a Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Fri, 7 Feb 2020 21:11:58 +0100 Subject: [PATCH 0330/1142] Introduce SortedStatistics --- osu.Game/Scoring/ScoreInfo.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Scoring/ScoreInfo.cs b/osu.Game/Scoring/ScoreInfo.cs index bed9104cad..a40f436a6e 100644 --- a/osu.Game/Scoring/ScoreInfo.cs +++ b/osu.Game/Scoring/ScoreInfo.cs @@ -151,6 +151,8 @@ namespace osu.Game.Scoring [JsonProperty("statistics")] public Dictionary Statistics = new Dictionary(); + public IOrderedEnumerable> SortedStatistics => Statistics.OrderByDescending(pair => pair.Key); + [JsonIgnore] [Column("Statistics")] public string StatisticsJson From 2770fb71b251fa315be1af4a83b1993ba5838e55 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Fri, 7 Feb 2020 21:12:21 +0100 Subject: [PATCH 0331/1142] Use SortedStatistics where needed --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 4 ++-- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 4 +--- osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 7a17412722..758140a12d 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -82,7 +82,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new TableColumn("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 90)) }; - foreach (var statistic in score.Statistics) + foreach (var statistic in score.SortedStatistics) columns.Add(new TableColumn(statistic.Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70))); columns.AddRange(new[] @@ -150,7 +150,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } }); - foreach (var kvp in score.Statistics) + foreach (var kvp in score.SortedStatistics) { content.Add(new OsuSpriteText { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 8a17fef367..6c9f0b0321 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -99,9 +99,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores maxComboColumn.Text = $@"{value.MaxCombo:N0}x"; ppColumn.Text = $@"{value.PP:N0}"; - statisticsColumns.ChildrenEnumerable = value.Statistics - .OrderByDescending(pair => pair.Key) - .Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); + statisticsColumns.ChildrenEnumerable = value.SortedStatistics.Select(kvp => createStatisticsColumn(kvp.Key, kvp.Value)); modsColumn.Mods = value.Mods; } } diff --git a/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs b/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs index 43234c0b29..0aab067de1 100644 --- a/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs +++ b/osu.Game/Screens/Ranking/Pages/ScoreResultsPage.cs @@ -188,7 +188,7 @@ namespace osu.Game.Screens.Ranking.Pages }, }; - statisticsContainer.ChildrenEnumerable = Score.Statistics.OrderByDescending(p => p.Key).Select(s => new DrawableScoreStatistic(s)); + statisticsContainer.ChildrenEnumerable = Score.SortedStatistics.Select(s => new DrawableScoreStatistic(s)); } protected override void LoadComplete() From 1ba8cc904a5b72693bad9f5309be5f4ae5f095fd Mon Sep 17 00:00:00 2001 From: jorolf Date: Fri, 7 Feb 2020 21:42:47 +0100 Subject: [PATCH 0332/1142] Make the caret blink to the beat --- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index f5b7bc3073..36740fb015 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -9,6 +10,9 @@ using osu.Game.Graphics.Sprites; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Input.Events; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics.Containers; +using osuTK; namespace osu.Game.Graphics.UserInterface { @@ -59,5 +63,47 @@ namespace osu.Game.Graphics.UserInterface } protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) }; + + protected override Caret CreateCaret() => new BeatCaret + { + CaretWidth = CaretWidth, + SelectionColour = SelectionColour, + }; + + private class BeatCaret : BasicCaret + { + private bool hasSelection; + + public BeatCaret() + { + AddInternal(new CaretBeatSyncedContainer(this)); + } + + public override void DisplayAt(Vector2 position, float? selectionWidth) + { + base.DisplayAt(position, selectionWidth); + + hasSelection = selectionWidth != null; + if (selectionWidth == null) + ClearTransforms(targetMember: nameof(Alpha)); + } + + private class CaretBeatSyncedContainer : BeatSyncedContainer + { + private readonly BeatCaret caret; + + public CaretBeatSyncedContainer(BeatCaret caret) + { + this.caret = caret; + MinimumBeatLength = 300; + } + + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) + { + if (!caret.hasSelection) + caret.FadeTo(0.7f).FadeTo(0.4f, timingPoint.BeatLength, Easing.InOutSine); + } + } + } } } From 8c10d31af947d8ace2265952bfa2bbbea62e2d43 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Fri, 7 Feb 2020 22:09:45 +0100 Subject: [PATCH 0333/1142] Make accuracy formatting more consistent --- osu.Game/Utils/FormatUtils.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs index b3758b3375..f2ab99f4b7 100644 --- a/osu.Game/Utils/FormatUtils.cs +++ b/osu.Game/Utils/FormatUtils.cs @@ -7,18 +7,16 @@ namespace osu.Game.Utils { /// /// Turns the provided accuracy into a percentage with 2 decimal places. - /// Omits all decimal places when equals 1d. /// /// The accuracy to be formatted /// formatted accuracy in percentage - public static string FormatAccuracy(this double accuracy) => accuracy == 1 ? "100%" : $"{accuracy:0.00%}"; + public static string FormatAccuracy(this double accuracy) => $"{accuracy:0.00%}"; /// /// Turns the provided accuracy into a percentage with 2 decimal places. - /// Omits all decimal places when equals 100m. /// /// The accuracy to be formatted /// formatted accuracy in percentage - public static string FormatAccuracy(this decimal accuracy) => accuracy == 100 ? "100%" : $"{accuracy:0.00}%"; + public static string FormatAccuracy(this decimal accuracy) => $"{accuracy:0.00}%"; } } From 393b566966c5cd8d6be9b765ebd79e8e9280f1fd Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Fri, 7 Feb 2020 22:16:06 +0100 Subject: [PATCH 0334/1142] Make PercentageCounter use FormatAccuracy --- osu.Game/Graphics/UserInterface/PercentageCounter.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/PercentageCounter.cs b/osu.Game/Graphics/UserInterface/PercentageCounter.cs index 064c663d59..940c9808ce 100644 --- a/osu.Game/Graphics/UserInterface/PercentageCounter.cs +++ b/osu.Game/Graphics/UserInterface/PercentageCounter.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Allocation; +using osu.Game.Utils; namespace osu.Game.Graphics.UserInterface { @@ -29,10 +30,7 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(OsuColour colours) => AccentColour = colours.BlueLighter; - protected override string FormatCount(double count) - { - return $@"{count:P2}"; - } + protected override string FormatCount(double count) => count.FormatAccuracy(); protected override double GetProportionalDuration(double currentValue, double newValue) { From 9bfd3a1a6348e4f7be4ef305bfbec7b2d207f8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 8 Feb 2020 00:11:19 +0100 Subject: [PATCH 0335/1142] Make PercentageBreakInfoLine use FormatAccuracy --- osu.Game/Screens/Play/Break/BreakInfoLine.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Break/BreakInfoLine.cs b/osu.Game/Screens/Play/Break/BreakInfoLine.cs index 70e7b8f297..18aab394f8 100644 --- a/osu.Game/Screens/Play/Break/BreakInfoLine.cs +++ b/osu.Game/Screens/Play/Break/BreakInfoLine.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Utils; namespace osu.Game.Screens.Play.Break { @@ -85,6 +86,6 @@ namespace osu.Game.Screens.Play.Break { } - protected override string Format(double count) => $@"{count:P2}"; + protected override string Format(double count) => count.FormatAccuracy(); } } From 801e39a5433f12e385c61da0860a640d1d1a617f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 8 Feb 2020 11:35:27 +0900 Subject: [PATCH 0336/1142] Improve xmldoc for PlacementObject --- osu.Game/Screens/Edit/EditorBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index e1f3ddf191..5216e85903 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -39,7 +39,7 @@ namespace osu.Game.Screens.Edit public readonly BindableList SelectedHitObjects = new BindableList(); /// - /// The current placement + /// The current placement. Null if there's no active placement. /// public readonly Bindable PlacementObject = new Bindable(); From e0de60a277c4f9792b889efc1bb44d39e0251f91 Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 7 Feb 2020 21:03:33 -0800 Subject: [PATCH 0337/1142] Update default background dim to 80% to match stable --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 4155381790..6ae3c7ac64 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -78,7 +78,7 @@ namespace osu.Game.Configuration Set(OsuSetting.MenuParallax, true); // Gameplay - Set(OsuSetting.DimLevel, 0.3, 0, 1, 0.01); + Set(OsuSetting.DimLevel, 0.8, 0, 1, 0.01); Set(OsuSetting.BlurLevel, 0, 0, 1, 0.01); Set(OsuSetting.LightenDuringBreaks, true); From 6d51b344abfc6929f5029044dc01b10f8e9dc28d Mon Sep 17 00:00:00 2001 From: Lucas A Date: Sun, 19 Jan 2020 20:24:46 +0100 Subject: [PATCH 0338/1142] Display a loading animation when the user is connecting --- .../Online/TestSceneOnlineViewContainer.cs | 4 ++ osu.Game/Online/OnlineViewContainer.cs | 57 ++++++++++++++----- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index 4579e4f428..ddb672dbf4 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -57,6 +57,10 @@ namespace osu.Game.Tests.Visual.Online AddStep("set status to online", () => ((DummyAPIAccess)API).State = APIState.Online); AddAssert("children are visible", () => onlineView.Children.First().Parent.IsPresent); + + AddStep("set status to connecting", () => ((DummyAPIAccess)API).State = APIState.Connecting); + + AddAssert("children are hidden", () => !onlineView.Children.First().Parent.IsPresent); } } } diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 0a8432ee12..35296409e5 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.Placeholders; @@ -15,12 +16,13 @@ namespace osu.Game.Online /// public class OnlineViewContainer : Container, IOnlineComponent { - private readonly Container content; private readonly Container placeholderContainer; private readonly Placeholder placeholder; + private readonly LoadingAnimation loading; private const int transform_time = 300; + private readonly Container content; protected override Container Content => content; [Resolved] @@ -40,6 +42,10 @@ namespace osu.Game.Online Alpha = 0, Child = placeholder = new LoginPlaceholder($@"Please sign in to {placeholderMessage}") }, + loading = new LoadingAnimation + { + Alpha = 0, + } }; } @@ -47,29 +53,43 @@ namespace osu.Game.Online { switch (state) { - case APIState.Offline: + case APIState.Failing: case APIState.Connecting: - Schedule(() => updatePlaceholderVisibility(true)); + Schedule(() => UpdatePlaceholderVisibility(PlaceholderStatus.Connecting)); break; - default: - Schedule(() => updatePlaceholderVisibility(false)); + case APIState.Offline: + Schedule(() => UpdatePlaceholderVisibility(PlaceholderStatus.Offline)); + break; + + case APIState.Online: + Schedule(() => UpdatePlaceholderVisibility(PlaceholderStatus.Online)); break; } } - private void updatePlaceholderVisibility(bool showPlaceholder) + protected void UpdatePlaceholderVisibility(PlaceholderStatus status) { - if (showPlaceholder) + switch (status) { - content.FadeOut(150, Easing.OutQuint); - placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_time, Easing.OutQuint); - placeholderContainer.FadeInFromZero(2 * transform_time, Easing.OutQuint); - } - else - { - placeholderContainer.FadeOut(150, Easing.OutQuint); - content.FadeIn(transform_time, Easing.OutQuint); + case PlaceholderStatus.Offline: + Content.FadeOut(150, Easing.OutQuint); + placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_time, Easing.OutQuint); + placeholderContainer.FadeInFromZero(2 * transform_time, Easing.OutQuint); + loading.Hide(); + break; + + case PlaceholderStatus.Online: + placeholderContainer.FadeOut(150, Easing.OutQuint); + Content.FadeIn(transform_time, Easing.OutQuint); + loading.Hide(); + break; + + case PlaceholderStatus.Connecting: + loading.Show(); + placeholderContainer.FadeOut(150, Easing.OutQuint); + Content.FadeOut(150, Easing.OutQuint); + break; } } @@ -84,5 +104,12 @@ namespace osu.Game.Online API?.Unregister(this); base.Dispose(isDisposing); } + + protected enum PlaceholderStatus + { + Offline, + Online, + Connecting, + } } } From d3dc0b63ff9cc9715b5e46909e39ef76435d5007 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 23 Jan 2020 19:09:34 +0100 Subject: [PATCH 0339/1142] Remove string concatenation from ctor --- osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs | 2 +- osu.Game/Online/OnlineViewContainer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index ddb672dbf4..fddb82d400 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Online Child = new Container { RelativeSizeAxes = Axes.Both, - Child = onlineView = new OnlineViewContainer(@"view dummy test content") + Child = onlineView = new OnlineViewContainer(@"Please sign in to view dummy test content") { RelativeSizeAxes = Axes.Both, Children = new Drawable[] diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 35296409e5..49174320d3 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -40,7 +40,7 @@ namespace osu.Game.Online { RelativeSizeAxes = Axes.Both, Alpha = 0, - Child = placeholder = new LoginPlaceholder($@"Please sign in to {placeholderMessage}") + Child = placeholder = new LoginPlaceholder(placeholderMessage) }, loading = new LoadingAnimation { From 7ca9f4dc2091c56bd66b11365cbc2dfaa403e4df Mon Sep 17 00:00:00 2001 From: Lucas A Date: Fri, 24 Jan 2020 21:10:31 +0100 Subject: [PATCH 0340/1142] Apply review suggestions --- .../Online/TestSceneOnlineViewContainer.cs | 85 ++++++++++++------- osu.Game/Online/OnlineViewContainer.cs | 48 +++-------- 2 files changed, 66 insertions(+), 67 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index fddb82d400..277146e4be 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -1,14 +1,13 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using osu.Game.Online; using osu.Game.Online.API; using osuTK.Graphics; @@ -18,49 +17,75 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestSceneOnlineViewContainer : OsuTestScene { - private readonly OnlineViewContainer onlineView; + private readonly TestOnlineViewContainer onlineView; public TestSceneOnlineViewContainer() { Child = new Container { RelativeSizeAxes = Axes.Both, - Child = onlineView = new OnlineViewContainer(@"Please sign in to view dummy test content") - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Blue.Opacity(0.8f), - }, - new OsuSpriteText - { - Text = "dummy online content", - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } - } - } + Child = onlineView = new TestOnlineViewContainer() }; } - [BackgroundDependencyLoader] - private void load() + private class TestOnlineViewContainer : OnlineViewContainer + { + public new Container Content => base.Content; + + public new LoadingAnimation LoadingAnimation => base.LoadingAnimation; + + public TestOnlineViewContainer() + : base(@"Please sign in to view dummy test content") + { + RelativeSizeAxes = Axes.Both; + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Blue.Opacity(0.8f), + }, + new OsuSpriteText + { + Text = "dummy online content", + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + } + } + + [Test] + public void TestOnlineStateVisibility() + { + AddStep("set status to online", () => ((DummyAPIAccess)API).State = APIState.Online); + + AddAssert("children are visible", () => onlineView.Content.IsPresent); + AddAssert("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); + } + + [Test] + public void TestOfflineStateVisibility() { AddStep("set status to offline", () => ((DummyAPIAccess)API).State = APIState.Offline); - AddAssert("children are hidden", () => !onlineView.Children.First().Parent.IsPresent); - - AddStep("set status to online", () => ((DummyAPIAccess)API).State = APIState.Online); - - AddAssert("children are visible", () => onlineView.Children.First().Parent.IsPresent); + AddAssert("children are hidden", () => !onlineView.Content.IsPresent); + AddAssert("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); + } + [Test] + public void TestConnectingStateVisibility() + { AddStep("set status to connecting", () => ((DummyAPIAccess)API).State = APIState.Connecting); - AddAssert("children are hidden", () => !onlineView.Children.First().Parent.IsPresent); + AddAssert("children are hidden", () => !onlineView.Content.IsPresent); + AddAssert("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); + + AddStep("set status to failing", () => ((DummyAPIAccess)API).State = APIState.Failing); + + AddAssert("children are hidden", () => !onlineView.Content.IsPresent); + AddAssert("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); } } } diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 49174320d3..7874a9fcaf 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -14,16 +14,15 @@ namespace osu.Game.Online /// A for dislaying online content who require a local user to be logged in. /// Shows its children only when the local user is logged in and supports displaying a placeholder if not. /// - public class OnlineViewContainer : Container, IOnlineComponent + public abstract class OnlineViewContainer : Container, IOnlineComponent { private readonly Container placeholderContainer; private readonly Placeholder placeholder; - private readonly LoadingAnimation loading; + protected readonly LoadingAnimation LoadingAnimation; private const int transform_time = 300; - private readonly Container content; - protected override Container Content => content; + protected override Container Content { get; } [Resolved] protected IAPIProvider API { get; private set; } @@ -32,7 +31,7 @@ namespace osu.Game.Online { InternalChildren = new Drawable[] { - content = new Container + Content = new Container { RelativeSizeAxes = Axes.Both, }, @@ -42,7 +41,7 @@ namespace osu.Game.Online Alpha = 0, Child = placeholder = new LoginPlaceholder(placeholderMessage) }, - loading = new LoadingAnimation + LoadingAnimation = new LoadingAnimation { Alpha = 0, } @@ -53,40 +52,22 @@ namespace osu.Game.Online { switch (state) { - case APIState.Failing: - case APIState.Connecting: - Schedule(() => UpdatePlaceholderVisibility(PlaceholderStatus.Connecting)); - break; - case APIState.Offline: - Schedule(() => UpdatePlaceholderVisibility(PlaceholderStatus.Offline)); - break; - - case APIState.Online: - Schedule(() => UpdatePlaceholderVisibility(PlaceholderStatus.Online)); - break; - } - } - - protected void UpdatePlaceholderVisibility(PlaceholderStatus status) - { - switch (status) - { - case PlaceholderStatus.Offline: Content.FadeOut(150, Easing.OutQuint); placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_time, Easing.OutQuint); placeholderContainer.FadeInFromZero(2 * transform_time, Easing.OutQuint); - loading.Hide(); + LoadingAnimation.Hide(); break; - case PlaceholderStatus.Online: + case APIState.Online: placeholderContainer.FadeOut(150, Easing.OutQuint); Content.FadeIn(transform_time, Easing.OutQuint); - loading.Hide(); + LoadingAnimation.Hide(); break; - case PlaceholderStatus.Connecting: - loading.Show(); + case APIState.Failing: + case APIState.Connecting: + LoadingAnimation.Show(); placeholderContainer.FadeOut(150, Easing.OutQuint); Content.FadeOut(150, Easing.OutQuint); break; @@ -104,12 +85,5 @@ namespace osu.Game.Online API?.Unregister(this); base.Dispose(isDisposing); } - - protected enum PlaceholderStatus - { - Offline, - Online, - Connecting, - } } } From 30e0a34e50d083af8726aaaff54fde5c3133f4b0 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 5 Feb 2020 15:04:10 +0100 Subject: [PATCH 0341/1142] Wrap Content into a container for animating visibility. --- .../Online/TestSceneOnlineViewContainer.cs | 14 ++++--- osu.Game/Online/OnlineViewContainer.cs | 39 ++++++++++--------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index 277146e4be..5427db5af3 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -30,8 +30,6 @@ namespace osu.Game.Tests.Visual.Online private class TestOnlineViewContainer : OnlineViewContainer { - public new Container Content => base.Content; - public new LoadingAnimation LoadingAnimation => base.LoadingAnimation; public TestOnlineViewContainer() @@ -54,6 +52,10 @@ namespace osu.Game.Tests.Visual.Online } }; } + + protected override void FadeContentOut(Drawable content) => content.Hide(); + + protected override void FadeContentIn(Drawable content) => content.Show(); } [Test] @@ -61,7 +63,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to online", () => ((DummyAPIAccess)API).State = APIState.Online); - AddAssert("children are visible", () => onlineView.Content.IsPresent); + AddAssert("children are visible", () => onlineView.TransformationTarget.IsPresent); AddAssert("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); } @@ -70,7 +72,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to offline", () => ((DummyAPIAccess)API).State = APIState.Offline); - AddAssert("children are hidden", () => !onlineView.Content.IsPresent); + AddAssert("children are hidden", () => !onlineView.TransformationTarget.IsPresent); AddAssert("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); } @@ -79,12 +81,12 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to connecting", () => ((DummyAPIAccess)API).State = APIState.Connecting); - AddAssert("children are hidden", () => !onlineView.Content.IsPresent); + AddAssert("children are hidden", () => !onlineView.TransformationTarget.IsPresent); AddAssert("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); AddStep("set status to failing", () => ((DummyAPIAccess)API).State = APIState.Failing); - AddAssert("children are hidden", () => !onlineView.Content.IsPresent); + AddAssert("children are hidden", () => !onlineView.TransformationTarget.IsPresent); AddAssert("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); } } diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 7874a9fcaf..ac5a7941ea 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -11,36 +11,35 @@ using osu.Game.Online.Placeholders; namespace osu.Game.Online { /// - /// A for dislaying online content who require a local user to be logged in. + /// A for dislaying online content which require a local user to be logged in. /// Shows its children only when the local user is logged in and supports displaying a placeholder if not. /// public abstract class OnlineViewContainer : Container, IOnlineComponent { - private readonly Container placeholderContainer; private readonly Placeholder placeholder; protected readonly LoadingAnimation LoadingAnimation; - private const int transform_time = 300; + protected const double TRANSFORM_TIME = 300.0; + internal readonly Container TransformationTarget; protected override Container Content { get; } [Resolved] protected IAPIProvider API { get; private set; } - public OnlineViewContainer(string placeholderMessage) + protected OnlineViewContainer(string placeholderMessage) { InternalChildren = new Drawable[] { - Content = new Container + TransformationTarget = new Container { RelativeSizeAxes = Axes.Both, + Child = Content = new Container + { + RelativeSizeAxes = Axes.Both, + } }, - placeholderContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - Child = placeholder = new LoginPlaceholder(placeholderMessage) - }, + placeholder = new LoginPlaceholder(placeholderMessage), LoadingAnimation = new LoadingAnimation { Alpha = 0, @@ -53,27 +52,31 @@ namespace osu.Game.Online switch (state) { case APIState.Offline: - Content.FadeOut(150, Easing.OutQuint); - placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_time, Easing.OutQuint); - placeholderContainer.FadeInFromZero(2 * transform_time, Easing.OutQuint); + FadeContentOut(TransformationTarget); + placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * TRANSFORM_TIME, Easing.OutQuint); + placeholder.FadeInFromZero(2 * TRANSFORM_TIME, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Online: - placeholderContainer.FadeOut(150, Easing.OutQuint); - Content.FadeIn(transform_time, Easing.OutQuint); + FadeContentIn(TransformationTarget); + placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Failing: case APIState.Connecting: + FadeContentOut(TransformationTarget); LoadingAnimation.Show(); - placeholderContainer.FadeOut(150, Easing.OutQuint); - Content.FadeOut(150, Easing.OutQuint); + placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); break; } } + protected abstract void FadeContentOut(Drawable content); + + protected abstract void FadeContentIn(Drawable content); + protected override void LoadComplete() { API?.Register(this); From 5b452293d6055754bf007582c5a151a9ad859ede Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Sat, 8 Feb 2020 18:05:27 +0100 Subject: [PATCH 0342/1142] Minor cleanups for legacy beatmap decoders Replaces some string.StartsWith(string, StringComparison.Ordinal) calls with ring.StartsWith(char) , when only one char is compared. Possible since .NET-Standard 2.1 And another LegacyStoryboardDecoder.handleEvents() cleanup, saves some MB of allocations. --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 11 ++++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 009da0656b..4b01b2490e 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -64,7 +64,7 @@ namespace osu.Game.Beatmaps.Formats hitObject.ApplyDefaults(this.beatmap.ControlPointInfo, this.beatmap.BeatmapInfo.BaseDifficulty); } - protected override bool ShouldSkipLine(string line) => base.ShouldSkipLine(line) || line.StartsWith(" ", StringComparison.Ordinal) || line.StartsWith("_", StringComparison.Ordinal); + protected override bool ShouldSkipLine(string line) => base.ShouldSkipLine(line) || line.StartsWith(' ') || line.StartsWith('_'); protected override void ParseLine(Beatmap beatmap, Section section, string line) { diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 0ec80eee41..e28e235788 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -33,7 +33,7 @@ namespace osu.Game.Beatmaps.Formats if (ShouldSkipLine(line)) continue; - if (line.StartsWith(@"[", StringComparison.Ordinal) && line.EndsWith(@"]", StringComparison.Ordinal)) + if (line.StartsWith('[') && line.EndsWith(']')) { if (!Enum.TryParse(line[1..^1], out section)) { diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 35576e0f33..6569f76b2d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -64,15 +64,16 @@ namespace osu.Game.Beatmaps.Formats private void handleEvents(string line) { var depth = 0; - var lineSpan = line.AsSpan(); - while (lineSpan.StartsWith(" ", StringComparison.Ordinal) || lineSpan.StartsWith("_", StringComparison.Ordinal)) + foreach (char c in line) { - lineSpan = lineSpan.Slice(1); - ++depth; + if (c == ' ' || c == '_') + depth++; + else + break; } - line = lineSpan.ToString(); + line = line.Substring(depth); decodeVariables(ref line); From c2e0c83724f0d981c780d5a1fb337c84f4248db7 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 8 Feb 2020 20:25:16 +0100 Subject: [PATCH 0343/1142] change the hierarchy layout --- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 69 +++++++++++++++---- 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index 36740fb015..d58a22685e 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.Sprites; using osuTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics.Containers; @@ -70,38 +71,82 @@ namespace osu.Game.Graphics.UserInterface SelectionColour = SelectionColour, }; - private class BeatCaret : BasicCaret + private class BeatCaret : Caret { - private bool hasSelection; + private const float caret_move_time = 60; + + private readonly CaretBeatSyncedContainer beatSync; public BeatCaret() { - AddInternal(new CaretBeatSyncedContainer(this)); + RelativeSizeAxes = Axes.Y; + Size = new Vector2(1, 0.9f); + + Colour = Color4.Transparent; + Anchor = Anchor.CentreLeft; + Origin = Anchor.CentreLeft; + + Masking = true; + CornerRadius = 1; + InternalChild = beatSync = new CaretBeatSyncedContainer + { + RelativeSizeAxes = Axes.Both, + }; } + public override void Hide() => this.FadeOut(200); + + public float CaretWidth { get; set; } + + public Color4 SelectionColour { get; set; } + public override void DisplayAt(Vector2 position, float? selectionWidth) { - base.DisplayAt(position, selectionWidth); + beatSync.HasSelection = selectionWidth != null; - hasSelection = selectionWidth != null; - if (selectionWidth == null) - ClearTransforms(targetMember: nameof(Alpha)); + if (selectionWidth != null) + { + this.MoveTo(new Vector2(position.X, position.Y), 60, Easing.Out); + this.ResizeWidthTo(selectionWidth.Value + CaretWidth / 2, caret_move_time, Easing.Out); + this.FadeColour(SelectionColour, 200, Easing.Out); + } + else + { + this.MoveTo(new Vector2(position.X - CaretWidth / 2, position.Y), 60, Easing.Out); + this.ResizeWidthTo(CaretWidth, caret_move_time, Easing.Out); + this.FadeColour(Color4.White, 200, Easing.Out); + } } private class CaretBeatSyncedContainer : BeatSyncedContainer { - private readonly BeatCaret caret; + private bool hasSelection; - public CaretBeatSyncedContainer(BeatCaret caret) + public bool HasSelection + { + set + { + hasSelection = value; + if (value) + + this.FadeTo(0.5f, 200, Easing.Out); + } + } + + public CaretBeatSyncedContainer() { - this.caret = caret; MinimumBeatLength = 300; + InternalChild = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.White, + }; } protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) { - if (!caret.hasSelection) - caret.FadeTo(0.7f).FadeTo(0.4f, timingPoint.BeatLength, Easing.InOutSine); + if (!hasSelection) + this.FadeTo(0.7f).FadeTo(0.4f, timingPoint.BeatLength, Easing.InOutSine); } } } From 93ff25d2a43ee62c40c46e4489515e51f39f5395 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 9 Feb 2020 15:36:44 +0900 Subject: [PATCH 0344/1142] Rename caret class --- osu.Game/Graphics/UserInterface/OsuTextBox.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuTextBox.cs b/osu.Game/Graphics/UserInterface/OsuTextBox.cs index d58a22685e..4abbf8db57 100644 --- a/osu.Game/Graphics/UserInterface/OsuTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuTextBox.cs @@ -65,19 +65,19 @@ namespace osu.Game.Graphics.UserInterface protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) }; - protected override Caret CreateCaret() => new BeatCaret + protected override Caret CreateCaret() => new OsuCaret { CaretWidth = CaretWidth, SelectionColour = SelectionColour, }; - private class BeatCaret : Caret + private class OsuCaret : Caret { private const float caret_move_time = 60; private readonly CaretBeatSyncedContainer beatSync; - public BeatCaret() + public OsuCaret() { RelativeSizeAxes = Axes.Y; Size = new Vector2(1, 0.9f); From 590429b43ba9ba9f12e0e7914d52fe866daf1a03 Mon Sep 17 00:00:00 2001 From: ProTheory8 Date: Sun, 9 Feb 2020 09:15:32 +0000 Subject: [PATCH 0345/1142] Now TestAutoOpenOnModSelect checks if customisation closes after deselecting mod --- osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index 22ba972390..a9353d189f 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void TestCustomisationOpensOnModSelect() + public void TestAutoOpenOnModSelect() { createModSelect(); @@ -71,6 +71,8 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("Customisation closed", () => modSelect.ModSettingsContainer.Alpha == 0); AddStep("select mod", () => modSelect.SelectMod(testCustomisableAutoOpenMod)); AddAssert("Customisation opened", () => modSelect.ModSettingsContainer.Alpha == 1); + AddStep("deselect mod", () => modSelect.SelectMod(testCustomisableAutoOpenMod)); + AddAssert("Customisation closed", () => modSelect.ModSettingsContainer.Alpha == 0); } private void createModSelect() From d73ef7c37e86639fbbeac95431077ba2d374201d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 9 Feb 2020 21:25:11 +0900 Subject: [PATCH 0346/1142] Change DummyBeatmap's track to be 0 length --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 05c344b199..30f2045a83 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps switch (lastObject) { case null: - length = excess_length; + length = 0; break; case IHasEndTime endTime: From c1f52ef5941dd5c84c3dd6432ccf261558dce8ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 9 Feb 2020 21:25:28 +0900 Subject: [PATCH 0347/1142] Refactor BeatSyncContainer to handle zero length tracks --- .../Containers/BeatSyncedContainer.cs | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index be9aefa359..f36079682e 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -59,9 +59,9 @@ namespace osu.Game.Graphics.Containers Track track = null; IBeatmap beatmap = null; - double currentTrackTime; - TimingControlPoint timingPoint; - EffectControlPoint effectPoint; + double currentTrackTime = 0; + TimingControlPoint timingPoint = null; + EffectControlPoint effectPoint = null; if (Beatmap.Value.TrackLoaded && Beatmap.Value.BeatmapLoaded) { @@ -69,24 +69,18 @@ namespace osu.Game.Graphics.Containers beatmap = Beatmap.Value.Beatmap; } - if (track != null && beatmap != null && track.IsRunning) + if (track != null && beatmap != null && track.IsRunning && track.Length > 0) { - currentTrackTime = track.Length > 0 ? track.CurrentTime + EarlyActivationMilliseconds : Clock.CurrentTime; + currentTrackTime = track.CurrentTime + EarlyActivationMilliseconds; timingPoint = beatmap.ControlPointInfo.TimingPointAt(currentTrackTime); effectPoint = beatmap.ControlPointInfo.EffectPointAt(currentTrackTime); - - if (timingPoint.BeatLength == 0) - { - IsBeatSyncedWithTrack = false; - return; - } - - IsBeatSyncedWithTrack = true; } - else + + IsBeatSyncedWithTrack = timingPoint?.BeatLength > 0; + + if (timingPoint == null || !IsBeatSyncedWithTrack) { - IsBeatSyncedWithTrack = false; currentTrackTime = Clock.CurrentTime; timingPoint = defaultTiming; effectPoint = defaultEffect; From 96574a98adc8b48c2637aabc3287562eb8893f06 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 9 Feb 2020 21:34:56 +0900 Subject: [PATCH 0348/1142] Use non-zero length for fallback virtual track (allows tests to work as expected) --- osu.Game/Beatmaps/WorkingBeatmap.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 30f2045a83..5dc483b61c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -39,7 +39,7 @@ namespace osu.Game.Beatmaps BeatmapSetInfo = beatmapInfo.BeatmapSet; Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); - track = new RecyclableLazy(() => GetTrack() ?? GetVirtualTrack()); + track = new RecyclableLazy(() => GetTrack() ?? GetVirtualTrack(1000)); background = new RecyclableLazy(GetBackground, BackgroundStillValid); waveform = new RecyclableLazy(GetWaveform); storyboard = new RecyclableLazy(GetStoryboard); @@ -48,7 +48,7 @@ namespace osu.Game.Beatmaps total_count.Value++; } - protected virtual Track GetVirtualTrack() + protected virtual Track GetVirtualTrack(double emptyLength = 0) { const double excess_length = 1000; @@ -59,7 +59,7 @@ namespace osu.Game.Beatmaps switch (lastObject) { case null: - length = 0; + length = emptyLength; break; case IHasEndTime endTime: From 404cb613429289faa85d05bdfcf1be181ecb6c69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 9 Feb 2020 14:39:27 +0100 Subject: [PATCH 0349/1142] Open mod select in a more reliable way --- .../Visual/UserInterface/TestSceneModSettings.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index a9353d189f..7781eeb315 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -38,8 +38,8 @@ namespace osu.Game.Tests.Visual.UserInterface public void TestButtonShowsOnCustomisableMod() { createModSelect(); + openModSelect(); - AddStep("open", () => modSelect.Show()); AddAssert("button disabled", () => !modSelect.CustomiseButton.Enabled.Value); AddUntilStep("wait for button load", () => modSelect.ButtonsLoaded); AddStep("select mod", () => modSelect.SelectMod(testCustomisableMod)); @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddAssert("mods still active", () => SelectedMods.Value.Count == 1); - AddStep("open", () => modSelect.Show()); + openModSelect(); AddAssert("button enabled", () => modSelect.CustomiseButton.Enabled.Value); } @@ -66,8 +66,8 @@ namespace osu.Game.Tests.Visual.UserInterface public void TestAutoOpenOnModSelect() { createModSelect(); + openModSelect(); - AddStep("open", () => modSelect.Show()); AddAssert("Customisation closed", () => modSelect.ModSettingsContainer.Alpha == 0); AddStep("select mod", () => modSelect.SelectMod(testCustomisableAutoOpenMod)); AddAssert("Customisation opened", () => modSelect.ModSettingsContainer.Alpha == 1); @@ -88,6 +88,12 @@ namespace osu.Game.Tests.Visual.UserInterface }); } + private void openModSelect() + { + AddStep("open", () => modSelect.Show()); + AddUntilStep("wait for ready", () => modSelect.State.Value == Visibility.Visible && modSelect.ButtonsLoaded); + } + private class TestModSelectOverlay : ModSelectOverlay { public new Container ModSettingsContainer => base.ModSettingsContainer; From 7e28f2fe6aae19fdf91e68211cca5c0d19bee6be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 9 Feb 2020 14:41:02 +0100 Subject: [PATCH 0350/1142] Rename test to better reflect its purpose --- osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs index 7781eeb315..7ff463361a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSettings.cs @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.UserInterface } [Test] - public void TestAutoOpenOnModSelect() + public void TestCustomisationMenuVisibility() { createModSelect(); openModSelect(); From b45f1ef99a6489984534cf86ac219469b6d0265f Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Sun, 9 Feb 2020 22:27:37 +0100 Subject: [PATCH 0351/1142] make timestamps hoverable --- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index 096e91b65b..485ca100c6 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -50,7 +51,7 @@ namespace osu.Game.Overlays.BeatmapSet fields.Children = new Drawable[] { new Field("mapped by", BeatmapSet.Metadata.Author.Username, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)), - new Field("submitted on", online.Submitted.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold)) + new Field("submitted", online.Submitted, OsuFont.GetFont(weight: FontWeight.Bold)) { Margin = new MarginPadding { Top = 5 }, }, @@ -58,11 +59,11 @@ namespace osu.Game.Overlays.BeatmapSet if (online.Ranked.HasValue) { - fields.Add(new Field("ranked on", online.Ranked.Value.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold))); + fields.Add(new Field("ranked", online.Ranked.Value, OsuFont.GetFont(weight: FontWeight.Bold))); } else if (online.LastUpdated.HasValue) { - fields.Add(new Field("last updated on", online.LastUpdated.Value.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold))); + fields.Add(new Field("last updated", online.LastUpdated.Value, OsuFont.GetFont(weight: FontWeight.Bold))); } } @@ -126,6 +127,25 @@ namespace osu.Game.Overlays.BeatmapSet }, }; } + + public Field(string first, DateTimeOffset second, FontUsage secondFont) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + + Children = new[] + { + new OsuSpriteText + { + Text = $"{first} ", + Font = OsuFont.GetFont(size: 13) + }, + new DrawableDate(second) + { + Font = secondFont.With(size: 13) + } + }; + } } } } From 867c7338093934caf6164ba27029b3e65d006614 Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Sun, 9 Feb 2020 23:19:32 +0100 Subject: [PATCH 0352/1142] make score date hoverable --- .../BeatmapSet/Scores/TopScoreUserSection.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 72a7efd777..ba1db8ef03 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,7 +13,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.Leaderboards; using osu.Game.Scoring; using osu.Game.Users.Drawables; -using osu.Game.Utils; using osuTK; using osuTK.Graphics; @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly UpdateableRank rank; private readonly UpdateableAvatar avatar; private readonly LinkFlowContainer usernameText; - private readonly SpriteText date; + private readonly DrawableDate achievedOn; private readonly UpdateableFlag flag; public TopScoreUserSection() @@ -92,11 +92,24 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, }, - date = new OsuSpriteText + new FillFlowContainer() { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) + Children = new[] + { + new OsuSpriteText + { + Text = "achieved ", + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) + }, + achievedOn = new DrawableDate(DateTimeOffset.MinValue) + { + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) + }, + } }, flag = new UpdateableFlag { @@ -125,7 +138,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { avatar.User = value.User; flag.Country = value.User.Country; - date.Text = $@"achieved {HumanizerUtils.Humanize(value.Date)}"; + achievedOn.Date = value.Date; usernameText.Clear(); usernameText.AddUserLink(value.User); @@ -134,4 +147,4 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } } -} +} \ No newline at end of file From 3e06324f61770bd6bcee4135c0573d5fc1720b0a Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Sun, 9 Feb 2020 23:39:34 +0100 Subject: [PATCH 0353/1142] fix formatting issue --- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index ba1db8ef03..6c33629c0e 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, }, - new FillFlowContainer() + new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, From ed8cb1d6bf42b35b97370810216404532acb114a Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Sun, 9 Feb 2020 23:46:06 +0100 Subject: [PATCH 0354/1142] add missing eof newline --- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 6c33629c0e..94a6334401 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -147,4 +147,4 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } } -} \ No newline at end of file +} From 88a56d00bfde67ba143e7b1d87a90d5b4ba0b5c4 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Sun, 9 Feb 2020 20:11:37 -0800 Subject: [PATCH 0355/1142] Allow specifying order to SettingSource --- .../Mods/CatchModDifficultyAdjust.cs | 4 +-- .../Mods/OsuModDifficultyAdjust.cs | 4 +-- .../Configuration/SettingSourceAttribute.cs | 28 +++++++++++++++++-- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 4 +-- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 8377b3786a..802802c155 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Fruit Size", "Override a beatmap's set CS.")] + [SettingSource("Fruit Size", "Override a beatmap's set CS.", SettingSourceAttribute.FIRST)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.")] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", SettingSourceAttribute.LAST)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 7eee71be81..5326e36282 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.")] + [SettingSource("Circle Size", "Override a beatmap's set CS.", SettingSourceAttribute.FIRST)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.")] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", SettingSourceAttribute.LAST)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index a3788e4582..79232b70dc 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using JetBrains.Annotations; using osu.Framework.Bindables; @@ -20,14 +21,25 @@ namespace osu.Game.Configuration [AttributeUsage(AttributeTargets.Property)] public class SettingSourceAttribute : Attribute { + public const int FIRST = 0; + public const int ORDERED_RELATIVE = 1; + public const int UNORDERED = 2; + public const int LAST = 3; + public string Label { get; } public string Description { get; } - public SettingSourceAttribute(string label, string description = null) + public int OrderMode { get; } + + public int OrderPosition { get; } + + public SettingSourceAttribute(string label, string description = null, int order = UNORDERED, int orderPosition = 0) { Label = label ?? string.Empty; Description = description ?? string.Empty; + OrderMode = order; + OrderPosition = orderPosition; } } @@ -35,7 +47,7 @@ namespace osu.Game.Configuration { public static IEnumerable CreateSettingsControls(this object obj) { - foreach (var (attr, property) in obj.GetSettingsSourceProperties()) + foreach (var (attr, property) in obj.GetOrderedSettingsSourceProperties()) { object value = property.GetValue(obj); @@ -116,5 +128,17 @@ namespace osu.Game.Configuration yield return (attr, property); } } + + public static IEnumerable<(SettingSourceAttribute, PropertyInfo)> GetOrderedSettingsSourceProperties(this object obj) + { + var original = obj.GetSettingsSourceProperties(); + + var first = original.Where(attr => attr.Item1.OrderMode == SettingSourceAttribute.FIRST); + var orderedRelative = original.Where(attr => attr.Item1.OrderMode == SettingSourceAttribute.ORDERED_RELATIVE).OrderBy(attr => attr.Item1.OrderPosition); + var unordered = original.Where(attr => attr.Item1.OrderMode == SettingSourceAttribute.UNORDERED); + var last = original.Where(attr => attr.Item1.OrderMode == SettingSourceAttribute.LAST); + + return first.Concat(orderedRelative).Concat(unordered).Concat(last); + } } } diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index d74e2ce2bc..8c6b9658b0 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModHardRock) }; - [SettingSource("Drain Rate", "Override a beatmap's set HP.")] + [SettingSource("Drain Rate", "Override a beatmap's set HP.", SettingSourceAttribute.ORDERED_RELATIVE, 1)] public BindableNumber DrainRate { get; } = new BindableFloat { Precision = 0.1f, @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - [SettingSource("Overall Difficulty", "Override a beatmap's set OD.")] + [SettingSource("Overall Difficulty", "Override a beatmap's set OD.", SettingSourceAttribute.ORDERED_RELATIVE, 1)] public BindableNumber OverallDifficulty { get; } = new BindableFloat { Precision = 0.1f, From 137181017b96ae3c7f786295c42023da197691ed Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Sun, 9 Feb 2020 20:36:54 -0800 Subject: [PATCH 0356/1142] Naming consistency with osu!web --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 2 +- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 802802c155..f4754696ff 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Fruit Size", "Override a beatmap's set CS.", SettingSourceAttribute.FIRST)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", SettingSourceAttribute.FIRST)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 8c6b9658b0..fae04dd13e 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModHardRock) }; - [SettingSource("Drain Rate", "Override a beatmap's set HP.", SettingSourceAttribute.ORDERED_RELATIVE, 1)] + [SettingSource("HP Drain", "Override a beatmap's set HP.", SettingSourceAttribute.ORDERED_RELATIVE, 1)] public BindableNumber DrainRate { get; } = new BindableFloat { Precision = 0.1f, @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - [SettingSource("Overall Difficulty", "Override a beatmap's set OD.", SettingSourceAttribute.ORDERED_RELATIVE, 1)] + [SettingSource("Accuracy", "Override a beatmap's set OD.", SettingSourceAttribute.ORDERED_RELATIVE, 1)] public BindableNumber OverallDifficulty { get; } = new BindableFloat { Precision = 0.1f, From 28cf5c7a5983b5ab9f9b6366faf751a94afb695d Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Mon, 10 Feb 2020 14:28:43 +0900 Subject: [PATCH 0357/1142] Add accessor --- osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 55b2b801e7..417d32ca4f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Compose.Components protected DragBox DragBox { get; private set; } - protected Container SelectionBlueprints; + protected Container SelectionBlueprints { get; private set; } private SelectionHandler selectionHandler; From ea521b466fdaa28dda69d8388f3f19a6183f040b Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Sun, 9 Feb 2020 21:37:40 -0800 Subject: [PATCH 0358/1142] Switch numerical consts to an enum --- .../Mods/CatchModDifficultyAdjust.cs | 5 ++-- .../Mods/OsuModDifficultyAdjust.cs | 5 ++-- .../Configuration/SettingSourceAttribute.cs | 25 +++++++++++-------- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 5 ++-- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index f4754696ff..17a2847fd1 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -5,12 +5,13 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; +using static osu.Game.Configuration.SettingSourceAttribute; namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", SettingSourceAttribute.FIRST)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", OrderMode.FIRST)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", SettingSourceAttribute.LAST)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", OrderMode.LAST)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 5326e36282..2b56042ead 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -5,12 +5,13 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; +using static osu.Game.Configuration.SettingSourceAttribute; namespace osu.Game.Rulesets.Osu.Mods { public class OsuModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", SettingSourceAttribute.FIRST)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", OrderMode.FIRST)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", SettingSourceAttribute.LAST)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", OrderMode.LAST)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index 79232b70dc..06e01bb042 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -21,24 +21,27 @@ namespace osu.Game.Configuration [AttributeUsage(AttributeTargets.Property)] public class SettingSourceAttribute : Attribute { - public const int FIRST = 0; - public const int ORDERED_RELATIVE = 1; - public const int UNORDERED = 2; - public const int LAST = 3; + public enum OrderMode + { + FIRST, + ORDERED_RELATIVE, + UNORDERED, + LAST + } public string Label { get; } public string Description { get; } - public int OrderMode { get; } + public OrderMode OrderingMode { get; } public int OrderPosition { get; } - public SettingSourceAttribute(string label, string description = null, int order = UNORDERED, int orderPosition = 0) + public SettingSourceAttribute(string label, string description = null, OrderMode order = OrderMode.UNORDERED, int orderPosition = 0) { Label = label ?? string.Empty; Description = description ?? string.Empty; - OrderMode = order; + OrderingMode = order; OrderPosition = orderPosition; } } @@ -133,10 +136,10 @@ namespace osu.Game.Configuration { var original = obj.GetSettingsSourceProperties(); - var first = original.Where(attr => attr.Item1.OrderMode == SettingSourceAttribute.FIRST); - var orderedRelative = original.Where(attr => attr.Item1.OrderMode == SettingSourceAttribute.ORDERED_RELATIVE).OrderBy(attr => attr.Item1.OrderPosition); - var unordered = original.Where(attr => attr.Item1.OrderMode == SettingSourceAttribute.UNORDERED); - var last = original.Where(attr => attr.Item1.OrderMode == SettingSourceAttribute.LAST); + var first = original.Where(attr => attr.Item1.OrderingMode == SettingSourceAttribute.OrderMode.FIRST); + var orderedRelative = original.Where(attr => attr.Item1.OrderingMode == SettingSourceAttribute.OrderMode.ORDERED_RELATIVE).OrderBy(attr => attr.Item1.OrderPosition); + var unordered = original.Where(attr => attr.Item1.OrderingMode == SettingSourceAttribute.OrderMode.UNORDERED); + var last = original.Where(attr => attr.Item1.OrderingMode == SettingSourceAttribute.OrderMode.LAST); return first.Concat(orderedRelative).Concat(unordered).Concat(last); } diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index fae04dd13e..958a0353ea 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Sprites; using System; using System.Collections.Generic; using osu.Game.Configuration; +using static osu.Game.Configuration.SettingSourceAttribute; namespace osu.Game.Rulesets.Mods { @@ -28,7 +29,7 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModHardRock) }; - [SettingSource("HP Drain", "Override a beatmap's set HP.", SettingSourceAttribute.ORDERED_RELATIVE, 1)] + [SettingSource("HP Drain", "Override a beatmap's set HP.", OrderMode.ORDERED_RELATIVE, 1)] public BindableNumber DrainRate { get; } = new BindableFloat { Precision = 0.1f, @@ -38,7 +39,7 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - [SettingSource("Accuracy", "Override a beatmap's set OD.", SettingSourceAttribute.ORDERED_RELATIVE, 1)] + [SettingSource("Accuracy", "Override a beatmap's set OD.", OrderMode.ORDERED_RELATIVE, 1)] public BindableNumber OverallDifficulty { get; } = new BindableFloat { Precision = 0.1f, From d61516e10c342a02ee20350bb49c7cd69a1eec05 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 Feb 2020 16:59:49 +0900 Subject: [PATCH 0359/1142] Add failing tests --- .../SongSelect/TestScenePlaySongSelect.cs | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 80192b9ebc..a5145f420d 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -17,6 +17,7 @@ using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -426,6 +427,40 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("start not requested", () => !startRequested); } + [TestCase(false)] + [TestCase(true)] + public void TestExternalBeatmapChangeWhileFiltered(bool differentRuleset) + { + createSongSelect(); + addManyTestMaps(); + + changeRuleset(0); + + AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); + + AddStep("set filter text", () => songSelect.FilterControl.ChildrenOfType().First().Text = "nonono"); + + AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap); + + BeatmapInfo target = null; + + AddStep("select beatmap externally", () => + { + target = manager.QueryBeatmapSets(b => b.Beatmaps.Any(bi => bi.RulesetID == (differentRuleset ? 1 : 0))) + .ElementAt(5).Beatmaps.First(); + + Beatmap.Value = manager.GetWorkingBeatmap(target); + }); + + AddUntilStep("correct beatmap selected", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); + AddAssert("carousel also correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID); + + AddStep("reset filter text", () => songSelect.FilterControl.ChildrenOfType().First().Text = string.Empty); + + AddAssert("still selected", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); + AddAssert("carousel also correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID); + } + [Test] public void TestAutoplayViaCtrlEnter() { @@ -468,6 +503,7 @@ namespace osu.Game.Tests.Visual.SongSelect private void importForRuleset(int id) => manager.Import(createTestBeatmapSet(getImportId(), rulesets.AvailableRulesets.Where(r => r.ID == id).ToArray())).Wait(); private static int importId; + private int getImportId() => ++importId; private void checkMusicPlaying(bool playing) => @@ -551,6 +587,8 @@ namespace osu.Game.Tests.Visual.SongSelect public new Bindable Ruleset => base.Ruleset; + public new FilterControl FilterControl => base.FilterControl; + public WorkingBeatmap CurrentBeatmap => Beatmap.Value; public WorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap; public new BeatmapCarousel Carousel => base.Carousel; From 66fb72cd8a476f33f07f408d0c0220d23233d950 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 Feb 2020 16:31:52 +0900 Subject: [PATCH 0360/1142] Fix song select not showing active beatmap if it is filtered by local criteria --- osu.Game/Screens/Select/BeatmapCarousel.cs | 12 ++++++++++++ .../Select/Carousel/CarouselBeatmapSet.cs | 2 +- osu.Game/Screens/Select/Carousel/CarouselItem.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 16 +++++++++++----- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 592e26adc2..5be4d24b2b 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -17,6 +17,7 @@ using osu.Framework.Caching; using osu.Framework.Threading; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Input.Events; +using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Cursor; @@ -229,6 +230,17 @@ namespace osu.Game.Screens.Select if (item != null) { select(item); + + // if we got here and the set is filtered, it means we were bypassing filters. + // in this case, reapplying the filter is necessary to ensure the panel is in the correct place + // (since it is forcefully being included in the carousel). + if (set.Filtered.Value) + { + Debug.Assert(bypassFilters); + + applyActiveCriteria(false, true); + } + return true; } } diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 301d0d4dae..8e323c66e2 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -62,7 +62,7 @@ namespace osu.Game.Screens.Select.Carousel /// /// All beatmaps which are not filtered and valid for display. /// - protected IEnumerable ValidBeatmaps => Beatmaps.Where(b => !b.Filtered.Value).Select(b => b.Beatmap); + protected IEnumerable ValidBeatmaps => Beatmaps.Where(b => !b.Filtered.Value || b.State.Value == CarouselItemState.Selected).Select(b => b.Beatmap); private int compareUsingAggregateMax(CarouselBeatmapSet other, Func func) { diff --git a/osu.Game/Screens/Select/Carousel/CarouselItem.cs b/osu.Game/Screens/Select/Carousel/CarouselItem.cs index 79c1a4cb6b..1108b72bd2 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselItem.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselItem.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Select.Carousel /// /// This item is not in a hidden state. /// - public bool Visible => State.Value != CarouselItemState.Collapsed && !Filtered.Value; + public bool Visible => State.Value == CarouselItemState.Selected || (State.Value != CarouselItemState.Collapsed && !Filtered.Value); public virtual List Drawables { diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 5037081b5e..0da260d752 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -376,16 +376,22 @@ namespace osu.Game.Screens.Select private void workingBeatmapChanged(ValueChangedEvent e) { - if (e.NewValue is DummyWorkingBeatmap) return; + if (e.NewValue is DummyWorkingBeatmap || !this.IsCurrentScreen()) return; - if (this.IsCurrentScreen() && !Carousel.SelectBeatmap(e.NewValue?.BeatmapInfo, false)) + if (!Carousel.SelectBeatmap(e.NewValue.BeatmapInfo, false)) { - // If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch - if (e.NewValue?.BeatmapInfo?.Ruleset != null && !e.NewValue.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) + // A selection may not have been possible with filters applied. + + // There was possibly a ruleset mismatch. This is a case we can help things along by updating the game-wide ruleset to match. + if (e.NewValue.BeatmapInfo.Ruleset != null && !e.NewValue.BeatmapInfo.Ruleset.Equals(decoupledRuleset.Value)) { Ruleset.Value = e.NewValue.BeatmapInfo.Ruleset; - Carousel.SelectBeatmap(e.NewValue.BeatmapInfo); + transferRulesetValue(); } + + // Even if a ruleset mismatch was not the cause (ie. a text filter is applied), + // we still want to forcefully show the new beatmap, bypassing filters. + Carousel.SelectBeatmap(e.NewValue.BeatmapInfo); } } From 2252f790848c8b8e695afab6d28be272229ce0e4 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2020 08:01:14 +0000 Subject: [PATCH 0361/1142] Bump Sentry from 2.0.1 to 2.0.2 Bumps [Sentry](https://github.com/getsentry/sentry-dotnet) from 2.0.1 to 2.0.2. - [Release notes](https://github.com/getsentry/sentry-dotnet/releases) - [Commits](https://github.com/getsentry/sentry-dotnet/compare/2.0.1...2.0.2) 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 21c9eab4c6..389fbe8210 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -24,7 +24,7 @@ - + From a988a53d69fc23585f1aaa08b79b03bb2c31f708 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Feb 2020 16:41:10 +0900 Subject: [PATCH 0362/1142] Better handle beatmap task cancel exception --- osu.Game/Beatmaps/WorkingBeatmap.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 5dc483b61c..1adf502004 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -159,8 +159,16 @@ namespace osu.Game.Beatmaps { return LoadBeatmapAsync().Result; } - catch (TaskCanceledException) + catch (AggregateException ae) { + foreach (var e in ae.InnerExceptions) + { + if (e is TaskCanceledException) + continue; + + Logger.Log(e.ToString()); + } + return null; } } From 51e2a934bdbfa6045ec94ee04f6e629521e8cb9e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Feb 2020 17:00:51 +0900 Subject: [PATCH 0363/1142] Fix possible beatmap nullref in logo visualisation --- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 06ca161fed..dcc68296f6 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Menu private void updateAmplitudes() { var track = beatmap.Value.TrackLoaded ? beatmap.Value.Track : null; - var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.Beatmap.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null; + var effect = beatmap.Value.BeatmapLoaded ? beatmap.Value.Beatmap?.ControlPointInfo.EffectPointAt(track?.CurrentTime ?? Time.Current) : null; float[] temporalAmplitudes = track?.CurrentAmplitudes.FrequencyAmplitudes; From cef682aa03b607079417a9eca096890689c9ec5a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Feb 2020 17:01:41 +0900 Subject: [PATCH 0364/1142] Make WorkingBeatmap non-disposable --- osu.Game.Tests/WaveformTestBeatmap.cs | 4 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 67 ++++++++++++--------------- osu.Game/OsuGame.cs | 11 ++--- osu.Game/Tests/Visual/OsuTestScene.cs | 4 +- 4 files changed, 39 insertions(+), 47 deletions(-) diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs index df6394ed34..53ce5def32 100644 --- a/osu.Game.Tests/WaveformTestBeatmap.cs +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -37,9 +37,9 @@ namespace osu.Game.Tests trackStore = audioManager.GetTrackStore(getZipReader()); } - protected override void Dispose(bool isDisposing) + ~WaveformTestBeatmap() { - base.Dispose(isDisposing); + // Remove the track store from the audio manager trackStore?.Dispose(); } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 1adf502004..6478b33e27 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -17,10 +17,11 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.UI; using osu.Game.Skinning; using osu.Framework.Graphics.Video; +using osu.Framework.Logging; namespace osu.Game.Beatmaps { - public abstract class WorkingBeatmap : IWorkingBeatmap, IDisposable + public abstract class WorkingBeatmap : IWorkingBeatmap { public readonly BeatmapInfo BeatmapInfo; @@ -133,11 +134,29 @@ namespace osu.Game.Beatmaps return converted; } - public override string ToString() => BeatmapInfo.ToString(); + private CancellationTokenSource loadCancellation = new CancellationTokenSource(); - public bool BeatmapLoaded => beatmapLoadTask?.IsCompleted ?? false; + /// + /// Beings loading the contents of this asynchronously. + /// + public void BeginAsyncLoad() + { + loadBeatmapAsync(); + } - public Task LoadBeatmapAsync() => beatmapLoadTask ??= Task.Factory.StartNew(() => + /// + /// Cancels the asynchronous loading of the contents of this . + /// + public void CancelAsyncLoad() + { + loadCancellation?.Cancel(); + loadCancellation = new CancellationTokenSource(); + + if (beatmapLoadTask?.IsCompleted != true) + beatmapLoadTask = null; + } + + private Task loadBeatmapAsync() => beatmapLoadTask ??= Task.Factory.StartNew(() => { // Todo: Handle cancellation during beatmap parsing var b = GetBeatmap() ?? new Beatmap(); @@ -149,7 +168,11 @@ namespace osu.Game.Beatmaps b.BeatmapInfo = BeatmapInfo; return b; - }, beatmapCancellation.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); + }, loadCancellation.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); + + public override string ToString() => BeatmapInfo.ToString(); + + public bool BeatmapLoaded => beatmapLoadTask?.IsCompleted ?? false; public IBeatmap Beatmap { @@ -157,7 +180,7 @@ namespace osu.Game.Beatmaps { try { - return LoadBeatmapAsync().Result; + return loadBeatmapAsync().Result; } catch (AggregateException ae) { @@ -174,7 +197,6 @@ namespace osu.Game.Beatmaps } } - private readonly CancellationTokenSource beatmapCancellation = new CancellationTokenSource(); protected abstract IBeatmap GetBeatmap(); private Task beatmapLoadTask; @@ -225,40 +247,11 @@ namespace osu.Game.Beatmaps ///
public virtual void RecycleTrack() => track.Recycle(); - #region Disposal - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private bool isDisposed; - - protected virtual void Dispose(bool isDisposing) - { - if (isDisposed) - return; - - isDisposed = true; - - // recycling logic is not here for the time being, as components which use - // retrieved objects from WorkingBeatmap may not hold a reference to the WorkingBeatmap itself. - // this should be fine as each retrieved component do have their own finalizers. - - // cancelling the beatmap load is safe for now since the retrieval is a synchronous - // operation. if we add an async retrieval method this may need to be reconsidered. - beatmapCancellation?.Cancel(); - total_count.Value--; - } - ~WorkingBeatmap() { - Dispose(false); + total_count.Value--; } - #endregion - public class RecyclableLazy { private Lazy lazy; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ff3dee55af..f848b1a328 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -401,15 +401,14 @@ namespace osu.Game if (nextBeatmap?.Track != null) nextBeatmap.Track.Completed += currentTrackCompleted; - using (var oldBeatmap = beatmap.OldValue) - { - if (oldBeatmap?.Track != null) - oldBeatmap.Track.Completed -= currentTrackCompleted; - } + var oldBeatmap = beatmap.OldValue; + if (oldBeatmap?.Track != null) + oldBeatmap.Track.Completed -= currentTrackCompleted; updateModDefaults(); - nextBeatmap?.LoadBeatmapAsync(); + oldBeatmap?.CancelAsyncLoad(); + nextBeatmap?.BeginAsyncLoad(); } private void modsChanged(ValueChangedEvent> mods) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 41ab7fce99..b203557fab 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -191,9 +191,9 @@ namespace osu.Game.Tests.Visual track = audio?.Tracks.GetVirtual(length); } - protected override void Dispose(bool isDisposing) + ~ClockBackedTestWorkingBeatmap() { - base.Dispose(isDisposing); + // Remove the track store from the audio manager store?.Dispose(); } From 668f36d7f3286f18bcc8a5c1fd26dcfa198cd512 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Feb 2020 17:04:31 +0900 Subject: [PATCH 0365/1142] Clean up logging --- osu.Game/Beatmaps/WorkingBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 6478b33e27..36479ddbb7 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -189,7 +189,7 @@ namespace osu.Game.Beatmaps if (e is TaskCanceledException) continue; - Logger.Log(e.ToString()); + Logger.Log(e.Message); } return null; From 8186f7250725472fd54039e91f44df57135a2f8d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 Feb 2020 17:12:45 +0900 Subject: [PATCH 0366/1142] Remove unused using --- osu.Game/Screens/Select/BeatmapCarousel.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 5be4d24b2b..7f36a23a86 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -17,7 +17,6 @@ using osu.Framework.Caching; using osu.Framework.Threading; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Input.Events; -using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Cursor; From 48781e5685bee2e428dd03e44b66979a2a8e7ed9 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 10 Feb 2020 08:24:12 +0000 Subject: [PATCH 0367/1142] Bump Microsoft.NET.Test.Sdk from 16.4.0 to 16.5.0 Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 16.4.0 to 16.5.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Commits](https://github.com/microsoft/vstest/compare/v16.4.0...v16.5.0) Signed-off-by: dependabot-preview[bot] --- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 9559d13328..8c371db257 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index dea6e6c0fb..6855b99f28 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 9d4e016eae..217707b180 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index d728d65bfd..f6054a5d6f 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -2,7 +2,7 @@ - + diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 6c799e5e90..35eb3fa161 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -3,7 +3,7 @@ - + diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj index 7ecfd6ef70..3b45fc83fd 100644 --- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj +++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj @@ -5,7 +5,7 @@ - + From 0ab3982494e59b4bad192c901073db53f4fd8034 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 10 Feb 2020 17:25:11 +0900 Subject: [PATCH 0368/1142] Unify error handling --- .../Beatmaps/BeatmapManager_WorkingBeatmap.cs | 15 ++++++++++----- osu.Game/Beatmaps/WorkingBeatmap.cs | 16 +++++++++------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index f9d71a2a6e..55c5175c5d 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -36,8 +36,9 @@ namespace osu.Game.Beatmaps using (var stream = new LineBufferedReader(store.GetStream(getPathForFile(BeatmapInfo.Path)))) return Decoder.GetDecoder(stream).Decode(stream); } - catch + catch (Exception e) { + Logger.Error(e, "Beatmap failed to load"); return null; } } @@ -59,8 +60,9 @@ namespace osu.Game.Beatmaps { return textureStore.Get(getPathForFile(Metadata.BackgroundFile)); } - catch + catch (Exception e) { + Logger.Error(e, "Background failed to load"); return null; } } @@ -74,8 +76,9 @@ namespace osu.Game.Beatmaps { return new VideoSprite(textureStore.GetStream(getPathForFile(Metadata.VideoFile))); } - catch + catch (Exception e) { + Logger.Error(e, "Video failed to load"); return null; } } @@ -86,8 +89,9 @@ namespace osu.Game.Beatmaps { return (trackStore ??= AudioManager.GetTrackStore(store)).Get(getPathForFile(Metadata.AudioFile)); } - catch + catch (Exception e) { + Logger.Error(e, "Track failed to load"); return null; } } @@ -115,8 +119,9 @@ namespace osu.Game.Beatmaps var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); return trackData == null ? null : new Waveform(trackData); } - catch + catch (Exception e) { + Logger.Error(e, "Waveform failed to load"); return null; } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 36479ddbb7..1e1ffad81e 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -184,14 +184,16 @@ namespace osu.Game.Beatmaps } catch (AggregateException ae) { - foreach (var e in ae.InnerExceptions) - { - if (e is TaskCanceledException) - continue; - - Logger.Log(e.Message); - } + // This is the exception that is generally expected here, which occurs via natural cancellation of the asynchronous load + if (ae.InnerExceptions.FirstOrDefault() is TaskCanceledException) + return null; + Logger.Error(ae, "Beatmap failed to load"); + return null; + } + catch (Exception e) + { + Logger.Error(e, "Beatmap failed to load"); return null; } } From 926cde9afc14ecbd3c75b043b22b1383cec4e3f2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 10 Feb 2020 18:17:27 +0900 Subject: [PATCH 0369/1142] Fix potential test failures --- .../Visual/SongSelect/TestScenePlaySongSelect.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index a5145f420d..bd06089514 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -452,13 +452,13 @@ namespace osu.Game.Tests.Visual.SongSelect Beatmap.Value = manager.GetWorkingBeatmap(target); }); - AddUntilStep("correct beatmap selected", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); - AddAssert("carousel also correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID); + AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmap?.OnlineBeatmapID == target.OnlineBeatmapID); + AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); AddStep("reset filter text", () => songSelect.FilterControl.ChildrenOfType().First().Text = string.Empty); - AddAssert("still selected", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); - AddAssert("carousel also correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID); + AddAssert("game still correct", () => Beatmap.Value?.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); + AddAssert("carousel still correct", () => songSelect.Carousel.SelectedBeatmap.OnlineBeatmapID == target.OnlineBeatmapID); } [Test] From 26afe0f31e4df35cfb530fd76d9f9eba83d56e53 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 10 Feb 2020 15:43:11 +0300 Subject: [PATCH 0370/1142] Add ability to load long comment trees in CommentsContainer --- .../Visual/Online/TestSceneCommentsPage.cs | 38 +- .../API/Requests/GetCommentRepliesRequest.cs | 45 ++ .../Online/API/Requests/Responses/Comment.cs | 6 - .../API/Requests/Responses/CommentBundle.cs | 25 +- .../Overlays/Comments/CommentsContainer.cs | 17 +- osu.Game/Overlays/Comments/CommentsPage.cs | 58 ++- osu.Game/Overlays/Comments/DrawableComment.cs | 386 +++++++++++------- .../Comments/GetCommentRepliesButton.cs | 45 ++ .../Overlays/Comments/ShowChildrenButton.cs | 13 +- 9 files changed, 420 insertions(+), 213 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetCommentRepliesRequest.cs create mode 100644 osu.Game/Overlays/Comments/GetCommentRepliesButton.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs index 1217ce6b42..0ed8864860 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneCommentsPage.cs @@ -58,8 +58,8 @@ namespace osu.Game.Tests.Visual.Online } }); - AddStep("load comments", () => createPage(comment_bundle)); - AddStep("load empty comments", () => createPage(empty_comment_bundle)); + AddStep("load comments", () => createPage(getCommentBundle())); + AddStep("load empty comments", () => createPage(getEmptyCommentBundle())); } private void createPage(CommentBundle commentBundle) @@ -71,13 +71,12 @@ namespace osu.Game.Tests.Visual.Online }); } - private static readonly CommentBundle empty_comment_bundle = new CommentBundle + private CommentBundle getEmptyCommentBundle() => new CommentBundle { Comments = new List(), - Total = 0, }; - private static readonly CommentBundle comment_bundle = new CommentBundle + private CommentBundle getCommentBundle() => new CommentBundle { Comments = new List { @@ -90,6 +89,33 @@ namespace osu.Game.Tests.Visual.Online VotesCount = 5 }, new Comment + { + Id = 100, + Message = "This comment has \"load replies\" button because it has unloaded replies", + LegacyName = "TestUser1100", + CreatedAt = DateTimeOffset.Now, + VotesCount = 5, + RepliesCount = 2, + }, + new Comment + { + Id = 111, + Message = "This comment has \"Show More\" button because it has unloaded replies, but some of them are loaded", + LegacyName = "TestUser1111", + CreatedAt = DateTimeOffset.Now, + VotesCount = 100, + RepliesCount = 2, + }, + new Comment + { + Id = 112, + ParentId = 111, + Message = "I'm here to make my parent work", + LegacyName = "someone", + CreatedAt = DateTimeOffset.Now, + VotesCount = 2, + }, + new Comment { Id = 2, Message = "This comment has been deleted :( but visible for admins", @@ -155,8 +181,6 @@ namespace osu.Game.Tests.Visual.Online Username = "Good_Admin" } }, - TopLevelCount = 4, - Total = 7 }; } } diff --git a/osu.Game/Online/API/Requests/GetCommentRepliesRequest.cs b/osu.Game/Online/API/Requests/GetCommentRepliesRequest.cs new file mode 100644 index 0000000000..203f5d5635 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetCommentRepliesRequest.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Humanizer; +using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; +using osu.Game.Overlays.Comments; + +namespace osu.Game.Online.API.Requests +{ + public class GetCommentRepliesRequest : APIRequest + { + private readonly long commentId; + private readonly CommentableType commentableType; + private readonly long commentableId; + private readonly int page; + private readonly CommentsSortCriteria sort; + + public GetCommentRepliesRequest(long commentId, CommentableType commentableType, long commentableId, CommentsSortCriteria sort, int page) + { + this.commentId = commentId; + this.page = page; + this.sort = sort; + + // These parameters are necessary to get deleted comments + this.commentableType = commentableType; + this.commentableId = commentableId; + } + + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + + req.AddParameter("parent_id", commentId.ToString()); + req.AddParameter("sort", sort.ToString().ToLowerInvariant()); + req.AddParameter("commentable_type", commentableType.ToString().Underscore().ToLowerInvariant()); + req.AddParameter("commentable_id", commentableId.ToString()); + req.AddParameter("page", page.ToString()); + + return req; + } + + protected override string Target => "comments"; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 3e38c3067b..05a24cec0e 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -4,8 +4,6 @@ using Newtonsoft.Json; using osu.Game.Users; using System; -using System.Collections.Generic; -using System.Linq; namespace osu.Game.Online.API.Requests.Responses { @@ -17,8 +15,6 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"parent_id")] public long? ParentId { get; set; } - public readonly List ChildComments = new List(); - public Comment ParentComment { get; set; } [JsonProperty(@"user_id")] @@ -71,7 +67,5 @@ namespace osu.Game.Online.API.Requests.Responses public bool HasMessage => !string.IsNullOrEmpty(Message); public bool IsVoted { get; set; } - - public int DeletedChildrenCount => ChildComments.Count(c => c.IsDeleted); } } diff --git a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs index 9b3ef8b6e5..f4c81bf66f 100644 --- a/osu.Game/Online/API/Requests/Responses/CommentBundle.cs +++ b/osu.Game/Online/API/Requests/Responses/CommentBundle.cs @@ -9,31 +9,8 @@ namespace osu.Game.Online.API.Requests.Responses { public class CommentBundle { - private List comments; - [JsonProperty(@"comments")] - public List Comments - { - get => comments; - set - { - comments = value; - comments.ForEach(child => - { - if (child.ParentId != null) - { - comments.ForEach(parent => - { - if (parent.Id == child.ParentId) - { - parent.ChildComments.Add(child); - child.ParentComment = parent; - } - }); - } - }); - } - } + public List Comments { get; set; } [JsonProperty(@"has_more")] public bool HasMore { get; set; } diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs index 33a6be0d7a..751fd8a353 100644 --- a/osu.Game/Overlays/Comments/CommentsContainer.cs +++ b/osu.Game/Overlays/Comments/CommentsContainer.cs @@ -18,8 +18,8 @@ namespace osu.Game.Overlays.Comments { public class CommentsContainer : CompositeDrawable { - private CommentableType type; - private long? id; + private readonly Bindable type = new Bindable(); + private readonly BindableLong id = new BindableLong(); public readonly Bindable Sort = new Bindable(); public readonly BindableBool ShowDeleted = new BindableBool(); @@ -127,8 +127,8 @@ namespace osu.Game.Overlays.Comments /// The id of the resource to get comments for. public void ShowComments(CommentableType type, long id) { - this.type = type; - this.id = id; + this.type.Value = type; + this.id.Value = id; if (!IsLoaded) return; @@ -147,12 +147,12 @@ namespace osu.Game.Overlays.Comments private void getComments() { - if (!id.HasValue) + if (id.Value == 0) return; request?.Cancel(); loadCancellation?.Cancel(); - request = new GetCommentsRequest(type, id.Value, Sort.Value, currentPage++); + request = new GetCommentsRequest(type.Value, id.Value, Sort.Value, currentPage++); request.Success += onSuccess; api.PerformAsync(request); } @@ -172,7 +172,10 @@ namespace osu.Game.Overlays.Comments LoadComponentAsync(new CommentsPage(response) { - ShowDeleted = { BindTarget = ShowDeleted } + ShowDeleted = { BindTarget = ShowDeleted }, + Sort = { BindTarget = Sort }, + Type = { BindTarget = type }, + CommentableId = { BindTarget = id } }, loaded => { content.Add(loaded); diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 153ce676eb..976af72abb 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -9,12 +9,22 @@ using osu.Game.Online.API.Requests.Responses; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Sprites; using System.Linq; +using osu.Game.Online.API.Requests; +using osu.Game.Online.API; +using System.Collections.Generic; +using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Game.Overlays.Comments { public class CommentsPage : CompositeDrawable { public readonly BindableBool ShowDeleted = new BindableBool(); + public readonly Bindable Sort = new Bindable(); + public readonly Bindable Type = new Bindable(); + public readonly BindableLong CommentableId = new BindableLong(); + + [Resolved] + private IAPIProvider api { get; set; } private readonly CommentBundle commentBundle; @@ -52,18 +62,58 @@ namespace osu.Game.Overlays.Comments return; } - foreach (var c in commentBundle.Comments) + foreach (var comment in commentBundle.Comments) { - if (c.IsTopLevel) + var drawableComment = createDrawableComment(comment); + + var children = commentBundle.Comments.Where(c => c.ParentId == comment.Id); + + if (children.Any()) { - flow.Add(new DrawableComment(c) + children.ForEach(c => { - ShowDeleted = { BindTarget = ShowDeleted } + c.ParentComment = comment; }); + drawableComment.OnLoadComplete += loaded => ((DrawableComment)loaded).AddReplies(children.Select(c => createDrawableComment(c))); } + + if (comment.IsTopLevel) + flow.Add(drawableComment); } } + private void onCommentRepliesRequested(DrawableComment drawableComment, int page) + { + var request = new GetCommentRepliesRequest(drawableComment.Comment.Id, Type.Value, CommentableId.Value, Sort.Value, page); + request.Success += response => onCommentRepliesReceived(response, drawableComment); + api.PerformAsync(request); + } + + private void onCommentRepliesReceived(CommentBundle response, DrawableComment drawableComment) + { + var receivedComments = response.Comments; + + var uniqueComments = new List(); + + // We may receive already loaded comments + receivedComments.ForEach(c => + { + if (drawableComment.LoadedReplies.All(loadedReply => loadedReply.Id != c.Id)) + uniqueComments.Add(c); + }); + + uniqueComments.ForEach(c => c.ParentComment = drawableComment.Comment); + + drawableComment.AddReplies(uniqueComments.Select(comment => createDrawableComment(comment))); + } + + private DrawableComment createDrawableComment(Comment comment) => new DrawableComment(comment) + { + ShowDeleted = { BindTarget = ShowDeleted }, + Sort = { BindTarget = Sort }, + RepliesRequested = onCommentRepliesRequested + }; + private class NoCommentsPlaceholder : CompositeDrawable { [BackgroundDependencyLoader] diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 70ea478814..e7aac3c44d 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -12,11 +12,14 @@ using osu.Game.Graphics.Containers; using osu.Game.Utils; using osu.Framework.Graphics.Cursor; using osu.Framework.Bindables; -using osu.Framework.Graphics.Shapes; using System.Linq; using osu.Game.Graphics.Sprites; using osu.Game.Online.Chat; using osu.Framework.Allocation; +using osuTK.Graphics; +using System.Collections.Generic; +using System; +using osu.Framework.Graphics.Shapes; namespace osu.Game.Overlays.Comments { @@ -25,24 +28,35 @@ namespace osu.Game.Overlays.Comments private const int avatar_size = 40; private const int margin = 10; + public Action RepliesRequested; + + public readonly Comment Comment; + public readonly BindableBool ShowDeleted = new BindableBool(); + public readonly Bindable Sort = new Bindable(); + public readonly List LoadedReplies = new List(); private readonly BindableBool childrenExpanded = new BindableBool(true); + private int currentPage; + private FillFlowContainer childCommentsVisibilityContainer; - private readonly Comment comment; + private FillFlowContainer childCommentsContainer; + private LoadMoreCommentsButton loadMoreCommentsButton; + private ShowMoreButton showMoreButton; + private RepliesButton repliesButton; + private ChevronButton chevronButton; + private DeletedCommentsCounter deletedCommentsCounter; public DrawableComment(Comment comment) { - this.comment = comment; + Comment = comment; } [BackgroundDependencyLoader] private void load() { LinkFlowContainer username; - FillFlowContainer childCommentsContainer; - DeletedCommentsCounter deletedCommentsCounter; FillFlowContainer info; LinkFlowContainer message; GridContainer content; @@ -50,234 +64,267 @@ namespace osu.Game.Overlays.Comments RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; - InternalChild = new FillFlowContainer + InternalChildren = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new FillFlowContainer { - new Container + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding(margin) { Left = margin + 5 }, - Child = content = new GridContainer + new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - ColumnDimensions = new[] + Padding = new MarginPadding(margin) { Left = margin + 5 }, + Child = content = new GridContainer { - new Dimension(GridSizeMode.AutoSize), - new Dimension(), - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize) - }, - Content = new[] - { - new Drawable[] + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + ColumnDimensions = new[] { - new FillFlowContainer + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new Drawable[] { - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Horizontal = margin }, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - Children = new Drawable[] + new FillFlowContainer { - new Container + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Horizontal = margin }, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Width = 40, - AutoSizeAxes = Axes.Y, - Child = votePill = new VotePill(comment) + new Container { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - } - }, - new UpdateableAvatar(comment.User) - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(avatar_size), - Masking = true, - CornerRadius = avatar_size / 2f, - CornerExponent = 2, - }, - } - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(0, 3), - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(7, 0), - Children = new Drawable[] - { - username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 40, + AutoSizeAxes = Axes.Y, + Child = votePill = new VotePill(Comment) { - AutoSizeAxes = Axes.Both, - }, - new ParentUsername(comment), - new OsuSpriteText - { - Alpha = comment.IsDeleted ? 1 : 0, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), - Text = @"deleted", + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, } - } - }, - message = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Right = 40 } - }, - info = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Colour = OsuColour.Gray(0.7f), - Children = new Drawable[] + }, + new UpdateableAvatar(Comment.User) { - new OsuSpriteText + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(avatar_size), + Masking = true, + CornerRadius = avatar_size / 2f, + CornerExponent = 2, + }, + } + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(0, 3), + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(7, 0), + Children = new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12), - Text = HumanizerUtils.Humanize(comment.CreatedAt) - }, - new RepliesButton(comment.RepliesCount) + username = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true)) + { + AutoSizeAxes = Axes.Both, + }, + new ParentUsername(Comment), + new OsuSpriteText + { + Alpha = Comment.IsDeleted ? 1 : 0, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + Text = @"deleted", + } + } + }, + message = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 14)) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Right = 40 } + }, + info = new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] { - Expanded = { BindTarget = childrenExpanded } - }, + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Colour = OsuColour.Gray(0.7f), + Text = HumanizerUtils.Humanize(Comment.CreatedAt) + }, + repliesButton = new RepliesButton(Comment.RepliesCount) + { + Expanded = { BindTarget = childrenExpanded } + }, + loadMoreCommentsButton = new LoadMoreCommentsButton + { + Action = () => RepliesRequested(this, ++currentPage) + } + } } } } } } } - } - }, - childCommentsVisibilityContainer = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] + }, + childCommentsVisibilityContainer = new FillFlowContainer { - childCommentsContainer = new FillFlowContainer + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - Padding = new MarginPadding { Left = 20 }, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical - }, - deletedCommentsCounter = new DeletedCommentsCounter - { - ShowDeleted = { BindTarget = ShowDeleted } + childCommentsContainer = new FillFlowContainer + { + Padding = new MarginPadding { Left = 20 }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical + }, + deletedCommentsCounter = new DeletedCommentsCounter + { + ShowDeleted = { BindTarget = ShowDeleted } + }, + showMoreButton = new ShowMoreButton + { + Action = () => RepliesRequested(this, ++currentPage) + } } - } + }, } + }, + chevronButton = new ChevronButton + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Margin = new MarginPadding { Right = 30, Top = margin }, + Expanded = { BindTarget = childrenExpanded }, + Alpha = 0 } }; - deletedCommentsCounter.Count.Value = comment.DeletedChildrenCount; - - if (comment.UserId.HasValue) - username.AddUserLink(comment.User); + if (Comment.UserId.HasValue) + username.AddUserLink(Comment.User); else - username.AddText(comment.LegacyName); + username.AddText(Comment.LegacyName); - if (comment.EditedAt.HasValue) + if (Comment.EditedAt.HasValue) { info.Add(new OsuSpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Font = OsuFont.GetFont(size: 12), - Text = $@"edited {HumanizerUtils.Humanize(comment.EditedAt.Value)} by {comment.EditedUser.Username}" + Text = $@"edited {HumanizerUtils.Humanize(Comment.EditedAt.Value)} by {Comment.EditedUser.Username}" }); } - if (comment.HasMessage) + if (Comment.HasMessage) { - var formattedSource = MessageFormatter.FormatText(comment.Message); + var formattedSource = MessageFormatter.FormatText(Comment.Message); message.AddLinks(formattedSource.Text, formattedSource.Links); } - if (comment.IsDeleted) + if (Comment.IsDeleted) { content.FadeColour(OsuColour.Gray(0.5f)); votePill.Hide(); } - if (comment.IsTopLevel) + if (Comment.IsTopLevel) { - AddInternal(new Container + AddInternal(new Box { - RelativeSizeAxes = Axes.X, - Height = 1.5f, Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.1f) - } + RelativeSizeAxes = Axes.X, + Height = 1.5f, + Colour = OsuColour.Gray(0.1f) }); - - if (comment.ChildComments.Any()) - { - AddInternal(new ChevronButton(comment) - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Margin = new MarginPadding { Right = 30, Top = margin }, - Expanded = { BindTarget = childrenExpanded } - }); - } } - - comment.ChildComments.ForEach(c => childCommentsContainer.Add(new DrawableComment(c) - { - ShowDeleted = { BindTarget = ShowDeleted } - })); } protected override void LoadComplete() { ShowDeleted.BindValueChanged(show => { - if (comment.IsDeleted) + if (Comment.IsDeleted) this.FadeTo(show.NewValue ? 1 : 0); }, true); childrenExpanded.BindValueChanged(expanded => childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0), true); + + updateButtonsState(); + base.LoadComplete(); } + public void AddReplies(IEnumerable replies) + { + LoadComponentAsync(createRepliesPage(replies), page => + { + var newReplies = replies.Select(reply => reply.Comment); + LoadedReplies.AddRange(newReplies); + deletedCommentsCounter.Count.Value += newReplies.Count(reply => reply.IsDeleted); + childCommentsContainer.Add(page); + updateButtonsState(); + }); + } + + private FillFlowContainer createRepliesPage(IEnumerable replies) => new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = replies.ToList() + }; + + private void updateButtonsState() + { + var loadedReplesCount = LoadedReplies.Count; + var hasUnloadedReplies = loadedReplesCount != Comment.RepliesCount; + + loadMoreCommentsButton.FadeTo(hasUnloadedReplies && loadedReplesCount == 0 ? 1 : 0); + showMoreButton.FadeTo(hasUnloadedReplies && loadedReplesCount > 0 ? 1 : 0); + repliesButton.FadeTo(loadedReplesCount != 0 ? 1 : 0); + + if (Comment.IsTopLevel) + chevronButton.FadeTo(loadedReplesCount != 0 ? 1 : 0); + + showMoreButton.IsLoading = loadMoreCommentsButton.IsLoading = false; + } + private class ChevronButton : ShowChildrenButton { private readonly SpriteIcon icon; - public ChevronButton(Comment comment) + public ChevronButton() { - Alpha = comment.IsTopLevel && comment.ChildComments.Any() ? 1 : 0; Child = icon = new SpriteIcon { Size = new Vector2(12), - Colour = OsuColour.Gray(0.7f) }; } @@ -296,7 +343,6 @@ namespace osu.Game.Overlays.Comments { this.count = count; - Alpha = count == 0 ? 0 : 1; Child = text = new OsuSpriteText { Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), @@ -309,6 +355,30 @@ namespace osu.Game.Overlays.Comments } } + private class LoadMoreCommentsButton : GetCommentRepliesButton + { + public LoadMoreCommentsButton() + { + IdleColour = OsuColour.Gray(0.7f); + HoverColour = Color4.White; + } + + protected override string GetText() => @"[+] load replies"; + } + + private class ShowMoreButton : GetCommentRepliesButton + { + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + Margin = new MarginPadding { Vertical = 10, Left = 80 }; + IdleColour = colourProvider.Light2; + HoverColour = colourProvider.Light1; + } + + protected override string GetText() => @"Show More"; + } + private class ParentUsername : FillFlowContainer, IHasTooltip { public string TooltipText => getParentMessage(); diff --git a/osu.Game/Overlays/Comments/GetCommentRepliesButton.cs b/osu.Game/Overlays/Comments/GetCommentRepliesButton.cs new file mode 100644 index 0000000000..a3817ba416 --- /dev/null +++ b/osu.Game/Overlays/Comments/GetCommentRepliesButton.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using System.Collections.Generic; +using osuTK; + +namespace osu.Game.Overlays.Comments +{ + public abstract class GetCommentRepliesButton : LoadingButton + { + private const int duration = 200; + + protected override IEnumerable EffectTargets => new[] { text }; + + private OsuSpriteText text; + + protected GetCommentRepliesButton() + { + AutoSizeAxes = Axes.Both; + LoadingAnimationSize = new Vector2(8); + } + + protected override Drawable CreateContent() => new Container + { + AutoSizeAxes = Axes.Both, + Child = text = new OsuSpriteText + { + AlwaysPresent = true, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Text = GetText() + } + }; + + protected abstract string GetText(); + + protected override void OnLoadStarted() => text.FadeOut(duration, Easing.OutQuint); + + protected override void OnLoadFinished() => text.FadeIn(duration, Easing.OutQuint); + } +} diff --git a/osu.Game/Overlays/Comments/ShowChildrenButton.cs b/osu.Game/Overlays/Comments/ShowChildrenButton.cs index be04b6e5de..5ec7c1d471 100644 --- a/osu.Game/Overlays/Comments/ShowChildrenButton.cs +++ b/osu.Game/Overlays/Comments/ShowChildrenButton.cs @@ -3,8 +3,9 @@ using osu.Framework.Graphics; using osu.Game.Graphics.Containers; -using osu.Framework.Input.Events; using osu.Framework.Bindables; +using osuTK.Graphics; +using osu.Game.Graphics; namespace osu.Game.Overlays.Comments { @@ -15,20 +16,18 @@ namespace osu.Game.Overlays.Comments protected ShowChildrenButton() { AutoSizeAxes = Axes.Both; + IdleColour = OsuColour.Gray(0.7f); + HoverColour = Color4.White; } protected override void LoadComplete() { + Action = Expanded.Toggle; + Expanded.BindValueChanged(OnExpandedChanged, true); base.LoadComplete(); } protected abstract void OnExpandedChanged(ValueChangedEvent expanded); - - protected override bool OnClick(ClickEvent e) - { - Expanded.Value = !Expanded.Value; - return true; - } } } From 8239f21cad20a4d3ea780a45d8832798c2de53ee Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 10 Feb 2020 15:52:12 +0300 Subject: [PATCH 0371/1142] Remove whitespace --- osu.Game/Overlays/Comments/DrawableComment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index e7aac3c44d..b0062ca1e5 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -288,7 +288,7 @@ namespace osu.Game.Overlays.Comments var newReplies = replies.Select(reply => reply.Comment); LoadedReplies.AddRange(newReplies); deletedCommentsCounter.Count.Value += newReplies.Count(reply => reply.IsDeleted); - childCommentsContainer.Add(page); + childCommentsContainer.Add(page); updateButtonsState(); }); } From d20a86087920b06598c4dfe42097784d2f91be9f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 10 Feb 2020 16:08:58 +0300 Subject: [PATCH 0372/1142] CI fix --- osu.Game/Overlays/Comments/CommentsPage.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 976af72abb..a6651aa325 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -74,7 +74,7 @@ namespace osu.Game.Overlays.Comments { c.ParentComment = comment; }); - drawableComment.OnLoadComplete += loaded => ((DrawableComment)loaded).AddReplies(children.Select(c => createDrawableComment(c))); + drawableComment.OnLoadComplete += loaded => ((DrawableComment)loaded).AddReplies(children.Select(createDrawableComment)); } if (comment.IsTopLevel) @@ -104,7 +104,7 @@ namespace osu.Game.Overlays.Comments uniqueComments.ForEach(c => c.ParentComment = drawableComment.Comment); - drawableComment.AddReplies(uniqueComments.Select(comment => createDrawableComment(comment))); + drawableComment.AddReplies(uniqueComments.Select(createDrawableComment)); } private DrawableComment createDrawableComment(Comment comment) => new DrawableComment(comment) From e2950d7027003db5f9f1327cefae551a9a745117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Feb 2020 20:27:46 +0100 Subject: [PATCH 0373/1142] Extract method to avoid nested ternaries --- .../BeatmapSet/Buttons/HeaderDownloadButton.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs index 5ed15cecd5..53003b0488 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs @@ -150,7 +150,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons }, new OsuSpriteText { - Text = BeatmapSet.Value.OnlineInfo.HasVideo ? (noVideo ? "without Video" : "with Video") : string.Empty, + Text = getVideoSuffixText(), Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold) }, }; @@ -163,5 +163,13 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons private void userChanged(ValueChangedEvent e) => button.Enabled.Value = !(e.NewValue is GuestUser); private void enabledChanged(ValueChangedEvent e) => this.FadeColour(e.NewValue ? Color4.White : Color4.Gray, 200, Easing.OutQuint); + + private string getVideoSuffixText() + { + if (!BeatmapSet.Value.OnlineInfo.HasVideo) + return string.Empty; + + return noVideo ? "without Video" : "with Video"; + } } } From 811553cd60e47cca3d86386dc9b9c5c561255e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Feb 2020 20:37:34 +0100 Subject: [PATCH 0374/1142] Remove unnecessary coercions Comparisons to null of nullable numbers are always false. --- osu.Game/Overlays/BeatmapSet/Details.cs | 2 +- osu.Game/Overlays/BeatmapSet/Info.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index bd13b4371e..488e181fa2 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -53,7 +53,7 @@ namespace osu.Game.Overlays.BeatmapSet private void updateDisplay() { Ratings.Metrics = BeatmapSet?.Metrics; - ratingBox.Alpha = (BeatmapSet?.OnlineInfo?.Status ?? 0) > 0 ? 1 : 0; + ratingBox.Alpha = BeatmapSet?.OnlineInfo?.Status > 0 ? 1 : 0; } public Details() diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 0a5415124e..85e871baca 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -132,7 +132,7 @@ namespace osu.Game.Overlays.BeatmapSet tags.Text = b.NewValue?.Metadata.Tags ?? string.Empty; genre.Text = b.NewValue?.OnlineInfo?.Genre?.Name ?? string.Empty; language.Text = b.NewValue?.OnlineInfo?.Language?.Name ?? string.Empty; - var setHasLeaderboard = (b.NewValue?.OnlineInfo?.Status ?? 0) > 0; + var setHasLeaderboard = b.NewValue?.OnlineInfo?.Status > 0; successRate.Alpha = setHasLeaderboard ? 1 : 0; unrankedPlaceholder.Alpha = setHasLeaderboard ? 0 : 1; }; From 35d5237dddf677dee02c7d2fc622e1d78abcacc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 10 Feb 2020 20:40:39 +0100 Subject: [PATCH 0375/1142] Adjust font sizes --- osu.Game/Overlays/BeatmapSet/Header.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index ab7b2d82ed..5f4782573d 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -134,7 +134,7 @@ namespace osu.Game.Overlays.BeatmapSet { title = new OsuSpriteText { - Font = OsuFont.GetFont(size: 37, weight: FontWeight.SemiBold, italics: true) + Font = OsuFont.GetFont(size: 37.5f, weight: FontWeight.SemiBold, italics: true) }, externalLink = new ExternalLinkButton { @@ -144,7 +144,7 @@ namespace osu.Game.Overlays.BeatmapSet }, } }, - artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 25, weight: FontWeight.Medium, italics: true) }, + artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true) }, new Container { RelativeSizeAxes = Axes.X, From e072042d4ecfd8e81517b34a845ebff5114e582c Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Mon, 10 Feb 2020 21:11:49 +0100 Subject: [PATCH 0376/1142] Match osu-web font size --- osu.Game/Overlays/BeatmapSet/Header.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 5f4782573d..29f09a1ad8 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -134,7 +134,7 @@ namespace osu.Game.Overlays.BeatmapSet { title = new OsuSpriteText { - Font = OsuFont.GetFont(size: 37.5f, weight: FontWeight.SemiBold, italics: true) + Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true) }, externalLink = new ExternalLinkButton { From 15b4e3386f94ba7dc5c5fe9895169dc4bcb1bf04 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 10 Feb 2020 23:57:48 +0300 Subject: [PATCH 0377/1142] Fix incorrect algorithm for comment tree creation Can cause one comment to be redrawn multiple times --- osu.Game/Overlays/Comments/CommentsPage.cs | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index a6651aa325..eb1044c853 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -62,24 +62,26 @@ namespace osu.Game.Overlays.Comments return; } - foreach (var comment in commentBundle.Comments) + commentBundle.Comments.ForEach(c => { - var drawableComment = createDrawableComment(comment); + if (c.IsTopLevel) + flow.Add(createCommentWithReplies(c, commentBundle)); + }); + } - var children = commentBundle.Comments.Where(c => c.ParentId == comment.Id); + private DrawableComment createCommentWithReplies(Comment comment, CommentBundle commentBundle) + { + var drawableComment = createDrawableComment(comment); - if (children.Any()) - { - children.ForEach(c => - { - c.ParentComment = comment; - }); - drawableComment.OnLoadComplete += loaded => ((DrawableComment)loaded).AddReplies(children.Select(createDrawableComment)); - } + var replies = commentBundle.Comments.Where(c => c.ParentId == comment.Id); - if (comment.IsTopLevel) - flow.Add(drawableComment); + if (replies.Any()) + { + replies.ForEach(c => c.ParentComment = comment); + drawableComment.OnLoadComplete += _ => drawableComment.AddReplies(replies.Select(reply => createCommentWithReplies(reply, commentBundle))); } + + return drawableComment; } private void onCommentRepliesRequested(DrawableComment drawableComment, int page) From b04a4b5c8ac28f3eb70150efee23f6085395854d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 01:44:56 +0300 Subject: [PATCH 0378/1142] Implement SpotlightsLayout --- .../TestSceneRankingsSpotlightSelector.cs | 6 - .../Online/TestSceneSpotlightsLayout.cs | 55 ++++++ .../Rankings/RankingsOverlayHeader.cs | 6 +- .../Overlays/Rankings/SpotlightSelector.cs | 86 ++++------ .../Overlays/Rankings/SpotlightsLayout.cs | 158 ++++++++++++++++++ 5 files changed, 249 insertions(+), 62 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneSpotlightsLayout.cs create mode 100644 osu.Game/Overlays/Rankings/SpotlightsLayout.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index f27ab1e775..e46c8a4a71 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -35,12 +35,6 @@ namespace osu.Game.Tests.Visual.Online Add(selector = new SpotlightSelector()); } - [Test] - public void TestVisibility() - { - AddStep("Toggle Visibility", selector.ToggleVisibility); - } - [Test] public void TestLocalSpotlights() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneSpotlightsLayout.cs b/osu.Game.Tests/Visual/Online/TestSceneSpotlightsLayout.cs new file mode 100644 index 0000000000..d025a8d7c2 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneSpotlightsLayout.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 osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays; +using osu.Game.Overlays.Rankings; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Catch; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Osu; +using osu.Game.Rulesets.Taiko; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneSpotlightsLayout : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(SpotlightsLayout), + typeof(SpotlightSelector), + }; + + protected override bool UseOnlineAPI => true; + + [Cached] + private readonly OverlayColourProvider overlayColour = new OverlayColourProvider(OverlayColourScheme.Green); + + public TestSceneSpotlightsLayout() + { + var ruleset = new Bindable(new OsuRuleset().RulesetInfo); + + Add(new BasicScrollContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Width = 0.8f, + Child = new SpotlightsLayout + { + Ruleset = { BindTarget = ruleset } + } + }); + + AddStep("Osu ruleset", () => ruleset.Value = new OsuRuleset().RulesetInfo); + AddStep("Mania ruleset", () => ruleset.Value = new ManiaRuleset().RulesetInfo); + AddStep("Taiko ruleset", () => ruleset.Value = new TaikoRuleset().RulesetInfo); + AddStep("Catch ruleset", () => ruleset.Value = new CatchRuleset().RulesetInfo); + } + } +} diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 538ae112b5..5b3744cf7f 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -60,8 +60,10 @@ namespace osu.Game.Overlays.Rankings base.LoadComplete(); } - private void onCurrentChanged(ValueChangedEvent scope) => - SpotlightSelector.State.Value = scope.NewValue == RankingsScope.Spotlights ? Visibility.Visible : Visibility.Hidden; + private void onCurrentChanged(ValueChangedEvent scope) + { + + } private class RankingsTitle : ScreenTitle { diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index 8bf75b2357..bc2d731772 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -18,11 +18,8 @@ using osu.Game.Online.API.Requests; namespace osu.Game.Overlays.Rankings { - public class SpotlightSelector : VisibilityContainer, IHasCurrentValue + public class SpotlightSelector : CompositeDrawable, IHasCurrentValue { - private const int height = 100; - private const int duration = 200; - private readonly Box background; private readonly SpotlightsDropdown dropdown; @@ -40,59 +37,52 @@ namespace osu.Game.Overlays.Rankings set => dropdown.Items = value; } - protected override bool StartHidden => true; - private readonly InfoColumn startDateColumn; private readonly InfoColumn endDateColumn; private readonly InfoColumn mapCountColumn; private readonly InfoColumn participantsColumn; - private readonly Container content; public SpotlightSelector() { RelativeSizeAxes = Axes.X; - Add(content = new Container + Height = 100; + AddRangeInternal(new Drawable[] { - Height = height, - RelativeSizeAxes = Axes.X, - Children = new Drawable[] + background = new Box { - background = new Box + RelativeSizeAxes = Axes.Both, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, - Children = new Drawable[] + dropdown = new SpotlightsDropdown { - dropdown = new SpotlightsDropdown + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Current = Current, + Depth = -float.MaxValue + }, + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(15, 0), + Children = new Drawable[] { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Current = Current, - Depth = -float.MaxValue - }, - new FillFlowContainer - { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(15, 0), - Children = new Drawable[] - { - startDateColumn = new InfoColumn(@"Start Date"), - endDateColumn = new InfoColumn(@"End Date"), - mapCountColumn = new InfoColumn(@"Map Count"), - participantsColumn = new InfoColumn(@"Participants") - } + startDateColumn = new InfoColumn(@"Start Date"), + endDateColumn = new InfoColumn(@"End Date"), + mapCountColumn = new InfoColumn(@"Map Count"), + participantsColumn = new InfoColumn(@"Participants") } } - }, - } + } + }, }); } @@ -110,18 +100,6 @@ namespace osu.Game.Overlays.Rankings participantsColumn.Value = response.Spotlight.Participants?.ToString("N0"); } - protected override void PopIn() - { - this.ResizeHeightTo(height, duration, Easing.OutQuint); - content.FadeIn(duration, Easing.OutQuint); - } - - protected override void PopOut() - { - this.ResizeHeightTo(0, duration, Easing.OutQuint); - content.FadeOut(duration, Easing.OutQuint); - } - private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); private class InfoColumn : FillFlowContainer diff --git a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs new file mode 100644 index 0000000000..fd1b73c4cd --- /dev/null +++ b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs @@ -0,0 +1,158 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Bindables; +using osu.Game.Rulesets; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.API.Requests.Responses; +using osuTK; +using osu.Framework.Allocation; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Overlays.Rankings.Tables; +using System.Linq; +using osu.Game.Overlays.Direct; +using System.Threading; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.Rankings +{ + public class SpotlightsLayout : CompositeDrawable + { + public readonly Bindable Ruleset = new Bindable(); + + private readonly Bindable selectedSpotlight = new Bindable(); + + [Resolved] + private IAPIProvider api { get; set; } + + [Resolved] + private RulesetStore rulesets { get; set; } + + private CancellationTokenSource cancellationToken; + private GetSpotlightRankingsRequest getRankingsRequest; + private GetSpotlightsRequest spotlightsRequest; + + private readonly SpotlightSelector selector; + private readonly Container content; + private readonly DimmedLoadingLayer loading; + + public SpotlightsLayout() + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + InternalChild = new ReverseChildIDFillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + selector = new SpotlightSelector + { + Current = selectedSpotlight, + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + content = new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }, + loading = new DimmedLoadingLayer(), + } + } + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + selectedSpotlight.BindValueChanged(onSpotlightChanged); + Ruleset.BindValueChanged(onRulesetChanged); + + getSpotlights(); + } + + private void getSpotlights() + { + spotlightsRequest = new GetSpotlightsRequest(); + spotlightsRequest.Success += response => selector.Spotlights = response.Spotlights; + api.Queue(spotlightsRequest); + } + + private void onRulesetChanged(ValueChangedEvent ruleset) + { + if (!selector.Spotlights.Any()) + return; + + selectedSpotlight.TriggerChange(); + } + + private void onSpotlightChanged(ValueChangedEvent spotlight) + { + loading.Show(); + + cancellationToken?.Cancel(); + getRankingsRequest?.Cancel(); + + getRankingsRequest = new GetSpotlightRankingsRequest(Ruleset.Value, spotlight.NewValue.Id); + getRankingsRequest.Success += onSuccess; + api.Queue(getRankingsRequest); + } + + private void onSuccess(GetSpotlightRankingsResponse response) + { + LoadComponentAsync(createContent(response), loaded => + { + selector.ShowInfo(response); + + content.Clear(); + content.Add(loaded); + + loading.Hide(); + }, (cancellationToken = new CancellationTokenSource()).Token); + } + + private Drawable createContent(GetSpotlightRankingsResponse response) => new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + new ScoresTable(1, response.Users), + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Spacing = new Vector2(10), + Children = response.BeatmapSets.Select(b => new DirectGridPanel(b.ToBeatmapSet(rulesets)) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }).ToList() + } + } + }; + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + spotlightsRequest?.Cancel(); + getRankingsRequest?.Cancel(); + cancellationToken?.Cancel(); + } + } +} From 0b6558dc40e9813712c0e6c0bfc28e354d62da42 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 02:35:23 +0300 Subject: [PATCH 0379/1142] Add SpotlightsLayout to RankingsOverlay --- .../Visual/Online/TestSceneRankingsHeader.cs | 21 +--- .../TestSceneRankingsSpotlightSelector.cs | 6 ++ .../Rankings/RankingsOverlayHeader.cs | 40 +------- .../Overlays/Rankings/SpotlightSelector.cs | 73 ++++++++------ .../Overlays/Rankings/SpotlightsLayout.cs | 15 +-- osu.Game/Overlays/RankingsOverlay.cs | 97 +++++-------------- 6 files changed, 85 insertions(+), 167 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs index bc0ae3d264..1e711b3cd7 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsHeader.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Rankings; using osu.Game.Rulesets; @@ -35,25 +34,7 @@ namespace osu.Game.Tests.Visual.Online { Current = { BindTarget = scope }, Country = { BindTarget = countryBindable }, - Ruleset = { BindTarget = ruleset }, - Spotlights = new[] - { - new APISpotlight - { - Id = 1, - Name = "Spotlight 1" - }, - new APISpotlight - { - Id = 2, - Name = "Spotlight 2" - }, - new APISpotlight - { - Id = 3, - Name = "Spotlight 3" - } - } + Ruleset = { BindTarget = ruleset } }); var country = new Country diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs index e46c8a4a71..f27ab1e775 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsSpotlightSelector.cs @@ -35,6 +35,12 @@ namespace osu.Game.Tests.Visual.Online Add(selector = new SpotlightSelector()); } + [Test] + public void TestVisibility() + { + AddStep("Toggle Visibility", selector.ToggleVisibility); + } + [Test] public void TestLocalSpotlights() { diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 5b3744cf7f..2674b3a81e 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -6,24 +6,14 @@ using osu.Framework.Bindables; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets; using osu.Game.Users; -using System.Collections.Generic; -using osu.Framework.Graphics.Containers; -using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Rankings { public class RankingsOverlayHeader : TabControlOverlayHeader { public readonly Bindable Ruleset = new Bindable(); - public readonly Bindable Spotlight = new Bindable(); public readonly Bindable Country = new Bindable(); - public IEnumerable Spotlights - { - get => SpotlightSelector.Spotlights; - set => SpotlightSelector.Spotlights = value; - } - protected override ScreenTitle CreateTitle() => new RankingsTitle { Scope = { BindTarget = Current } @@ -34,37 +24,11 @@ namespace osu.Game.Overlays.Rankings Current = Ruleset }; - public SpotlightSelector SpotlightSelector; - - protected override Drawable CreateContent() => new FillFlowContainer + protected override Drawable CreateContent() => new CountryFilter { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new CountryFilter - { - Current = Country - }, - SpotlightSelector = new SpotlightSelector - { - Current = { BindTarget = Spotlight } - } - } + Current = Country }; - protected override void LoadComplete() - { - Current.BindValueChanged(onCurrentChanged, true); - base.LoadComplete(); - } - - private void onCurrentChanged(ValueChangedEvent scope) - { - - } - private class RankingsTitle : ScreenTitle { public readonly Bindable Scope = new Bindable(); diff --git a/osu.Game/Overlays/Rankings/SpotlightSelector.cs b/osu.Game/Overlays/Rankings/SpotlightSelector.cs index bc2d731772..f019b50ae8 100644 --- a/osu.Game/Overlays/Rankings/SpotlightSelector.cs +++ b/osu.Game/Overlays/Rankings/SpotlightSelector.cs @@ -18,8 +18,10 @@ using osu.Game.Online.API.Requests; namespace osu.Game.Overlays.Rankings { - public class SpotlightSelector : CompositeDrawable, IHasCurrentValue + public class SpotlightSelector : VisibilityContainer, IHasCurrentValue { + private const int duration = 300; + private readonly Box background; private readonly SpotlightsDropdown dropdown; @@ -37,52 +39,59 @@ namespace osu.Game.Overlays.Rankings set => dropdown.Items = value; } + protected override bool StartHidden => true; + private readonly InfoColumn startDateColumn; private readonly InfoColumn endDateColumn; private readonly InfoColumn mapCountColumn; private readonly InfoColumn participantsColumn; + private readonly Container content; public SpotlightSelector() { RelativeSizeAxes = Axes.X; Height = 100; - AddRangeInternal(new Drawable[] + Add(content = new Container { - background = new Box + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, - Children = new Drawable[] + background = new Box { - dropdown = new SpotlightsDropdown + RelativeSizeAxes = Axes.Both, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = UserProfileOverlay.CONTENT_X_MARGIN, Vertical = 10 }, + Children = new Drawable[] { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - RelativeSizeAxes = Axes.X, - Current = Current, - Depth = -float.MaxValue - }, - new FillFlowContainer - { - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(15, 0), - Children = new Drawable[] + dropdown = new SpotlightsDropdown { - startDateColumn = new InfoColumn(@"Start Date"), - endDateColumn = new InfoColumn(@"End Date"), - mapCountColumn = new InfoColumn(@"Map Count"), - participantsColumn = new InfoColumn(@"Participants") + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + RelativeSizeAxes = Axes.X, + Current = Current, + Depth = -float.MaxValue + }, + new FillFlowContainer + { + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(15, 0), + Children = new Drawable[] + { + startDateColumn = new InfoColumn(@"Start Date"), + endDateColumn = new InfoColumn(@"End Date"), + mapCountColumn = new InfoColumn(@"Map Count"), + participantsColumn = new InfoColumn(@"Participants") + } } } } - }, + } }); } @@ -100,6 +109,10 @@ namespace osu.Game.Overlays.Rankings participantsColumn.Value = response.Spotlight.Participants?.ToString("N0"); } + protected override void PopIn() => content.FadeIn(duration, Easing.OutQuint); + + protected override void PopOut() => content.FadeOut(duration, Easing.OutQuint); + private string dateToString(DateTimeOffset date) => date.ToString("yyyy-MM-dd"); private class InfoColumn : FillFlowContainer diff --git a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs index fd1b73c4cd..33811cc982 100644 --- a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs +++ b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs @@ -35,11 +35,12 @@ namespace osu.Game.Overlays.Rankings private GetSpotlightRankingsRequest getRankingsRequest; private GetSpotlightsRequest spotlightsRequest; - private readonly SpotlightSelector selector; - private readonly Container content; - private readonly DimmedLoadingLayer loading; + private SpotlightSelector selector; + private Container content; + private DimmedLoadingLayer loading; - public SpotlightsLayout() + [BackgroundDependencyLoader] + private void load() { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -48,7 +49,6 @@ namespace osu.Game.Overlays.Rankings RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), Children = new Drawable[] { selector = new SpotlightSelector @@ -65,8 +65,9 @@ namespace osu.Game.Overlays.Rankings { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Vertical = 10 } }, - loading = new DimmedLoadingLayer(), + loading = new DimmedLoadingLayer() } } } @@ -77,6 +78,8 @@ namespace osu.Game.Overlays.Rankings { base.LoadComplete(); + selector.Show(); + selectedSpotlight.BindValueChanged(onSpotlightChanged); Ruleset.BindValueChanged(onRulesetChanged); diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index a0aeff082e..f3215d07fa 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -14,10 +14,6 @@ using osu.Game.Online.API; using System.Threading; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Rankings.Tables; -using osu.Game.Online.API.Requests.Responses; -using System.Linq; -using osuTK; -using osu.Game.Overlays.Direct; namespace osu.Game.Overlays { @@ -26,13 +22,11 @@ namespace osu.Game.Overlays protected readonly Bindable Country = new Bindable(); protected readonly Bindable Scope = new Bindable(); private readonly Bindable ruleset = new Bindable(); - private readonly Bindable spotlight = new Bindable(); private readonly BasicScrollContainer scrollFlow; private readonly Container contentContainer; private readonly DimmedLoadingLayer loading; private readonly Box background; - private readonly RankingsOverlayHeader header; private APIRequest lastRequest; private CancellationTokenSource cancellationToken; @@ -40,9 +34,6 @@ namespace osu.Game.Overlays [Resolved] private IAPIProvider api { get; set; } - [Resolved] - private RulesetStore rulesets { get; set; } - public RankingsOverlay() : base(OverlayColourScheme.Green) { @@ -63,15 +54,14 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - header = new RankingsOverlayHeader + new RankingsOverlayHeader { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Depth = -float.MaxValue, Country = { BindTarget = Country }, Current = { BindTarget = Scope }, - Ruleset = { BindTarget = ruleset }, - Spotlight = { BindTarget = spotlight } + Ruleset = { BindTarget = ruleset } }, new Container { @@ -85,7 +75,7 @@ namespace osu.Game.Overlays Origin = Anchor.TopCentre, AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Margin = new MarginPadding { Vertical = 10 } + Margin = new MarginPadding { Bottom = 10 } }, loading = new DimmedLoadingLayer(), } @@ -110,30 +100,25 @@ namespace osu.Game.Overlays if (Country.Value != null) Scope.Value = RankingsScope.Performance; - if (Scope.Value != RankingsScope.Spotlights) - Scheduler.AddOnce(loadNewContent); + Scheduler.AddOnce(loadNewContent); }, true); Scope.BindValueChanged(_ => { - spotlightsRequest?.Cancel(); - // country filtering is only valid for performance scope. if (Scope.Value != RankingsScope.Performance) Country.Value = null; - if (Scope.Value == RankingsScope.Spotlights && !header.Spotlights.Any()) - { - getSpotlights(); - return; - } - Scheduler.AddOnce(loadNewContent); }, true); - ruleset.BindValueChanged(_ => Scheduler.AddOnce(loadNewContent), true); + ruleset.BindValueChanged(_ => + { + if (Scope.Value == RankingsScope.Spotlights) + return; - spotlight.BindValueChanged(_ => Scheduler.AddOnce(loadNewContent), true); + Scheduler.AddOnce(loadNewContent); + }, true); base.LoadComplete(); } @@ -148,16 +133,6 @@ namespace osu.Game.Overlays Country.Value = requested; } - private GetSpotlightsRequest spotlightsRequest; - - private void getSpotlights() - { - loading.Show(); - spotlightsRequest = new GetSpotlightsRequest(); - spotlightsRequest.Success += response => header.Spotlights = response.Spotlights; - api.Queue(spotlightsRequest); - } - private void loadNewContent() { loading.Show(); @@ -165,6 +140,15 @@ namespace osu.Game.Overlays cancellationToken?.Cancel(); lastRequest?.Cancel(); + if (Scope.Value == RankingsScope.Spotlights) + { + loadContent(new SpotlightsLayout + { + Ruleset = { BindTarget = ruleset } + }); + return; + } + var request = createScopedRequest(); lastRequest = request; @@ -174,8 +158,9 @@ namespace osu.Game.Overlays return; } - request.Success += () => loadContent(createContentFromResponse(request)); + request.Success += () => loadContent(createTableFromResponse(request)); request.Failure += _ => loadContent(null); + api.Queue(request); } @@ -191,15 +176,12 @@ namespace osu.Game.Overlays case RankingsScope.Score: return new GetUserRankingsRequest(ruleset.Value, UserRankingsType.Score); - - case RankingsScope.Spotlights: - return new GetSpotlightRankingsRequest(ruleset.Value, header.Spotlight.Value.Id); } return null; } - private Drawable createContentFromResponse(APIRequest request) + private Drawable createTableFromResponse(APIRequest request) { switch (request) { @@ -217,42 +199,11 @@ namespace osu.Game.Overlays case GetCountryRankingsRequest countryRequest: return new CountriesTable(1, countryRequest.Result.Countries); - - case GetSpotlightRankingsRequest spotlightRequest: - return getSpotlightContent(spotlightRequest.Result); } return null; } - private Drawable getSpotlightContent(GetSpotlightRankingsResponse response) - { - header.SpotlightSelector.ShowInfo(response); - - return new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - new ScoresTable(1, response.Users), - new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Spacing = new Vector2(10), - Children = response.BeatmapSets.Select(b => new DirectGridPanel(b.ToBeatmapSet(rulesets)) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - }).ToList() - } - } - }; - } - private void loadContent(Drawable content) { scrollFlow.ScrollToStart(); @@ -264,10 +215,10 @@ namespace osu.Game.Overlays return; } - LoadComponentAsync(content, t => + LoadComponentAsync(content, loaded => { loading.Hide(); - contentContainer.Child = content; + contentContainer.Child = loaded; }, (cancellationToken = new CancellationTokenSource()).Token); } } From ca237fd987cc677f7bbda1923a421836763f884d Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Mon, 10 Feb 2020 16:21:49 -0800 Subject: [PATCH 0380/1142] Simplify ordering by using only numbers, add xmldoc --- .../Mods/CatchModDifficultyAdjust.cs | 5 ++-- .../Mods/OsuModDifficultyAdjust.cs | 5 ++-- .../Configuration/SettingSourceAttribute.cs | 25 ++++++------------- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 5 ++-- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index 17a2847fd1..de7adaa261 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -5,13 +5,12 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; -using static osu.Game.Configuration.SettingSourceAttribute; namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", OrderMode.FIRST)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", 0)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -21,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", OrderMode.LAST)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", 3)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 2b56042ead..2c6eb19f3d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -5,13 +5,12 @@ using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Mods; -using static osu.Game.Configuration.SettingSourceAttribute; namespace osu.Game.Rulesets.Osu.Mods { public class OsuModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", OrderMode.FIRST)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", 0)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -21,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", OrderMode.LAST)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", 3)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index 06e01bb042..4dcd2c6122 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -17,31 +17,24 @@ namespace osu.Game.Configuration /// An attribute to mark a bindable as being exposed to the user via settings controls. /// Can be used in conjunction with to automatically create UI controls. ///
+ /// + /// All controls with OrderPosition set to an int greater than 0 will be placed first in ascending order. + /// All controls with no OrderPosition will come afterward in default order. + /// [MeansImplicitUse] [AttributeUsage(AttributeTargets.Property)] public class SettingSourceAttribute : Attribute { - public enum OrderMode - { - FIRST, - ORDERED_RELATIVE, - UNORDERED, - LAST - } - public string Label { get; } public string Description { get; } - public OrderMode OrderingMode { get; } - public int OrderPosition { get; } - public SettingSourceAttribute(string label, string description = null, OrderMode order = OrderMode.UNORDERED, int orderPosition = 0) + public SettingSourceAttribute(string label, string description = null, int orderPosition = -1) { Label = label ?? string.Empty; Description = description ?? string.Empty; - OrderingMode = order; OrderPosition = orderPosition; } } @@ -136,12 +129,10 @@ namespace osu.Game.Configuration { var original = obj.GetSettingsSourceProperties(); - var first = original.Where(attr => attr.Item1.OrderingMode == SettingSourceAttribute.OrderMode.FIRST); - var orderedRelative = original.Where(attr => attr.Item1.OrderingMode == SettingSourceAttribute.OrderMode.ORDERED_RELATIVE).OrderBy(attr => attr.Item1.OrderPosition); - var unordered = original.Where(attr => attr.Item1.OrderingMode == SettingSourceAttribute.OrderMode.UNORDERED); - var last = original.Where(attr => attr.Item1.OrderingMode == SettingSourceAttribute.OrderMode.LAST); + var orderedRelative = original.Where(attr => attr.Item1.OrderPosition > -1).OrderBy(attr => attr.Item1.OrderPosition); + var unordered = original.Except(orderedRelative); - return first.Concat(orderedRelative).Concat(unordered).Concat(last); + return orderedRelative.Concat(unordered); } } } diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 958a0353ea..6ba54ff8fb 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics.Sprites; using System; using System.Collections.Generic; using osu.Game.Configuration; -using static osu.Game.Configuration.SettingSourceAttribute; namespace osu.Game.Rulesets.Mods { @@ -29,7 +28,7 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModHardRock) }; - [SettingSource("HP Drain", "Override a beatmap's set HP.", OrderMode.ORDERED_RELATIVE, 1)] + [SettingSource("HP Drain", "Override a beatmap's set HP.", 1)] public BindableNumber DrainRate { get; } = new BindableFloat { Precision = 0.1f, @@ -39,7 +38,7 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - [SettingSource("Accuracy", "Override a beatmap's set OD.", OrderMode.ORDERED_RELATIVE, 1)] + [SettingSource("Accuracy", "Override a beatmap's set OD.", 2)] public BindableNumber OverallDifficulty { get; } = new BindableFloat { Precision = 0.1f, From 333f976580cc8e159b09e268bef438f09200e3d9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 11 Feb 2020 17:41:48 +0900 Subject: [PATCH 0381/1142] Fix test finding deleted beatmaps under dotnet-test --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index bd06089514..9474c08c5a 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -442,16 +442,20 @@ namespace osu.Game.Tests.Visual.SongSelect AddUntilStep("dummy selected", () => Beatmap.Value is DummyWorkingBeatmap); + AddUntilStep("has no selection", () => songSelect.Carousel.SelectedBeatmap == null); + BeatmapInfo target = null; AddStep("select beatmap externally", () => { - target = manager.QueryBeatmapSets(b => b.Beatmaps.Any(bi => bi.RulesetID == (differentRuleset ? 1 : 0))) + target = manager.GetAllUsableBeatmapSets().Where(b => b.Beatmaps.Any(bi => bi.RulesetID == (differentRuleset ? 1 : 0))) .ElementAt(5).Beatmaps.First(); Beatmap.Value = manager.GetWorkingBeatmap(target); }); + AddUntilStep("has selection", () => songSelect.Carousel.SelectedBeatmap != null); + AddUntilStep("carousel has correct", () => songSelect.Carousel.SelectedBeatmap?.OnlineBeatmapID == target.OnlineBeatmapID); AddUntilStep("game has correct", () => Beatmap.Value.BeatmapInfo.OnlineBeatmapID == target.OnlineBeatmapID); From 17791259ed16767dfced844a094fe9116d9a5db4 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 11 Feb 2020 16:21:31 +0700 Subject: [PATCH 0382/1142] Fix InfoColumn minWidth implementation --- .../Scores/TopScoreStatisticsSection.cs | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 6c9f0b0321..c441cb3101 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -118,26 +118,42 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { AutoSizeAxes = Axes.Both; - InternalChild = new FillFlowContainer + InternalChild = new GridContainer { AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 1), - Children = new[] + ColumnDimensions = new[] { - text = new OsuSpriteText + new Dimension(GridSizeMode.AutoSize, minSize: minWidth ?? 0) + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Absolute, 4), + new Dimension(GridSizeMode.AutoSize) + }, + Content = new[] + { + new[] { - Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), - Text = title.ToUpper() + text = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), + Text = title.ToUpper() + } }, - separator = new Box + new[] { - RelativeSizeAxes = minWidth == null ? Axes.X : Axes.None, - Width = minWidth ?? 1f, - Height = 2, - Margin = new MarginPadding { Top = 2 } + separator = new Box + { + Anchor = Anchor.CentreLeft, + RelativeSizeAxes = Axes.X, + Height = 2 + } }, - content + new[] + { + content + } } }; } From 28a39fd8faa1ff463ea606de60048cdb10488ce3 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 11 Feb 2020 17:12:32 +0700 Subject: [PATCH 0383/1142] Use explicit typing --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index c441cb3101..8a6927e048 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -131,9 +131,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new Dimension(GridSizeMode.Absolute, 4), new Dimension(GridSizeMode.AutoSize) }, - Content = new[] + Content = new Drawable[][] { - new[] + new [] { text = new OsuSpriteText { From 44568ac9e6343a115fc9ed70db6a3194baf7b007 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 11 Feb 2020 17:36:10 +0700 Subject: [PATCH 0384/1142] Avoid covariant array conversion --- .../BeatmapSet/Scores/TopScoreStatisticsSection.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index 8a6927e048..be6151278c 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -131,9 +131,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new Dimension(GridSizeMode.Absolute, 4), new Dimension(GridSizeMode.AutoSize) }, - Content = new Drawable[][] + Content = new[] { - new [] + new Drawable[] { text = new OsuSpriteText { @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Text = title.ToUpper() } }, - new[] + new Drawable[] { separator = new Box { @@ -150,7 +150,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Height = 2 } }, - new[] + new Drawable[] { content } From 2be7d1a873b3de01080f00b850d00174a9d645d3 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Tue, 11 Feb 2020 18:19:08 +0700 Subject: [PATCH 0385/1142] Remove redundant type specification --- .../Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index be6151278c..a7066c4827 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -150,7 +150,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Height = 2 } }, - new Drawable[] + new[] { content } From 627833844839dec52e21f1ad7bc00cd796933a9c Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Tue, 11 Feb 2020 14:21:12 +0100 Subject: [PATCH 0386/1142] implement custom tooltip for DrawableDate --- osu.Game/Graphics/DrawableDate.cs | 75 ++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 0224c77ee8..dcbea96071 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -4,13 +4,16 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Sprites; using osu.Game.Utils; +using osuTK; namespace osu.Game.Graphics { - public class DrawableDate : OsuSpriteText, IHasTooltip + public class DrawableDate : OsuSpriteText, IHasCustomTooltip { private DateTimeOffset date; @@ -75,6 +78,74 @@ namespace osu.Game.Graphics private void updateTime() => Text = Format(); - public virtual string TooltipText => string.Format($"{Date:MMMM d, yyyy h:mm tt \"UTC\"z}"); + public ITooltip GetCustomTooltip() => new DateTooltip(); + + public object TooltipContent => Date; + + private class DateTooltip : VisibilityContainer, ITooltip + { + private readonly OsuSpriteText dateText, timeText; + private readonly Box background; + + public DateTooltip() + { + AutoSizeAxes = Axes.Both; + Masking = true; + CornerRadius = 5; + + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding(10), + Children = new Drawable[] + { + dateText = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + }, + timeText = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular), + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + } + } + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + // Temporary colour since it's currently impossible to change it without bugs (see https://github.com/ppy/osu-framework/issues/3231) + // If above is fixed, this should use OverlayColourProvider + background.Colour = colours.Gray1; + timeText.Colour = colours.GreyCyanLighter; + } + + protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); + protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); + + public bool SetContent(object content) + { + if (!(content is DateTimeOffset date)) + return false; + + dateText.Text = string.Format($"{date:d MMMM yyyy}") + " "; + timeText.Text = string.Format($"{date:hh:mm:ss \"UTC\"z}"); + return true; + } + + public void Move(Vector2 pos) => Position = pos; + } } } From 2a67246b218f323710572f3a1b53c56722171d55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 11 Feb 2020 22:37:38 +0900 Subject: [PATCH 0387/1142] Ensure game is at main menu before performing exit on screen --- osu.Game/OsuGame.cs | 2 +- osu.Game/Screens/Menu/MainMenu.cs | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ff3dee55af..79616ef97c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -446,7 +446,7 @@ namespace osu.Game ///
/// The action to perform once we are in the correct state. /// An optional collection of valid screen types. If any of these screens are already current we can perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. - protected void PerformFromScreen(Action action, IEnumerable validScreens = null) + public void PerformFromScreen(Action action, IEnumerable validScreens = null) { performFromMainMenuTask?.Cancel(); diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index cb5ceefb0f..c70fbb67a4 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -141,12 +141,15 @@ namespace osu.Game.Screens.Menu preloadSongSelect(); } + [Resolved] + private OsuGame game { get; set; } + private void confirmAndExit() { if (exitConfirmed) return; exitConfirmed = true; - this.Exit(); + game.PerformFromScreen(menu => menu.Exit()); } private void preloadSongSelect() From 482f622c94202a483092f8e6df306fbcc234af6a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 18:46:49 +0300 Subject: [PATCH 0388/1142] CommentEditor basic implementation --- .../UserInterface/TestSceneCommentEditor.cs | 43 ++++++++++++++ osu.Game/Overlays/Comments/CommentEditor.cs | 59 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs create mode 100644 osu.Game/Overlays/Comments/CommentEditor.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs new file mode 100644 index 0000000000..f349c81b38 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays; +using osu.Game.Overlays.Comments; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneCommentEditor : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(CommentEditor), + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + + public TestSceneCommentEditor() + { + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Y, + Width = 800, + Child = new TestCommentEditor() + }); + } + + private class TestCommentEditor : CommentEditor + { + protected override string EmptyTextboxText() => @"This textbox is empty"; + + protected override string FooterText() => @"Footer text. And it is pretty long. Cool."; + } + } +} diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs new file mode 100644 index 0000000000..a1995530bb --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -0,0 +1,59 @@ +// 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.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.Comments +{ + public abstract class CommentEditor : CompositeDrawable + { + private const int footer_height = 40; + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + RelativeSizeAxes = Axes.X; + Height = footer_height * 2; + Masking = true; + CornerRadius = 6; + + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background3 + }, + new Container + { + Name = "Footer", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = footer_height, + Padding = new MarginPadding { Horizontal = 8 }, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Shadow = false, + Text = FooterText() + } + } + } + }); + } + + protected abstract string FooterText(); + + protected abstract string EmptyTextboxText(); + } +} From 829152c8e89444f3146f582509d8b9879a1b6ba3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 20:08:24 +0300 Subject: [PATCH 0389/1142] Implement EditorTextbox --- .../UserInterface/TestSceneCommentEditor.cs | 6 +- osu.Game/Overlays/Comments/CommentEditor.cs | 81 +++++++++++++++---- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index f349c81b38..a1f1999090 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -35,9 +35,11 @@ namespace osu.Game.Tests.Visual.UserInterface private class TestCommentEditor : CommentEditor { - protected override string EmptyTextboxText() => @"This textbox is empty"; + protected override string FooterText => @"Footer text. And it is pretty long. Cool."; - protected override string FooterText() => @"Footer text. And it is pretty long. Cool."; + protected override string CommitButtonText => @"Commit"; + + protected override string TextboxPlaceholderText => @"This textbox is empty"; } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index a1995530bb..9252194377 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -7,20 +7,32 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Graphics.Sprites; +using osuTK.Graphics; namespace osu.Game.Overlays.Comments { public abstract class CommentEditor : CompositeDrawable { private const int footer_height = 40; + private const int side_padding = 8; + + protected abstract string FooterText { get; } + + protected abstract string CommitButtonText { get; } + + protected abstract string TextboxPlaceholderText { get; } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { RelativeSizeAxes = Axes.X; - Height = footer_height * 2; + AutoSizeAxes = Axes.Y; Masking = true; CornerRadius = 6; + BorderThickness = 3; + BorderColour = colourProvider.Background3; AddRangeInternal(new Drawable[] { @@ -29,31 +41,70 @@ namespace osu.Game.Overlays.Comments RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background3 }, - new Container + new FillFlowContainer { - Name = "Footer", - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, + AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Height = footer_height, - Padding = new MarginPadding { Horizontal = 8 }, + Direction = FillDirection.Vertical, Children = new Drawable[] { - new OsuSpriteText + new EditorTextbox { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12), - Shadow = false, - Text = FooterText() + Height = footer_height, + RelativeSizeAxes = Axes.X, + PlaceholderText = TextboxPlaceholderText + }, + new Container + { + Name = "Footer", + RelativeSizeAxes = Axes.X, + Height = footer_height, + Padding = new MarginPadding { Horizontal = side_padding }, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), + Text = FooterText + } + } } } } }); } - protected abstract string FooterText(); + private class EditorTextbox : BasicTextBox + { + protected override float LeftRightPadding => side_padding; - protected abstract string EmptyTextboxText(); + protected override Color4 SelectionColour => Color4.LightSkyBlue; + + private OsuSpriteText placeholder; + + public EditorTextbox() + { + Masking = false; + TextContainer.Height = 0.4f; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + BackgroundUnfocused = BackgroundFocused = colourProvider.Background5; + placeholder.Colour = colourProvider.Background3; + BackgroundCommit = Color4.LightSkyBlue; + } + + + protected override SpriteText CreatePlaceholder() => placeholder = new OsuSpriteText + { + Font = OsuFont.GetFont(weight: FontWeight.Regular), + }; + + protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) }; + } } } From b9e10cb49872c4eb0253a6498050e5cca49a96e0 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Tue, 11 Feb 2020 18:10:46 +0100 Subject: [PATCH 0390/1142] Privatize ViewTarget --- .../Online/TestSceneOnlineViewContainer.cs | 18 ++++++++++++------ osu.Game/Online/OnlineViewContainer.cs | 16 ++++++++-------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index 5427db5af3..2b9609f6e0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -32,6 +32,8 @@ namespace osu.Game.Tests.Visual.Online { public new LoadingAnimation LoadingAnimation => base.LoadingAnimation; + public CompositeDrawable ViewTarget => base.Content.Parent; + public TestOnlineViewContainer() : base(@"Please sign in to view dummy test content") { @@ -53,9 +55,9 @@ namespace osu.Game.Tests.Visual.Online }; } - protected override void FadeContentOut(Drawable content) => content.Hide(); + protected override void PopContentOut(Drawable content) => content.Hide(); - protected override void FadeContentIn(Drawable content) => content.Show(); + protected override void PopContentIn(Drawable content) => content.Show(); } [Test] @@ -63,7 +65,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to online", () => ((DummyAPIAccess)API).State = APIState.Online); - AddAssert("children are visible", () => onlineView.TransformationTarget.IsPresent); + AddAssert("children are visible", () => onlineView.ViewTarget.IsPresent); AddAssert("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); } @@ -72,7 +74,7 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to offline", () => ((DummyAPIAccess)API).State = APIState.Offline); - AddAssert("children are hidden", () => !onlineView.TransformationTarget.IsPresent); + AddAssert("children are hidden", () => !onlineView.ViewTarget.IsPresent); AddAssert("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); } @@ -81,12 +83,16 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to connecting", () => ((DummyAPIAccess)API).State = APIState.Connecting); - AddAssert("children are hidden", () => !onlineView.TransformationTarget.IsPresent); + AddAssert("children are hidden", () => !onlineView.ViewTarget.IsPresent); AddAssert("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); + } + [Test] + public void TestFailingStateVisibility() + { AddStep("set status to failing", () => ((DummyAPIAccess)API).State = APIState.Failing); - AddAssert("children are hidden", () => !onlineView.TransformationTarget.IsPresent); + AddAssert("children are hidden", () => !onlineView.ViewTarget.IsPresent); AddAssert("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); } } diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index ac5a7941ea..c512ca531a 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -11,7 +11,7 @@ using osu.Game.Online.Placeholders; namespace osu.Game.Online { /// - /// A for dislaying online content which require a local user to be logged in. + /// A for displaying online content which require a local user to be logged in. /// Shows its children only when the local user is logged in and supports displaying a placeholder if not. /// public abstract class OnlineViewContainer : Container, IOnlineComponent @@ -21,7 +21,7 @@ namespace osu.Game.Online protected const double TRANSFORM_TIME = 300.0; - internal readonly Container TransformationTarget; + private readonly Container viewTarget; protected override Container Content { get; } [Resolved] @@ -31,7 +31,7 @@ namespace osu.Game.Online { InternalChildren = new Drawable[] { - TransformationTarget = new Container + viewTarget = new Container { RelativeSizeAxes = Axes.Both, Child = Content = new Container @@ -52,30 +52,30 @@ namespace osu.Game.Online switch (state) { case APIState.Offline: - FadeContentOut(TransformationTarget); + PopContentOut(viewTarget); placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * TRANSFORM_TIME, Easing.OutQuint); placeholder.FadeInFromZero(2 * TRANSFORM_TIME, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Online: - FadeContentIn(TransformationTarget); + PopContentIn(viewTarget); placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Failing: case APIState.Connecting: - FadeContentOut(TransformationTarget); + PopContentOut(viewTarget); LoadingAnimation.Show(); placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); break; } } - protected abstract void FadeContentOut(Drawable content); + protected abstract void PopContentOut(Drawable content); - protected abstract void FadeContentIn(Drawable content); + protected abstract void PopContentIn(Drawable content); protected override void LoadComplete() { From 730c115f49fbb29b5f72f37ad0446e9f4174d939 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 20:11:22 +0300 Subject: [PATCH 0391/1142] Fix some size values --- osu.Game/Overlays/Comments/CommentEditor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 9252194377..4ad59ff754 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -15,7 +15,6 @@ namespace osu.Game.Overlays.Comments { public abstract class CommentEditor : CompositeDrawable { - private const int footer_height = 40; private const int side_padding = 8; protected abstract string FooterText { get; } @@ -50,7 +49,7 @@ namespace osu.Game.Overlays.Comments { new EditorTextbox { - Height = footer_height, + Height = 40, RelativeSizeAxes = Axes.X, PlaceholderText = TextboxPlaceholderText }, @@ -58,7 +57,7 @@ namespace osu.Game.Overlays.Comments { Name = "Footer", RelativeSizeAxes = Axes.X, - Height = footer_height, + Height = 35, Padding = new MarginPadding { Horizontal = side_padding }, Children = new Drawable[] { From c022cf72b58a8bd13861c8cde85eca6cc3484672 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 20:47:51 +0300 Subject: [PATCH 0392/1142] Implement CancellableCommentEditor --- .../UserInterface/TestSceneCommentEditor.cs | 21 +++++- .../Comments/CancellableCommentEditor.cs | 71 +++++++++++++++++++ osu.Game/Overlays/Comments/CommentEditor.cs | 10 +++ osu.Game/Overlays/OverlayColourProvider.cs | 42 +++++------ 4 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CancellableCommentEditor.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index a1f1999090..86179886e5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Overlays.Comments; +using osuTK; namespace osu.Game.Tests.Visual.UserInterface { @@ -16,6 +17,7 @@ namespace osu.Game.Tests.Visual.UserInterface public override IReadOnlyList RequiredTypes => new[] { typeof(CommentEditor), + typeof(CancellableCommentEditor), }; [Cached] @@ -23,13 +25,19 @@ namespace osu.Game.Tests.Visual.UserInterface public TestSceneCommentEditor() { - Add(new Container + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Y, Width = 800, - Child = new TestCommentEditor() + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + new TestCommentEditor(), + new TestCancellableCommentEditor() + } }); } @@ -41,5 +49,14 @@ namespace osu.Game.Tests.Visual.UserInterface protected override string TextboxPlaceholderText => @"This textbox is empty"; } + + private class TestCancellableCommentEditor : CancellableCommentEditor + { + protected override string FooterText => @"Wow, another one. Sicc"; + + protected override string CommitButtonText => @"Save"; + + protected override string TextboxPlaceholderText => @"Miltiline textboxes soon"; + } } } diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs new file mode 100644 index 0000000000..ad5686910a --- /dev/null +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -0,0 +1,71 @@ +// 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.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.Comments +{ + public abstract class CancellableCommentEditor : CommentEditor + { + public Action OnCancel; + + [BackgroundDependencyLoader] + private void load() + { + ButtonsContainer.Add(new CancelButton + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Action = () => OnCancel?.Invoke() + }); + } + + private class CancelButton : OsuHoverContainer + { + protected override IEnumerable EffectTargets => new[] { background }; + + private readonly Box background; + + public CancelButton() + { + AutoSizeAxes = Axes.Both; + Child = new CircularContainer + { + Masking = true, + Height = 25, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Margin = new MarginPadding { Horizontal = 20 }, + Text = @"Cancel" + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + IdleColour = colourProvider.GetColour(0.5f, 0.45f); + HoverColour = colourProvider.GetColour(0.5f, 0.6f); + } + } + } +} diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 4ad59ff754..bb8ae7f114 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -23,6 +23,8 @@ namespace osu.Game.Overlays.Comments protected abstract string TextboxPlaceholderText { get; } + protected FillFlowContainer ButtonsContainer; + [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { @@ -67,6 +69,14 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.CentreLeft, Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), Text = FooterText + }, + ButtonsContainer = new FillFlowContainer + { + Name = "Buttons", + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, } } } diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index 9816f313ad..c0984073e6 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -16,28 +16,28 @@ namespace osu.Game.Overlays this.colourScheme = colourScheme; } - public Color4 Highlight1 => getColour(1, 0.7f); - public Color4 Content1 => getColour(0.4f, 1); - public Color4 Content2 => getColour(0.4f, 0.9f); - public Color4 Light1 => getColour(0.4f, 0.8f); - public Color4 Light2 => getColour(0.4f, 0.75f); - public Color4 Light3 => getColour(0.4f, 0.7f); - public Color4 Light4 => getColour(0.4f, 0.5f); - public Color4 Dark1 => getColour(0.2f, 0.35f); - public Color4 Dark2 => getColour(0.2f, 0.3f); - public Color4 Dark3 => getColour(0.2f, 0.25f); - public Color4 Dark4 => getColour(0.2f, 0.2f); - public Color4 Dark5 => getColour(0.2f, 0.15f); - public Color4 Dark6 => getColour(0.2f, 0.1f); - public Color4 Foreground1 => getColour(0.1f, 0.6f); - public Color4 Background1 => getColour(0.1f, 0.4f); - public Color4 Background2 => getColour(0.1f, 0.3f); - public Color4 Background3 => getColour(0.1f, 0.25f); - public Color4 Background4 => getColour(0.1f, 0.2f); - public Color4 Background5 => getColour(0.1f, 0.15f); - public Color4 Background6 => getColour(0.1f, 0.1f); + public Color4 Highlight1 => GetColour(1, 0.7f); + public Color4 Content1 => GetColour(0.4f, 1); + public Color4 Content2 => GetColour(0.4f, 0.9f); + public Color4 Light1 => GetColour(0.4f, 0.8f); + public Color4 Light2 => GetColour(0.4f, 0.75f); + public Color4 Light3 => GetColour(0.4f, 0.7f); + public Color4 Light4 => GetColour(0.4f, 0.5f); + public Color4 Dark1 => GetColour(0.2f, 0.35f); + public Color4 Dark2 => GetColour(0.2f, 0.3f); + public Color4 Dark3 => GetColour(0.2f, 0.25f); + public Color4 Dark4 => GetColour(0.2f, 0.2f); + public Color4 Dark5 => GetColour(0.2f, 0.15f); + public Color4 Dark6 => GetColour(0.2f, 0.1f); + public Color4 Foreground1 => GetColour(0.1f, 0.6f); + public Color4 Background1 => GetColour(0.1f, 0.4f); + public Color4 Background2 => GetColour(0.1f, 0.3f); + public Color4 Background3 => GetColour(0.1f, 0.25f); + public Color4 Background4 => GetColour(0.1f, 0.2f); + public Color4 Background5 => GetColour(0.1f, 0.15f); + public Color4 Background6 => GetColour(0.1f, 0.1f); - private Color4 getColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); + public Color4 GetColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 private static float getBaseHue(OverlayColourScheme colourScheme) From 5a3daf1bd71939f6f1c4b34d1911d74b6789a6f1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 00:57:06 +0300 Subject: [PATCH 0393/1142] Implement CommitButton --- .../Comments/CancellableCommentEditor.cs | 4 +- osu.Game/Overlays/Comments/CommentEditor.cs | 72 ++++++++++++++++++- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index ad5686910a..f58627efb3 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -22,8 +22,8 @@ namespace osu.Game.Overlays.Comments { ButtonsContainer.Add(new CancelButton { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, Action = () => OnCancel?.Invoke() }); } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index bb8ae7f114..624e15a047 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -10,6 +10,10 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.Sprites; using osuTK.Graphics; +using osu.Game.Graphics.UserInterface; +using System.Collections.Generic; +using System; +using osuTK; namespace osu.Game.Overlays.Comments { @@ -17,6 +21,8 @@ namespace osu.Game.Overlays.Comments { private const int side_padding = 8; + public Action OnCommit; + protected abstract string FooterText { get; } protected abstract string CommitButtonText { get; } @@ -28,6 +34,9 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { + EditorTextbox textbox; + CommitButton commitButton; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Masking = true; @@ -49,7 +58,7 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - new EditorTextbox + textbox = new EditorTextbox { Height = 40, RelativeSizeAxes = Axes.X, @@ -77,12 +86,21 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Child = commitButton = new CommitButton(CommitButtonText) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Action = () => OnCommit?.Invoke(textbox.Text) + } } } } } } }); + + textbox.OnCommit += (u, v) => commitButton.Click(); } private class EditorTextbox : BasicTextBox @@ -107,7 +125,6 @@ namespace osu.Game.Overlays.Comments BackgroundCommit = Color4.LightSkyBlue; } - protected override SpriteText CreatePlaceholder() => placeholder = new OsuSpriteText { Font = OsuFont.GetFont(weight: FontWeight.Regular), @@ -115,5 +132,56 @@ namespace osu.Game.Overlays.Comments protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) }; } + + private class CommitButton : LoadingButton + { + private const int duration = 200; + + protected override IEnumerable EffectTargets => new[] { background }; + + private OsuSpriteText drawableText; + private Box background; + + public CommitButton(string text) + { + AutoSizeAxes = Axes.Both; + LoadingAnimationSize = new Vector2(10); + + drawableText.Text = text; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + IdleColour = colourProvider.GetColour(0.5f, 0.45f); + HoverColour = colourProvider.GetColour(0.5f, 0.6f); + } + + protected override Drawable CreateContent() => new CircularContainer + { + Masking = true, + Height = 25, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + drawableText = new OsuSpriteText + { + AlwaysPresent = true, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Margin = new MarginPadding { Horizontal = 20 } + } + } + }; + + protected override void OnLoadStarted() => drawableText.FadeOut(duration, Easing.OutQuint); + + protected override void OnLoadFinished() => drawableText.FadeIn(duration, Easing.OutQuint); + } } } From 53a2b65dbdffda9ee3f053108dd8080b9ed85a5f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 01:35:08 +0300 Subject: [PATCH 0394/1142] Create dependency between textbox and commit button --- osu.Game/Overlays/Comments/CommentEditor.cs | 56 ++++++++++++++++++--- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 624e15a047..7adb33663c 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -14,6 +14,7 @@ using osu.Game.Graphics.UserInterface; using System.Collections.Generic; using System; using osuTK; +using osu.Framework.Bindables; namespace osu.Game.Overlays.Comments { @@ -31,11 +32,14 @@ namespace osu.Game.Overlays.Comments protected FillFlowContainer ButtonsContainer; + private readonly Bindable current = new Bindable(); + + private CommitButton commitButton; + [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { EditorTextbox textbox; - CommitButton commitButton; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -62,7 +66,8 @@ namespace osu.Game.Overlays.Comments { Height = 40, RelativeSizeAxes = Axes.X, - PlaceholderText = TextboxPlaceholderText + PlaceholderText = TextboxPlaceholderText, + Current = current }, new Container { @@ -91,7 +96,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Action = () => OnCommit?.Invoke(textbox.Text) + Action = () => OnCommit?.Invoke(current.Value) } } } @@ -100,14 +105,28 @@ namespace osu.Game.Overlays.Comments } }); - textbox.OnCommit += (u, v) => commitButton.Click(); + textbox.OnCommit += (u, v) => + { + if (!commitButton.IsReady.Value) + return; + + commitButton.Click(); + current.Value = string.Empty; + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + current.BindValueChanged(text => commitButton.IsReady.Value = !string.IsNullOrEmpty(text.NewValue), true); } private class EditorTextbox : BasicTextBox { protected override float LeftRightPadding => side_padding; - protected override Color4 SelectionColour => Color4.LightSkyBlue; + protected override Color4 SelectionColour => Color4.Gray; private OsuSpriteText placeholder; @@ -122,7 +141,7 @@ namespace osu.Game.Overlays.Comments { BackgroundUnfocused = BackgroundFocused = colourProvider.Background5; placeholder.Colour = colourProvider.Background3; - BackgroundCommit = Color4.LightSkyBlue; + BackgroundCommit = colourProvider.Background3; } protected override SpriteText CreatePlaceholder() => placeholder = new OsuSpriteText @@ -137,8 +156,15 @@ namespace osu.Game.Overlays.Comments { private const int duration = 200; + public readonly BindableBool IsReady = new BindableBool(); + + public override bool PropagatePositionalInputSubTree => IsReady.Value && base.PropagatePositionalInputSubTree; + protected override IEnumerable EffectTargets => new[] { background }; + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + private OsuSpriteText drawableText; private Box background; @@ -151,12 +177,28 @@ namespace osu.Game.Overlays.Comments } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load() { IdleColour = colourProvider.GetColour(0.5f, 0.45f); HoverColour = colourProvider.GetColour(0.5f, 0.6f); } + protected override void LoadComplete() + { + base.LoadComplete(); + IsReady.BindValueChanged(onReadyStateChanged, true); + } + + private void onReadyStateChanged(ValueChangedEvent isReady) + { + drawableText.FadeColour(isReady.NewValue ? Color4.White : colourProvider.Foreground1, duration, Easing.OutQuint); + + if (isReady.NewValue) + background.FadeColour(IsHovered ? HoverColour : IdleColour, duration, Easing.OutQuint); + else + background.FadeColour(colourProvider.Background5, duration, Easing.OutQuint); + } + protected override Drawable CreateContent() => new CircularContainer { Masking = true, From 9ac6c271ac3331e390b8d00d168fee539e97c556 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 02:05:45 +0300 Subject: [PATCH 0395/1142] Naming adjustments --- .../UserInterface/TestSceneCommentEditor.cs | 36 +++++++++++++++++-- osu.Game/Overlays/Comments/CommentEditor.cs | 26 ++++++++------ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 86179886e5..e32bf05197 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.Comments; using osuTK; @@ -23,8 +25,21 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + private readonly OsuSpriteText text; + private readonly TestCommentEditor commentEditor; + private readonly TestCancellableCommentEditor cancellableCommentEditor; + public TestSceneCommentEditor() { + Add(new Container + { + AutoSizeAxes = Axes.Both, + Child = text = new OsuSpriteText + { + Font = OsuFont.GetFont() + } + }); + Add(new FillFlowContainer { Anchor = Anchor.Centre, @@ -35,12 +50,29 @@ namespace osu.Game.Tests.Visual.UserInterface Spacing = new Vector2(0, 20), Children = new Drawable[] { - new TestCommentEditor(), - new TestCancellableCommentEditor() + commentEditor = new TestCommentEditor + { + OnCommit = onCommit + }, + cancellableCommentEditor = new TestCancellableCommentEditor + { + OnCommit = onCommit + } } }); } + private void onCommit(string value) + { + text.Text = $@"Invoked text: {value}"; + + Scheduler.AddDelayed(() => + { + commentEditor.IsLoading = false; + cancellableCommentEditor.IsLoading = false; + }, 500); + } + private class TestCommentEditor : CommentEditor { protected override string FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 7adb33663c..34aa036938 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -24,6 +24,12 @@ namespace osu.Game.Overlays.Comments public Action OnCommit; + public bool IsLoading + { + get => commitButton.IsLoading; + set => commitButton.IsLoading = value; + } + protected abstract string FooterText { get; } protected abstract string CommitButtonText { get; } @@ -107,7 +113,7 @@ namespace osu.Game.Overlays.Comments textbox.OnCommit += (u, v) => { - if (!commitButton.IsReady.Value) + if (commitButton.IsBlocked.Value) return; commitButton.Click(); @@ -119,7 +125,7 @@ namespace osu.Game.Overlays.Comments { base.LoadComplete(); - current.BindValueChanged(text => commitButton.IsReady.Value = !string.IsNullOrEmpty(text.NewValue), true); + current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } private class EditorTextbox : BasicTextBox @@ -156,9 +162,9 @@ namespace osu.Game.Overlays.Comments { private const int duration = 200; - public readonly BindableBool IsReady = new BindableBool(); + public readonly BindableBool IsBlocked = new BindableBool(); - public override bool PropagatePositionalInputSubTree => IsReady.Value && base.PropagatePositionalInputSubTree; + public override bool PropagatePositionalInputSubTree => !IsBlocked.Value && base.PropagatePositionalInputSubTree; protected override IEnumerable EffectTargets => new[] { background }; @@ -186,17 +192,17 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { base.LoadComplete(); - IsReady.BindValueChanged(onReadyStateChanged, true); + IsBlocked.BindValueChanged(onBlockedStateChanged, true); } - private void onReadyStateChanged(ValueChangedEvent isReady) + private void onBlockedStateChanged(ValueChangedEvent isBlocked) { - drawableText.FadeColour(isReady.NewValue ? Color4.White : colourProvider.Foreground1, duration, Easing.OutQuint); + drawableText.FadeColour(isBlocked.NewValue ? colourProvider.Foreground1 : Color4.White, duration, Easing.OutQuint); - if (isReady.NewValue) - background.FadeColour(IsHovered ? HoverColour : IdleColour, duration, Easing.OutQuint); - else + if (isBlocked.NewValue) background.FadeColour(colourProvider.Background5, duration, Easing.OutQuint); + else + background.FadeColour(IsHovered ? HoverColour : IdleColour, duration, Easing.OutQuint); } protected override Drawable CreateContent() => new CircularContainer From 2901ec9f261d8d9963f964ef114f5c3b06063267 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Tue, 11 Feb 2020 20:05:26 -0800 Subject: [PATCH 0396/1142] Select specific difficulties using their icons --- osu.Game/Screens/Select/BeatmapCarousel.cs | 7 ++++- .../Select/Carousel/CarouselBeatmapSet.cs | 5 +++- .../Carousel/DrawableCarouselBeatmapSet.cs | 28 +++++++++++++++++-- osu.Game/Screens/Select/SongSelect.cs | 1 + 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 592e26adc2..1777527ced 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -53,6 +53,11 @@ namespace osu.Game.Screens.Select ///
public Action SelectionChanged; + /// + /// Raised when user finalises beatmap selection using + /// + public Action SelectionFinalised; + public override bool HandleNonPositionalInput => AllowSelection; public override bool HandlePositionalInput => AllowSelection; @@ -577,7 +582,7 @@ namespace osu.Game.Screens.Select b.Metadata = beatmapSet.Metadata; } - var set = new CarouselBeatmapSet(beatmapSet); + var set = new CarouselBeatmapSet(beatmapSet, this); foreach (var c in set.Beatmaps) { diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 301d0d4dae..66ee4d2aee 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -15,8 +15,9 @@ namespace osu.Game.Screens.Select.Carousel public IEnumerable Beatmaps => InternalChildren.OfType(); public BeatmapSetInfo BeatmapSet; + public BeatmapCarousel Carousel; - public CarouselBeatmapSet(BeatmapSetInfo beatmapSet) + public CarouselBeatmapSet(BeatmapSetInfo beatmapSet, BeatmapCarousel carousel) { BeatmapSet = beatmapSet ?? throw new ArgumentNullException(nameof(beatmapSet)); @@ -24,6 +25,8 @@ namespace osu.Game.Screens.Select.Carousel .Where(b => !b.Hidden) .Select(b => new CarouselBeatmap(b)) .ForEach(AddChild); + + Carousel = carousel; } protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmapSet(this); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 699e01bca7..536fca9e6f 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; @@ -33,10 +34,13 @@ namespace osu.Game.Screens.Select.Carousel private DialogOverlay dialogOverlay; private readonly BeatmapSetInfo beatmapSet; + private BeatmapCarousel carousel; + public DrawableCarouselBeatmapSet(CarouselBeatmapSet set) : base(set) { beatmapSet = set.BeatmapSet; + carousel = set.Carousel; } [BackgroundDependencyLoader(true)] @@ -117,7 +121,7 @@ namespace osu.Game.Screens.Select.Carousel return beatmaps.Count > maximum_difficulty_icons ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) - : beatmaps.Select(b => new FilterableDifficultyIcon(b)); + : beatmaps.Select(b => new FilterableDifficultyIcon(b, carousel)); } public MenuItem[] ContextMenuItems @@ -210,12 +214,32 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - public FilterableDifficultyIcon(CarouselBeatmap item) + private BeatmapCarousel carousel; + private BeatmapInfo info; + + public FilterableDifficultyIcon(CarouselBeatmap item, BeatmapCarousel carousel) : base(item.Beatmap) { filtered.BindTo(item.Filtered); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); + + this.carousel = carousel; + info = item.Beatmap; + } + + protected override bool OnClick(ClickEvent e) + { + if(e.AltPressed || carousel.SelectedBeatmap == info) + { + Schedule(() => carousel.SelectionFinalised?.Invoke(info)); + } + else + { + carousel.SelectBeatmap(info); + } + + return true; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 5037081b5e..bfa693cf3d 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -155,6 +155,7 @@ namespace osu.Game.Screens.Select Origin = Anchor.CentreRight, RelativeSizeAxes = Axes.Both, SelectionChanged = updateSelectedBeatmap, + SelectionFinalised = beatmapInfo => { FinaliseSelection(beatmapInfo); }, BeatmapSetsChanged = carouselBeatmapsLoaded, }, } From e9b51371476ca3adb6a00e9aca26ff5b600dae51 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Tue, 11 Feb 2020 21:52:22 -0800 Subject: [PATCH 0397/1142] Remove >-1 limitation by using a separate constructor --- osu.Game/Configuration/SettingSourceAttribute.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index 4dcd2c6122..013621d7b7 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -29,12 +29,17 @@ namespace osu.Game.Configuration public string Description { get; } - public int OrderPosition { get; } + public int? OrderPosition { get; } - public SettingSourceAttribute(string label, string description = null, int orderPosition = -1) + public SettingSourceAttribute(string label, string description = null) { Label = label ?? string.Empty; Description = description ?? string.Empty; + } + + public SettingSourceAttribute(string label, string description, int orderPosition) + : this(label, description) + { OrderPosition = orderPosition; } } @@ -129,7 +134,7 @@ namespace osu.Game.Configuration { var original = obj.GetSettingsSourceProperties(); - var orderedRelative = original.Where(attr => attr.Item1.OrderPosition > -1).OrderBy(attr => attr.Item1.OrderPosition); + var orderedRelative = original.Where(attr => attr.Item1.OrderPosition != null).OrderBy(attr => attr.Item1.OrderPosition); var unordered = original.Except(orderedRelative); return orderedRelative.Concat(unordered); From c386589cc09682ccf21db710775aa4bc6420e64e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Feb 2020 19:02:25 +0900 Subject: [PATCH 0398/1142] Reapply current state, not idle --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index e391157b5b..f4ce71b803 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Objects.Drawables HitObject.DefaultsApplied += onDefaultsApplied; startTimeBindable = HitObject.StartTimeBindable.GetBoundCopy(); - startTimeBindable.BindValueChanged(_ => updateState(ArmedState.Idle, true)); + startTimeBindable.BindValueChanged(_ => updateState(State.Value, true)); if (HitObject is IHasComboInformation combo) { From f7ee675102c4dc76f6b69711046f4678515988b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Feb 2020 19:02:54 +0900 Subject: [PATCH 0399/1142] Clear and revert to negative infinity, avoiding transforms getting left behind on StartTime change --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index f4ce71b803..d3a0b3450f 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -250,8 +250,8 @@ namespace osu.Game.Rulesets.Objects.Drawables double transformTime = HitObject.StartTime - InitialLifetimeOffset; - base.ApplyTransformsAt(transformTime, true); - base.ClearTransformsAfter(transformTime, true); + base.ApplyTransformsAt(double.MinValue, true); + base.ClearTransformsAfter(double.MinValue, true); using (BeginAbsoluteSequence(transformTime, true)) { From 85a443783755a52cc2d46581644180a264339a2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 12 Feb 2020 19:03:22 +0900 Subject: [PATCH 0400/1142] Fix editor custom FadeOut causing overlapping issues by removing existing FadeOut --- osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs index 22b4c3e82e..a8719e0aa8 100644 --- a/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs +++ b/osu.Game.Rulesets.Osu/Edit/DrawableOsuEditRuleset.cs @@ -40,6 +40,8 @@ namespace osu.Game.Rulesets.Osu.Edit if (existing == null) return; + hitObject.RemoveTransform(existing); + using (hitObject.BeginAbsoluteSequence(existing.StartTime)) hitObject.FadeOut(editor_hit_object_fade_out_extension).Expire(); break; From ab7adb3a9798dd0c68cfd4dab5939c36918faf5a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 13:28:49 +0300 Subject: [PATCH 0401/1142] Adjust button colours --- .../Comments/CancellableCommentEditor.cs | 4 +- osu.Game/Overlays/Comments/CommentEditor.cs | 4 +- osu.Game/Overlays/OverlayColourProvider.cs | 42 +++++++++---------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index f58627efb3..c226b7f07f 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -63,8 +63,8 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - IdleColour = colourProvider.GetColour(0.5f, 0.45f); - HoverColour = colourProvider.GetColour(0.5f, 0.6f); + IdleColour = colourProvider.Light4; + HoverColour = colourProvider.Light3; } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 34aa036938..ac355e9c98 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -185,8 +185,8 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load() { - IdleColour = colourProvider.GetColour(0.5f, 0.45f); - HoverColour = colourProvider.GetColour(0.5f, 0.6f); + IdleColour = colourProvider.Light4; + HoverColour = colourProvider.Light3; } protected override void LoadComplete() diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index c0984073e6..9816f313ad 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -16,28 +16,28 @@ namespace osu.Game.Overlays this.colourScheme = colourScheme; } - public Color4 Highlight1 => GetColour(1, 0.7f); - public Color4 Content1 => GetColour(0.4f, 1); - public Color4 Content2 => GetColour(0.4f, 0.9f); - public Color4 Light1 => GetColour(0.4f, 0.8f); - public Color4 Light2 => GetColour(0.4f, 0.75f); - public Color4 Light3 => GetColour(0.4f, 0.7f); - public Color4 Light4 => GetColour(0.4f, 0.5f); - public Color4 Dark1 => GetColour(0.2f, 0.35f); - public Color4 Dark2 => GetColour(0.2f, 0.3f); - public Color4 Dark3 => GetColour(0.2f, 0.25f); - public Color4 Dark4 => GetColour(0.2f, 0.2f); - public Color4 Dark5 => GetColour(0.2f, 0.15f); - public Color4 Dark6 => GetColour(0.2f, 0.1f); - public Color4 Foreground1 => GetColour(0.1f, 0.6f); - public Color4 Background1 => GetColour(0.1f, 0.4f); - public Color4 Background2 => GetColour(0.1f, 0.3f); - public Color4 Background3 => GetColour(0.1f, 0.25f); - public Color4 Background4 => GetColour(0.1f, 0.2f); - public Color4 Background5 => GetColour(0.1f, 0.15f); - public Color4 Background6 => GetColour(0.1f, 0.1f); + public Color4 Highlight1 => getColour(1, 0.7f); + public Color4 Content1 => getColour(0.4f, 1); + public Color4 Content2 => getColour(0.4f, 0.9f); + public Color4 Light1 => getColour(0.4f, 0.8f); + public Color4 Light2 => getColour(0.4f, 0.75f); + public Color4 Light3 => getColour(0.4f, 0.7f); + public Color4 Light4 => getColour(0.4f, 0.5f); + public Color4 Dark1 => getColour(0.2f, 0.35f); + public Color4 Dark2 => getColour(0.2f, 0.3f); + public Color4 Dark3 => getColour(0.2f, 0.25f); + public Color4 Dark4 => getColour(0.2f, 0.2f); + public Color4 Dark5 => getColour(0.2f, 0.15f); + public Color4 Dark6 => getColour(0.2f, 0.1f); + public Color4 Foreground1 => getColour(0.1f, 0.6f); + public Color4 Background1 => getColour(0.1f, 0.4f); + public Color4 Background2 => getColour(0.1f, 0.3f); + public Color4 Background3 => getColour(0.1f, 0.25f); + public Color4 Background4 => getColour(0.1f, 0.2f); + public Color4 Background5 => getColour(0.1f, 0.15f); + public Color4 Background6 => getColour(0.1f, 0.1f); - public Color4 GetColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); + private Color4 getColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 private static float getBaseHue(OverlayColourScheme colourScheme) From 62051c036b1f90bd16f7972ca6b4d9dd13e8d6ce Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 13:43:56 +0300 Subject: [PATCH 0402/1142] Small CommitButton improvements --- osu.Game/Overlays/Comments/CommentEditor.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index ac355e9c98..edd09cc95f 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -102,7 +102,11 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Action = () => OnCommit?.Invoke(current.Value) + Action = () => + { + OnCommit?.Invoke(current.Value); + current.Value = string.Empty; + } } } } @@ -117,7 +121,6 @@ namespace osu.Game.Overlays.Comments return; commitButton.Click(); - current.Value = string.Empty; }; } @@ -173,6 +176,7 @@ namespace osu.Game.Overlays.Comments private OsuSpriteText drawableText; private Box background; + private Box blockedBackground; public CommitButton(string text) { @@ -187,6 +191,7 @@ namespace osu.Game.Overlays.Comments { IdleColour = colourProvider.Light4; HoverColour = colourProvider.Light3; + blockedBackground.Colour = colourProvider.Background5; } protected override void LoadComplete() @@ -198,11 +203,7 @@ namespace osu.Game.Overlays.Comments private void onBlockedStateChanged(ValueChangedEvent isBlocked) { drawableText.FadeColour(isBlocked.NewValue ? colourProvider.Foreground1 : Color4.White, duration, Easing.OutQuint); - - if (isBlocked.NewValue) - background.FadeColour(colourProvider.Background5, duration, Easing.OutQuint); - else - background.FadeColour(IsHovered ? HoverColour : IdleColour, duration, Easing.OutQuint); + background.FadeTo(isBlocked.NewValue ? 0 : 1, duration, Easing.OutQuint); } protected override Drawable CreateContent() => new CircularContainer @@ -212,6 +213,10 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.X, Children = new Drawable[] { + blockedBackground = new Box + { + RelativeSizeAxes = Axes.Both + }, background = new Box { RelativeSizeAxes = Axes.Both From e2b3494352b950ad9c0687fcc1b74cd1639ef465 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 00:19:21 +0300 Subject: [PATCH 0403/1142] Remove dependency on load state for DrawableComment.AddReplies --- osu.Game/Overlays/Comments/CommentsPage.cs | 2 +- osu.Game/Overlays/Comments/DrawableComment.cs | 36 +++++++++++++++---- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index eb1044c853..f93cf90e88 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -78,7 +78,7 @@ namespace osu.Game.Overlays.Comments if (replies.Any()) { replies.ForEach(c => c.ParentComment = comment); - drawableComment.OnLoadComplete += _ => drawableComment.AddReplies(replies.Select(reply => createCommentWithReplies(reply, commentBundle))); + drawableComment.InitialReplies.AddRange(replies.Select(reply => createCommentWithReplies(reply, commentBundle))); } return drawableComment; diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index b0062ca1e5..7b7f4726f7 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -36,6 +36,11 @@ namespace osu.Game.Overlays.Comments public readonly Bindable Sort = new Bindable(); public readonly List LoadedReplies = new List(); + /// + /// s which will be added to this as replies when it will be loaded. + /// + public readonly List InitialReplies = new List(); + private readonly BindableBool childrenExpanded = new BindableBool(true); private int currentPage; @@ -265,6 +270,9 @@ namespace osu.Game.Overlays.Comments Colour = OsuColour.Gray(0.1f) }); } + + if (InitialReplies.Any()) + AddReplies(InitialReplies); } protected override void LoadComplete() @@ -283,14 +291,28 @@ namespace osu.Game.Overlays.Comments public void AddReplies(IEnumerable replies) { - LoadComponentAsync(createRepliesPage(replies), page => + if (LoadState == LoadState.NotLoaded) + throw new NotSupportedException($@"Can't use {nameof(AddReplies)} when not loaded."); + + var page = createRepliesPage(replies); + + if (LoadState == LoadState.Loading) { - var newReplies = replies.Select(reply => reply.Comment); - LoadedReplies.AddRange(newReplies); - deletedCommentsCounter.Count.Value += newReplies.Count(reply => reply.IsDeleted); - childCommentsContainer.Add(page); - updateButtonsState(); - }); + addRepliesPage(page, replies); + return; + } + + LoadComponentAsync(page, loaded => addRepliesPage(loaded, replies)); + } + + private void addRepliesPage(FillFlowContainer page, IEnumerable replies) + { + childCommentsContainer.Add(page); + + var newReplies = replies.Select(reply => reply.Comment); + LoadedReplies.AddRange(newReplies); + deletedCommentsCounter.Count.Value += newReplies.Count(reply => reply.IsDeleted); + updateButtonsState(); } private FillFlowContainer createRepliesPage(IEnumerable replies) => new FillFlowContainer From 5201c1c87bc5f3df3bb7679d52435b4e283979c6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 02:21:13 +0300 Subject: [PATCH 0404/1142] Use new algorithm for comments tree creation --- .../Online/API/Requests/Responses/Comment.cs | 3 + osu.Game/Overlays/Comments/CommentsPage.cs | 63 ++++++++++++++----- osu.Game/Overlays/Comments/DrawableComment.cs | 7 ++- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/osu.Game/Online/API/Requests/Responses/Comment.cs b/osu.Game/Online/API/Requests/Responses/Comment.cs index 05a24cec0e..03ed8916e2 100644 --- a/osu.Game/Online/API/Requests/Responses/Comment.cs +++ b/osu.Game/Online/API/Requests/Responses/Comment.cs @@ -4,6 +4,7 @@ using Newtonsoft.Json; using osu.Game.Users; using System; +using System.Collections.Generic; namespace osu.Game.Online.API.Requests.Responses { @@ -15,6 +16,8 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"parent_id")] public long? ParentId { get; set; } + public readonly List ChildComments = new List(); + public Comment ParentComment { get; set; } [JsonProperty(@"user_id")] diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index f93cf90e88..3f63481458 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -12,7 +12,6 @@ using System.Linq; using osu.Game.Online.API.Requests; using osu.Game.Online.API; using System.Collections.Generic; -using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Game.Overlays.Comments { @@ -27,6 +26,7 @@ namespace osu.Game.Overlays.Comments private IAPIProvider api { get; set; } private readonly CommentBundle commentBundle; + private FillFlowContainer flow; public CommentsPage(CommentBundle commentBundle) { @@ -36,8 +36,6 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - FillFlowContainer flow; - RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -62,24 +60,59 @@ namespace osu.Game.Overlays.Comments return; } - commentBundle.Comments.ForEach(c => - { - if (c.IsTopLevel) - flow.Add(createCommentWithReplies(c, commentBundle)); - }); + createBaseTree(commentBundle.Comments); } - private DrawableComment createCommentWithReplies(Comment comment, CommentBundle commentBundle) + private void createBaseTree(List comments) + { + var nodeDictionary = new Dictionary(); + var topLevelNodes = new List(); + var orphanedNodes = new List(); + + foreach (var comment in comments) + { + nodeDictionary.Add(comment.Id, comment); + + if (comment.IsTopLevel) + topLevelNodes.Add(comment); + + var orphanedNodesCopy = new List(orphanedNodes); + + foreach (var orphan in orphanedNodesCopy) + { + if (orphan.ParentId == comment.Id) + { + orphan.ParentComment = comment; + comment.ChildComments.Add(orphan); + orphanedNodes.Remove(orphan); + } + } + + // No need to find parent for top-level comment + if (comment.IsTopLevel) + continue; + + if (nodeDictionary.ContainsKey(comment.ParentId.Value)) + { + comment.ParentComment = nodeDictionary[comment.ParentId.Value]; + nodeDictionary[comment.ParentId.Value].ChildComments.Add(comment); + } + else + orphanedNodes.Add(comment); + } + + foreach (var comment in topLevelNodes) + flow.Add(createCommentWithReplies(comment)); + } + + private DrawableComment createCommentWithReplies(Comment comment) { var drawableComment = createDrawableComment(comment); - var replies = commentBundle.Comments.Where(c => c.ParentId == comment.Id); + var replies = comment.ChildComments; if (replies.Any()) - { - replies.ForEach(c => c.ParentComment = comment); - drawableComment.InitialReplies.AddRange(replies.Select(reply => createCommentWithReplies(reply, commentBundle))); - } + drawableComment.InitialReplies.AddRange(replies.Select(createCommentWithReplies)); return drawableComment; } @@ -100,7 +133,7 @@ namespace osu.Game.Overlays.Comments // We may receive already loaded comments receivedComments.ForEach(c => { - if (drawableComment.LoadedReplies.All(loadedReply => loadedReply.Id != c.Id)) + if (!drawableComment.LoadedReplies.ContainsKey(c.Id)) uniqueComments.Add(c); }); diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 7b7f4726f7..7334c89eb5 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -20,6 +20,7 @@ using osuTK.Graphics; using System.Collections.Generic; using System; using osu.Framework.Graphics.Shapes; +using osu.Framework.Extensions.IEnumerableExtensions; namespace osu.Game.Overlays.Comments { @@ -34,10 +35,10 @@ namespace osu.Game.Overlays.Comments public readonly BindableBool ShowDeleted = new BindableBool(); public readonly Bindable Sort = new Bindable(); - public readonly List LoadedReplies = new List(); + public readonly Dictionary LoadedReplies = new Dictionary(); /// - /// s which will be added to this as replies when it will be loaded. + /// s which will be added to this as replies on initial load. /// public readonly List InitialReplies = new List(); @@ -310,7 +311,7 @@ namespace osu.Game.Overlays.Comments childCommentsContainer.Add(page); var newReplies = replies.Select(reply => reply.Comment); - LoadedReplies.AddRange(newReplies); + newReplies.ForEach(reply => LoadedReplies.Add(reply.Id, reply)); deletedCommentsCounter.Count.Value += newReplies.Count(reply => reply.IsDeleted); updateButtonsState(); } From c6f8e157fd0e5b459ef8b57d3ea8d4d9d95c8581 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 02:37:41 +0300 Subject: [PATCH 0405/1142] Make loadedReplies dictionary private --- osu.Game/Overlays/Comments/CommentsPage.cs | 2 +- osu.Game/Overlays/Comments/DrawableComment.cs | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 3f63481458..ebce2177cf 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -133,7 +133,7 @@ namespace osu.Game.Overlays.Comments // We may receive already loaded comments receivedComments.ForEach(c => { - if (!drawableComment.LoadedReplies.ContainsKey(c.Id)) + if (!drawableComment.ContainsReply(c.Id)) uniqueComments.Add(c); }); diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 7334c89eb5..8bc989761e 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -35,7 +35,7 @@ namespace osu.Game.Overlays.Comments public readonly BindableBool ShowDeleted = new BindableBool(); public readonly Bindable Sort = new Bindable(); - public readonly Dictionary LoadedReplies = new Dictionary(); + private readonly Dictionary loadedReplies = new Dictionary(); /// /// s which will be added to this as replies on initial load. @@ -290,6 +290,8 @@ namespace osu.Game.Overlays.Comments base.LoadComplete(); } + public bool ContainsReply(long replyId) => loadedReplies.ContainsKey(replyId); + public void AddReplies(IEnumerable replies) { if (LoadState == LoadState.NotLoaded) @@ -311,7 +313,7 @@ namespace osu.Game.Overlays.Comments childCommentsContainer.Add(page); var newReplies = replies.Select(reply => reply.Comment); - newReplies.ForEach(reply => LoadedReplies.Add(reply.Id, reply)); + newReplies.ForEach(reply => loadedReplies.Add(reply.Id, reply)); deletedCommentsCounter.Count.Value += newReplies.Count(reply => reply.IsDeleted); updateButtonsState(); } @@ -326,7 +328,7 @@ namespace osu.Game.Overlays.Comments private void updateButtonsState() { - var loadedReplesCount = LoadedReplies.Count; + var loadedReplesCount = loadedReplies.Count; var hasUnloadedReplies = loadedReplesCount != Comment.RepliesCount; loadMoreCommentsButton.FadeTo(hasUnloadedReplies && loadedReplesCount == 0 ? 1 : 0); From b0db1555650b4c9298e2dab6a78039c5e7e2ca18 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 02:47:13 +0300 Subject: [PATCH 0406/1142] Make replies addition more consistent --- osu.Game/Overlays/Comments/CommentsPage.cs | 6 +++--- osu.Game/Overlays/Comments/DrawableComment.cs | 16 ++++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index ebce2177cf..cab3e49f62 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -89,7 +89,7 @@ namespace osu.Game.Overlays.Comments } // No need to find parent for top-level comment - if (comment.IsTopLevel) + if (!comment.ParentId.HasValue) continue; if (nodeDictionary.ContainsKey(comment.ParentId.Value)) @@ -112,7 +112,7 @@ namespace osu.Game.Overlays.Comments var replies = comment.ChildComments; if (replies.Any()) - drawableComment.InitialReplies.AddRange(replies.Select(createCommentWithReplies)); + drawableComment.Replies.AddRange(replies.Select(createCommentWithReplies)); return drawableComment; } @@ -139,7 +139,7 @@ namespace osu.Game.Overlays.Comments uniqueComments.ForEach(c => c.ParentComment = drawableComment.Comment); - drawableComment.AddReplies(uniqueComments.Select(createDrawableComment)); + drawableComment.Replies.AddRange(uniqueComments.Select(createDrawableComment)); } private DrawableComment createDrawableComment(Comment comment) => new DrawableComment(comment) diff --git a/osu.Game/Overlays/Comments/DrawableComment.cs b/osu.Game/Overlays/Comments/DrawableComment.cs index 8bc989761e..7774921f00 100644 --- a/osu.Game/Overlays/Comments/DrawableComment.cs +++ b/osu.Game/Overlays/Comments/DrawableComment.cs @@ -37,10 +37,7 @@ namespace osu.Game.Overlays.Comments public readonly Bindable Sort = new Bindable(); private readonly Dictionary loadedReplies = new Dictionary(); - /// - /// s which will be added to this as replies on initial load. - /// - public readonly List InitialReplies = new List(); + public readonly BindableList Replies = new BindableList(); private readonly BindableBool childrenExpanded = new BindableBool(true); @@ -272,8 +269,10 @@ namespace osu.Game.Overlays.Comments }); } - if (InitialReplies.Any()) - AddReplies(InitialReplies); + Replies.ItemsAdded += onRepliesAdded; + + if (Replies.Any()) + onRepliesAdded(Replies); } protected override void LoadComplete() @@ -292,11 +291,8 @@ namespace osu.Game.Overlays.Comments public bool ContainsReply(long replyId) => loadedReplies.ContainsKey(replyId); - public void AddReplies(IEnumerable replies) + private void onRepliesAdded(IEnumerable replies) { - if (LoadState == LoadState.NotLoaded) - throw new NotSupportedException($@"Can't use {nameof(AddReplies)} when not loaded."); - var page = createRepliesPage(replies); if (LoadState == LoadState.Loading) From a8eb9ba45c71fe67fce625c74776919dea430d82 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Wed, 12 Feb 2020 15:55:16 -0800 Subject: [PATCH 0407/1142] Update xmldoc --- osu.Game/Configuration/SettingSourceAttribute.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Configuration/SettingSourceAttribute.cs b/osu.Game/Configuration/SettingSourceAttribute.cs index 013621d7b7..4bdbb5fc24 100644 --- a/osu.Game/Configuration/SettingSourceAttribute.cs +++ b/osu.Game/Configuration/SettingSourceAttribute.cs @@ -18,8 +18,8 @@ namespace osu.Game.Configuration /// Can be used in conjunction with to automatically create UI controls. /// /// - /// All controls with OrderPosition set to an int greater than 0 will be placed first in ascending order. - /// All controls with no OrderPosition will come afterward in default order. + /// All controls with set will be placed first in ascending order. + /// All controls with no will come afterward in default order. /// [MeansImplicitUse] [AttributeUsage(AttributeTargets.Property)] From 0fe41fd50a04c6b481eb8df4ad4b4622afda7f32 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 09:03:48 +0900 Subject: [PATCH 0408/1142] Fix blueprint showing even when mouse outside of container --- .../Edit/Blueprints/HoldNotePlacementBlueprint.cs | 2 +- .../Edit/Blueprints/ManiaPlacementBlueprint.cs | 2 +- .../Blueprints/Sliders/SliderPlacementBlueprint.cs | 2 +- .../Spinners/SpinnerPlacementBlueprint.cs | 2 +- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 14 ++++++++------ .../Components/ComposeBlueprintContainer.cs | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs index bcbc1ee527..7bbde400ea 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints { base.UpdatePosition(screenSpacePosition); - if (PlacementBegun) + if (PlacementActive) { var endTime = TimeAt(screenSpacePosition); diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs index 362d6d40a8..a3657d3bb9 100644 --- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs @@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints public override void UpdatePosition(Vector2 screenSpacePosition) { - if (!PlacementBegun) + if (!PlacementActive) Column = ColumnAt(screenSpacePosition); if (Column == null) return; diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index 75d05b9b6c..a780653796 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders private void beginCurve() { - BeginPlacement(); + BeginPlacement(commitStart: true); setState(PlacementState.Body); } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs index 2c125aa7c3..74b563d922 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Spinners/SpinnerPlacementBlueprint.cs @@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners if (e.Button != MouseButton.Left) return false; - BeginPlacement(); + BeginPlacement(commitStart: true); piece.FadeTo(1f, 150, Easing.OutQuint); isPlacingEnd = true; diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 24fa96e1c5..8a4ed61d00 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -28,9 +28,9 @@ namespace osu.Game.Rulesets.Edit public event Action StateChanged; /// - /// Whether the is currently being placed, but has not necessarily finished being placed. + /// Whether the is currently mid-placement, but has not necessarily finished being placed. /// - public bool PlacementBegun { get; private set; } + public bool PlacementActive { get; private set; } /// /// The that is being placed. @@ -92,23 +92,25 @@ namespace osu.Game.Rulesets.Edit /// Signals that the placement of has started. /// /// The start time of at the placement point. If null, the current clock time is used. - protected void BeginPlacement(double? startTime = null) + /// Whether this call is committing a value for HitObject.StartTime and continuing with further adjustments. + protected void BeginPlacement(double? startTime = null, bool commitStart = false) { HitObject.StartTime = startTime ?? EditorClock.CurrentTime; placementHandler.BeginPlacement(HitObject); - PlacementBegun = true; + PlacementActive |= commitStart; } /// /// Signals that the placement of has finished. - /// This will destroy this , and add the to the . + /// This will destroy this , and add the HitObject.StartTime to the . /// /// Whether the object should be committed. public void EndPlacement(bool commit) { - if (!PlacementBegun) + if (!PlacementActive) BeginPlacement(); placementHandler.EndPlacement(HitObject, commit); + PlacementActive = false; } /// diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index b257688568..9ebfaef563 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -107,7 +107,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { if (composer.CursorInPlacementArea) currentPlacement.State = PlacementState.Shown; - else if (currentPlacement?.PlacementBegun == false) + else if (currentPlacement?.PlacementActive == false) currentPlacement.State = PlacementState.Hidden; } } From 483bbac6fd0a8b27b24a7a6eaad3a2b86b07d01e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 03:13:56 +0300 Subject: [PATCH 0409/1142] Simplify CommentsPage.onCommentRepliesReceived --- osu.Game/Overlays/Comments/CommentsPage.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index cab3e49f62..5d64313e4f 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -126,16 +126,8 @@ namespace osu.Game.Overlays.Comments private void onCommentRepliesReceived(CommentBundle response, DrawableComment drawableComment) { - var receivedComments = response.Comments; - - var uniqueComments = new List(); - // We may receive already loaded comments - receivedComments.ForEach(c => - { - if (!drawableComment.ContainsReply(c.Id)) - uniqueComments.Add(c); - }); + var uniqueComments = response.Comments.Where(c => !drawableComment.ContainsReply(c.Id)).ToList(); uniqueComments.ForEach(c => c.ParentComment = drawableComment.Comment); From b65e839bd26c00507d2038cfca6cc85e2ef218be Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 10:00:09 +0900 Subject: [PATCH 0410/1142] Simplify blueprints by removing visible state --- osu.Game/Rulesets/Edit/PlacementBlueprint.cs | 38 +------------------ .../Components/ComposeBlueprintContainer.cs | 22 ++++++----- 2 files changed, 14 insertions(+), 46 deletions(-) diff --git a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs index 8a4ed61d00..ea77a6091a 100644 --- a/osu.Game/Rulesets/Edit/PlacementBlueprint.cs +++ b/osu.Game/Rulesets/Edit/PlacementBlueprint.cs @@ -1,8 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -20,13 +18,8 @@ namespace osu.Game.Rulesets.Edit /// /// A blueprint which governs the creation of a new to actualisation. /// - public abstract class PlacementBlueprint : CompositeDrawable, IStateful + public abstract class PlacementBlueprint : CompositeDrawable { - /// - /// Invoked when has changed. - /// - public event Action StateChanged; - /// /// Whether the is currently mid-placement, but has not necessarily finished being placed. /// @@ -53,8 +46,6 @@ namespace osu.Game.Rulesets.Edit // This is required to allow the blueprint's position to be updated via OnMouseMove/Handle // on the same frame it is made visible via a PlacementState change. AlwaysPresent = true; - - Alpha = 0; } [BackgroundDependencyLoader] @@ -67,27 +58,6 @@ namespace osu.Game.Rulesets.Edit ApplyDefaultsToHitObject(); } - private PlacementState state; - - public PlacementState State - { - get => state; - set - { - if (state == value) - return; - - state = value; - - if (state == PlacementState.Shown) - Show(); - else - Hide(); - - StateChanged?.Invoke(value); - } - } - /// /// Signals that the placement of has started. /// @@ -144,10 +114,4 @@ namespace osu.Game.Rulesets.Edit } } } - - public enum PlacementState - { - Hidden, - Shown, - } } diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 9ebfaef563..48c570b8d0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -64,8 +64,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { placementBlueprintContainer.Clear(); - currentPlacement?.EndPlacement(false); - currentPlacement = null; + removePlacement(); var blueprint = CurrentTool?.CreatePlacementBlueprint(); @@ -103,18 +102,14 @@ namespace osu.Game.Screens.Edit.Compose.Components { base.Update(); - if (currentPlacement != null) - { - if (composer.CursorInPlacementArea) - currentPlacement.State = PlacementState.Shown; - else if (currentPlacement?.PlacementActive == false) - currentPlacement.State = PlacementState.Hidden; - } + if (currentPlacement?.PlacementActive == false && !composer.CursorInPlacementArea) + removePlacement(); } protected sealed override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) { var drawable = drawableHitObjects.FirstOrDefault(d => d.HitObject == hitObject); + if (drawable == null) return null; @@ -129,6 +124,14 @@ namespace osu.Game.Screens.Edit.Compose.Components base.AddBlueprintFor(hitObject); } + private void removePlacement() + { + if (currentPlacement == null) return; + + currentPlacement.EndPlacement(false); + currentPlacement = null; + } + private HitObjectCompositionTool currentTool; /// @@ -137,6 +140,7 @@ namespace osu.Game.Screens.Edit.Compose.Components public HitObjectCompositionTool CurrentTool { get => currentTool; + set { if (currentTool == value) From c391a464a5ecffb8fda5ba27cabcc9aa733503fd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 04:06:34 +0300 Subject: [PATCH 0411/1142] Add tests --- .../UserInterface/TestSceneCommentEditor.cs | 106 +++++++++++++++--- osu.Game/Overlays/Comments/CommentEditor.cs | 13 ++- 2 files changed, 96 insertions(+), 23 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index e32bf05197..a7888bb0b4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -3,18 +3,19 @@ using System; using System.Collections.Generic; +using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.Comments; using osuTK; +using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneCommentEditor : OsuTestScene + public class TestSceneCommentEditor : ManualInputManagerTestScene { public override IReadOnlyList RequiredTypes => new[] { @@ -25,20 +26,76 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); - private readonly OsuSpriteText text; - private readonly TestCommentEditor commentEditor; - private readonly TestCancellableCommentEditor cancellableCommentEditor; + private TestCommentEditor commentEditor; + private TestCancellableCommentEditor cancellableCommentEditor; + private string commitText; + private bool cancelActionFired; - public TestSceneCommentEditor() + [Test] + public void TestCommitViaKeyboard() { - Add(new Container + AddStep("Create", createEditors); + AddStep("Click on textbox", () => { - AutoSizeAxes = Axes.Both, - Child = text = new OsuSpriteText - { - Font = OsuFont.GetFont() - } + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); }); + AddStep("Write something", () => commentEditor.Current.Value = "text"); + AddStep("Click Enter", () => press(Key.Enter)); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Button is loading", () => commentEditor.IsLoading); + } + + [Test] + public void TestCommitViaKeyboardWhenEmpty() + { + AddStep("Create", createEditors); + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); + }); + AddStep("Click Enter", () => press(Key.Enter)); + AddAssert("Text not invoked", () => string.IsNullOrEmpty(commitText)); + AddAssert("Button is not loading", () => !commentEditor.IsLoading); + } + + [Test] + public void TestCommitViaButton() + { + AddStep("Create", createEditors); + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); + }); + AddStep("Write something", () => commentEditor.Current.Value = "text"); + AddStep("Click on button", () => + { + InputManager.MoveMouseTo(commentEditor.ButtonsContainer); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Button is loading", () => commentEditor.IsLoading); + } + + [Test] + public void TestCancelAction() + { + AddStep("Create", createEditors); + AddStep("Click on cancel button", () => + { + InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Cancel action is fired", () => cancelActionFired); + } + + private void createEditors() + { + Clear(); + commitText = string.Empty; + cancelActionFired = false; Add(new FillFlowContainer { @@ -52,11 +109,12 @@ namespace osu.Game.Tests.Visual.UserInterface { commentEditor = new TestCommentEditor { - OnCommit = onCommit + OnCommit = onCommit, }, cancellableCommentEditor = new TestCancellableCommentEditor { - OnCommit = onCommit + OnCommit = onCommit, + OnCancel = onCancel } } }); @@ -64,17 +122,29 @@ namespace osu.Game.Tests.Visual.UserInterface private void onCommit(string value) { - text.Text = $@"Invoked text: {value}"; + commitText = value; Scheduler.AddDelayed(() => { commentEditor.IsLoading = false; cancellableCommentEditor.IsLoading = false; - }, 500); + }, 1000); + } + + private void onCancel() => cancelActionFired = true; + + private void press(Key key) + { + InputManager.PressKey(key); + InputManager.ReleaseKey(key); } private class TestCommentEditor : CommentEditor { + public new Bindable Current => base.Current; + + public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; + protected override string FooterText => @"Footer text. And it is pretty long. Cool."; protected override string CommitButtonText => @"Commit"; @@ -84,6 +154,8 @@ namespace osu.Game.Tests.Visual.UserInterface private class TestCancellableCommentEditor : CancellableCommentEditor { + public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; + protected override string FooterText => @"Wow, another one. Sicc"; protected override string CommitButtonText => @"Save"; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index edd09cc95f..765e5e228c 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Comments protected FillFlowContainer ButtonsContainer; - private readonly Bindable current = new Bindable(); + protected readonly Bindable Current = new Bindable(); private CommitButton commitButton; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Comments Height = 40, RelativeSizeAxes = Axes.X, PlaceholderText = TextboxPlaceholderText, - Current = current + Current = Current }, new Container { @@ -104,8 +104,8 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.CentreRight, Action = () => { - OnCommit?.Invoke(current.Value); - current.Value = string.Empty; + OnCommit?.Invoke(Current.Value); + Current.Value = string.Empty; } } } @@ -128,7 +128,7 @@ namespace osu.Game.Overlays.Comments { base.LoadComplete(); - current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); + Current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } private class EditorTextbox : BasicTextBox @@ -219,7 +219,8 @@ namespace osu.Game.Overlays.Comments }, background = new Box { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Alpha = 0 }, drawableText = new OsuSpriteText { From 2b6f99d4043adef41cd9740a72bd84db1d37b17f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 10:05:50 +0900 Subject: [PATCH 0412/1142] Standardise placement blueprint creation and destruction --- .../Components/ComposeBlueprintContainer.cs | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 48c570b8d0..8b47ea2c6c 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -62,19 +62,8 @@ namespace osu.Game.Screens.Edit.Compose.Components /// private void refreshTool() { - placementBlueprintContainer.Clear(); - removePlacement(); - - var blueprint = CurrentTool?.CreatePlacementBlueprint(); - - if (blueprint != null) - { - placementBlueprintContainer.Child = currentPlacement = blueprint; - - // Fixes a 1-frame position discrepancy due to the first mouse move event happening in the next frame - updatePlacementPosition(inputManager.CurrentState.Mouse.Position); - } + createPlacement(); } private void updatePlacementPosition(Vector2 screenSpacePosition) @@ -102,7 +91,9 @@ namespace osu.Game.Screens.Edit.Compose.Components { base.Update(); - if (currentPlacement?.PlacementActive == false && !composer.CursorInPlacementArea) + if (composer.CursorInPlacementArea) + createPlacement(); + else if (currentPlacement?.PlacementActive == false) removePlacement(); } @@ -124,11 +115,27 @@ namespace osu.Game.Screens.Edit.Compose.Components base.AddBlueprintFor(hitObject); } + private void createPlacement() + { + if (currentPlacement != null) return; + + var blueprint = CurrentTool?.CreatePlacementBlueprint(); + + if (blueprint != null) + { + placementBlueprintContainer.Child = currentPlacement = blueprint; + + // Fixes a 1-frame position discrepancy due to the first mouse move event happening in the next frame + updatePlacementPosition(inputManager.CurrentState.Mouse.Position); + } + } + private void removePlacement() { if (currentPlacement == null) return; currentPlacement.EndPlacement(false); + currentPlacement.Expire(); currentPlacement = null; } From e34a24a063dc7e67a48dc16abe1463012e4133ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 10:45:16 +0900 Subject: [PATCH 0413/1142] Update placement blueprint more often for better display --- .../Components/ComposeBlueprintContainer.cs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 8b47ea2c6c..7087eac6b6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -76,17 +76,6 @@ namespace osu.Game.Screens.Edit.Compose.Components #endregion - protected override bool OnMouseMove(MouseMoveEvent e) - { - if (currentPlacement != null) - { - updatePlacementPosition(e.ScreenSpaceMousePosition); - return true; - } - - return base.OnMouseMove(e); - } - protected override void Update() { base.Update(); @@ -95,6 +84,9 @@ namespace osu.Game.Screens.Edit.Compose.Components createPlacement(); else if (currentPlacement?.PlacementActive == false) removePlacement(); + + if (currentPlacement != null) + updatePlacementPosition(inputManager.CurrentState.Mouse.Position); } protected sealed override SelectionBlueprint CreateBlueprintFor(HitObject hitObject) From b1b2e4a0419ef5cb5f45b7ad5ccb0b3b97507b1d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 04:50:04 +0300 Subject: [PATCH 0414/1142] Simplify parent comment assignment --- osu.Game/Overlays/Comments/CommentsPage.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentsPage.cs b/osu.Game/Overlays/Comments/CommentsPage.cs index 5d64313e4f..43a223be8b 100644 --- a/osu.Game/Overlays/Comments/CommentsPage.cs +++ b/osu.Game/Overlays/Comments/CommentsPage.cs @@ -63,9 +63,10 @@ namespace osu.Game.Overlays.Comments createBaseTree(commentBundle.Comments); } + private readonly Dictionary nodeDictionary = new Dictionary(); + private void createBaseTree(List comments) { - var nodeDictionary = new Dictionary(); var topLevelNodes = new List(); var orphanedNodes = new List(); @@ -82,7 +83,6 @@ namespace osu.Game.Overlays.Comments { if (orphan.ParentId == comment.Id) { - orphan.ParentComment = comment; comment.ChildComments.Add(orphan); orphanedNodes.Remove(orphan); } @@ -93,10 +93,7 @@ namespace osu.Game.Overlays.Comments continue; if (nodeDictionary.ContainsKey(comment.ParentId.Value)) - { - comment.ParentComment = nodeDictionary[comment.ParentId.Value]; nodeDictionary[comment.ParentId.Value].ChildComments.Add(comment); - } else orphanedNodes.Add(comment); } @@ -107,6 +104,9 @@ namespace osu.Game.Overlays.Comments private DrawableComment createCommentWithReplies(Comment comment) { + if (comment.ParentId.HasValue) + comment.ParentComment = nodeDictionary[comment.ParentId.Value]; + var drawableComment = createDrawableComment(comment); var replies = comment.ChildComments; From 487dd47c9e9496969921ed90986297c1f4318422 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 11:14:09 +0900 Subject: [PATCH 0415/1142] Add mouse down repeat support to timeline zoom buttons --- .../Components/Timeline/TimelineButton.cs | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs index 8865bf31ea..5550c6a748 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineButton.cs @@ -6,10 +6,13 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osuTK; using osuTK.Graphics; +using osuTK.Input; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { @@ -52,6 +55,45 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline HoverColour = OsuColour.Gray(0.25f); FlashColour = OsuColour.Gray(0.5f); } + + private ScheduledDelegate repeatSchedule; + + /// + /// The initial delay before mouse down repeat begins. + /// + private const int repeat_initial_delay = 250; + + /// + /// The delay between mouse down repeats after the initial repeat. + /// + private const int repeat_tick_rate = 70; + + protected override bool OnClick(ClickEvent e) + { + // don't actuate a click since we are manually handling repeats. + return true; + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + if (e.Button == MouseButton.Left) + { + Action clickAction = () => base.OnClick(new ClickEvent(e.CurrentState, e.Button)); + + // run once for initial down + clickAction(); + + Scheduler.Add(repeatSchedule = new ScheduledDelegate(clickAction, Clock.CurrentTime + repeat_initial_delay, repeat_tick_rate)); + } + + return base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseUpEvent e) + { + repeatSchedule?.Cancel(); + base.OnMouseUp(e); + } } } } From 03bf10f9a24a7a5b259e13435a9979c4e32adfea Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 11:15:00 +0900 Subject: [PATCH 0416/1142] Remove unused using statement --- .../Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs index 7087eac6b6..0eb77a8561 100644 --- a/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/ComposeBlueprintContainer.cs @@ -7,7 +7,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; -using osu.Framework.Input.Events; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Tools; using osu.Game.Rulesets.Objects; From 118f862342dd5903cfdea4661c15302ca6b361f1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 12:02:10 +0900 Subject: [PATCH 0417/1142] Fix not being able to seek using scroll wheel in timeline while playing track --- .../Components/Timeline/ZoomableScrollContainer.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index 7ce8a751e0..baaad63e57 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -2,10 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transforms; using osu.Framework.Input.Events; +using osu.Framework.Timing; using osu.Framework.Utils; using osu.Game.Graphics.Containers; using osuTK; @@ -30,6 +32,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private float currentZoom = 1; + [Resolved] + private IFrameBasedClock editorClock { get; set; } + public ZoomableScrollContainer() : base(Direction.Horizontal) { @@ -104,8 +109,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override bool OnScroll(ScrollEvent e) { if (e.IsPrecise) + { + // can't handle scroll correctly while playing. + // the editor will handle this case for us. + if (editorClock.IsRunning) + return false; + // for now, we don't support zoom when using a precision scroll device. this needs gesture support. return base.OnScroll(e); + } setZoomTarget(zoomTarget + e.ScrollDelta.Y, zoomedContent.ToLocalSpace(e.ScreenSpaceMousePosition).X); return true; From b126c002924788acd7dd62cc410821db081da0fa Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Wed, 12 Feb 2020 19:05:08 -0800 Subject: [PATCH 0418/1142] Use dependency loader to get SongSelect instance --- osu.Game/Screens/Select/BeatmapCarousel.cs | 7 +---- .../Select/Carousel/CarouselBeatmapSet.cs | 5 +--- .../Carousel/DrawableCarouselBeatmapSet.cs | 27 ++++++++++--------- osu.Game/Screens/Select/SongSelect.cs | 3 +-- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 1777527ced..592e26adc2 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -53,11 +53,6 @@ namespace osu.Game.Screens.Select /// public Action SelectionChanged; - /// - /// Raised when user finalises beatmap selection using - /// - public Action SelectionFinalised; - public override bool HandleNonPositionalInput => AllowSelection; public override bool HandlePositionalInput => AllowSelection; @@ -582,7 +577,7 @@ namespace osu.Game.Screens.Select b.Metadata = beatmapSet.Metadata; } - var set = new CarouselBeatmapSet(beatmapSet, this); + var set = new CarouselBeatmapSet(beatmapSet); foreach (var c in set.Beatmaps) { diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 66ee4d2aee..301d0d4dae 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -15,9 +15,8 @@ namespace osu.Game.Screens.Select.Carousel public IEnumerable Beatmaps => InternalChildren.OfType(); public BeatmapSetInfo BeatmapSet; - public BeatmapCarousel Carousel; - public CarouselBeatmapSet(BeatmapSetInfo beatmapSet, BeatmapCarousel carousel) + public CarouselBeatmapSet(BeatmapSetInfo beatmapSet) { BeatmapSet = beatmapSet ?? throw new ArgumentNullException(nameof(beatmapSet)); @@ -25,8 +24,6 @@ namespace osu.Game.Screens.Select.Carousel .Where(b => !b.Hidden) .Select(b => new CarouselBeatmap(b)) .ForEach(AddChild); - - Carousel = carousel; } protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmapSet(this); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 536fca9e6f..fd13bdc3eb 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -34,18 +34,20 @@ namespace osu.Game.Screens.Select.Carousel private DialogOverlay dialogOverlay; private readonly BeatmapSetInfo beatmapSet; - private BeatmapCarousel carousel; + private SongSelect songSelect; public DrawableCarouselBeatmapSet(CarouselBeatmapSet set) : base(set) { beatmapSet = set.BeatmapSet; - carousel = set.Carousel; } [BackgroundDependencyLoader(true)] - private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) + private void load(SongSelect songSelect, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) { + if(songSelect != null) + this.songSelect = songSelect; + restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); dialogOverlay = overlay; if (beatmapOverlay != null) @@ -121,7 +123,7 @@ namespace osu.Game.Screens.Select.Carousel return beatmaps.Count > maximum_difficulty_icons ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) - : beatmaps.Select(b => new FilterableDifficultyIcon(b, carousel)); + : beatmaps.Select(b => new FilterableDifficultyIcon(b, songSelect, songSelect.Carousel)); } public MenuItem[] ContextMenuItems @@ -214,32 +216,33 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); + private SongSelect songSelect; private BeatmapCarousel carousel; private BeatmapInfo info; - public FilterableDifficultyIcon(CarouselBeatmap item, BeatmapCarousel carousel) + public FilterableDifficultyIcon(CarouselBeatmap item, SongSelect songSelect, BeatmapCarousel carousel) : base(item.Beatmap) { filtered.BindTo(item.Filtered); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); + this.songSelect = songSelect; this.carousel = carousel; info = item.Beatmap; } protected override bool OnClick(ClickEvent e) { - if(e.AltPressed || carousel.SelectedBeatmap == info) + if(!filtered.Value) { - Schedule(() => carousel.SelectionFinalised?.Invoke(info)); - } - else - { - carousel.SelectBeatmap(info); + carousel?.SelectBeatmap(info); + + if (e.AltPressed) + songSelect?.FinaliseSelection(); } - return true; + return base.OnClick(e); } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index bfa693cf3d..463a17989a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Select protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); - protected BeatmapCarousel Carousel { get; private set; } + public BeatmapCarousel Carousel { get; private set; } private BeatmapInfoWedge beatmapInfoWedge; private DialogOverlay dialogOverlay; @@ -155,7 +155,6 @@ namespace osu.Game.Screens.Select Origin = Anchor.CentreRight, RelativeSizeAxes = Axes.Both, SelectionChanged = updateSelectedBeatmap, - SelectionFinalised = beatmapInfo => { FinaliseSelection(beatmapInfo); }, BeatmapSetsChanged = carouselBeatmapsLoaded, }, } From f8b69fe63285186a2e6b661e875353696e86ce1f Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Wed, 12 Feb 2020 20:11:39 -0800 Subject: [PATCH 0419/1142] Remove unnecessary carousel variable, fix code formatting --- .../Carousel/DrawableCarouselBeatmapSet.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index fd13bdc3eb..80dae575ff 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Select.Carousel [BackgroundDependencyLoader(true)] private void load(SongSelect songSelect, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) { - if(songSelect != null) + if (songSelect != null) this.songSelect = songSelect; restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); @@ -123,7 +123,7 @@ namespace osu.Game.Screens.Select.Carousel return beatmaps.Count > maximum_difficulty_icons ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) - : beatmaps.Select(b => new FilterableDifficultyIcon(b, songSelect, songSelect.Carousel)); + : beatmaps.Select(b => new FilterableDifficultyIcon(b, songSelect)); } public MenuItem[] ContextMenuItems @@ -216,11 +216,10 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private SongSelect songSelect; - private BeatmapCarousel carousel; - private BeatmapInfo info; + private readonly SongSelect songSelect; + private readonly BeatmapInfo info; - public FilterableDifficultyIcon(CarouselBeatmap item, SongSelect songSelect, BeatmapCarousel carousel) + public FilterableDifficultyIcon(CarouselBeatmap item, SongSelect songSelect) : base(item.Beatmap) { filtered.BindTo(item.Filtered); @@ -228,15 +227,14 @@ namespace osu.Game.Screens.Select.Carousel filtered.TriggerChange(); this.songSelect = songSelect; - this.carousel = carousel; info = item.Beatmap; } protected override bool OnClick(ClickEvent e) { - if(!filtered.Value) + if (!filtered.Value) { - carousel?.SelectBeatmap(info); + songSelect?.Carousel.SelectBeatmap(info); if (e.AltPressed) songSelect?.FinaliseSelection(); From 045d1f9c5b8db2974b53f8157bad41e0d2947e9c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 13:34:59 +0900 Subject: [PATCH 0420/1142] Disallow seeking on osu!direct download progress bars --- osu.Game/Overlays/Direct/DownloadProgressBar.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Direct/DownloadProgressBar.cs b/osu.Game/Overlays/Direct/DownloadProgressBar.cs index a6cefaae84..9a8644efd2 100644 --- a/osu.Game/Overlays/Direct/DownloadProgressBar.cs +++ b/osu.Game/Overlays/Direct/DownloadProgressBar.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Direct public DownloadProgressBar(BeatmapSetInfo beatmapSet) : base(beatmapSet) { - AddInternal(progressBar = new ProgressBar + AddInternal(progressBar = new InteractionDisabledProgressBar { Height = 0, Alpha = 0, @@ -64,5 +64,11 @@ namespace osu.Game.Overlays.Direct } }, true); } + + private class InteractionDisabledProgressBar : ProgressBar + { + public override bool HandlePositionalInput => false; + public override bool HandleNonPositionalInput => false; + } } } From 6f7196b0b81c4063c43006f655090e434df259a9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 12 Feb 2020 19:52:47 +0900 Subject: [PATCH 0421/1142] Make beatmap detail area abstractable --- osu.Game/Configuration/OsuConfigManager.cs | 2 +- osu.Game/Screens/Select/BeatmapDetailArea.cs | 106 +++++++------ .../Select/BeatmapDetailAreaDetailTabItem.cs | 10 ++ .../BeatmapDetailAreaLeaderboardTabItem.cs | 22 +++ .../Select/BeatmapDetailAreaTabControl.cs | 51 ++++--- .../Select/BeatmapDetailAreaTabItem.cs | 35 +++++ osu.Game/Screens/Select/MatchSongSelect.cs | 2 + .../Screens/Select/PlayBeatmapDetailArea.cs | 143 ++++++++++++++++++ osu.Game/Screens/Select/PlaySongSelect.cs | 4 + osu.Game/Screens/Select/SongSelect.cs | 20 +-- 10 files changed, 318 insertions(+), 77 deletions(-) create mode 100644 osu.Game/Screens/Select/BeatmapDetailAreaDetailTabItem.cs create mode 100644 osu.Game/Screens/Select/BeatmapDetailAreaLeaderboardTabItem.cs create mode 100644 osu.Game/Screens/Select/BeatmapDetailAreaTabItem.cs create mode 100644 osu.Game/Screens/Select/PlayBeatmapDetailArea.cs diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 6ae3c7ac64..ce959e9057 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -20,7 +20,7 @@ namespace osu.Game.Configuration Set(OsuSetting.Ruleset, 0, 0, int.MaxValue); Set(OsuSetting.Skin, 0, -1, int.MaxValue); - Set(OsuSetting.BeatmapDetailTab, BeatmapDetailTab.Details); + Set(OsuSetting.BeatmapDetailTab, PlayBeatmapDetailArea.TabType.Details); Set(OsuSetting.ShowConvertedBeatmaps, true); Set(OsuSetting.DisplayStarsMinimum, 0.0, 0, 10, 0.1); diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 71733c9f06..1aae0cc243 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -2,37 +2,44 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -using osu.Game.Screens.Select.Leaderboards; namespace osu.Game.Screens.Select { - public class BeatmapDetailArea : Container + public abstract class BeatmapDetailArea : Container { private const float details_padding = 10; - private readonly Container content; - protected override Container Content => content; - - public readonly BeatmapDetails Details; - public readonly BeatmapLeaderboard Leaderboard; - private WorkingBeatmap beatmap; - public WorkingBeatmap Beatmap + public virtual WorkingBeatmap Beatmap { get => beatmap; set { beatmap = value; - Details.Beatmap = beatmap?.BeatmapInfo; - Leaderboard.Beatmap = beatmap is DummyWorkingBeatmap ? null : beatmap?.BeatmapInfo; + + Details.Beatmap = value?.BeatmapInfo; } } - public BeatmapDetailArea() + public readonly BeatmapDetails Details; + + protected Bindable CurrentTab + { + get => tabControl.Current; + set => tabControl.Current = value; + } + + private readonly Container content; + protected override Container Content => content; + + private readonly BeatmapDetailAreaTabControl tabControl; + + protected BeatmapDetailArea() { AddRangeInternal(new Drawable[] { @@ -40,51 +47,62 @@ namespace osu.Game.Screens.Select { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = BeatmapDetailAreaTabControl.HEIGHT }, - }, - new BeatmapDetailAreaTabControl - { - RelativeSizeAxes = Axes.X, - OnFilter = (tab, mods) => + Child = Details = new BeatmapDetails { - Leaderboard.FilterMods = mods; - - switch (tab) - { - case BeatmapDetailTab.Details: - Details.Show(); - Leaderboard.Hide(); - break; - - default: - Details.Hide(); - Leaderboard.Scope = (BeatmapLeaderboardScope)tab - 1; - Leaderboard.Show(); - break; - } - }, + RelativeSizeAxes = Axes.X, + Alpha = 0, + Margin = new MarginPadding { Top = details_padding }, + } }, - }); - - AddRange(new Drawable[] - { - Details = new BeatmapDetails + tabControl = new BeatmapDetailAreaTabControl { RelativeSizeAxes = Axes.X, - Alpha = 0, - Margin = new MarginPadding { Top = details_padding }, + TabItems = CreateTabItems(), + OnFilter = OnTabChanged, }, - Leaderboard = new BeatmapLeaderboard - { - RelativeSizeAxes = Axes.Both, - } }); } + /// + /// Refreshes the currently-displayed details. + /// + public virtual void Refresh() + { + } + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); Details.Height = Math.Min(DrawHeight - details_padding * 3 - BeatmapDetailAreaTabControl.HEIGHT, 450); } + + /// + /// Invoked when a new tab is selected. + /// + /// The tab that was selected. + /// Whether the currently-selected mods should be considered. + protected virtual void OnTabChanged(BeatmapDetailAreaTabItem tab, bool selectedMods) + { + switch (tab) + { + case BeatmapDetailAreaDetailTabItem _: + Details.Show(); + break; + + default: + Details.Hide(); + break; + } + } + + /// + /// Creates the tabs to be displayed. + /// + /// The tabs. + protected virtual BeatmapDetailAreaTabItem[] CreateTabItems() => new BeatmapDetailAreaTabItem[] + { + new BeatmapDetailAreaDetailTabItem(), + }; } } diff --git a/osu.Game/Screens/Select/BeatmapDetailAreaDetailTabItem.cs b/osu.Game/Screens/Select/BeatmapDetailAreaDetailTabItem.cs new file mode 100644 index 0000000000..7376cb4708 --- /dev/null +++ b/osu.Game/Screens/Select/BeatmapDetailAreaDetailTabItem.cs @@ -0,0 +1,10 @@ +// 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.Screens.Select +{ + public class BeatmapDetailAreaDetailTabItem : BeatmapDetailAreaTabItem + { + public override string Name => "Details"; + } +} diff --git a/osu.Game/Screens/Select/BeatmapDetailAreaLeaderboardTabItem.cs b/osu.Game/Screens/Select/BeatmapDetailAreaLeaderboardTabItem.cs new file mode 100644 index 0000000000..066944e9d2 --- /dev/null +++ b/osu.Game/Screens/Select/BeatmapDetailAreaLeaderboardTabItem.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 System; + +namespace osu.Game.Screens.Select +{ + public class BeatmapDetailAreaLeaderboardTabItem : BeatmapDetailAreaTabItem + where TScope : Enum + { + public override string Name => Scope.ToString(); + + public override bool FilterableByMods => true; + + public readonly TScope Scope; + + public BeatmapDetailAreaLeaderboardTabItem(TScope scope) + { + Scope = scope; + } + } +} diff --git a/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs b/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs index 19ecdb6dbf..f4bf1ab059 100644 --- a/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs +++ b/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -18,14 +19,25 @@ namespace osu.Game.Screens.Select public class BeatmapDetailAreaTabControl : Container { public const float HEIGHT = 24; + + public Bindable Current + { + get => tabs.Current; + set => tabs.Current = value; + } + + public Action OnFilter; //passed the selected tab and if mods is checked + + public IReadOnlyList TabItems + { + get => tabs.Items; + set => tabs.Items = value; + } + private readonly OsuTabControlCheckbox modsCheckbox; - private readonly OsuTabControl tabs; + private readonly OsuTabControl tabs; private readonly Container tabsContainer; - public Action OnFilter; //passed the selected tab and if mods is checked - - private Bindable selectedTab; - public BeatmapDetailAreaTabControl() { Height = HEIGHT; @@ -43,7 +55,7 @@ namespace osu.Game.Screens.Select tabsContainer = new Container { RelativeSizeAxes = Axes.Both, - Child = tabs = new OsuTabControl + Child = tabs = new OsuTabControl { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, @@ -68,29 +80,22 @@ namespace osu.Game.Screens.Select private void load(OsuColour colour, OsuConfigManager config) { modsCheckbox.AccentColour = tabs.AccentColour = colour.YellowLight; - - selectedTab = config.GetBindable(OsuSetting.BeatmapDetailTab); - - tabs.Current.BindTo(selectedTab); - tabs.Current.TriggerChange(); } private void invokeOnFilter() { OnFilter?.Invoke(tabs.Current.Value, modsCheckbox.Current.Value); - modsCheckbox.FadeTo(tabs.Current.Value == BeatmapDetailTab.Details ? 0 : 1, 200, Easing.OutQuint); - - tabsContainer.Padding = new MarginPadding { Right = tabs.Current.Value == BeatmapDetailTab.Details ? 0 : 100 }; + if (tabs.Current.Value.FilterableByMods) + { + modsCheckbox.FadeTo(1, 200, Easing.OutQuint); + tabsContainer.Padding = new MarginPadding { Right = 100 }; + } + else + { + modsCheckbox.FadeTo(0, 200, Easing.OutQuint); + tabsContainer.Padding = new MarginPadding(); + } } } - - public enum BeatmapDetailTab - { - Details, - Local, - Country, - Global, - Friends - } } diff --git a/osu.Game/Screens/Select/BeatmapDetailAreaTabItem.cs b/osu.Game/Screens/Select/BeatmapDetailAreaTabItem.cs new file mode 100644 index 0000000000..f28e5a7c22 --- /dev/null +++ b/osu.Game/Screens/Select/BeatmapDetailAreaTabItem.cs @@ -0,0 +1,35 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; + +namespace osu.Game.Screens.Select +{ + public abstract class BeatmapDetailAreaTabItem : IEquatable + { + /// + /// The name of this tab, to be displayed in the tab control. + /// + public abstract string Name { get; } + + /// + /// Whether the contents of this tab can be filtered by the user's currently-selected mods. + /// + public virtual bool FilterableByMods => false; + + public override string ToString() => Name; + + public bool Equals(BeatmapDetailAreaTabItem other) + { + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + + return Name == other.Name; + } + + public override int GetHashCode() + { + return Name != null ? Name.GetHashCode() : 0; + } + } +} diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 6ba4157797..fd7a8a539c 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -34,6 +34,8 @@ namespace osu.Game.Screens.Select Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING }; } + protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea(); // Todo: Temporary + protected override bool OnStart() { var item = new PlaylistItem diff --git a/osu.Game/Screens/Select/PlayBeatmapDetailArea.cs b/osu.Game/Screens/Select/PlayBeatmapDetailArea.cs new file mode 100644 index 0000000000..d719502a4f --- /dev/null +++ b/osu.Game/Screens/Select/PlayBeatmapDetailArea.cs @@ -0,0 +1,143 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Screens.Select.Leaderboards; + +namespace osu.Game.Screens.Select +{ + public class PlayBeatmapDetailArea : BeatmapDetailArea + { + public readonly BeatmapLeaderboard Leaderboard; + + public override WorkingBeatmap Beatmap + { + get => base.Beatmap; + set + { + base.Beatmap = value; + + Leaderboard.Beatmap = value is DummyWorkingBeatmap ? null : value?.BeatmapInfo; + } + } + + private Bindable selectedTab; + + public PlayBeatmapDetailArea() + { + Add(Leaderboard = new BeatmapLeaderboard { RelativeSizeAxes = Axes.Both }); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + selectedTab = config.GetBindable(OsuSetting.BeatmapDetailTab); + selectedTab.BindValueChanged(tab => CurrentTab.Value = getTabItemFromTabType(tab.NewValue), true); + CurrentTab.BindValueChanged(tab => selectedTab.Value = getTabTypeFromTabItem(tab.NewValue)); + } + + public override void Refresh() + { + base.Refresh(); + + Leaderboard.RefreshScores(); + } + + protected override void OnTabChanged(BeatmapDetailAreaTabItem tab, bool selectedMods) + { + base.OnTabChanged(tab, selectedMods); + + Leaderboard.FilterMods = selectedMods; + + switch (tab) + { + case BeatmapDetailAreaLeaderboardTabItem leaderboard: + Leaderboard.Scope = leaderboard.Scope; + Leaderboard.Show(); + break; + + default: + Leaderboard.Hide(); + break; + } + } + + protected override BeatmapDetailAreaTabItem[] CreateTabItems() => base.CreateTabItems().Concat(new BeatmapDetailAreaTabItem[] + { + new BeatmapDetailAreaLeaderboardTabItem(BeatmapLeaderboardScope.Local), + new BeatmapDetailAreaLeaderboardTabItem(BeatmapLeaderboardScope.Country), + new BeatmapDetailAreaLeaderboardTabItem(BeatmapLeaderboardScope.Global), + new BeatmapDetailAreaLeaderboardTabItem(BeatmapLeaderboardScope.Friend), + }).ToArray(); + + private BeatmapDetailAreaTabItem getTabItemFromTabType(TabType type) + { + switch (type) + { + case TabType.Details: + return new BeatmapDetailAreaDetailTabItem(); + + case TabType.Local: + return new BeatmapDetailAreaLeaderboardTabItem(BeatmapLeaderboardScope.Local); + + case TabType.Country: + return new BeatmapDetailAreaLeaderboardTabItem(BeatmapLeaderboardScope.Country); + + case TabType.Global: + return new BeatmapDetailAreaLeaderboardTabItem(BeatmapLeaderboardScope.Global); + + case TabType.Friends: + return new BeatmapDetailAreaLeaderboardTabItem(BeatmapLeaderboardScope.Friend); + + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + } + + private TabType getTabTypeFromTabItem(BeatmapDetailAreaTabItem item) + { + switch (item) + { + case BeatmapDetailAreaDetailTabItem _: + return TabType.Details; + + case BeatmapDetailAreaLeaderboardTabItem leaderboardTab: + switch (leaderboardTab.Scope) + { + case BeatmapLeaderboardScope.Local: + return TabType.Local; + + case BeatmapLeaderboardScope.Country: + return TabType.Country; + + case BeatmapLeaderboardScope.Global: + return TabType.Global; + + case BeatmapLeaderboardScope.Friend: + return TabType.Friends; + + default: + throw new ArgumentOutOfRangeException(nameof(item)); + } + + default: + throw new ArgumentOutOfRangeException(nameof(item)); + } + } + + public enum TabType + { + Details, + Local, + Country, + Global, + Friends + } + } +} diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index f1dd125362..e744fd6a7b 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -29,8 +29,12 @@ namespace osu.Game.Screens.Select ValidForResume = false; Edit(); }, Key.Number4); + + ((PlayBeatmapDetailArea)BeatmapDetails).Leaderboard.ScoreSelected += score => this.Push(new SoloResults(score)); } + protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea(); + public override void OnResuming(IScreen last) { base.OnResuming(last); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 0da260d752..67626d1e4f 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -23,7 +23,6 @@ using osu.Game.Rulesets.Mods; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Edit; using osu.Game.Screens.Menu; -using osu.Game.Screens.Play; using osu.Game.Screens.Select.Options; using osu.Game.Skinning; using osuTK; @@ -207,11 +206,11 @@ namespace osu.Game.Screens.Select Left = left_area_padding, Right = left_area_padding * 2, }, - Child = BeatmapDetails = new BeatmapDetailArea + Child = BeatmapDetails = CreateBeatmapDetailArea().With(d => { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 10, Right = 5 }, - }, + d.RelativeSizeAxes = Axes.Both; + d.Padding = new MarginPadding { Top = 10, Right = 5 }; + }) }, } }, @@ -262,8 +261,6 @@ namespace osu.Game.Screens.Select }); } - BeatmapDetails.Leaderboard.ScoreSelected += score => this.Push(new SoloResults(score)); - if (Footer != null) { Footer.AddButton(new FooterButtonMods { Current = Mods }, ModSelect); @@ -319,6 +316,11 @@ namespace osu.Game.Screens.Select return dependencies; } + /// + /// Creates the beatmap details to be displayed underneath the wedge. + /// + protected abstract BeatmapDetailArea CreateBeatmapDetailArea(); + public void Edit(BeatmapInfo beatmap = null) { if (!AllowEditing) @@ -533,7 +535,7 @@ namespace osu.Game.Screens.Select Carousel.AllowSelection = true; - BeatmapDetails.Leaderboard.RefreshScores(); + BeatmapDetails.Refresh(); Beatmap.Value.Track.Looping = true; music?.ResetTrackAdjustments(); @@ -716,7 +718,7 @@ namespace osu.Game.Screens.Select dialogOverlay?.Push(new BeatmapClearScoresDialog(beatmap, () => // schedule done here rather than inside the dialog as the dialog may fade out and never callback. - Schedule(() => BeatmapDetails.Leaderboard.RefreshScores()))); + Schedule(() => BeatmapDetails.Refresh()))); } public virtual bool OnPressed(GlobalAction action) From 53b62816f8db94b3aa90fe0be77ceca296a4feab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 14:07:37 +0900 Subject: [PATCH 0422/1142] Add index constants for cross-class safety --- osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs | 4 ++-- osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs | 4 ++-- osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs | 8 ++++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs index de7adaa261..e2465d727e 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Mods { public class CatchModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", 0)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", 3)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", LAST_SETTING_ORDER + 1)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs index 2c6eb19f3d..75de6896a3 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModDifficultyAdjust : ModDifficultyAdjust { - [SettingSource("Circle Size", "Override a beatmap's set CS.", 0)] + [SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1)] public BindableNumber CircleSize { get; } = new BindableFloat { Precision = 0.1f, @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Mods Value = 5, }; - [SettingSource("Approach Rate", "Override a beatmap's set AR.", 3)] + [SettingSource("Approach Rate", "Override a beatmap's set AR.", LAST_SETTING_ORDER + 1)] public BindableNumber ApproachRate { get; } = new BindableFloat { Precision = 0.1f, diff --git a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs index 6ba54ff8fb..2083671072 100644 --- a/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs +++ b/osu.Game/Rulesets/Mods/ModDifficultyAdjust.cs @@ -28,7 +28,11 @@ namespace osu.Game.Rulesets.Mods public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModHardRock) }; - [SettingSource("HP Drain", "Override a beatmap's set HP.", 1)] + protected const int FIRST_SETTING_ORDER = 1; + + protected const int LAST_SETTING_ORDER = 2; + + [SettingSource("HP Drain", "Override a beatmap's set HP.", FIRST_SETTING_ORDER)] public BindableNumber DrainRate { get; } = new BindableFloat { Precision = 0.1f, @@ -38,7 +42,7 @@ namespace osu.Game.Rulesets.Mods Value = 5, }; - [SettingSource("Accuracy", "Override a beatmap's set OD.", 2)] + [SettingSource("Accuracy", "Override a beatmap's set OD.", LAST_SETTING_ORDER)] public BindableNumber OverallDifficulty { get; } = new BindableFloat { Precision = 0.1f, From ad0de2796427ee9025d01afe82fe062d9a0a2b8e Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Wed, 12 Feb 2020 22:11:26 -0800 Subject: [PATCH 0423/1142] Safer dependency injection and accessibility levels --- osu.Game/OsuGame.cs | 47 +++++++++++-------- .../Carousel/DrawableCarouselBeatmapSet.cs | 26 +++++----- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ff3dee55af..3d6b93c87d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -311,22 +311,12 @@ namespace osu.Game public void ShowBeatmap(int beatmapId) => waitForReady(() => beatmapSetOverlay, _ => beatmapSetOverlay.FetchAndShowBeatmap(beatmapId)); /// - /// Present a beatmap at song select immediately. + /// Present a specific beatmap difficulty at song select immediately. /// The user should have already requested this interactively. /// /// The beatmap to select. - public void PresentBeatmap(BeatmapSetInfo beatmap) + public void PresentBeatmap(BeatmapInfo beatmap) { - var databasedSet = beatmap.OnlineBeatmapSetID != null - ? BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID) - : BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmap.Hash); - - if (databasedSet == null) - { - Logger.Log("The requested beatmap could not be loaded.", LoggingTarget.Information); - return; - } - PerformFromScreen(screen => { // we might already be at song select, so a check is required before performing the load to solo. @@ -334,19 +324,36 @@ namespace osu.Game menuScreen.LoadToSolo(); // we might even already be at the song - if (Beatmap.Value.BeatmapSetInfo.Hash == databasedSet.Hash) - { + if (Beatmap.Value.BeatmapInfo.Hash == beatmap.Hash) return; - } - // Use first beatmap available for current ruleset, else switch ruleset. - var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); - - Ruleset.Value = first.Ruleset; - Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); + Ruleset.Value = beatmap.Ruleset; + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap); }, validScreens: new[] { typeof(PlaySongSelect) }); } + /// + /// + /// Instead of selecting a specific difficulty, this will select the first difficulty of the current ruleset in a beatmapset, + /// or the first difficulty of the set if there is none. + /// + /// The beatmapset to select. + public void PresentBeatmap(BeatmapSetInfo beatmapSet) + { + var databasedSet = beatmapSet.OnlineBeatmapSetID != null + ? BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmapSet.OnlineBeatmapSetID) + : BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmapSet.Hash); + + if (databasedSet == null) + { + Logger.Log("The requested beatmap could not be loaded.", LoggingTarget.Information); + return; + } + + var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); + PresentBeatmap(first); + } + /// /// Present a score's replay immediately. /// The user should have already requested this interactively. diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 80dae575ff..9e4f31b15b 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -34,8 +34,6 @@ namespace osu.Game.Screens.Select.Carousel private DialogOverlay dialogOverlay; private readonly BeatmapSetInfo beatmapSet; - private SongSelect songSelect; - public DrawableCarouselBeatmapSet(CarouselBeatmapSet set) : base(set) { @@ -43,11 +41,8 @@ namespace osu.Game.Screens.Select.Carousel } [BackgroundDependencyLoader(true)] - private void load(SongSelect songSelect, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) + private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) { - if (songSelect != null) - this.songSelect = songSelect; - restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); dialogOverlay = overlay; if (beatmapOverlay != null) @@ -123,7 +118,7 @@ namespace osu.Game.Screens.Select.Carousel return beatmaps.Count > maximum_difficulty_icons ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) - : beatmaps.Select(b => new FilterableDifficultyIcon(b, songSelect)); + : beatmaps.Select(b => new FilterableDifficultyIcon(b)); } public MenuItem[] ContextMenuItems @@ -216,17 +211,17 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private readonly SongSelect songSelect; + private OsuGame game; + private SongSelect songSelect; private readonly BeatmapInfo info; - public FilterableDifficultyIcon(CarouselBeatmap item, SongSelect songSelect) + public FilterableDifficultyIcon(CarouselBeatmap item) : base(item.Beatmap) { filtered.BindTo(item.Filtered); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); - this.songSelect = songSelect; info = item.Beatmap; } @@ -234,7 +229,7 @@ namespace osu.Game.Screens.Select.Carousel { if (!filtered.Value) { - songSelect?.Carousel.SelectBeatmap(info); + game.PresentBeatmap(info); if (e.AltPressed) songSelect?.FinaliseSelection(); @@ -242,6 +237,15 @@ namespace osu.Game.Screens.Select.Carousel return base.OnClick(e); } + + [BackgroundDependencyLoader] + private void load(OsuGame game, SongSelect songSelect) + { + this.game = game; + + if (songSelect != null) + this.songSelect = songSelect; + } } public class FilterableGroupedDifficultyIcon : GroupedDifficultyIcon diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 463a17989a..5037081b5e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Select protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); - public BeatmapCarousel Carousel { get; private set; } + protected BeatmapCarousel Carousel { get; private set; } private BeatmapInfoWedge beatmapInfoWedge; private DialogOverlay dialogOverlay; From d4f14e552a26c041cf09f61043e2d96ac2e86a1e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Feb 2020 18:05:53 +0900 Subject: [PATCH 0424/1142] Improve extensibility of mod display expansion --- .../UserInterface/TestSceneModDisplay.cs | 40 +++++++++++++++++++ osu.Game/Screens/Play/HUD/ModDisplay.cs | 28 +++++++++++-- osu.Game/Screens/Select/FooterButtonMods.cs | 2 +- 3 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneModDisplay.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModDisplay.cs new file mode 100644 index 0000000000..8168faa106 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModDisplay.cs @@ -0,0 +1,40 @@ +// 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.Graphics; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Screens.Play.HUD; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneModDisplay : OsuTestScene + { + [TestCase(ExpansionMode.ExpandOnHover)] + [TestCase(ExpansionMode.AlwaysExpanded)] + [TestCase(ExpansionMode.AlwaysContracted)] + public void TestMode(ExpansionMode mode) + { + AddStep("create mod display", () => + { + Child = new ModDisplay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + ExpansionMode = mode, + Current = + { + Value = new Mod[] + { + new OsuModHardRock(), + new OsuModDoubleTime(), + new OsuModDifficultyAdjust(), + new OsuModEasy(), + } + } + }; + }); + } + } +} diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs index 00edd4db99..336b03544f 100644 --- a/osu.Game/Screens/Play/HUD/ModDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Play.HUD public bool DisplayUnrankedText = true; - public bool AllowExpand = true; + public ExpansionMode ExpansionMode = ExpansionMode.ExpandOnHover; private readonly Bindable> current = new Bindable>(); @@ -110,11 +110,15 @@ namespace osu.Game.Screens.Play.HUD private void expand() { - if (AllowExpand) + if (ExpansionMode != ExpansionMode.AlwaysContracted) IconsContainer.TransformSpacingTo(new Vector2(5, 0), 500, Easing.OutQuint); } - private void contract() => IconsContainer.TransformSpacingTo(new Vector2(-25, 0), 500, Easing.OutQuint); + private void contract() + { + if (ExpansionMode != ExpansionMode.AlwaysExpanded) + IconsContainer.TransformSpacingTo(new Vector2(-25, 0), 500, Easing.OutQuint); + } protected override bool OnHover(HoverEvent e) { @@ -128,4 +132,22 @@ namespace osu.Game.Screens.Play.HUD base.OnHoverLost(e); } } + + public enum ExpansionMode + { + /// + /// The will expand only when hovered. + /// + ExpandOnHover, + + /// + /// The will always be expanded. + /// + AlwaysExpanded, + + /// + /// The will always be contracted. + /// + AlwaysContracted + } } diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 4f2369847f..2411cf26f9 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -91,7 +91,7 @@ namespace osu.Game.Screens.Select public FooterModDisplay() { - AllowExpand = false; + ExpansionMode = ExpansionMode.AlwaysContracted; IconsContainer.Margin = new MarginPadding(); } } From 91edadfe9d918f191baeb56c5ae7b555dada624a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Feb 2020 18:12:47 +0900 Subject: [PATCH 0425/1142] Make playlist beatmap and ruleset into bindables --- .../TestSceneLoungeRoomsContainer.cs | 9 +++-- .../Multiplayer/TestSceneMatchBeatmapPanel.cs | 10 ++--- .../Multiplayer/TestSceneMatchHeader.cs | 19 ++++++---- .../Visual/Multiplayer/TestSceneMatchInfo.cs | 38 +++++++++++-------- .../TestSceneMatchSettingsOverlay.cs | 2 +- osu.Game/Online/Multiplayer/PlaylistItem.cs | 30 +++++++-------- .../Screens/Multi/Components/BeatmapTitle.cs | 6 +-- .../Multi/Components/BeatmapTypeInfo.cs | 2 +- .../Screens/Multi/Components/ModeTypeInfo.cs | 2 +- .../Components/MultiplayerBackgroundSprite.cs | 2 +- .../Multi/Lounge/Components/RoomsContainer.cs | 2 +- .../Screens/Multi/Match/Components/Header.cs | 1 + .../Screens/Multi/Match/Components/Info.cs | 2 +- .../Match/Components/MatchBeatmapPanel.cs | 2 +- .../Screens/Multi/Match/MatchSubScreen.cs | 7 ++-- .../Screens/Multi/Play/TimeshiftPlayer.cs | 4 +- osu.Game/Screens/Select/MatchSongSelect.cs | 9 +++-- 17 files changed, 79 insertions(+), 68 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs index fe14a1ff0a..b5d946d049 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomsContainer.cs @@ -121,10 +121,13 @@ namespace osu.Game.Tests.Visual.Multiplayer { room.Playlist.Add(new PlaylistItem { - Ruleset = ruleset, - Beatmap = new BeatmapInfo + Ruleset = { Value = ruleset }, + Beatmap = { - Metadata = new BeatmapMetadata() + Value = new BeatmapInfo + { + Metadata = new BeatmapMetadata() + } } }); } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs index 1e3e06ce7a..84ab6f9ccc 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs @@ -32,11 +32,11 @@ namespace osu.Game.Tests.Visual.Multiplayer Origin = Anchor.Centre, }); - Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1763072 } }); - Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 2101557 } }); - Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1973466 } }); - Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 2109801 } }); - Room.Playlist.Add(new PlaylistItem { Beatmap = new BeatmapInfo { OnlineBeatmapID = 1922035 } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 1763072 } } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 2101557 } } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 1973466 } } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 2109801 } } }); + Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 1922035 } } }); } protected override void LoadComplete() diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs index e42042f2ea..7d7e7f85db 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs @@ -23,16 +23,19 @@ namespace osu.Game.Tests.Visual.Multiplayer { Room.Playlist.Add(new PlaylistItem { - Beatmap = new BeatmapInfo + Beatmap = { - Metadata = new BeatmapMetadata + Value = new BeatmapInfo { - Title = "Title", - Artist = "Artist", - AuthorString = "Author", - }, - Version = "Version", - Ruleset = new OsuRuleset().RulesetInfo + Metadata = new BeatmapMetadata + { + Title = "Title", + Artist = "Artist", + AuthorString = "Author", + }, + Version = "Version", + Ruleset = new OsuRuleset().RulesetInfo + } }, RequiredMods = { diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs index a6c036a876..6ee9ceb2dd 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs @@ -37,16 +37,19 @@ namespace osu.Game.Tests.Visual.Multiplayer Room.Playlist.Clear(); Room.Playlist.Add(new PlaylistItem { - Beatmap = new BeatmapInfo + Beatmap = { - StarDifficulty = 2.4, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata + Value = new BeatmapInfo { - Title = @"My Song", - Artist = @"VisualTests", - AuthorString = @"osu!lazer", - }, + StarDifficulty = 2.4, + Ruleset = rulesets.GetRuleset(0), + Metadata = new BeatmapMetadata + { + Title = @"My Song", + Artist = @"VisualTests", + AuthorString = @"osu!lazer", + }, + } } }); }); @@ -60,16 +63,19 @@ namespace osu.Game.Tests.Visual.Multiplayer Room.Playlist.Clear(); Room.Playlist.Add(new PlaylistItem { - Beatmap = new BeatmapInfo + Beatmap = { - StarDifficulty = 4.2, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata + Value = new BeatmapInfo { - Title = @"Your Song", - Artist = @"Tester", - AuthorString = @"Someone", - }, + StarDifficulty = 4.2, + Ruleset = rulesets.GetRuleset(3), + Metadata = new BeatmapMetadata + { + Title = @"Your Song", + Artist = @"Tester", + AuthorString = @"Someone", + }, + } } }); }); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSettingsOverlay.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSettingsOverlay.cs index 8d842fc865..047e9d860d 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSettingsOverlay.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSettingsOverlay.cs @@ -56,7 +56,7 @@ namespace osu.Game.Tests.Visual.Multiplayer AddStep("set name", () => Room.Name.Value = "Room name"); AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value); - AddStep("set beatmap", () => Room.Playlist.Add(new PlaylistItem { Beatmap = CreateBeatmap(Ruleset.Value).BeatmapInfo })); + AddStep("set beatmap", () => Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = CreateBeatmap(Ruleset.Value).BeatmapInfo } })); AddAssert("button enabled", () => settings.ApplyButton.Enabled.Value); AddStep("clear name", () => Room.Name.Value = ""); diff --git a/osu.Game/Online/Multiplayer/PlaylistItem.cs b/osu.Game/Online/Multiplayer/PlaylistItem.cs index 5f8edc607b..e243cfca08 100644 --- a/osu.Game/Online/Multiplayer/PlaylistItem.cs +++ b/osu.Game/Online/Multiplayer/PlaylistItem.cs @@ -1,9 +1,9 @@ // 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.Generic; using System.Linq; using Newtonsoft.Json; +using osu.Framework.Bindables; using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; @@ -24,24 +24,16 @@ namespace osu.Game.Online.Multiplayer public int RulesetID { get; set; } [JsonIgnore] - public BeatmapInfo Beatmap - { - get => beatmap; - set - { - beatmap = value; - BeatmapID = value?.OnlineBeatmapID ?? 0; - } - } + public readonly Bindable Beatmap = new Bindable(); [JsonIgnore] - public RulesetInfo Ruleset { get; set; } + public readonly Bindable Ruleset = new Bindable(); [JsonIgnore] - public readonly List AllowedMods = new List(); + public readonly BindableList AllowedMods = new BindableList(); [JsonIgnore] - public readonly List RequiredMods = new List(); + public readonly BindableList RequiredMods = new BindableList(); [JsonProperty("beatmap")] private APIBeatmap apiBeatmap { get; set; } @@ -64,16 +56,20 @@ namespace osu.Game.Online.Multiplayer set => requiredModsBacking = value; } - private BeatmapInfo beatmap; + public PlaylistItem() + { + Beatmap.BindValueChanged(beatmap => BeatmapID = beatmap.NewValue?.OnlineBeatmapID ?? 0); + Ruleset.BindValueChanged(ruleset => RulesetID = ruleset.NewValue?.ID ?? 0); + } public void MapObjects(BeatmapManager beatmaps, RulesetStore rulesets) { // If we don't have an api beatmap, the request occurred as a result of room creation, so we can query the local beatmap instead // Todo: Is this a bug? Room creation only returns the beatmap ID - Beatmap = apiBeatmap == null ? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == BeatmapID) : apiBeatmap.ToBeatmap(rulesets); - Ruleset = rulesets.GetRuleset(RulesetID); + Beatmap.Value = apiBeatmap == null ? beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == BeatmapID) : apiBeatmap.ToBeatmap(rulesets); + Ruleset.Value = rulesets.GetRuleset(RulesetID); - Ruleset rulesetInstance = Ruleset.CreateInstance(); + Ruleset rulesetInstance = Ruleset.Value.CreateInstance(); if (allowedModsBacking != null) { diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index b41b2d073e..b991a3d68d 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs @@ -70,7 +70,7 @@ namespace osu.Game.Screens.Multi.Components { new OsuSpriteText { - Text = new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)), + Text = new LocalisedString((beatmap.Value.Metadata.ArtistUnicode, beatmap.Value.Metadata.Artist)), Font = OsuFont.GetFont(size: TextSize), }, new OsuSpriteText @@ -80,10 +80,10 @@ namespace osu.Game.Screens.Multi.Components }, new OsuSpriteText { - Text = new LocalisedString((beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title)), + Text = new LocalisedString((beatmap.Value.Metadata.TitleUnicode, beatmap.Value.Metadata.Title)), Font = OsuFont.GetFont(size: TextSize), } - }, LinkAction.OpenBeatmap, beatmap.OnlineBeatmapID.ToString(), "Open beatmap"); + }, LinkAction.OpenBeatmap, beatmap.Value.OnlineBeatmapID.ToString(), "Open beatmap"); } } } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index d63f2fecd2..21b228bb5c 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs @@ -59,7 +59,7 @@ namespace osu.Game.Screens.Multi.Components if (beatmap != null) { beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f)); - beatmapAuthor.AddUserLink(beatmap.Metadata.Author); + beatmapAuthor.AddUserLink(beatmap.Value.Metadata.Author); } }, true); } diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 6080458aec..5465463888 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Multi.Components if (item?.Beatmap != null) { drawableRuleset.FadeIn(transition_duration); - drawableRuleset.Child = new DifficultyIcon(item.Beatmap, item.Ruleset) { Size = new Vector2(height) }; + drawableRuleset.Child = new DifficultyIcon(item.Beatmap.Value, item.Ruleset.Value) { Size = new Vector2(height) }; } else drawableRuleset.FadeOut(transition_duration); diff --git a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs index 968fa6e72e..9a1a482699 100644 --- a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs +++ b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs @@ -23,7 +23,7 @@ namespace osu.Game.Screens.Multi.Components InternalChild = sprite = CreateBackgroundSprite(); - CurrentItem.BindValueChanged(item => sprite.Beatmap.Value = item.NewValue?.Beatmap, true); + CurrentItem.BindValueChanged(item => sprite.Beatmap.Value = item.NewValue?.Beatmap.Value, true); } protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(beatmapSetCoverType) { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs index 063957d816..64618a1d85 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomsContainer.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components { bool matchingFilter = true; - matchingFilter &= r.Room.Playlist.Count == 0 || r.Room.Playlist.Any(i => i.Ruleset.Equals(criteria.Ruleset)); + matchingFilter &= r.Room.Playlist.Count == 0 || r.Room.Playlist.Any(i => i.Ruleset.Value.Equals(criteria.Ruleset)); if (!string.IsNullOrEmpty(criteria.SearchString)) matchingFilter &= r.FilterTerms.Any(term => term.IndexOf(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase) >= 0); diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index a52d43acf4..991060cac0 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index 74f000c21f..f0b54baa4c 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -89,7 +89,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - CurrentItem.BindValueChanged(item => readyButton.Beatmap.Value = item.NewValue?.Beatmap, true); + CurrentItem.BindValueChanged(item => readyButton.Beatmap.Value = item.NewValue?.Beatmap.Value, true); hostInfo.Host.BindTo(Host); } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs index 7c1fe91393..f67f6d9f43 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - CurrentItem.BindValueChanged(item => loadNewPanel(item.NewValue?.Beatmap), true); + CurrentItem.BindValueChanged(item => loadNewPanel(item.NewValue?.Beatmap.Value), true); } private void loadNewPanel(BeatmapInfo beatmap) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index c2bb7da6b5..9165ef6d0f 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -183,13 +184,13 @@ namespace osu.Game.Screens.Multi.Match private void currentItemChanged(ValueChangedEvent e) { // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info - var localBeatmap = e.NewValue?.Beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == e.NewValue.Beatmap.OnlineBeatmapID); + var localBeatmap = e.NewValue?.Beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == e.NewValue.Beatmap.Value.OnlineBeatmapID); Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); Mods.Value = e.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(); if (e.NewValue?.Ruleset != null) - Ruleset.Value = e.NewValue.Ruleset; + Ruleset.Value = e.NewValue.Ruleset.Value; previewTrackManager.StopAnyPlaying(this); } @@ -206,7 +207,7 @@ namespace osu.Game.Screens.Multi.Match return; // Try to retrieve the corresponding local beatmap - var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == CurrentItem.Value.Beatmap.OnlineBeatmapID); + var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == CurrentItem.Value.Beatmap.Value.OnlineBeatmapID); if (localBeatmap != null) Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); diff --git a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs index 88c6fc5e2e..3afacf2f31 100644 --- a/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs +++ b/osu.Game/Screens/Multi/Play/TimeshiftPlayer.cs @@ -50,10 +50,10 @@ namespace osu.Game.Screens.Multi.Play bool failed = false; // Sanity checks to ensure that TimeshiftPlayer matches the settings for the current PlaylistItem - if (Beatmap.Value.BeatmapInfo.OnlineBeatmapID != playlistItem.Beatmap.OnlineBeatmapID) + if (Beatmap.Value.BeatmapInfo.OnlineBeatmapID != playlistItem.Beatmap.Value.OnlineBeatmapID) throw new InvalidOperationException("Current Beatmap does not match PlaylistItem's Beatmap"); - if (ruleset.Value.ID != playlistItem.Ruleset.ID) + if (ruleset.Value.ID != playlistItem.Ruleset.Value.ID) throw new InvalidOperationException("Current Ruleset does not match PlaylistItem's Ruleset"); if (!playlistItem.RequiredMods.All(m => Mods.Value.Any(m.Equals))) diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 6ba4157797..ff0544d227 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -38,8 +39,8 @@ namespace osu.Game.Screens.Select { var item = new PlaylistItem { - Beatmap = Beatmap.Value.BeatmapInfo, - Ruleset = Ruleset.Value, + Beatmap = { Value = Beatmap.Value.BeatmapInfo }, + Ruleset = { Value = Ruleset.Value }, RulesetID = Ruleset.Value.ID ?? 0 }; @@ -60,8 +61,8 @@ namespace osu.Game.Screens.Select if (CurrentItem.Value != null) { - Ruleset.Value = CurrentItem.Value.Ruleset; - Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value.Beatmap); + Ruleset.Value = CurrentItem.Value.Ruleset.Value; + Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value.Beatmap.Value); Mods.Value = CurrentItem.Value.RequiredMods?.ToArray() ?? Array.Empty(); } From be2d1c6b4305897f12a1b25802bf1e0cfdc71fbe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 18:35:31 +0900 Subject: [PATCH 0426/1142] 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 25bde037db..494842f38f 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 389fbe8210..50d8c25b11 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 3ed25360c5..e56fc41b07 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -74,7 +74,7 @@ - + @@ -82,7 +82,7 @@ - + From 75bef15583aecec6bb2f4d0d223a7e0b64a5fd5e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Feb 2020 18:48:28 +0900 Subject: [PATCH 0427/1142] Remove "current" multiplayer room item --- .../Multiplayer/TestSceneMatchBeatmapPanel.cs | 12 ------- osu.Game/Online/Multiplayer/PlaylistItem.cs | 12 ++++++- osu.Game/Online/Multiplayer/Room.cs | 24 ++------------ .../Screens/Multi/Components/BeatmapTitle.cs | 8 +++-- .../Multi/Components/BeatmapTypeInfo.cs | 32 ++++++++++-------- .../Screens/Multi/Components/ModeTypeInfo.cs | 13 +++++--- .../Components/MultiplayerBackgroundSprite.cs | 14 ++++++-- .../Screens/Multi/Match/Components/Header.cs | 16 +++++++-- .../Screens/Multi/Match/Components/Info.cs | 16 +++++++-- .../Match/Components/MatchBeatmapPanel.cs | 11 +++++-- .../Screens/Multi/Match/MatchSubScreen.cs | 33 ++++++++++++------- .../Screens/Multi/MultiplayerComposite.cs | 3 -- osu.Game/Screens/Select/MatchSongSelect.cs | 16 +++++---- 13 files changed, 123 insertions(+), 87 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs index 84ab6f9ccc..f014b08325 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs @@ -7,7 +7,6 @@ using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Match.Components; using osu.Framework.Graphics; -using osu.Framework.Utils; using osu.Game.Audio; using osu.Framework.Allocation; @@ -38,16 +37,5 @@ namespace osu.Game.Tests.Visual.Multiplayer Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 2109801 } } }); Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 1922035 } } }); } - - protected override void LoadComplete() - { - base.LoadComplete(); - - AddStep("Select random beatmap", () => - { - Room.CurrentItem.Value = Room.Playlist[RNG.Next(Room.Playlist.Count)]; - previewTrackManager.StopAnyPlaying(this); - }); - } } } diff --git a/osu.Game/Online/Multiplayer/PlaylistItem.cs b/osu.Game/Online/Multiplayer/PlaylistItem.cs index e243cfca08..69e1f0db13 100644 --- a/osu.Game/Online/Multiplayer/PlaylistItem.cs +++ b/osu.Game/Online/Multiplayer/PlaylistItem.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Linq; using Newtonsoft.Json; using osu.Framework.Bindables; @@ -12,7 +13,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Online.Multiplayer { - public class PlaylistItem + public class PlaylistItem : IEquatable { [JsonProperty("id")] public int ID { get; set; } @@ -90,5 +91,14 @@ namespace osu.Game.Online.Multiplayer public bool ShouldSerializeID() => false; public bool ShouldSerializeapiBeatmap() => false; + + public bool Equals(PlaylistItem other) => ID == other?.ID && BeatmapID == other.BeatmapID && RulesetID == other.RulesetID; + + public override int GetHashCode() + { + // ReSharper disable NonReadonlyMemberInGetHashCode + return HashCode.Combine(ID, BeatmapID, RulesetID); + // ReSharper restore NonReadonlyMemberInGetHashCode + } } } diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 53089897f7..1f123de1a3 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -31,10 +31,6 @@ namespace osu.Game.Online.Multiplayer [JsonProperty("playlist")] public BindableList Playlist { get; private set; } = new BindableList(); - [Cached] - [JsonIgnore] - public Bindable CurrentItem { get; private set; } = new Bindable(); - [Cached] [JsonProperty("channel_id")] public Bindable ChannelId { get; private set; } = new Bindable(); @@ -70,18 +66,6 @@ namespace osu.Game.Online.Multiplayer [Cached] public Bindable ParticipantCount { get; private set; } = new Bindable(); - public Room() - { - Playlist.ItemsAdded += updateCurrent; - Playlist.ItemsRemoved += updateCurrent; - updateCurrent(Playlist); - } - - private void updateCurrent(IEnumerable playlist) - { - CurrentItem.Value = playlist.FirstOrDefault(); - } - // todo: TEMPORARY [JsonProperty("participant_count")] private int? participantCount @@ -136,11 +120,9 @@ namespace osu.Game.Online.Multiplayer if (DateTimeOffset.Now >= EndDate.Value) Status.Value = new RoomStatusEnded(); - // Todo: Temporary, should only remove/add new items (requires framework changes) - if (Playlist.Count == 0) - Playlist.AddRange(other.Playlist); - else if (other.Playlist.Count > 0) - Playlist.First().ID = other.Playlist.First().ID; + foreach (var removedItem in Playlist.Except(other.Playlist).ToArray()) + Playlist.Remove(removedItem); + Playlist.AddRange(other.Playlist.Except(Playlist).ToArray()); Position = other.Position; } diff --git a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs b/osu.Game/Screens/Multi/Components/BeatmapTitle.cs index b991a3d68d..baf11dfe0d 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTitle.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTitle.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.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Localisation; @@ -25,7 +26,10 @@ namespace osu.Game.Screens.Multi.Components [BackgroundDependencyLoader] private void load() { - CurrentItem.BindValueChanged(_ => updateText(), true); + Playlist.ItemsAdded += _ => updateText(); + Playlist.ItemsRemoved += _ => updateText(); + + updateText(); } private float textSize = OsuFont.DEFAULT_FONT_SIZE; @@ -54,7 +58,7 @@ namespace osu.Game.Screens.Multi.Components textFlow.Clear(); - var beatmap = CurrentItem.Value?.Beatmap; + var beatmap = Playlist.FirstOrDefault()?.Beatmap; if (beatmap == null) { diff --git a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs index 21b228bb5c..a1334101b8 100644 --- a/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/BeatmapTypeInfo.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.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,6 +13,8 @@ namespace osu.Game.Screens.Multi.Components { public class BeatmapTypeInfo : MultiplayerComposite { + private LinkFlowContainer beatmapAuthor; + public BeatmapTypeInfo() { AutoSizeAxes = Axes.Both; @@ -20,8 +23,6 @@ namespace osu.Game.Screens.Multi.Components [BackgroundDependencyLoader] private void load() { - LinkFlowContainer beatmapAuthor; - InternalChild = new FillFlowContainer { AutoSizeAxes = Axes.Both, @@ -50,18 +51,23 @@ namespace osu.Game.Screens.Multi.Components } }; - CurrentItem.BindValueChanged(item => + Playlist.ItemsAdded += _ => updateInfo(); + Playlist.ItemsRemoved += _ => updateInfo(); + + updateInfo(); + } + + private void updateInfo() + { + beatmapAuthor.Clear(); + + var beatmap = Playlist.FirstOrDefault()?.Beatmap; + + if (beatmap != null) { - beatmapAuthor.Clear(); - - var beatmap = item.NewValue?.Beatmap; - - if (beatmap != null) - { - beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f)); - beatmapAuthor.AddUserLink(beatmap.Value.Metadata.Author); - } - }, true); + beatmapAuthor.AddText("mapped by ", s => s.Colour = OsuColour.Gray(0.8f)); + beatmapAuthor.AddUserLink(beatmap.Value.Metadata.Author); + } } } } diff --git a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs index 5465463888..258541bbd6 100644 --- a/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs +++ b/osu.Game/Screens/Multi/Components/ModeTypeInfo.cs @@ -1,11 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps.Drawables; -using osu.Game.Online.Multiplayer; using osuTK; namespace osu.Game.Screens.Multi.Components @@ -46,13 +46,18 @@ namespace osu.Game.Screens.Multi.Components }, }; - CurrentItem.BindValueChanged(item => updateBeatmap(item.NewValue), true); - Type.BindValueChanged(type => gameTypeContainer.Child = new DrawableGameType(type.NewValue) { Size = new Vector2(height) }, true); + + Playlist.ItemsAdded += _ => updateBeatmap(); + Playlist.ItemsRemoved += _ => updateBeatmap(); + + updateBeatmap(); } - private void updateBeatmap(PlaylistItem item) + private void updateBeatmap() { + var item = Playlist.FirstOrDefault(); + if (item?.Beatmap != null) { drawableRuleset.FadeIn(transition_duration); diff --git a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs index 9a1a482699..5e2f2e530a 100644 --- a/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.cs +++ b/osu.Game/Screens/Multi/Components/MultiplayerBackgroundSprite.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.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps.Drawables; @@ -10,6 +11,7 @@ namespace osu.Game.Screens.Multi.Components public class MultiplayerBackgroundSprite : MultiplayerComposite { private readonly BeatmapSetCoverType beatmapSetCoverType; + private UpdateableBeatmapBackgroundSprite sprite; public MultiplayerBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover) { @@ -19,11 +21,17 @@ namespace osu.Game.Screens.Multi.Components [BackgroundDependencyLoader] private void load() { - UpdateableBeatmapBackgroundSprite sprite; - InternalChild = sprite = CreateBackgroundSprite(); - CurrentItem.BindValueChanged(item => sprite.Beatmap.Value = item.NewValue?.Beatmap.Value, true); + Playlist.ItemsAdded += _ => updateBeatmap(); + Playlist.ItemsRemoved += _ => updateBeatmap(); + + updateBeatmap(); + } + + private void updateBeatmap() + { + sprite.Beatmap.Value = Playlist.FirstOrDefault()?.Beatmap.Value; } protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(beatmapSetCoverType) { RelativeSizeAxes = Axes.Both }; diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index 991060cac0..cf1eb6b6ed 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -33,6 +33,7 @@ namespace osu.Game.Screens.Multi.Match.Components public Action RequestBeatmapSelection; private MatchBeatmapPanel beatmapPanel; + private ModDisplay modDisplay; public Header() { @@ -44,7 +45,6 @@ namespace osu.Game.Screens.Multi.Match.Components private void load(OsuColour colours) { BeatmapSelectButton beatmapButton; - ModDisplay modDisplay; InternalChildren = new Drawable[] { @@ -120,9 +120,12 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - CurrentItem.BindValueChanged(item => modDisplay.Current.Value = item.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(), true); - beatmapButton.Action = () => RequestBeatmapSelection?.Invoke(); + + Playlist.ItemsAdded += _ => updateMods(); + Playlist.ItemsRemoved += _ => updateMods(); + + updateMods(); } protected override void LoadComplete() @@ -131,6 +134,13 @@ namespace osu.Game.Screens.Multi.Match.Components ShowBeatmapPanel.BindValueChanged(value => beatmapPanel.FadeTo(value.NewValue ? 1 : 0, 200, Easing.OutQuint), true); } + private void updateMods() + { + var item = Playlist.FirstOrDefault(); + + modDisplay.Current.Value = item?.RequiredMods?.ToArray() ?? Array.Empty(); + } + private class BeatmapSelectButton : HeaderButton { [Resolved(typeof(Room), nameof(Room.RoomID))] diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs index f0b54baa4c..a320b08cc4 100644 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ b/osu.Game/Screens/Multi/Match/Components/Info.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -18,6 +19,8 @@ namespace osu.Game.Screens.Multi.Match.Components { public Action OnStart; + private ReadyButton readyButton; + public Info() { RelativeSizeAxes = Axes.X; @@ -27,7 +30,6 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - ReadyButton readyButton; HostInfo hostInfo; InternalChildren = new Drawable[] @@ -89,9 +91,17 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - CurrentItem.BindValueChanged(item => readyButton.Beatmap.Value = item.NewValue?.Beatmap.Value, true); - hostInfo.Host.BindTo(Host); + + Playlist.ItemsAdded += _ => updateBeatmap(); + Playlist.ItemsRemoved += _ => updateBeatmap(); + + updateBeatmap(); + } + + private void updateBeatmap() + { + readyButton.Beatmap.Value = Playlist.FirstOrDefault()?.Beatmap.Value; } } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs index f67f6d9f43..c8de066caa 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs @@ -1,10 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Linq; using System.Threading; using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Game.Beatmaps; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.Direct; @@ -32,10 +32,13 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load() { - CurrentItem.BindValueChanged(item => loadNewPanel(item.NewValue?.Beatmap.Value), true); + Playlist.ItemsAdded += _ => loadNewPanel(); + Playlist.ItemsRemoved += _ => loadNewPanel(); + + loadNewPanel(); } - private void loadNewPanel(BeatmapInfo beatmap) + private void loadNewPanel() { loadCancellation?.Cancel(); request?.Cancel(); @@ -44,6 +47,8 @@ namespace osu.Game.Screens.Multi.Match.Components panel?.Expire(); panel = null; + var beatmap = Playlist.FirstOrDefault()?.Beatmap.Value; + if (beatmap?.OnlineBeatmapID == null) return; diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 9165ef6d0f..890664e99b 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -41,9 +41,6 @@ namespace osu.Game.Screens.Multi.Match [Resolved(typeof(Room))] protected BindableList Playlist { get; private set; } - [Resolved(typeof(Room))] - protected Bindable CurrentItem { get; private set; } - [Resolved] private BeatmapManager beatmapManager { get; set; } @@ -53,6 +50,7 @@ namespace osu.Game.Screens.Multi.Match [Resolved(CanBeNull = true)] private OsuGame game { get; set; } + private readonly Bindable selectedItem = new Bindable(); private MatchLeaderboard leaderboard; public MatchSubScreen(Room room) @@ -166,7 +164,16 @@ namespace osu.Game.Screens.Multi.Match { base.LoadComplete(); - CurrentItem.BindValueChanged(currentItemChanged, true); + Playlist.ItemsAdded += _ => updateSelectedItem(); + Playlist.ItemsRemoved += _ => updateSelectedItem(); + + updateSelectedItem(); + } + + private void updateSelectedItem() + { + selectedItem.Value = Playlist.FirstOrDefault(); + currentItemChanged(); } public override bool OnExiting(IScreen next) @@ -181,16 +188,18 @@ namespace osu.Game.Screens.Multi.Match /// /// Handles propagation of the current playlist item's content to game-wide mechanisms. /// - private void currentItemChanged(ValueChangedEvent e) + private void currentItemChanged() { + var item = selectedItem.Value; + // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info - var localBeatmap = e.NewValue?.Beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == e.NewValue.Beatmap.Value.OnlineBeatmapID); + var localBeatmap = item?.Beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.Beatmap.Value.OnlineBeatmapID); Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); - Mods.Value = e.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(); + Mods.Value = item?.RequiredMods?.ToArray() ?? Array.Empty(); - if (e.NewValue?.Ruleset != null) - Ruleset.Value = e.NewValue.Ruleset.Value; + if (item?.Ruleset != null) + Ruleset.Value = item.Ruleset.Value; previewTrackManager.StopAnyPlaying(this); } @@ -203,11 +212,11 @@ namespace osu.Game.Screens.Multi.Match if (Beatmap.Value != beatmapManager.DefaultBeatmap) return; - if (CurrentItem.Value == null) + if (selectedItem.Value == null) return; // Try to retrieve the corresponding local beatmap - var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == CurrentItem.Value.Beatmap.Value.OnlineBeatmapID); + var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == selectedItem.Value.Beatmap.Value.OnlineBeatmapID); if (localBeatmap != null) Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); @@ -224,7 +233,7 @@ namespace osu.Game.Screens.Multi.Match { default: case GameTypeTimeshift _: - multiplayer?.Start(() => new TimeshiftPlayer(CurrentItem.Value) + multiplayer?.Start(() => new TimeshiftPlayer(selectedItem.Value) { Exited = () => leaderboard.RefreshScores() }); diff --git a/osu.Game/Screens/Multi/MultiplayerComposite.cs b/osu.Game/Screens/Multi/MultiplayerComposite.cs index 8c09d576ff..cf4a189951 100644 --- a/osu.Game/Screens/Multi/MultiplayerComposite.cs +++ b/osu.Game/Screens/Multi/MultiplayerComposite.cs @@ -31,9 +31,6 @@ namespace osu.Game.Screens.Multi [Resolved(typeof(Room))] protected BindableList Playlist { get; private set; } - [Resolved(typeof(Room))] - protected Bindable CurrentItem { get; private set; } - [Resolved(typeof(Room))] protected Bindable> Participants { get; private set; } diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index ff0544d227..251456bf0d 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -22,11 +22,11 @@ namespace osu.Game.Screens.Select public string ShortTitle => "song selection"; public override string Title => ShortTitle.Humanize(); - [Resolved(typeof(Room))] - protected Bindable CurrentItem { get; private set; } - public override bool AllowEditing => false; + [Resolved(typeof(Room), nameof(Room.Playlist))] + protected BindableList Playlist { get; private set; } + [Resolved] private BeatmapManager beatmaps { get; set; } @@ -59,11 +59,13 @@ namespace osu.Game.Screens.Select if (base.OnExiting(next)) return true; - if (CurrentItem.Value != null) + var firstItem = Playlist.FirstOrDefault(); + + if (firstItem != null) { - Ruleset.Value = CurrentItem.Value.Ruleset.Value; - Beatmap.Value = beatmaps.GetWorkingBeatmap(CurrentItem.Value.Beatmap.Value); - Mods.Value = CurrentItem.Value.RequiredMods?.ToArray() ?? Array.Empty(); + Ruleset.Value = firstItem.Ruleset.Value; + Beatmap.Value = beatmaps.GetWorkingBeatmap(firstItem.Beatmap.Value); + Mods.Value = firstItem.RequiredMods?.ToArray() ?? Array.Empty(); } return false; From bce9c8f3f30352ffa9b29d705fd72557d98b55f9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Feb 2020 18:59:15 +0900 Subject: [PATCH 0428/1142] Make room participants into a bindable list --- .../Multiplayer/TestSceneMatchParticipants.cs | 6 +++--- osu.Game/Online/Multiplayer/Room.cs | 7 +++++-- .../Multi/Match/Components/Participants.cs | 13 +++++++++---- .../Screens/Multi/MultiplayerComposite.cs | 3 +-- osu.Game/Users/UserPanel.cs | 19 ++++++++++--------- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchParticipants.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchParticipants.cs index 1ac914e27d..a6f47961e9 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchParticipants.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchParticipants.cs @@ -16,7 +16,7 @@ namespace osu.Game.Tests.Visual.Multiplayer Add(new Participants { RelativeSizeAxes = Axes.Both }); AddStep(@"set max to null", () => Room.MaxParticipants.Value = null); - AddStep(@"set users", () => Room.Participants.Value = new[] + AddStep(@"set users", () => Room.Participants.AddRange(new[] { new User { @@ -42,10 +42,10 @@ namespace osu.Game.Tests.Visual.Multiplayer CoverUrl = @"https://assets.ppy.sh/user-profile-covers/5287410/5cfeaa9dd41cbce038ecdc9d781396ed4b0108089170bf7f50492ef8eadeb368.jpeg", IsSupporter = true, }, - }); + })); AddStep(@"set max", () => Room.MaxParticipants.Value = 10); - AddStep(@"clear users", () => Room.Participants.Value = System.Array.Empty()); + AddStep(@"clear users", () => Room.Participants.Clear()); AddStep(@"set max to null", () => Room.MaxParticipants.Value = null); } } diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index 53089897f7..0f4abeafd4 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -65,7 +65,7 @@ namespace osu.Game.Online.Multiplayer [Cached] [JsonIgnore] - public Bindable> Participants { get; private set; } = new Bindable>(Enumerable.Empty()); + public BindableList Participants { get; private set; } = new BindableList(); [Cached] public Bindable ParticipantCount { get; private set; } = new Bindable(); @@ -130,7 +130,6 @@ namespace osu.Game.Online.Multiplayer Type.Value = other.Type.Value; MaxParticipants.Value = other.MaxParticipants.Value; ParticipantCount.Value = other.ParticipantCount.Value; - Participants.Value = other.Participants.Value.ToArray(); EndDate.Value = other.EndDate.Value; if (DateTimeOffset.Now >= EndDate.Value) @@ -142,6 +141,10 @@ namespace osu.Game.Online.Multiplayer else if (other.Playlist.Count > 0) Playlist.First().ID = other.Playlist.First().ID; + foreach (var removedItem in Participants.Except(other.Participants).ToArray()) + Participants.Remove(removedItem); + Participants.AddRange(other.Participants.Except(Participants).ToArray()); + Position = other.Position; } diff --git a/osu.Game/Screens/Multi/Match/Components/Participants.cs b/osu.Game/Screens/Multi/Match/Components/Participants.cs index ad38ec6a99..00d2f3e150 100644 --- a/osu.Game/Screens/Multi/Match/Components/Participants.cs +++ b/osu.Game/Screens/Multi/Match/Components/Participants.cs @@ -51,9 +51,9 @@ namespace osu.Game.Screens.Multi.Match.Components }, }; - Participants.BindValueChanged(participants => + Participants.ItemsAdded += users => { - usersFlow.Children = participants.NewValue.Select(u => + usersFlow.AddRange(users.Select(u => { var panel = new UserPanel(u) { @@ -65,8 +65,13 @@ namespace osu.Game.Screens.Multi.Match.Components panel.OnLoadComplete += d => d.FadeInFromZero(60); return panel; - }).ToList(); - }, true); + }).ToList()); + }; + + Participants.ItemsRemoved += users => + { + usersFlow.RemoveAll(p => users.Contains(p.User)); + }; } } } diff --git a/osu.Game/Screens/Multi/MultiplayerComposite.cs b/osu.Game/Screens/Multi/MultiplayerComposite.cs index 8c09d576ff..346f78f2c6 100644 --- a/osu.Game/Screens/Multi/MultiplayerComposite.cs +++ b/osu.Game/Screens/Multi/MultiplayerComposite.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics.Containers; @@ -35,7 +34,7 @@ namespace osu.Game.Screens.Multi protected Bindable CurrentItem { get; private set; } [Resolved(typeof(Room))] - protected Bindable> Participants { get; private set; } + protected BindableList Participants { get; private set; } [Resolved(typeof(Room))] protected Bindable ParticipantCount { get; private set; } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 6ddbc13a06..6f34466e94 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -26,11 +26,12 @@ namespace osu.Game.Users { public class UserPanel : OsuClickableContainer, IHasContextMenu { - private readonly User user; private const float height = 100; private const float content_padding = 10; private const float status_height = 30; + public readonly User User; + [Resolved(canBeNull: true)] private OsuColour colours { get; set; } @@ -54,7 +55,7 @@ namespace osu.Game.Users if (user == null) throw new ArgumentNullException(nameof(user)); - this.user = user; + User = user; Height = height - status_height; } @@ -86,7 +87,7 @@ namespace osu.Game.Users RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - User = user, + User = User, }, 300, 5000) { RelativeSizeAxes = Axes.Both, @@ -106,7 +107,7 @@ namespace osu.Game.Users new UpdateableAvatar { Size = new Vector2(height - status_height - content_padding * 2), - User = user, + User = User, Masking = true, CornerRadius = 5, OpenOnClick = { Value = false }, @@ -125,7 +126,7 @@ namespace osu.Game.Users { new OsuSpriteText { - Text = user.Username, + Text = User.Username, Font = OsuFont.GetFont(weight: FontWeight.SemiBold, size: 18, italics: true), }, infoContainer = new FillFlowContainer @@ -138,7 +139,7 @@ namespace osu.Game.Users Spacing = new Vector2(5f, 0f), Children = new Drawable[] { - new UpdateableFlag(user.Country) + new UpdateableFlag(User.Country) { Width = 30f, RelativeSizeAxes = Axes.Y, @@ -191,12 +192,12 @@ namespace osu.Game.Users } }); - if (user.IsSupporter) + if (User.IsSupporter) { infoContainer.Add(new SupporterIcon { Height = 20f, - SupportLevel = user.SupportLevel + SupportLevel = User.SupportLevel }); } @@ -206,7 +207,7 @@ namespace osu.Game.Users base.Action = ViewProfile = () => { Action?.Invoke(); - profile?.ShowUser(user); + profile?.ShowUser(User); }; } From bc1c4f6b583eae9b2b6020f0f896cba6c21e1907 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 13 Feb 2020 19:04:23 +0900 Subject: [PATCH 0429/1142] Add missing null-allowance --- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index c9131883bb..1f52a4481b 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -55,7 +55,7 @@ namespace osu.Game.Online.Leaderboards private List statisticsLabels; - [Resolved] + [Resolved(CanBeNull = true)] private DialogOverlay dialogOverlay { get; set; } public LeaderboardScore(ScoreInfo score, int rank, bool allowHighlight = true) From a677aa6cfc5212223175d40f34279cb3573c78ae Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 13:39:33 +0300 Subject: [PATCH 0430/1142] Add rankings overlay to the game --- osu.Game/OsuGame.cs | 5 ++++- osu.Game/Overlays/Toolbar/Toolbar.cs | 1 + .../Overlays/Toolbar/ToolbarRankingsButton.cs | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e7fffd49b4..e034fcc3ac 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -65,6 +65,8 @@ namespace osu.Game private DirectOverlay direct; + private RankingsOverlay rankings; + private SocialOverlay social; private UserProfileOverlay userProfile; @@ -600,6 +602,7 @@ namespace osu.Game //overlay elements loadComponentSingleFile(direct = new DirectOverlay(), overlayContent.Add, true); loadComponentSingleFile(social = new SocialOverlay(), overlayContent.Add, true); + loadComponentSingleFile(rankings = new RankingsOverlay(), overlayContent.Add, true); loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); loadComponentSingleFile(Settings = new SettingsOverlay { GetToolbarHeight = () => ToolbarOffset }, leftFloatingOverlayContent.Add, true); @@ -643,7 +646,7 @@ namespace osu.Game } // eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time. - var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile }; + var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile, rankings }; foreach (var overlay in informationalOverlays) { diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index b044bc4de0..897587d198 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -70,6 +70,7 @@ namespace osu.Game.Overlays.Toolbar Children = new Drawable[] { new ToolbarChangelogButton(), + new ToolbarRankingsButton(), new ToolbarDirectButton(), new ToolbarChatButton(), new ToolbarSocialButton(), diff --git a/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.cs new file mode 100644 index 0000000000..cbd097696d --- /dev/null +++ b/osu.Game/Overlays/Toolbar/ToolbarRankingsButton.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.Allocation; +using osu.Framework.Graphics.Sprites; + +namespace osu.Game.Overlays.Toolbar +{ + public class ToolbarRankingsButton : ToolbarOverlayToggleButton + { + public ToolbarRankingsButton() + { + SetIcon(FontAwesome.Regular.ChartBar); + } + + [BackgroundDependencyLoader(true)] + private void load(RankingsOverlay rankings) + { + StateContainer = rankings; + } + } +} From f05c1de4c10a68c910ae7435f2a04a288cebf250 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 14:11:53 +0300 Subject: [PATCH 0431/1142] Fix possible nullref --- osu.Game/Overlays/RankingsOverlay.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index f3215d07fa..69ca687871 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -135,6 +135,9 @@ namespace osu.Game.Overlays private void loadNewContent() { + if (ruleset.Value == null) + return; + loading.Show(); cancellationToken?.Cancel(); From 11c59a141f24aebf68f21fb7d79f88980b1233f1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 14:12:10 +0300 Subject: [PATCH 0432/1142] Add background to rankings header --- osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 2674b3a81e..72d5b6462d 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -29,6 +29,8 @@ namespace osu.Game.Overlays.Rankings Current = Country }; + protected override Drawable CreateBackground() => new OverlayHeaderBackground(@"Headers/rankings"); + private class RankingsTitle : ScreenTitle { public readonly Bindable Scope = new Bindable(); From 382cc1a91ba24fa00e89e641e5f86ff517d2e34e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 14:26:35 +0300 Subject: [PATCH 0433/1142] Fix incorrect overlays overlapping --- osu.Game/OsuGame.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e034fcc3ac..c31f15716b 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -65,8 +65,6 @@ namespace osu.Game private DirectOverlay direct; - private RankingsOverlay rankings; - private SocialOverlay social; private UserProfileOverlay userProfile; @@ -602,7 +600,7 @@ namespace osu.Game //overlay elements loadComponentSingleFile(direct = new DirectOverlay(), overlayContent.Add, true); loadComponentSingleFile(social = new SocialOverlay(), overlayContent.Add, true); - loadComponentSingleFile(rankings = new RankingsOverlay(), overlayContent.Add, true); + var rankingsOverlay = loadComponentSingleFile(new RankingsOverlay(), overlayContent.Add, true); loadComponentSingleFile(channelManager = new ChannelManager(), AddInternal, true); loadComponentSingleFile(chatOverlay = new ChatOverlay(), overlayContent.Add, true); loadComponentSingleFile(Settings = new SettingsOverlay { GetToolbarHeight = () => ToolbarOffset }, leftFloatingOverlayContent.Add, true); @@ -646,7 +644,7 @@ namespace osu.Game } // eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time. - var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile, rankings }; + var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile }; foreach (var overlay in informationalOverlays) { @@ -659,7 +657,7 @@ namespace osu.Game } // ensure only one of these overlays are open at once. - var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, social, direct, changelogOverlay }; + var singleDisplayOverlays = new OverlayContainer[] { chatOverlay, social, direct, changelogOverlay, rankingsOverlay }; foreach (var overlay in singleDisplayOverlays) { From b2fbeab7732437b8671c512fe69eabeb6deefb47 Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Thu, 13 Feb 2020 14:07:14 +0100 Subject: [PATCH 0434/1142] simplify string formatting and fix color --- osu.Game/Graphics/DrawableDate.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index dcbea96071..8c520f4e10 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -126,10 +126,8 @@ namespace osu.Game.Graphics [BackgroundDependencyLoader] private void load(OsuColour colours) { - // Temporary colour since it's currently impossible to change it without bugs (see https://github.com/ppy/osu-framework/issues/3231) - // If above is fixed, this should use OverlayColourProvider - background.Colour = colours.Gray1; - timeText.Colour = colours.GreyCyanLighter; + background.Colour = colours.GreySeafoamDarker; + timeText.Colour = colours.BlueLighter; } protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); @@ -140,8 +138,8 @@ namespace osu.Game.Graphics if (!(content is DateTimeOffset date)) return false; - dateText.Text = string.Format($"{date:d MMMM yyyy}") + " "; - timeText.Text = string.Format($"{date:hh:mm:ss \"UTC\"z}"); + dateText.Text = $"{date:d MMMM yyyy} "; + timeText.Text = $"{date:hh:mm:ss \"UTC\"z}"; return true; } From e181a95c855d1ba6562219a7df9776955f1a7a4d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 13 Feb 2020 22:28:37 +0900 Subject: [PATCH 0435/1142] Remove unused using --- osu.Game/Online/Multiplayer/Room.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Online/Multiplayer/Room.cs b/osu.Game/Online/Multiplayer/Room.cs index ff11a74a1a..400afb39a1 100644 --- a/osu.Game/Online/Multiplayer/Room.cs +++ b/osu.Game/Online/Multiplayer/Room.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using osu.Framework.Allocation; From e67e4f708ea996e594992321a0e01cf037a967ed Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 19:01:26 +0300 Subject: [PATCH 0436/1142] 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 0437/1142] 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 dac0148c94076026b579a8bc31fbba93bdd134c3 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 13 Feb 2020 20:08:14 +0100 Subject: [PATCH 0438/1142] Apply review suggestions. --- .../Online/TestSceneOnlineViewContainer.cs | 2 +- osu.Game/Online/OnlineViewContainer.cs | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index 2b9609f6e0..9dac28d347 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -32,7 +32,7 @@ namespace osu.Game.Tests.Visual.Online { public new LoadingAnimation LoadingAnimation => base.LoadingAnimation; - public CompositeDrawable ViewTarget => base.Content.Parent; + public CompositeDrawable ViewTarget => base.Content; public TestOnlineViewContainer() : base(@"Please sign in to view dummy test content") diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index c512ca531a..4b59f6ae80 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -21,8 +21,8 @@ namespace osu.Game.Online protected const double TRANSFORM_TIME = 300.0; - private readonly Container viewTarget; - protected override Container Content { get; } + private Container viewContent; + protected override Container Content => viewContent; [Resolved] protected IAPIProvider API { get; private set; } @@ -31,13 +31,9 @@ namespace osu.Game.Online { InternalChildren = new Drawable[] { - viewTarget = new Container + viewContent = new Container { RelativeSizeAxes = Axes.Both, - Child = Content = new Container - { - RelativeSizeAxes = Axes.Both, - } }, placeholder = new LoginPlaceholder(placeholderMessage), LoadingAnimation = new LoadingAnimation @@ -52,21 +48,21 @@ namespace osu.Game.Online switch (state) { case APIState.Offline: - PopContentOut(viewTarget); + PopContentOut(viewContent); placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * TRANSFORM_TIME, Easing.OutQuint); placeholder.FadeInFromZero(2 * TRANSFORM_TIME, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Online: - PopContentIn(viewTarget); + PopContentIn(viewContent); placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Failing: case APIState.Connecting: - PopContentOut(viewTarget); + PopContentOut(viewContent); LoadingAnimation.Show(); placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); break; From cc625e3b897dd2669fe6300de9a6924082e97652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Feb 2020 20:44:02 +0100 Subject: [PATCH 0439/1142] Move initialisation logic to [SetUp] --- .../UserInterface/TestSceneCommentEditor.cs | 122 +++++++++--------- 1 file changed, 59 insertions(+), 63 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index a7888bb0b4..aaf26f78a7 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -31,73 +31,13 @@ namespace osu.Game.Tests.Visual.UserInterface private string commitText; private bool cancelActionFired; - [Test] - public void TestCommitViaKeyboard() + [SetUp] + public void SetUp() { - AddStep("Create", createEditors); - AddStep("Click on textbox", () => - { - InputManager.MoveMouseTo(commentEditor); - InputManager.Click(MouseButton.Left); - }); - AddStep("Write something", () => commentEditor.Current.Value = "text"); - AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); - AddAssert("Button is loading", () => commentEditor.IsLoading); - } - - [Test] - public void TestCommitViaKeyboardWhenEmpty() - { - AddStep("Create", createEditors); - AddStep("Click on textbox", () => - { - InputManager.MoveMouseTo(commentEditor); - InputManager.Click(MouseButton.Left); - }); - AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text not invoked", () => string.IsNullOrEmpty(commitText)); - AddAssert("Button is not loading", () => !commentEditor.IsLoading); - } - - [Test] - public void TestCommitViaButton() - { - AddStep("Create", createEditors); - AddStep("Click on textbox", () => - { - InputManager.MoveMouseTo(commentEditor); - InputManager.Click(MouseButton.Left); - }); - AddStep("Write something", () => commentEditor.Current.Value = "text"); - AddStep("Click on button", () => - { - InputManager.MoveMouseTo(commentEditor.ButtonsContainer); - InputManager.Click(MouseButton.Left); - }); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); - AddAssert("Button is loading", () => commentEditor.IsLoading); - } - - [Test] - public void TestCancelAction() - { - AddStep("Create", createEditors); - AddStep("Click on cancel button", () => - { - InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); - InputManager.Click(MouseButton.Left); - }); - AddAssert("Cancel action is fired", () => cancelActionFired); - } - - private void createEditors() - { - Clear(); commitText = string.Empty; cancelActionFired = false; - Add(new FillFlowContainer + Schedule(() => Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -117,7 +57,63 @@ namespace osu.Game.Tests.Visual.UserInterface OnCancel = onCancel } } + })); + } + + [Test] + public void TestCommitViaKeyboard() + { + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); }); + AddStep("Write something", () => commentEditor.Current.Value = "text"); + AddStep("Click Enter", () => press(Key.Enter)); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Button is loading", () => commentEditor.IsLoading); + } + + [Test] + public void TestCommitViaKeyboardWhenEmpty() + { + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); + }); + AddStep("Click Enter", () => press(Key.Enter)); + AddAssert("Text not invoked", () => string.IsNullOrEmpty(commitText)); + AddAssert("Button is not loading", () => !commentEditor.IsLoading); + } + + [Test] + public void TestCommitViaButton() + { + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); + }); + AddStep("Write something", () => commentEditor.Current.Value = "text"); + AddStep("Click on button", () => + { + InputManager.MoveMouseTo(commentEditor.ButtonsContainer); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Button is loading", () => commentEditor.IsLoading); + } + + [Test] + public void TestCancelAction() + { + AddStep("Click on cancel button", () => + { + InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Cancel action is fired", () => cancelActionFired); } private void onCommit(string value) From 09b2e7beed1d317bfa0bce11f02b3dd7f86f35bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Feb 2020 20:56:34 +0100 Subject: [PATCH 0440/1142] Encapsulate test editors --- .../UserInterface/TestSceneCommentEditor.cs | 68 ++++++++----------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index aaf26f78a7..8005e9a2bc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -28,16 +28,10 @@ namespace osu.Game.Tests.Visual.UserInterface private TestCommentEditor commentEditor; private TestCancellableCommentEditor cancellableCommentEditor; - private string commitText; - private bool cancelActionFired; [SetUp] - public void SetUp() - { - commitText = string.Empty; - cancelActionFired = false; - - Schedule(() => Add(new FillFlowContainer + public void SetUp() => Schedule(() => + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -47,18 +41,10 @@ namespace osu.Game.Tests.Visual.UserInterface Spacing = new Vector2(0, 20), Children = new Drawable[] { - commentEditor = new TestCommentEditor - { - OnCommit = onCommit, - }, - cancellableCommentEditor = new TestCancellableCommentEditor - { - OnCommit = onCommit, - OnCancel = onCancel - } + commentEditor = new TestCommentEditor(), + cancellableCommentEditor = new TestCancellableCommentEditor() } })); - } [Test] public void TestCommitViaKeyboard() @@ -70,7 +56,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddStep("Write something", () => commentEditor.Current.Value = "text"); AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commentEditor.CommittedText)); AddAssert("Button is loading", () => commentEditor.IsLoading); } @@ -83,7 +69,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text not invoked", () => string.IsNullOrEmpty(commitText)); + AddAssert("Text not invoked", () => string.IsNullOrEmpty(commentEditor.CommittedText)); AddAssert("Button is not loading", () => !commentEditor.IsLoading); } @@ -101,7 +87,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(commentEditor.ButtonsContainer); InputManager.Click(MouseButton.Left); }); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commentEditor.CommittedText)); AddAssert("Button is loading", () => commentEditor.IsLoading); } @@ -113,22 +99,9 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); InputManager.Click(MouseButton.Left); }); - AddAssert("Cancel action is fired", () => cancelActionFired); + AddAssert("Cancel action is fired", () => cancellableCommentEditor.Cancelled); } - private void onCommit(string value) - { - commitText = value; - - Scheduler.AddDelayed(() => - { - commentEditor.IsLoading = false; - cancellableCommentEditor.IsLoading = false; - }, 1000); - } - - private void onCancel() => cancelActionFired = true; - private void press(Key key) { InputManager.PressKey(key); @@ -138,24 +111,39 @@ namespace osu.Game.Tests.Visual.UserInterface private class TestCommentEditor : CommentEditor { public new Bindable Current => base.Current; - public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; + public string CommittedText { get; private set; } + + public TestCommentEditor() + { + OnCommit = onCommit; + } + + private void onCommit(string value) + { + CommittedText = value; + Scheduler.AddDelayed(() => IsLoading = false, 1000); + } + protected override string FooterText => @"Footer text. And it is pretty long. Cool."; - protected override string CommitButtonText => @"Commit"; - protected override string TextboxPlaceholderText => @"This textbox is empty"; } private class TestCancellableCommentEditor : CancellableCommentEditor { public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; - protected override string FooterText => @"Wow, another one. Sicc"; - protected override string CommitButtonText => @"Save"; + public bool Cancelled { get; private set; } + public TestCancellableCommentEditor() + { + OnCancel = () => Cancelled = true; + } + + protected override string CommitButtonText => @"Save"; protected override string TextboxPlaceholderText => @"Miltiline textboxes soon"; } } From 5646083ed9ae4214e9f436b6ff1a7f0d8e107576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Feb 2020 21:01:25 +0100 Subject: [PATCH 0441/1142] Adjust code style in test --- .../UserInterface/TestSceneCommentEditor.cs | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 8005e9a2bc..a5ef8b046d 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -49,57 +49,64 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestCommitViaKeyboard() { - AddStep("Click on textbox", () => + AddStep("click on text box", () => { InputManager.MoveMouseTo(commentEditor); InputManager.Click(MouseButton.Left); }); - AddStep("Write something", () => commentEditor.Current.Value = "text"); - AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commentEditor.CommittedText)); - AddAssert("Button is loading", () => commentEditor.IsLoading); + AddStep("enter text", () => commentEditor.Current.Value = "text"); + + AddStep("press Enter", () => press(Key.Enter)); + + AddAssert("text committed", () => commentEditor.CommittedText == "text"); + AddAssert("button is loading", () => commentEditor.IsLoading); } [Test] public void TestCommitViaKeyboardWhenEmpty() { - AddStep("Click on textbox", () => + AddStep("click on text box", () => { InputManager.MoveMouseTo(commentEditor); InputManager.Click(MouseButton.Left); }); - AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text not invoked", () => string.IsNullOrEmpty(commentEditor.CommittedText)); - AddAssert("Button is not loading", () => !commentEditor.IsLoading); + + AddStep("press Enter", () => press(Key.Enter)); + + AddAssert("no text committed", () => commentEditor.CommittedText == null); + AddAssert("button is not loading", () => !commentEditor.IsLoading); } [Test] public void TestCommitViaButton() { - AddStep("Click on textbox", () => + AddStep("click on text box", () => { InputManager.MoveMouseTo(commentEditor); InputManager.Click(MouseButton.Left); }); - AddStep("Write something", () => commentEditor.Current.Value = "text"); - AddStep("Click on button", () => + AddStep("enter text", () => commentEditor.Current.Value = "some other text"); + + AddStep("click submit", () => { InputManager.MoveMouseTo(commentEditor.ButtonsContainer); InputManager.Click(MouseButton.Left); }); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commentEditor.CommittedText)); - AddAssert("Button is loading", () => commentEditor.IsLoading); + + AddAssert("text committed", () => commentEditor.CommittedText == "some other text"); + AddAssert("button is loading", () => commentEditor.IsLoading); } [Test] public void TestCancelAction() { - AddStep("Click on cancel button", () => + AddStep("click cancel button", () => { InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); InputManager.Click(MouseButton.Left); }); - AddAssert("Cancel action is fired", () => cancellableCommentEditor.Cancelled); + + AddAssert("cancel action fired", () => cancellableCommentEditor.Cancelled); } private void press(Key key) @@ -128,7 +135,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override string FooterText => @"Footer text. And it is pretty long. Cool."; protected override string CommitButtonText => @"Commit"; - protected override string TextboxPlaceholderText => @"This textbox is empty"; + protected override string TextboxPlaceholderText => @"This text box is empty"; } private class TestCancellableCommentEditor : CancellableCommentEditor @@ -144,7 +151,7 @@ namespace osu.Game.Tests.Visual.UserInterface } protected override string CommitButtonText => @"Save"; - protected override string TextboxPlaceholderText => @"Miltiline textboxes soon"; + protected override string TextboxPlaceholderText => @"Multiline textboxes soon"; } } } From 0f25864faed05910713df23ecdf5d6310f295a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Feb 2020 21:04:53 +0100 Subject: [PATCH 0442/1142] Textbox -> TextBox rename pass --- .../Visual/UserInterface/TestSceneCommentEditor.cs | 4 ++-- osu.Game/Overlays/Comments/CommentEditor.cs | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index a5ef8b046d..7b0b644dab 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -135,7 +135,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override string FooterText => @"Footer text. And it is pretty long. Cool."; protected override string CommitButtonText => @"Commit"; - protected override string TextboxPlaceholderText => @"This text box is empty"; + protected override string TextBoxPlaceholder => @"This text box is empty"; } private class TestCancellableCommentEditor : CancellableCommentEditor @@ -151,7 +151,7 @@ namespace osu.Game.Tests.Visual.UserInterface } protected override string CommitButtonText => @"Save"; - protected override string TextboxPlaceholderText => @"Multiline textboxes soon"; + protected override string TextBoxPlaceholder => @"Multiline textboxes soon"; } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 765e5e228c..f7e53addbe 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Comments protected abstract string CommitButtonText { get; } - protected abstract string TextboxPlaceholderText { get; } + protected abstract string TextBoxPlaceholder { get; } protected FillFlowContainer ButtonsContainer; @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - EditorTextbox textbox; + EditorTextBox textBox; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -68,11 +68,11 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - textbox = new EditorTextbox + textBox = new EditorTextBox { Height = 40, RelativeSizeAxes = Axes.X, - PlaceholderText = TextboxPlaceholderText, + PlaceholderText = TextBoxPlaceholder, Current = Current }, new Container @@ -115,7 +115,7 @@ namespace osu.Game.Overlays.Comments } }); - textbox.OnCommit += (u, v) => + textBox.OnCommit += (u, v) => { if (commitButton.IsBlocked.Value) return; @@ -131,7 +131,7 @@ namespace osu.Game.Overlays.Comments Current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } - private class EditorTextbox : BasicTextBox + private class EditorTextBox : BasicTextBox { protected override float LeftRightPadding => side_padding; @@ -139,7 +139,7 @@ namespace osu.Game.Overlays.Comments private OsuSpriteText placeholder; - public EditorTextbox() + public EditorTextBox() { Masking = false; TextContainer.Height = 0.4f; From ab84f4085a83d8f8d597ddaa3e3aca8955d8c76a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 23:20:45 +0300 Subject: [PATCH 0443/1142] Fix possible error on SpotlightsLayout disposal --- osu.Game/Overlays/Rankings/SpotlightsLayout.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs index 33811cc982..cb409a2135 100644 --- a/osu.Game/Overlays/Rankings/SpotlightsLayout.cs +++ b/osu.Game/Overlays/Rankings/SpotlightsLayout.cs @@ -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 049b0d93d13530c090612a20a27124ee79fcaf38 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Thu, 13 Feb 2020 21:40:08 +0100 Subject: [PATCH 0444/1142] Add back default content fade transitions --- .../Visual/Online/TestSceneOnlineViewContainer.cs | 4 ---- osu.Game/Online/OnlineViewContainer.cs | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index 9dac28d347..39b9fd71d0 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -54,10 +54,6 @@ namespace osu.Game.Tests.Visual.Online } }; } - - protected override void PopContentOut(Drawable content) => content.Hide(); - - protected override void PopContentIn(Drawable content) => content.Show(); } [Test] diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 4b59f6ae80..2a9aa60e2d 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Online protected const double TRANSFORM_TIME = 300.0; - private Container viewContent; + private readonly Container viewContent; protected override Container Content => viewContent; [Resolved] @@ -69,9 +69,9 @@ namespace osu.Game.Online } } - protected abstract void PopContentOut(Drawable content); + protected virtual void PopContentOut(Drawable content) => content.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); - protected abstract void PopContentIn(Drawable content); + protected virtual void PopContentIn(Drawable content) => content.FadeIn(TRANSFORM_TIME, Easing.OutQuint); protected override void LoadComplete() { From c68c347503df8514ca0337ec01f9716d643b7da7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 14 Feb 2020 00:40:52 +0300 Subject: [PATCH 0445/1142] 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 c871f07d2ef9f55d1c91f9ac6138fd2d162e7ed3 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Thu, 13 Feb 2020 17:14:46 -0800 Subject: [PATCH 0446/1142] Use CarouselBeatmap action to select beatmap --- osu.Game/OsuGame.cs | 55 ++++++++----------- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 + .../Select/Carousel/CarouselBeatmap.cs | 5 ++ .../Carousel/DrawableCarouselBeatmapSet.cs | 23 +------- 4 files changed, 34 insertions(+), 51 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3d6b93c87d..79616ef97c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -311,38 +311,15 @@ namespace osu.Game public void ShowBeatmap(int beatmapId) => waitForReady(() => beatmapSetOverlay, _ => beatmapSetOverlay.FetchAndShowBeatmap(beatmapId)); /// - /// Present a specific beatmap difficulty at song select immediately. + /// Present a beatmap at song select immediately. /// The user should have already requested this interactively. /// /// The beatmap to select. - public void PresentBeatmap(BeatmapInfo beatmap) + public void PresentBeatmap(BeatmapSetInfo beatmap) { - PerformFromScreen(screen => - { - // we might already be at song select, so a check is required before performing the load to solo. - if (screen is MainMenu) - menuScreen.LoadToSolo(); - - // we might even already be at the song - if (Beatmap.Value.BeatmapInfo.Hash == beatmap.Hash) - return; - - Ruleset.Value = beatmap.Ruleset; - Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap); - }, validScreens: new[] { typeof(PlaySongSelect) }); - } - - /// - /// - /// Instead of selecting a specific difficulty, this will select the first difficulty of the current ruleset in a beatmapset, - /// or the first difficulty of the set if there is none. - /// - /// The beatmapset to select. - public void PresentBeatmap(BeatmapSetInfo beatmapSet) - { - var databasedSet = beatmapSet.OnlineBeatmapSetID != null - ? BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmapSet.OnlineBeatmapSetID) - : BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmapSet.Hash); + var databasedSet = beatmap.OnlineBeatmapSetID != null + ? BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID) + : BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmap.Hash); if (databasedSet == null) { @@ -350,8 +327,24 @@ namespace osu.Game return; } - var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); - PresentBeatmap(first); + PerformFromScreen(screen => + { + // we might already be at song select, so a check is required before performing the load to solo. + if (screen is MainMenu) + menuScreen.LoadToSolo(); + + // we might even already be at the song + if (Beatmap.Value.BeatmapSetInfo.Hash == databasedSet.Hash) + { + return; + } + + // Use first beatmap available for current ruleset, else switch ruleset. + var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); + + Ruleset.Value = first.Ruleset; + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); + }, validScreens: new[] { typeof(PlaySongSelect) }); } /// @@ -453,7 +446,7 @@ namespace osu.Game /// /// The action to perform once we are in the correct state. /// An optional collection of valid screen types. If any of these screens are already current we can perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. - protected void PerformFromScreen(Action action, IEnumerable validScreens = null) + public void PerformFromScreen(Action action, IEnumerable validScreens = null) { performFromMainMenuTask?.Cancel(); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 592e26adc2..f6e0e6bf70 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -592,6 +592,8 @@ namespace osu.Game.Screens.Select scrollPositionCache.Invalidate(); } }; + + c.Select = () => SelectBeatmap(c.Beatmap); } return set; diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 2ffb73f226..116053b4f2 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -13,6 +13,11 @@ namespace osu.Game.Screens.Select.Carousel { public readonly BeatmapInfo Beatmap; + /// + /// Select this beatmap on the carousel. + /// + public Action Select; + public CarouselBeatmap(BeatmapInfo beatmap) { Beatmap = beatmap; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 9e4f31b15b..5ef0e8a018 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -211,9 +211,7 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private OsuGame game; - private SongSelect songSelect; - private readonly BeatmapInfo info; + private readonly Action select; public FilterableDifficultyIcon(CarouselBeatmap item) : base(item.Beatmap) @@ -222,30 +220,15 @@ namespace osu.Game.Screens.Select.Carousel filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); - info = item.Beatmap; + select = item.Select; } protected override bool OnClick(ClickEvent e) { - if (!filtered.Value) - { - game.PresentBeatmap(info); - - if (e.AltPressed) - songSelect?.FinaliseSelection(); - } + select?.Invoke(); return base.OnClick(e); } - - [BackgroundDependencyLoader] - private void load(OsuGame game, SongSelect songSelect) - { - this.game = game; - - if (songSelect != null) - this.songSelect = songSelect; - } } public class FilterableGroupedDifficultyIcon : GroupedDifficultyIcon From 368e6f9579492d6321c89850cf4fe114a0337c83 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Thu, 13 Feb 2020 17:47:16 -0800 Subject: [PATCH 0447/1142] Use CarouselBeatmap.State to select --- osu.Game/OsuGame.cs | 2 +- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 -- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 5 ----- .../Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 8 ++++---- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 79616ef97c..ff3dee55af 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -446,7 +446,7 @@ namespace osu.Game /// /// The action to perform once we are in the correct state. /// An optional collection of valid screen types. If any of these screens are already current we can perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. - public void PerformFromScreen(Action action, IEnumerable validScreens = null) + protected void PerformFromScreen(Action action, IEnumerable validScreens = null) { performFromMainMenuTask?.Cancel(); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index f6e0e6bf70..592e26adc2 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -592,8 +592,6 @@ namespace osu.Game.Screens.Select scrollPositionCache.Invalidate(); } }; - - c.Select = () => SelectBeatmap(c.Beatmap); } return set; diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 116053b4f2..2ffb73f226 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -13,11 +13,6 @@ namespace osu.Game.Screens.Select.Carousel { public readonly BeatmapInfo Beatmap; - /// - /// Select this beatmap on the carousel. - /// - public Action Select; - public CarouselBeatmap(BeatmapInfo beatmap) { Beatmap = beatmap; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 5ef0e8a018..572580f7c1 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -211,7 +211,7 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private readonly Action select; + private readonly CarouselBeatmap item; public FilterableDifficultyIcon(CarouselBeatmap item) : base(item.Beatmap) @@ -220,14 +220,14 @@ namespace osu.Game.Screens.Select.Carousel filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); - select = item.Select; + this.item = item; } protected override bool OnClick(ClickEvent e) { - select?.Invoke(); + item.State.Value = CarouselItemState.Selected; - return base.OnClick(e); + return true; } } From 50899ddccba2e8dfc89d0282ee5a547728c53f3e Mon Sep 17 00:00:00 2001 From: Berkan Diler Date: Fri, 14 Feb 2020 03:19:25 +0100 Subject: [PATCH 0448/1142] Use Span for OsuColour.FromHex --- osu.Game/Graphics/OsuColour.cs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index c8298543a1..59dd823266 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Globalization; using osu.Game.Beatmaps; using osuTK.Graphics; @@ -14,41 +15,40 @@ namespace osu.Game.Graphics public static Color4 FromHex(string hex) { - if (hex[0] == '#') - hex = hex.Substring(1); + var hexSpan = hex[0] == '#' ? hex.AsSpan().Slice(1) : hex.AsSpan(); - switch (hex.Length) + switch (hexSpan.Length) { default: throw new ArgumentException(@"Invalid hex string length!"); case 3: return new Color4( - (byte)(Convert.ToByte(hex.Substring(0, 1), 16) * 17), - (byte)(Convert.ToByte(hex.Substring(1, 1), 16) * 17), - (byte)(Convert.ToByte(hex.Substring(2, 1), 16) * 17), + (byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17), + (byte)(byte.Parse(hexSpan.Slice(1, 1), NumberStyles.HexNumber) * 17), + (byte)(byte.Parse(hexSpan.Slice(2, 1), NumberStyles.HexNumber) * 17), 255); case 6: return new Color4( - Convert.ToByte(hex.Substring(0, 2), 16), - Convert.ToByte(hex.Substring(2, 2), 16), - Convert.ToByte(hex.Substring(4, 2), 16), + byte.Parse(hexSpan.Slice(0, 2), NumberStyles.HexNumber), + byte.Parse(hexSpan.Slice(2, 2), NumberStyles.HexNumber), + byte.Parse(hexSpan.Slice(4, 2), NumberStyles.HexNumber), 255); case 4: return new Color4( - (byte)(Convert.ToByte(hex.Substring(0, 1), 16) * 17), - (byte)(Convert.ToByte(hex.Substring(1, 1), 16) * 17), - (byte)(Convert.ToByte(hex.Substring(2, 1), 16) * 17), - (byte)(Convert.ToByte(hex.Substring(3, 1), 16) * 17)); + (byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17), + (byte)(byte.Parse(hexSpan.Slice(1, 1), NumberStyles.HexNumber) * 17), + (byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17), + (byte)(byte.Parse(hexSpan.Slice(0, 1), NumberStyles.HexNumber) * 17)); case 8: return new Color4( - Convert.ToByte(hex.Substring(0, 2), 16), - Convert.ToByte(hex.Substring(2, 2), 16), - Convert.ToByte(hex.Substring(4, 2), 16), - Convert.ToByte(hex.Substring(6, 2), 16)); + byte.Parse(hexSpan.Slice(0, 2), NumberStyles.HexNumber), + byte.Parse(hexSpan.Slice(2, 2), NumberStyles.HexNumber), + byte.Parse(hexSpan.Slice(4, 2), NumberStyles.HexNumber), + byte.Parse(hexSpan.Slice(6, 2), NumberStyles.HexNumber)); } } From 884a5fbad44f1eb58731de2176d7cf67428dd521 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 12:30:11 +0900 Subject: [PATCH 0449/1142] Fix osu! gameplay cursor not adjusting to mod/convert circle size changes --- .../TestSceneGameplayCursor.cs | 46 +++++++++++++++++-- .../UI/Cursor/OsuCursorContainer.cs | 44 +++++++++++++----- osu.Game/Screens/Play/GameplayBeatmap.cs | 42 +++++++++++++++++ osu.Game/Screens/Play/Player.cs | 11 +++++ 4 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 osu.Game/Screens/Play/GameplayBeatmap.cs diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs index aa170eae1e..90f1cdb2ea 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs @@ -7,7 +7,9 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Testing.Input; +using osu.Game.Configuration; using osu.Game.Rulesets.Osu.UI.Cursor; +using osu.Game.Screens.Play; using osuTK; namespace osu.Game.Rulesets.Osu.Tests @@ -21,12 +23,50 @@ namespace osu.Game.Rulesets.Osu.Tests typeof(CursorTrail) }; - [BackgroundDependencyLoader] - private void load() + [Cached] + private GameplayBeatmap gameplayBeatmap; + + private ClickingCursorContainer lastContainer; + + [Resolved] + private OsuConfigManager config { get; set; } + + public TestSceneGameplayCursor() + { + gameplayBeatmap = new GameplayBeatmap(CreateBeatmap(new OsuRuleset().RulesetInfo)); + } + + [TestCase(1, 1)] + [TestCase(5, 1)] + [TestCase(10, 1)] + [TestCase(1, 1.5f)] + [TestCase(5, 1.5f)] + [TestCase(10, 1.5f)] + public void TestSizing(int circleSize, float userScale) + { + AddStep($"set user scale to {userScale}", () => config.Set(OsuSetting.GameplayCursorSize, userScale)); + AddStep($"adjust cs to {circleSize}", () => gameplayBeatmap.BeatmapInfo.BaseDifficulty.CircleSize = circleSize); + AddStep("turn on autosizing", () => config.Set(OsuSetting.AutoCursorSize, true)); + + AddStep("load content", loadContent); + + AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == OsuCursorContainer.GetScaleForCircleSize(circleSize) * userScale); + + AddStep("set user scale to 1", () => config.Set(OsuSetting.GameplayCursorSize, 1f)); + AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == OsuCursorContainer.GetScaleForCircleSize(circleSize)); + + AddStep("turn off autosizing", () => config.Set(OsuSetting.AutoCursorSize, false)); + AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == 1); + + AddStep($"set user scale to {userScale}", () => config.Set(OsuSetting.GameplayCursorSize, userScale)); + AddUntilStep("cursor size correct", () => lastContainer.ActiveCursor.Scale.X == userScale); + } + + private void loadContent() { SetContents(() => new MovingCursorInputManager { - Child = new ClickingCursorContainer + Child = lastContainer = new ClickingCursorContainer { RelativeSizeAxes = Axes.Both, Masking = true, diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 79b5d1b7f8..7ebc26ebfb 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -12,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.UI; +using osu.Game.Screens.Play; using osu.Game.Skinning; using osuTK; @@ -32,7 +33,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor public Bindable CursorScale; private Bindable userCursorScale; private Bindable autoCursorScale; - private readonly IBindable beatmap = new Bindable(); public OsuCursorContainer() { @@ -43,13 +43,21 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor }; } + [Resolved(canBeNull: true)] + private GameplayBeatmap beatmap { get; set; } + + [Resolved] + private OsuConfigManager config { get; set; } + [BackgroundDependencyLoader(true)] - private void load(OsuConfigManager config, OsuRulesetConfigManager rulesetConfig, IBindable beatmap) + private void load(OsuConfigManager config, OsuRulesetConfigManager rulesetConfig) { rulesetConfig?.BindWith(OsuRulesetSetting.ShowCursorTrail, showTrail); + } - this.beatmap.BindTo(beatmap); - this.beatmap.ValueChanged += _ => calculateScale(); + protected override void LoadComplete() + { + showTrail.BindValueChanged(v => cursorTrail.FadeTo(v.NewValue ? 1 : 0, 200), true); userCursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); userCursorScale.ValueChanged += _ => calculateScale(); @@ -58,29 +66,41 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor autoCursorScale.ValueChanged += _ => calculateScale(); CursorScale = new BindableFloat(); - CursorScale.ValueChanged += e => ActiveCursor.Scale = cursorTrail.Scale = new Vector2(e.NewValue); + CursorScale.ValueChanged += e => + { + var newScale = new Vector2(e.NewValue); + + ActiveCursor.Scale = newScale; + cursorTrail.Scale = newScale; + }; calculateScale(); + + base.LoadComplete(); } + /// + /// Get the scale applicable to the ActiveCursor based on a beatmap's circle size. + /// + public static float GetScaleForCircleSize(float circleSize) => + 1f - 0.7f * (1f + circleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY; + private void calculateScale() { float scale = userCursorScale.Value; - if (autoCursorScale.Value && beatmap.Value != null) + if (autoCursorScale.Value && beatmap != null) { // if we have a beatmap available, let's get its circle size to figure out an automatic cursor scale modifier. - scale *= 1f - 0.7f * (1f + beatmap.Value.BeatmapInfo.BaseDifficulty.CircleSize - BeatmapDifficulty.DEFAULT_DIFFICULTY) / BeatmapDifficulty.DEFAULT_DIFFICULTY; + scale *= GetScaleForCircleSize(beatmap.BeatmapInfo.BaseDifficulty.CircleSize); } CursorScale.Value = scale; - } - protected override void LoadComplete() - { - base.LoadComplete(); + var newScale = new Vector2(scale); - showTrail.BindValueChanged(v => cursorTrail.FadeTo(v.NewValue ? 1 : 0, 200), true); + ActiveCursor.ScaleTo(newScale, 400, Easing.OutQuint); + cursorTrail.Scale = newScale; } private int downCount; diff --git a/osu.Game/Screens/Play/GameplayBeatmap.cs b/osu.Game/Screens/Play/GameplayBeatmap.cs new file mode 100644 index 0000000000..d7f939a883 --- /dev/null +++ b/osu.Game/Screens/Play/GameplayBeatmap.cs @@ -0,0 +1,42 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Objects; + +namespace osu.Game.Screens.Play +{ + public class GameplayBeatmap : Component, IBeatmap + { + public readonly IBeatmap PlayableBeatmap; + + public GameplayBeatmap(IBeatmap playableBeatmap) + { + PlayableBeatmap = playableBeatmap; + } + + public BeatmapInfo BeatmapInfo + { + get => PlayableBeatmap.BeatmapInfo; + set => PlayableBeatmap.BeatmapInfo = value; + } + + public BeatmapMetadata Metadata => PlayableBeatmap.Metadata; + + public ControlPointInfo ControlPointInfo => PlayableBeatmap.ControlPointInfo; + + public List Breaks => PlayableBeatmap.Breaks; + + public double TotalBreakTime => PlayableBeatmap.TotalBreakTime; + + public IReadOnlyList HitObjects => PlayableBeatmap.HitObjects; + + public IEnumerable GetStatistics() => PlayableBeatmap.GetStatistics(); + + public IBeatmap Clone() => PlayableBeatmap.Clone(); + } +} diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index aecd35f7dc..9bfdcd79fe 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -110,6 +110,13 @@ namespace osu.Game.Screens.Play this.showResults = showResults; } + private GameplayBeatmap gameplayBeatmap; + + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); + [BackgroundDependencyLoader] private void load(AudioManager audio, IAPIProvider api, OsuConfigManager config) { @@ -143,6 +150,10 @@ namespace osu.Game.Screens.Play InternalChild = GameplayClockContainer = new GameplayClockContainer(Beatmap.Value, Mods.Value, DrawableRuleset.GameplayStartTime); + AddInternal(gameplayBeatmap = new GameplayBeatmap(playableBeatmap)); + + dependencies.CacheAs(gameplayBeatmap); + addUnderlayComponents(GameplayClockContainer); addGameplayComponents(GameplayClockContainer, Beatmap.Value); addOverlayComponents(GameplayClockContainer, Beatmap.Value); From 0e439e3a7025a2cfded813fda28f90c8d9a79a88 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 14:41:55 +0900 Subject: [PATCH 0450/1142] Fix missing dependency in ZoomableScrollContainer test --- .../Compose/Components/Timeline/ZoomableScrollContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index baaad63e57..227eecf9c7 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private float currentZoom = 1; - [Resolved] + [Resolved(canBeNull: true)] private IFrameBasedClock editorClock { get; set; } public ZoomableScrollContainer() @@ -112,7 +112,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { // can't handle scroll correctly while playing. // the editor will handle this case for us. - if (editorClock.IsRunning) + if (editorClock?.IsRunning == true) return false; // for now, we don't support zoom when using a precision scroll device. this needs gesture support. From 3a0b2508d42b1d09da1aa30bbc356d88b5b4f76d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 15:01:30 +0900 Subject: [PATCH 0451/1142] Fix possible nullrefs --- osu.Game/Overlays/Direct/PanelDownloadButton.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Direct/PanelDownloadButton.cs b/osu.Game/Overlays/Direct/PanelDownloadButton.cs index ed44f1e960..1b3657f010 100644 --- a/osu.Game/Overlays/Direct/PanelDownloadButton.cs +++ b/osu.Game/Overlays/Direct/PanelDownloadButton.cs @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Direct [BackgroundDependencyLoader(true)] private void load(OsuGame game, BeatmapManager beatmaps) { - if (BeatmapSet.Value.OnlineInfo.Availability?.DownloadDisabled ?? false) + if (BeatmapSet.Value?.OnlineInfo?.Availability?.DownloadDisabled ?? false) { button.Enabled.Value = false; button.TooltipText = "this beatmap is currently not available for download."; @@ -62,7 +62,7 @@ namespace osu.Game.Overlays.Direct break; case DownloadState.LocallyAvailable: - game.PresentBeatmap(BeatmapSet.Value); + game?.PresentBeatmap(BeatmapSet.Value); break; default: From eb14dbcd77ffc141ff717f4307df40028027d451 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 15:01:45 +0900 Subject: [PATCH 0452/1142] Initial implementation of rearrangeable playlist --- .../TestSceneDrawableRoomPlaylist.cs | 86 +++++ .../Screens/Multi/DrawableRoomPlaylist.cs | 81 ++++ .../Screens/Multi/DrawableRoomPlaylistItem.cs | 347 ++++++++++++++++++ 3 files changed, 514 insertions(+) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs create mode 100644 osu.Game/Screens/Multi/DrawableRoomPlaylist.cs create mode 100644 osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs new file mode 100644 index 0000000000..b906ce82e9 --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -0,0 +1,86 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Utils; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Screens.Multi; +using osuTK; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneDrawableRoomPlaylist : OsuTestScene + { + [Resolved] + private BeatmapManager beatmapManager { get; set; } + + [Resolved] + private RulesetStore rulesetStore { get; set; } + + private DrawableRoomPlaylist playlist; + + [Test] + public void TestItemsCanNotBeRemovedOrSelectedFromNonEditableAndNonSelectablePlaylist() + { + createPlaylist(false, false); + } + + [Test] + public void TestItemsCanBeRemovedFromEditablePlaylist() + { + createPlaylist(true, false); + } + + [Test] + public void TestItemsCanBeSelectedInSelectablePlaylist() + { + createPlaylist(false, true); + } + + [Test] + public void TestItemsCanBeSelectedAndRemovedFromEditableAndSelectablePlaylist() + { + createPlaylist(true, true); + } + + private void createPlaylist(bool allowEdit, bool allowSelection) => AddStep("create playlist", () => + { + Child = playlist = new DrawableRoomPlaylist(allowEdit, allowSelection) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(500, 300) + }; + + var beatmapSets = beatmapManager.GetAllUsableBeatmapSets(); + var rulesets = rulesetStore.AvailableRulesets.ToList(); + + for (int i = 0; i < 20; i++) + { + var set = beatmapSets[RNG.Next(0, beatmapSets.Count)]; + var beatmap = set.Beatmaps[RNG.Next(0, set.Beatmaps.Count)]; + + beatmap.BeatmapSet = set; + beatmap.Metadata = set.Metadata; + + playlist.Items.Add(new PlaylistItem + { + Beatmap = { Value = beatmap }, + Ruleset = { Value = rulesets[RNG.Next(0, rulesets.Count)] }, + RequiredMods = + { + new OsuModHardRock(), + new OsuModDoubleTime(), + new OsuModAutoplay() + } + }); + } + }); + } +} diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs new file mode 100644 index 0000000000..b42a8575ec --- /dev/null +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs @@ -0,0 +1,81 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Bindables; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.Containers; +using osu.Game.Online.Multiplayer; +using osuTK; + +namespace osu.Game.Screens.Multi +{ + public class DrawableRoomPlaylist : RearrangeableListContainer + { + public readonly Bindable SelectedItem = new Bindable(); + + private readonly bool allowEdit; + private readonly bool allowSelection; + + public DrawableRoomPlaylist(bool allowEdit, bool allowSelection) + { + this.allowEdit = allowEdit; + this.allowSelection = allowSelection; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + SelectedItem.BindValueChanged(item => + { + if (item.OldValue != null && ItemMap.TryGetValue(item.OldValue, out var oldItem)) + ((DrawableRoomPlaylistItem)oldItem).Deselect(); + + if (item.NewValue != null && ItemMap.TryGetValue(item.NewValue, out var newItem)) + ((DrawableRoomPlaylistItem)newItem).Select(); + }, true); + + Items.ItemsRemoved += items => + { + if (items.Any(i => i == SelectedItem.Value)) + SelectedItem.Value = null; + }; + } + + protected override ScrollContainer CreateScrollContainer() => new OsuScrollContainer + { + ScrollbarVisible = false + }; + + protected override FillFlowContainer> CreateListFillFlowContainer() => new FillFlowContainer> + { + LayoutDuration = 200, + LayoutEasing = Easing.OutQuint, + Spacing = new Vector2(0, 2) + }; + + protected override RearrangeableListItem CreateDrawable(PlaylistItem item) => new DrawableRoomPlaylistItem(item, allowEdit, allowSelection) + { + RequestSelection = requestSelection, + RequestDeletion = requestDeletion + }; + + private void requestSelection(PlaylistItem item) => SelectedItem.Value = item; + + private void requestDeletion(PlaylistItem item) + { + if (SelectedItem.Value == item) + { + if (Items.Count == 1) + SelectedItem.Value = null; + else + SelectedItem.Value = Items.GetNext(item) ?? Items[^2]; + } + + Items.Remove(item); + } + } +} diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs new file mode 100644 index 0000000000..d2788a5c4b --- /dev/null +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs @@ -0,0 +1,347 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Framework.Threading; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Chat; +using osu.Game.Online.Multiplayer; +using osu.Game.Overlays.Direct; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Play.HUD; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Multi +{ + public class DrawableRoomPlaylistItem : RearrangeableListItem + { + public Action RequestSelection; + public Action RequestDeletion; + + private Container maskingContainer; + private Container difficultyIconContainer; + private LinkFlowContainer beatmapText; + private LinkFlowContainer authorText; + private ItemHandle handle; + private ModDisplay modDisplay; + + private readonly Bindable beatmap = new Bindable(); + private readonly Bindable ruleset = new Bindable(); + private readonly BindableList requiredMods = new BindableList(); + + private readonly PlaylistItem item; + private readonly bool allowEdit; + private readonly bool allowSelection; + + public DrawableRoomPlaylistItem(PlaylistItem item, bool allowEdit, bool allowSelection) + : base(item) + { + this.item = item; + this.allowEdit = allowEdit; + this.allowSelection = allowSelection; + + RelativeSizeAxes = Axes.X; + Height = 50; + + beatmap.BindTo(item.Beatmap); + ruleset.BindTo(item.Ruleset); + requiredMods.BindTo(item.RequiredMods); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Alpha = allowEdit ? 1 : 0, + Child = handle = new ItemHandle + { + Size = new Vector2(12), + AlwaysPresent = true, + Alpha = 0, + }, + }, + maskingContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 10, + BorderColour = colours.Yellow, + Children = new Drawable[] + { + new Box // A transparent box that forces the border to be drawn if the panel background is opaque + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + }, + new PanelBackground + { + RelativeSizeAxes = Axes.Both, + Beatmap = { BindTarget = beatmap } + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = 8 }, + Spacing = new Vector2(8, 0), + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + difficultyIconContainer = new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + beatmapText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, + modDisplay = new ModDisplay + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.4f), + DisplayUnrankedText = false, + ExpansionMode = ExpansionMode.AlwaysExpanded + } + } + } + } + } + } + }, + new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + X = -18, + Children = new Drawable[] + { + new IconButton + { + Icon = FontAwesome.Solid.MinusSquare, + Alpha = allowEdit ? 1 : 0, + Action = () => RequestDeletion?.Invoke(Model), + }, + new PanelDownloadButton(item.Beatmap.Value.BeatmapSet) + { + Size = new Vector2(50, 30), + Alpha = allowEdit ? 0 : 1 + } + } + } + } + } + }, + }, + ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + beatmap.BindValueChanged(_ => scheduleRefresh()); + ruleset.BindValueChanged(_ => scheduleRefresh()); + + requiredMods.ItemsAdded += _ => scheduleRefresh(); + requiredMods.ItemsRemoved += _ => scheduleRefresh(); + + refresh(); + } + + private ScheduledDelegate scheduledRefresh; + + private void scheduleRefresh() + { + scheduledRefresh?.Cancel(); + scheduledRefresh = Schedule(refresh); + } + + private void refresh() + { + difficultyIconContainer.Child = new DifficultyIcon(beatmap.Value, ruleset.Value) { Size = new Vector2(32) }; + + beatmapText.Clear(); + beatmapText.AddLink(item.Beatmap.ToString(), LinkAction.OpenBeatmap, item.Beatmap.Value.OnlineBeatmapID.ToString()); + + authorText.Clear(); + + if (item.Beatmap?.Value?.Metadata?.Author != null) + { + authorText.AddText("mapped by "); + authorText.AddUserLink(item.Beatmap.Value?.Metadata.Author); + } + + modDisplay.Current.Value = requiredMods.ToArray(); + } + + protected override bool IsDraggableAt(Vector2 screenSpacePos) => handle.HandlingDrag; + + protected override bool OnHover(HoverEvent e) + { + handle.UpdateHoverState(true); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) => handle.UpdateHoverState(false); + + protected override bool OnClick(ClickEvent e) + { + if (allowSelection) + RequestSelection?.Invoke(Model); + return true; + } + + public void Select() => maskingContainer.BorderThickness = 5; + + public void Deselect() => maskingContainer.BorderThickness = 0; + + // For now, this is the same implementation as in PanelBackground, but supports a beatmap info rather than a working beatmap + private class PanelBackground : Container // todo: should be a buffered container (https://github.com/ppy/osu-framework/issues/3222) + { + public readonly Bindable Beatmap = new Bindable(); + + public PanelBackground() + { + InternalChildren = new Drawable[] + { + new UpdateableBeatmapBackgroundSprite + { + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fill, + Beatmap = { BindTarget = Beatmap } + }, + new Container + { + Depth = -1, + RelativeSizeAxes = Axes.Both, + // This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle + Shear = new Vector2(0.8f, 0), + Alpha = 0.5f, + Children = new[] + { + // The left half with no gradient applied + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Colour = Color4.Black, + Width = 0.4f, + }, + // Piecewise-linear gradient with 3 segments to make it appear smoother + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)), + Width = 0.05f, + X = 0.4f, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)), + Width = 0.2f, + X = 0.45f, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)), + Width = 0.05f, + X = 0.65f, + }, + } + } + }; + } + } + + private class ItemHandle : SpriteIcon + { + public bool HandlingDrag { get; private set; } + private bool isHovering; + + public ItemHandle() + { + Margin = new MarginPadding { Horizontal = 5 }; + + Icon = FontAwesome.Solid.Bars; + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + base.OnMouseDown(e); + + HandlingDrag = true; + UpdateHoverState(isHovering); + + return false; + } + + protected override void OnMouseUp(MouseUpEvent e) + { + base.OnMouseUp(e); + + HandlingDrag = false; + UpdateHoverState(isHovering); + } + + public void UpdateHoverState(bool hovering) + { + isHovering = hovering; + + if (isHovering || HandlingDrag) + this.FadeIn(100); + else + this.FadeOut(100); + } + } + } +} From aa7efe6141e0ca80c3a908e3902b1dba5c95d4e9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:26:55 +0900 Subject: [PATCH 0453/1142] Fix tests potentially failing due to timing issues --- .../Online/TestSceneOnlineViewContainer.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index 39b9fd71d0..d656600a18 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -61,8 +61,8 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to online", () => ((DummyAPIAccess)API).State = APIState.Online); - AddAssert("children are visible", () => onlineView.ViewTarget.IsPresent); - AddAssert("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); + AddUntilStep("children are visible", () => onlineView.ViewTarget.IsPresent); + AddUntilStep("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); } [Test] @@ -70,8 +70,8 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to offline", () => ((DummyAPIAccess)API).State = APIState.Offline); - AddAssert("children are hidden", () => !onlineView.ViewTarget.IsPresent); - AddAssert("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); + AddUntilStep("children are not visible", () => !onlineView.ViewTarget.IsPresent); + AddUntilStep("loading animation is not visible", () => !onlineView.LoadingAnimation.IsPresent); } [Test] @@ -79,8 +79,8 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to connecting", () => ((DummyAPIAccess)API).State = APIState.Connecting); - AddAssert("children are hidden", () => !onlineView.ViewTarget.IsPresent); - AddAssert("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); + AddUntilStep("children are not visible", () => !onlineView.ViewTarget.IsPresent); + AddUntilStep("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); } [Test] @@ -88,8 +88,8 @@ namespace osu.Game.Tests.Visual.Online { AddStep("set status to failing", () => ((DummyAPIAccess)API).State = APIState.Failing); - AddAssert("children are hidden", () => !onlineView.ViewTarget.IsPresent); - AddAssert("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); + AddUntilStep("children are not visible", () => !onlineView.ViewTarget.IsPresent); + AddUntilStep("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); } } } From c34f1f40eafd8e06f6a7009fc4661105e40664cc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:27:09 +0900 Subject: [PATCH 0454/1142] Fix test text not being centered --- osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index d656600a18..2bd0d59632 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -6,6 +6,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Online; @@ -38,6 +39,7 @@ namespace osu.Game.Tests.Visual.Online : base(@"Please sign in to view dummy test content") { RelativeSizeAxes = Axes.Both; + Children = new Drawable[] { new Box @@ -48,7 +50,7 @@ namespace osu.Game.Tests.Visual.Online new OsuSpriteText { Text = "dummy online content", - RelativeSizeAxes = Axes.Both, + Font = OsuFont.Default.With(size: 40), Anchor = Anchor.Centre, Origin = Anchor.Centre, } From b86b5e9adb3369f675346d0ef2b22429d87c7a61 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:27:39 +0900 Subject: [PATCH 0455/1142] Move nested class to bottom of file --- .../Online/TestSceneOnlineViewContainer.cs | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs index 2bd0d59632..3c2735ca56 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneOnlineViewContainer.cs @@ -29,35 +29,6 @@ namespace osu.Game.Tests.Visual.Online }; } - private class TestOnlineViewContainer : OnlineViewContainer - { - public new LoadingAnimation LoadingAnimation => base.LoadingAnimation; - - public CompositeDrawable ViewTarget => base.Content; - - public TestOnlineViewContainer() - : base(@"Please sign in to view dummy test content") - { - RelativeSizeAxes = Axes.Both; - - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Blue.Opacity(0.8f), - }, - new OsuSpriteText - { - Text = "dummy online content", - Font = OsuFont.Default.With(size: 40), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } - }; - } - } - [Test] public void TestOnlineStateVisibility() { @@ -93,5 +64,34 @@ namespace osu.Game.Tests.Visual.Online AddUntilStep("children are not visible", () => !onlineView.ViewTarget.IsPresent); AddUntilStep("loading animation is visible", () => onlineView.LoadingAnimation.IsPresent); } + + private class TestOnlineViewContainer : OnlineViewContainer + { + public new LoadingAnimation LoadingAnimation => base.LoadingAnimation; + + public CompositeDrawable ViewTarget => base.Content; + + public TestOnlineViewContainer() + : base(@"Please sign in to view dummy test content") + { + RelativeSizeAxes = Axes.Both; + + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Blue.Opacity(0.8f), + }, + new OsuSpriteText + { + Text = "dummy online content", + Font = OsuFont.Default.With(size: 40), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }; + } + } } } From 4d5abab2ee0b39704f0e5b91bf41e01e7b50f83b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:29:50 +0900 Subject: [PATCH 0456/1142] Remove unnecessary content private storage --- osu.Game/Online/OnlineViewContainer.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 2a9aa60e2d..0ffb342bfc 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -21,8 +21,7 @@ namespace osu.Game.Online protected const double TRANSFORM_TIME = 300.0; - private readonly Container viewContent; - protected override Container Content => viewContent; + protected override Container Content { get; } [Resolved] protected IAPIProvider API { get; private set; } @@ -31,7 +30,7 @@ namespace osu.Game.Online { InternalChildren = new Drawable[] { - viewContent = new Container + Content = new Container { RelativeSizeAxes = Axes.Both, }, @@ -48,21 +47,21 @@ namespace osu.Game.Online switch (state) { case APIState.Offline: - PopContentOut(viewContent); + PopContentOut(Content); placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * TRANSFORM_TIME, Easing.OutQuint); placeholder.FadeInFromZero(2 * TRANSFORM_TIME, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Online: - PopContentIn(viewContent); + PopContentIn(Content); placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Failing: case APIState.Connecting: - PopContentOut(viewContent); + PopContentOut(Content); LoadingAnimation.Show(); placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); break; From 7e6c194d4a9c9f04712db293bc39f5f6baf201f5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:34:46 +0900 Subject: [PATCH 0457/1142] Add missing xmldoc --- osu.Game/Online/OnlineViewContainer.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 0ffb342bfc..50b4820d15 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -68,8 +68,14 @@ namespace osu.Game.Online } } + /// + /// Applies a transform to the online content to make it hidden. + /// protected virtual void PopContentOut(Drawable content) => content.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); + /// + /// Applies a transform to the online content to make it visible. + /// protected virtual void PopContentIn(Drawable content) => content.FadeIn(TRANSFORM_TIME, Easing.OutQuint); protected override void LoadComplete() From 6f1cecd86f7fc4efa6e00c0da8e44972f332f880 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:35:39 +0900 Subject: [PATCH 0458/1142] Move LoadComplete up in method --- osu.Game/Online/OnlineViewContainer.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 50b4820d15..3b2243c97a 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -42,6 +42,12 @@ namespace osu.Game.Online }; } + protected override void LoadComplete() + { + API?.Register(this); + base.LoadComplete(); + } + public virtual void APIStateChanged(IAPIProvider api, APIState state) { switch (state) @@ -78,12 +84,6 @@ namespace osu.Game.Online ///
protected virtual void PopContentIn(Drawable content) => content.FadeIn(TRANSFORM_TIME, Easing.OutQuint); - protected override void LoadComplete() - { - API?.Register(this); - base.LoadComplete(); - } - protected override void Dispose(bool isDisposing) { API?.Unregister(this); From edf9cfc8635580d7e40c188828a2533ec5b824ab Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:36:06 +0900 Subject: [PATCH 0459/1142] API can't be null on load --- osu.Game/Online/OnlineViewContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 3b2243c97a..b16fbb7aed 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -44,7 +44,7 @@ namespace osu.Game.Online protected override void LoadComplete() { - API?.Register(this); + API.Register(this); base.LoadComplete(); } From eb75d26c8f5c3365fda1965401f4df77fb900078 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 15:36:16 +0900 Subject: [PATCH 0460/1142] Extract common rearrangeable list design --- .../OsuRearrangeableListContainer.cs | 26 +++ .../Containers/OsuRearrangeableListItem.cs | 149 ++++++++++++++++++ osu.Game/Overlays/Music/Playlist.cs | 12 +- osu.Game/Overlays/Music/PlaylistItem.cs | 121 ++------------ 4 files changed, 190 insertions(+), 118 deletions(-) create mode 100644 osu.Game/Graphics/Containers/OsuRearrangeableListContainer.cs create mode 100644 osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs diff --git a/osu.Game/Graphics/Containers/OsuRearrangeableListContainer.cs b/osu.Game/Graphics/Containers/OsuRearrangeableListContainer.cs new file mode 100644 index 0000000000..47aed1c500 --- /dev/null +++ b/osu.Game/Graphics/Containers/OsuRearrangeableListContainer.cs @@ -0,0 +1,26 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; + +namespace osu.Game.Graphics.Containers +{ + public abstract class OsuRearrangeableListContainer : RearrangeableListContainer + { + /// + /// Whether any item is currently being dragged. Used to hide other items' drag handles. + /// + private readonly BindableBool playlistDragActive = new BindableBool(); + + protected override ScrollContainer CreateScrollContainer() => new OsuScrollContainer(); + + protected sealed override RearrangeableListItem CreateDrawable(TModel item) => CreateOsuDrawable(item).With(d => + { + d.PlaylistDragActive.BindTo(playlistDragActive); + }); + + protected abstract OsuRearrangeableListItem CreateOsuDrawable(TModel item); + } +} diff --git a/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs b/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs new file mode 100644 index 0000000000..f75a3330e2 --- /dev/null +++ b/osu.Game/Graphics/Containers/OsuRearrangeableListItem.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 osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Graphics.Containers +{ + public abstract class OsuRearrangeableListItem : RearrangeableListItem + { + public const float FADE_DURATION = 100; + + /// + /// Whether any item is currently being dragged. Used to hide other items' drag handles. + /// + public readonly BindableBool PlaylistDragActive = new BindableBool(); + + private Color4 handleColour = Color4.White; + + protected Color4 HandleColour + { + get => handleColour; + set + { + if (handleColour == value) + return; + + handleColour = value; + + if (handle != null) + handle.Colour = value; + } + } + + private PlaylistItemHandle handle; + + protected OsuRearrangeableListItem(TModel item) + : base(item) + { + RelativeSizeAxes = Axes.X; + AutoSizeAxes = Axes.Y; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Content = new[] + { + new[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 5 }, + Child = handle = new PlaylistItemHandle + { + Size = new Vector2(12), + Colour = HandleColour, + AlwaysPresent = true, + Alpha = 0 + } + }, + CreateContent() + } + }, + ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, + RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } + }; + } + + protected override bool OnDragStart(DragStartEvent e) + { + if (!base.OnDragStart(e)) + return false; + + PlaylistDragActive.Value = true; + return true; + } + + protected override void OnDragEnd(DragEndEvent e) + { + PlaylistDragActive.Value = false; + base.OnDragEnd(e); + } + + protected override bool IsDraggableAt(Vector2 screenSpacePos) => handle.HandlingDrag; + + protected override bool OnHover(HoverEvent e) + { + handle.UpdateHoverState(IsDragged || !PlaylistDragActive.Value); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) => handle.UpdateHoverState(false); + + protected abstract Drawable CreateContent(); + + private class PlaylistItemHandle : SpriteIcon + { + public bool HandlingDrag { get; private set; } + private bool isHovering; + + public PlaylistItemHandle() + { + Icon = FontAwesome.Solid.Bars; + } + + protected override bool OnMouseDown(MouseDownEvent e) + { + base.OnMouseDown(e); + + HandlingDrag = true; + UpdateHoverState(isHovering); + + return false; + } + + protected override void OnMouseUp(MouseUpEvent e) + { + base.OnMouseUp(e); + + HandlingDrag = false; + UpdateHoverState(isHovering); + } + + public void UpdateHoverState(bool hovering) + { + isHovering = hovering; + + if (isHovering || HandlingDrag) + this.FadeIn(FADE_DURATION); + else + this.FadeOut(FADE_DURATION); + } + } + } +} diff --git a/osu.Game/Overlays/Music/Playlist.cs b/osu.Game/Overlays/Music/Playlist.cs index 1ba568443d..621a533dd6 100644 --- a/osu.Game/Overlays/Music/Playlist.cs +++ b/osu.Game/Overlays/Music/Playlist.cs @@ -12,17 +12,12 @@ using osuTK; namespace osu.Game.Overlays.Music { - public class Playlist : RearrangeableListContainer + public class Playlist : OsuRearrangeableListContainer { public Action RequestSelection; public readonly Bindable SelectedSet = new Bindable(); - /// - /// Whether any item is currently being dragged. Used to hide other items' drag handles. - /// - private readonly BindableBool playlistDragActive = new BindableBool(); - public new MarginPadding Padding { get => base.Padding; @@ -33,15 +28,12 @@ namespace osu.Game.Overlays.Music public BeatmapSetInfo FirstVisibleSet => Items.FirstOrDefault(i => ((PlaylistItem)ItemMap[i]).MatchingFilter); - protected override RearrangeableListItem CreateDrawable(BeatmapSetInfo item) => new PlaylistItem(item) + protected override OsuRearrangeableListItem CreateOsuDrawable(BeatmapSetInfo item) => new PlaylistItem(item) { SelectedSet = { BindTarget = SelectedSet }, - PlaylistDragActive = { BindTarget = playlistDragActive }, RequestSelection = set => RequestSelection?.Invoke(set) }; - protected override ScrollContainer CreateScrollContainer() => new OsuScrollContainer(); - protected override FillFlowContainer> CreateListFillFlowContainer() => new SearchContainer> { Spacing = new Vector2(0, 3), diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 0569261867..8cafbc694a 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -14,36 +14,27 @@ using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osuTK; using osuTK.Graphics; namespace osu.Game.Overlays.Music { - public class PlaylistItem : RearrangeableListItem, IFilterable + public class PlaylistItem : OsuRearrangeableListItem, IFilterable { - private const float fade_duration = 100; - - public BindableBool PlaylistDragActive = new BindableBool(); - public readonly Bindable SelectedSet = new Bindable(); public Action RequestSelection; - private PlaylistItemHandle handle; private TextFlowContainer text; private IEnumerable titleSprites; private ILocalisedBindableString titleBind; private ILocalisedBindableString artistBind; - private Color4 hoverColour; + private Color4 selectedColour; private Color4 artistColour; public PlaylistItem(BeatmapSetInfo item) : base(item) { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - Padding = new MarginPadding { Left = 5 }; FilterTerms = item.Metadata.SearchableTerms; @@ -52,42 +43,12 @@ namespace osu.Game.Overlays.Music [BackgroundDependencyLoader] private void load(OsuColour colours, LocalisationManager localisation) { - hoverColour = colours.Yellow; + selectedColour = colours.Yellow; artistColour = colours.Gray9; - - InternalChild = new GridContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Content = new[] - { - new Drawable[] - { - handle = new PlaylistItemHandle - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Size = new Vector2(12), - Colour = colours.Gray5, - AlwaysPresent = true, - Alpha = 0 - }, - text = new OsuTextFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Left = 5 }, - }, - } - }, - ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, - RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } - }; + 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))); - - artistBind.BindValueChanged(_ => recreateText(), true); } protected override void LoadComplete() @@ -100,10 +61,18 @@ namespace osu.Game.Overlays.Music return; foreach (Drawable s in titleSprites) - s.FadeColour(set.NewValue == Model ? hoverColour : Color4.White, fade_duration); + s.FadeColour(set.NewValue == Model ? selectedColour : Color4.White, FADE_DURATION); }, true); + + artistBind.BindValueChanged(_ => recreateText(), true); } + protected override Drawable CreateContent() => text = new OsuTextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + }; + private void recreateText() { text.Clear(); @@ -125,31 +94,6 @@ namespace osu.Game.Overlays.Music return true; } - protected override bool OnDragStart(DragStartEvent e) - { - if (!base.OnDragStart(e)) - return false; - - PlaylistDragActive.Value = true; - return true; - } - - protected override void OnDragEnd(DragEndEvent e) - { - PlaylistDragActive.Value = false; - base.OnDragEnd(e); - } - - protected override bool IsDraggableAt(Vector2 screenSpacePos) => handle.HandlingDrag; - - protected override bool OnHover(HoverEvent e) - { - handle.UpdateHoverState(IsDragged || !PlaylistDragActive.Value); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) => handle.UpdateHoverState(false); - public IEnumerable FilterTerms { get; } private bool matching = true; @@ -168,44 +112,5 @@ namespace osu.Game.Overlays.Music } public bool FilteringActive { get; set; } - - private class PlaylistItemHandle : SpriteIcon - { - public bool HandlingDrag { get; private set; } - private bool isHovering; - - public PlaylistItemHandle() - { - Icon = FontAwesome.Solid.Bars; - } - - protected override bool OnMouseDown(MouseDownEvent e) - { - base.OnMouseDown(e); - - HandlingDrag = true; - UpdateHoverState(isHovering); - - return false; - } - - protected override void OnMouseUp(MouseUpEvent e) - { - base.OnMouseUp(e); - - HandlingDrag = false; - UpdateHoverState(isHovering); - } - - public void UpdateHoverState(bool hovering) - { - isHovering = hovering; - - if (isHovering || HandlingDrag) - this.FadeIn(fade_duration); - else - this.FadeOut(fade_duration); - } - } } } From 5e871f9838b16f5319cfa5886dc4a81c93137641 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 15:36:47 +0900 Subject: [PATCH 0461/1142] Make room playlist use the common rearrangeable design --- .../TestSceneDrawableRoomPlaylist.cs | 16 +- .../Screens/Multi/DrawableRoomPlaylist.cs | 10 +- .../Screens/Multi/DrawableRoomPlaylistItem.cs | 263 +++++++----------- 3 files changed, 112 insertions(+), 177 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index b906ce82e9..393fd281d4 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.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; +using System.Collections.Generic; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; @@ -17,6 +19,12 @@ namespace osu.Game.Tests.Visual.Multiplayer { public class TestSceneDrawableRoomPlaylist : OsuTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(DrawableRoomPlaylist), + typeof(DrawableRoomPlaylistItem) + }; + [Resolved] private BeatmapManager beatmapManager { get; set; } @@ -26,25 +34,25 @@ namespace osu.Game.Tests.Visual.Multiplayer private DrawableRoomPlaylist playlist; [Test] - public void TestItemsCanNotBeRemovedOrSelectedFromNonEditableAndNonSelectablePlaylist() + public void TestNonEditableNonSelectable() { createPlaylist(false, false); } [Test] - public void TestItemsCanBeRemovedFromEditablePlaylist() + public void TestEditable() { createPlaylist(true, false); } [Test] - public void TestItemsCanBeSelectedInSelectablePlaylist() + public void TestSelectable() { createPlaylist(false, true); } [Test] - public void TestItemsCanBeSelectedAndRemovedFromEditableAndSelectablePlaylist() + public void TestEditableSelectable() { createPlaylist(true, true); } diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs index b42a8575ec..021a8ca176 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs @@ -12,7 +12,7 @@ using osuTK; namespace osu.Game.Screens.Multi { - public class DrawableRoomPlaylist : RearrangeableListContainer + public class DrawableRoomPlaylist : OsuRearrangeableListContainer { public readonly Bindable SelectedItem = new Bindable(); @@ -45,10 +45,10 @@ namespace osu.Game.Screens.Multi }; } - protected override ScrollContainer CreateScrollContainer() => new OsuScrollContainer + protected override ScrollContainer CreateScrollContainer() => base.CreateScrollContainer().With(d => { - ScrollbarVisible = false - }; + d.ScrollbarVisible = false; + }); protected override FillFlowContainer> CreateListFillFlowContainer() => new FillFlowContainer> { @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Multi Spacing = new Vector2(0, 2) }; - protected override RearrangeableListItem CreateDrawable(PlaylistItem item) => new DrawableRoomPlaylistItem(item, allowEdit, allowSelection) + protected override OsuRearrangeableListItem CreateOsuDrawable(PlaylistItem item) => new DrawableRoomPlaylistItem(item, allowEdit, allowSelection) { RequestSelection = requestSelection, RequestDeletion = requestDeletion diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs index d2788a5c4b..2bc593d779 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; @@ -28,7 +29,7 @@ using osuTK.Graphics; namespace osu.Game.Screens.Multi { - public class DrawableRoomPlaylistItem : RearrangeableListItem + public class DrawableRoomPlaylistItem : OsuRearrangeableListItem { public Action RequestSelection; public Action RequestDeletion; @@ -37,7 +38,6 @@ namespace osu.Game.Screens.Multi private Container difficultyIconContainer; private LinkFlowContainer beatmapText; private LinkFlowContainer authorText; - private ItemHandle handle; private ModDisplay modDisplay; private readonly Bindable beatmap = new Bindable(); @@ -55,9 +55,6 @@ namespace osu.Game.Screens.Multi this.allowEdit = allowEdit; this.allowSelection = allowSelection; - RelativeSizeAxes = Axes.X; - Height = 50; - beatmap.BindTo(item.Beatmap); ruleset.BindTo(item.Ruleset); requiredMods.BindTo(item.RequiredMods); @@ -66,118 +63,10 @@ namespace osu.Game.Screens.Multi [BackgroundDependencyLoader] private void load(OsuColour colours) { - InternalChild = new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Alpha = allowEdit ? 1 : 0, - Child = handle = new ItemHandle - { - Size = new Vector2(12), - AlwaysPresent = true, - Alpha = 0, - }, - }, - maskingContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Masking = true, - CornerRadius = 10, - BorderColour = colours.Yellow, - Children = new Drawable[] - { - new Box // A transparent box that forces the border to be drawn if the panel background is opaque - { - RelativeSizeAxes = Axes.Both, - Alpha = 0, - AlwaysPresent = true - }, - new PanelBackground - { - RelativeSizeAxes = Axes.Both, - Beatmap = { BindTarget = beatmap } - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = 8 }, - Spacing = new Vector2(8, 0), - Direction = FillDirection.Horizontal, - Children = new Drawable[] - { - difficultyIconContainer = new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - beatmapText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10, 0), - Children = new Drawable[] - { - authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, - modDisplay = new ModDisplay - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.4f), - DisplayUnrankedText = false, - ExpansionMode = ExpansionMode.AlwaysExpanded - } - } - } - } - } - } - }, - new Container - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - AutoSizeAxes = Axes.Both, - X = -18, - Children = new Drawable[] - { - new IconButton - { - Icon = FontAwesome.Solid.MinusSquare, - Alpha = allowEdit ? 1 : 0, - Action = () => RequestDeletion?.Invoke(Model), - }, - new PanelDownloadButton(item.Beatmap.Value.BeatmapSet) - { - Size = new Vector2(50, 30), - Alpha = allowEdit ? 0 : 1 - } - } - } - } - } - }, - }, - ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, - }; + if (!allowEdit) + HandleColour = HandleColour.Opacity(0); + + maskingContainer.BorderColour = colours.Yellow; } protected override void LoadComplete() @@ -193,6 +82,95 @@ namespace osu.Game.Screens.Multi refresh(); } + protected override Drawable CreateContent() => maskingContainer = new Container + { + RelativeSizeAxes = Axes.X, + Height = 50, + Masking = true, + CornerRadius = 10, + Children = new Drawable[] + { + new Box // A transparent box that forces the border to be drawn if the panel background is opaque + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + AlwaysPresent = true + }, + new PanelBackground + { + RelativeSizeAxes = Axes.Both, + Beatmap = { BindTarget = beatmap } + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = 8 }, + Spacing = new Vector2(8, 0), + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + difficultyIconContainer = new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + beatmapText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, + modDisplay = new ModDisplay + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Scale = new Vector2(0.4f), + DisplayUnrankedText = false, + ExpansionMode = ExpansionMode.AlwaysExpanded + } + } + } + } + } + } + }, + new Container + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + X = -18, + Children = new Drawable[] + { + new IconButton + { + Icon = FontAwesome.Solid.MinusSquare, + Alpha = allowEdit ? 1 : 0, + Action = () => RequestDeletion?.Invoke(Model), + }, + new PanelDownloadButton(item.Beatmap.Value.BeatmapSet) + { + Size = new Vector2(50, 30), + Alpha = allowEdit ? 0 : 1 + } + } + } + } + }; + private ScheduledDelegate scheduledRefresh; private void scheduleRefresh() @@ -219,16 +197,6 @@ namespace osu.Game.Screens.Multi modDisplay.Current.Value = requiredMods.ToArray(); } - protected override bool IsDraggableAt(Vector2 screenSpacePos) => handle.HandlingDrag; - - protected override bool OnHover(HoverEvent e) - { - handle.UpdateHoverState(true); - return base.OnHover(e); - } - - protected override void OnHoverLost(HoverLostEvent e) => handle.UpdateHoverState(false); - protected override bool OnClick(ClickEvent e) { if (allowSelection) @@ -302,46 +270,5 @@ namespace osu.Game.Screens.Multi }; } } - - private class ItemHandle : SpriteIcon - { - public bool HandlingDrag { get; private set; } - private bool isHovering; - - public ItemHandle() - { - Margin = new MarginPadding { Horizontal = 5 }; - - Icon = FontAwesome.Solid.Bars; - } - - protected override bool OnMouseDown(MouseDownEvent e) - { - base.OnMouseDown(e); - - HandlingDrag = true; - UpdateHoverState(isHovering); - - return false; - } - - protected override void OnMouseUp(MouseUpEvent e) - { - base.OnMouseUp(e); - - HandlingDrag = false; - UpdateHoverState(isHovering); - } - - public void UpdateHoverState(bool hovering) - { - isHovering = hovering; - - if (isHovering || HandlingDrag) - this.FadeIn(100); - else - this.FadeOut(100); - } - } } } From 720ceca78a3cdd5c90acf75684c8a0d65af2f67b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:38:47 +0900 Subject: [PATCH 0462/1142] Final tidy-up pass --- osu.Game/Online/OnlineViewContainer.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index b16fbb7aed..83fbff733f 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -19,7 +19,7 @@ namespace osu.Game.Online private readonly Placeholder placeholder; protected readonly LoadingAnimation LoadingAnimation; - protected const double TRANSFORM_TIME = 300.0; + private const double transform_duration = 300; protected override Container Content { get; } @@ -44,8 +44,9 @@ namespace osu.Game.Online protected override void LoadComplete() { - API.Register(this); base.LoadComplete(); + + API.Register(this); } public virtual void APIStateChanged(IAPIProvider api, APIState state) @@ -54,14 +55,14 @@ namespace osu.Game.Online { case APIState.Offline: PopContentOut(Content); - placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * TRANSFORM_TIME, Easing.OutQuint); - placeholder.FadeInFromZero(2 * TRANSFORM_TIME, Easing.OutQuint); + placeholder.ScaleTo(0.8f).Then().ScaleTo(1, 3 * transform_duration, Easing.OutQuint); + placeholder.FadeInFromZero(2 * transform_duration, Easing.OutQuint); LoadingAnimation.Hide(); break; case APIState.Online: PopContentIn(Content); - placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); + placeholder.FadeOut(transform_duration / 2, Easing.OutQuint); LoadingAnimation.Hide(); break; @@ -69,7 +70,7 @@ namespace osu.Game.Online case APIState.Connecting: PopContentOut(Content); LoadingAnimation.Show(); - placeholder.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); + placeholder.FadeOut(transform_duration / 2, Easing.OutQuint); break; } } @@ -77,12 +78,12 @@ namespace osu.Game.Online /// /// Applies a transform to the online content to make it hidden. /// - protected virtual void PopContentOut(Drawable content) => content.FadeOut(TRANSFORM_TIME / 2, Easing.OutQuint); + protected virtual void PopContentOut(Drawable content) => content.FadeOut(transform_duration / 2, Easing.OutQuint); /// /// Applies a transform to the online content to make it visible. /// - protected virtual void PopContentIn(Drawable content) => content.FadeIn(TRANSFORM_TIME, Easing.OutQuint); + protected virtual void PopContentIn(Drawable content) => content.FadeIn(transform_duration, Easing.OutQuint); protected override void Dispose(bool isDisposing) { From a75715607b3882c14ccab7984cc9ee4a97534522 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:41:46 +0900 Subject: [PATCH 0463/1142] Move drawable load to asynchronous context --- osu.Game/Online/OnlineViewContainer.cs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/osu.Game/Online/OnlineViewContainer.cs b/osu.Game/Online/OnlineViewContainer.cs index 83fbff733f..689c1c0afb 100644 --- a/osu.Game/Online/OnlineViewContainer.cs +++ b/osu.Game/Online/OnlineViewContainer.cs @@ -16,24 +16,30 @@ namespace osu.Game.Online ///
public abstract class OnlineViewContainer : Container, IOnlineComponent { - private readonly Placeholder placeholder; - protected readonly LoadingAnimation LoadingAnimation; + protected LoadingAnimation LoadingAnimation { get; private set; } + + protected override Container Content { get; } = new Container { RelativeSizeAxes = Axes.Both }; + + private readonly string placeholderMessage; + + private Placeholder placeholder; private const double transform_duration = 300; - protected override Container Content { get; } - [Resolved] protected IAPIProvider API { get; private set; } protected OnlineViewContainer(string placeholderMessage) + { + this.placeholderMessage = placeholderMessage; + } + + [BackgroundDependencyLoader] + private void load() { InternalChildren = new Drawable[] { - Content = new Container - { - RelativeSizeAxes = Axes.Both, - }, + Content, placeholder = new LoginPlaceholder(placeholderMessage), LoadingAnimation = new LoadingAnimation { From 9cbb37b682fe35508c1aa030b4a97dad3ece41f4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 15:59:59 +0900 Subject: [PATCH 0464/1142] Fix bindable being created far too late in construction --- osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs index 7ebc26ebfb..28600ef55b 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs @@ -30,7 +30,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private readonly Drawable cursorTrail; - public Bindable CursorScale; + public Bindable CursorScale = new BindableFloat(1); + private Bindable userCursorScale; private Bindable autoCursorScale; @@ -57,6 +58,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor protected override void LoadComplete() { + base.LoadComplete(); + showTrail.BindValueChanged(v => cursorTrail.FadeTo(v.NewValue ? 1 : 0, 200), true); userCursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); @@ -65,7 +68,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor autoCursorScale = config.GetBindable(OsuSetting.AutoCursorSize); autoCursorScale.ValueChanged += _ => calculateScale(); - CursorScale = new BindableFloat(); CursorScale.ValueChanged += e => { var newScale = new Vector2(e.NewValue); @@ -75,8 +77,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor }; calculateScale(); - - base.LoadComplete(); } /// From 1909ea2bd3a17cd3d6a877dd4b01c1585d4f631c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 16:09:15 +0900 Subject: [PATCH 0465/1142] Add a way to hide the drag handle --- .../Containers/OsuRearrangeableListItem.cs | 17 +++++++++++++++-- .../Screens/Multi/DrawableRoomPlaylistItem.cs | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs b/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs index f75a3330e2..29553954fe 100644 --- a/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs +++ b/osu.Game/Graphics/Containers/OsuRearrangeableListItem.cs @@ -23,6 +23,9 @@ namespace osu.Game.Graphics.Containers private Color4 handleColour = Color4.White; + /// + /// The colour of the drag handle. + /// protected Color4 HandleColour { get => handleColour; @@ -38,6 +41,11 @@ namespace osu.Game.Graphics.Containers } } + /// + /// Whether the drag handle should be shown. + /// + protected virtual bool ShowDragHandle => true; + private PlaylistItemHandle handle; protected OsuRearrangeableListItem(TModel item) @@ -50,6 +58,8 @@ namespace osu.Game.Graphics.Containers [BackgroundDependencyLoader] private void load() { + Container handleContainer; + InternalChild = new GridContainer { RelativeSizeAxes = Axes.X, @@ -58,7 +68,7 @@ namespace osu.Game.Graphics.Containers { new[] { - new Container + handleContainer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -78,6 +88,9 @@ namespace osu.Game.Graphics.Containers ColumnDimensions = new[] { new Dimension(GridSizeMode.AutoSize) }, RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) } }; + + if (!ShowDragHandle) + handleContainer.Alpha = 0; } protected override bool OnDragStart(DragStartEvent e) @@ -107,7 +120,7 @@ namespace osu.Game.Graphics.Containers protected abstract Drawable CreateContent(); - private class PlaylistItemHandle : SpriteIcon + public class PlaylistItemHandle : SpriteIcon { public bool HandlingDrag { get; private set; } private bool isHovering; diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs index 2bc593d779..7156839dfc 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs @@ -34,6 +34,8 @@ namespace osu.Game.Screens.Multi public Action RequestSelection; public Action RequestDeletion; + protected override bool ShowDragHandle => allowEdit; + private Container maskingContainer; private Container difficultyIconContainer; private LinkFlowContainer beatmapText; From d6768bba628c2feafac4c28b5719cc83ed83e48a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 16:09:30 +0900 Subject: [PATCH 0466/1142] Make test playlist items unique --- .../Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index 393fd281d4..d43bf9edea 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -79,6 +79,7 @@ namespace osu.Game.Tests.Visual.Multiplayer playlist.Items.Add(new PlaylistItem { + ID = i, Beatmap = { Value = beatmap }, Ruleset = { Value = rulesets[RNG.Next(0, rulesets.Count)] }, RequiredMods = From afd3e4604b5649e4f27e52afa6869e64249e8e2a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 16:48:23 +0900 Subject: [PATCH 0467/1142] Fix race condition causing selection to be reset incorrectly --- osu.Game/Screens/Multi/DrawableRoomPlaylist.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs index 021a8ca176..01f173db4e 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using osu.Framework.Bindables; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; @@ -38,11 +37,11 @@ namespace osu.Game.Screens.Multi ((DrawableRoomPlaylistItem)newItem).Select(); }, true); - Items.ItemsRemoved += items => + Items.ItemsRemoved += items => Schedule(() => { - if (items.Any(i => i == SelectedItem.Value)) + if (!Items.Contains(SelectedItem.Value)) SelectedItem.Value = null; - }; + }); } protected override ScrollContainer CreateScrollContainer() => base.CreateScrollContainer().With(d => From 6a466ea2f584e8c8c74ed8e92414ea00c5532dce Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 16:48:30 +0900 Subject: [PATCH 0468/1142] Improve test cases --- .../TestSceneDrawableRoomPlaylist.cs | 148 +++++++++++++++++- 1 file changed, 147 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index d43bf9edea..267496bba2 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -7,17 +7,22 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Multi; using osuTK; +using osuTK.Input; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneDrawableRoomPlaylist : OsuTestScene + public class TestSceneDrawableRoomPlaylist : ManualInputManagerTestScene { public override IReadOnlyList RequiredTypes => new[] { @@ -37,26 +42,167 @@ namespace osu.Game.Tests.Visual.Multiplayer public void TestNonEditableNonSelectable() { createPlaylist(false, false); + + moveToItem(0); + assertHandleVisibility(0, false); + assertDeleteButtonVisibility(0, false); } [Test] public void TestEditable() { createPlaylist(true, false); + + moveToItem(0); + assertHandleVisibility(0, true); + assertDeleteButtonVisibility(0, true); } [Test] public void TestSelectable() { createPlaylist(false, true); + + moveToItem(0); + assertHandleVisibility(0, false); + assertDeleteButtonVisibility(0, false); + + AddStep("click", () => InputManager.Click(MouseButton.Left)); + + AddAssert("item 0 is selected", () => playlist.SelectedItem.Value == playlist.Items[0]); } [Test] public void TestEditableSelectable() { createPlaylist(true, true); + + moveToItem(0); + assertHandleVisibility(0, true); + assertDeleteButtonVisibility(0, true); + + AddStep("click", () => InputManager.Click(MouseButton.Left)); + + AddAssert("item 0 is selected", () => playlist.SelectedItem.Value == playlist.Items[0]); } + [Test] + public void TestSelectionNotLostAfterRearrangement() + { + createPlaylist(true, true); + + moveToItem(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + + moveToDragger(0); + AddStep("begin drag", () => InputManager.PressButton(MouseButton.Left)); + moveToDragger(1, new Vector2(0, 5)); + AddStep("end drag", () => InputManager.ReleaseButton(MouseButton.Left)); + + AddAssert("item 1 is selected", () => playlist.SelectedItem.Value == playlist.Items[1]); + } + + [Test] + public void TestItemRemovedOnDeletion() + { + PlaylistItem selectedItem = null; + + createPlaylist(true, true); + + moveToItem(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + AddStep("retrieve selection", () => selectedItem = playlist.SelectedItem.Value); + + moveToDeleteButton(0); + AddStep("click delete button", () => InputManager.Click(MouseButton.Left)); + + AddAssert("item removed", () => !playlist.Items.Contains(selectedItem)); + } + + [Test] + public void TestNextItemSelectedAfterDeletion() + { + createPlaylist(true, true); + + moveToItem(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + + moveToDeleteButton(0); + AddStep("click delete button", () => InputManager.Click(MouseButton.Left)); + + AddAssert("item 0 is selected", () => playlist.SelectedItem.Value == playlist.Items[0]); + } + + [Test] + public void TestLastItemSelectedAfterLastItemDeleted() + { + createPlaylist(true, true); + + AddWaitStep("wait for flow", 5); // Items may take 1 update frame to flow. A wait count of 5 is guaranteed to result in the flow being updated as desired. + AddStep("scroll to bottom", () => playlist.ChildrenOfType>().First().ScrollToEnd(false)); + + moveToItem(19); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + + moveToDeleteButton(19); + AddStep("click delete button", () => InputManager.Click(MouseButton.Left)); + + AddAssert("item 18 is selected", () => playlist.SelectedItem.Value == playlist.Items[18]); + } + + [Test] + public void TestSelectionResetWhenAllItemsDeleted() + { + createPlaylist(true, true); + + AddStep("remove all but one item", () => + { + playlist.Items.RemoveRange(1, playlist.Items.Count - 1); + }); + + moveToItem(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + moveToDeleteButton(0); + AddStep("click delete button", () => InputManager.Click(MouseButton.Left)); + + AddAssert("selected item is null", () => playlist.SelectedItem.Value == null); + } + + // Todo: currently not possible due to bindable list shortcomings (https://github.com/ppy/osu-framework/issues/3081) + // [Test] + public void TestNextItemSelectedAfterExternalDeletion() + { + createPlaylist(true, true); + + moveToItem(0); + AddStep("click", () => InputManager.Click(MouseButton.Left)); + AddStep("remove item 0", () => playlist.Items.RemoveAt(0)); + + AddAssert("item 0 is selected", () => playlist.SelectedItem.Value == playlist.Items[0]); + } + + private void moveToItem(int index, Vector2? offset = null) + => AddStep($"move mouse to item {index}", () => InputManager.MoveMouseTo(playlist.ChildrenOfType>().ElementAt(index), offset)); + + private void moveToDragger(int index, Vector2? offset = null) => AddStep($"move mouse to dragger {index}", () => + { + var item = playlist.ChildrenOfType>().ElementAt(index); + InputManager.MoveMouseTo(item.ChildrenOfType.PlaylistItemHandle>().Single(), offset); + }); + + private void moveToDeleteButton(int index, Vector2? offset = null) => AddStep($"move mouse to delete button {index}", () => + { + var item = playlist.ChildrenOfType>().ElementAt(index); + InputManager.MoveMouseTo(item.ChildrenOfType().ElementAt(0), offset); + }); + + private void assertHandleVisibility(int index, bool visible) + => AddAssert($"handle {index} {(visible ? "is" : "is not")} visible", + () => (playlist.ChildrenOfType.PlaylistItemHandle>().ElementAt(index).Alpha > 0) == visible); + + private void assertDeleteButtonVisibility(int index, bool visible) + => AddAssert($"delete button {index} {(visible ? "is" : "is not")} visible", () => (playlist.ChildrenOfType().ElementAt(2 + index * 2).Alpha > 0) == visible); + private void createPlaylist(bool allowEdit, bool allowSelection) => AddStep("create playlist", () => { Child = playlist = new DrawableRoomPlaylist(allowEdit, allowSelection) From aceba8791c2e3bbbb1a541351257900ae3a56fa0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 16:55:05 +0900 Subject: [PATCH 0469/1142] Clean up selection handling --- .../TestSceneDrawableRoomPlaylist.cs | 8 ++- .../Screens/Multi/DrawableRoomPlaylist.cs | 12 +--- .../Screens/Multi/DrawableRoomPlaylistItem.cs | 63 +++++++++---------- 3 files changed, 40 insertions(+), 43 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index 267496bba2..c93d59acdf 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -46,6 +46,9 @@ namespace osu.Game.Tests.Visual.Multiplayer moveToItem(0); assertHandleVisibility(0, false); assertDeleteButtonVisibility(0, false); + + AddStep("click", () => InputManager.Click(MouseButton.Left)); + AddAssert("no item selected", () => playlist.SelectedItem.Value == null); } [Test] @@ -56,6 +59,9 @@ namespace osu.Game.Tests.Visual.Multiplayer moveToItem(0); assertHandleVisibility(0, true); assertDeleteButtonVisibility(0, true); + + AddStep("click", () => InputManager.Click(MouseButton.Left)); + AddAssert("no item selected", () => playlist.SelectedItem.Value == null); } [Test] @@ -165,7 +171,7 @@ namespace osu.Game.Tests.Visual.Multiplayer moveToDeleteButton(0); AddStep("click delete button", () => InputManager.Click(MouseButton.Left)); - AddAssert("selected item is null", () => playlist.SelectedItem.Value == null); + AddAssert("no item selected", () => playlist.SelectedItem.Value == null); } // Todo: currently not possible due to bindable list shortcomings (https://github.com/ppy/osu-framework/issues/3081) diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs index 01f173db4e..b139c61166 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylist.cs @@ -28,15 +28,7 @@ namespace osu.Game.Screens.Multi { base.LoadComplete(); - SelectedItem.BindValueChanged(item => - { - if (item.OldValue != null && ItemMap.TryGetValue(item.OldValue, out var oldItem)) - ((DrawableRoomPlaylistItem)oldItem).Deselect(); - - if (item.NewValue != null && ItemMap.TryGetValue(item.NewValue, out var newItem)) - ((DrawableRoomPlaylistItem)newItem).Select(); - }, true); - + // Scheduled since items are removed and re-added upon rearrangement Items.ItemsRemoved += items => Schedule(() => { if (!Items.Contains(SelectedItem.Value)) @@ -58,7 +50,7 @@ namespace osu.Game.Screens.Multi protected override OsuRearrangeableListItem CreateOsuDrawable(PlaylistItem item) => new DrawableRoomPlaylistItem(item, allowEdit, allowSelection) { - RequestSelection = requestSelection, + SelectedItem = { BindTarget = SelectedItem }, RequestDeletion = requestDeletion }; diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs index 7156839dfc..b1e69e4c4f 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs @@ -31,9 +31,10 @@ namespace osu.Game.Screens.Multi { public class DrawableRoomPlaylistItem : OsuRearrangeableListItem { - public Action RequestSelection; public Action RequestDeletion; + public readonly Bindable SelectedItem = new Bindable(); + protected override bool ShowDragHandle => allowEdit; private Container maskingContainer; @@ -75,6 +76,8 @@ namespace osu.Game.Screens.Multi { base.LoadComplete(); + SelectedItem.BindValueChanged(selected => maskingContainer.BorderThickness = selected.NewValue == Model ? 5 : 0); + beatmap.BindValueChanged(_ => scheduleRefresh()); ruleset.BindValueChanged(_ => scheduleRefresh()); @@ -84,6 +87,32 @@ namespace osu.Game.Screens.Multi refresh(); } + private ScheduledDelegate scheduledRefresh; + + private void scheduleRefresh() + { + scheduledRefresh?.Cancel(); + scheduledRefresh = Schedule(refresh); + } + + private void refresh() + { + difficultyIconContainer.Child = new DifficultyIcon(beatmap.Value, ruleset.Value) { Size = new Vector2(32) }; + + beatmapText.Clear(); + beatmapText.AddLink(item.Beatmap.ToString(), LinkAction.OpenBeatmap, item.Beatmap.Value.OnlineBeatmapID.ToString()); + + authorText.Clear(); + + if (item.Beatmap?.Value?.Metadata?.Author != null) + { + authorText.AddText("mapped by "); + authorText.AddUserLink(item.Beatmap.Value?.Metadata.Author); + } + + modDisplay.Current.Value = requiredMods.ToArray(); + } + protected override Drawable CreateContent() => maskingContainer = new Container { RelativeSizeAxes = Axes.X, @@ -173,43 +202,13 @@ namespace osu.Game.Screens.Multi } }; - private ScheduledDelegate scheduledRefresh; - - private void scheduleRefresh() - { - scheduledRefresh?.Cancel(); - scheduledRefresh = Schedule(refresh); - } - - private void refresh() - { - difficultyIconContainer.Child = new DifficultyIcon(beatmap.Value, ruleset.Value) { Size = new Vector2(32) }; - - beatmapText.Clear(); - beatmapText.AddLink(item.Beatmap.ToString(), LinkAction.OpenBeatmap, item.Beatmap.Value.OnlineBeatmapID.ToString()); - - authorText.Clear(); - - if (item.Beatmap?.Value?.Metadata?.Author != null) - { - authorText.AddText("mapped by "); - authorText.AddUserLink(item.Beatmap.Value?.Metadata.Author); - } - - modDisplay.Current.Value = requiredMods.ToArray(); - } - protected override bool OnClick(ClickEvent e) { if (allowSelection) - RequestSelection?.Invoke(Model); + SelectedItem.Value = Model; return true; } - public void Select() => maskingContainer.BorderThickness = 5; - - public void Deselect() => maskingContainer.BorderThickness = 0; - // For now, this is the same implementation as in PanelBackground, but supports a beatmap info rather than a working beatmap private class PanelBackground : Container // todo: should be a buffered container (https://github.com/ppy/osu-framework/issues/3222) { From 9ea6912520954aa28e6a5b1eb23d16da90716f95 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 16:58:56 +0900 Subject: [PATCH 0470/1142] Improve overall readability of OsuModeRelax --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 45 +++++++++++++++-------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 649b01c132..7ebb6fd76d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -19,33 +19,46 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Description => @"You don't need to click. Give your clicking/tapping fingers a break from the heat of things."; public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray(); + /// + /// How early before a hitobject's start time to trigger a hit. + /// + private const float relax_leniency = 3; + public void Update(Playfield playfield) { bool requiresHold = false; bool requiresHit = false; - const float relax_leniency = 3; + double time = playfield.Clock.CurrentTime; - foreach (var drawable in playfield.HitObjectContainer.AliveObjects) + foreach (var h in playfield.HitObjectContainer.AliveObjects.OfType()) { - if (!(drawable is DrawableOsuHitObject osuHit)) + // we are not yet close enough to the object. + if (time < h.HitObject.StartTime - relax_leniency) + break; + + // already hit or beyond the hittable end time. + if (h.IsHit || (h.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime)) continue; - double time = osuHit.Clock.CurrentTime; - double relativetime = time - osuHit.HitObject.StartTime; - - if (time < osuHit.HitObject.StartTime - relax_leniency) continue; - - if ((osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime) || osuHit.IsHit) - continue; - - if (osuHit is DrawableHitCircle && osuHit.IsHovered) + switch (h) { - Debug.Assert(osuHit.HitObject.HitWindows != null); - requiresHit |= osuHit.HitObject.HitWindows.CanBeHit(relativetime); - } + case DrawableHitCircle _: + if (!h.IsHovered) + break; - requiresHold |= (osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered)) || osuHit is DrawableSpinner; + Debug.Assert(h.HitObject.HitWindows != null); + requiresHit |= h.HitObject.HitWindows.CanBeHit(time - h.HitObject.StartTime); + break; + + case DrawableSlider slider: + requiresHold |= slider.Ball.IsHovered || h.IsHovered; + break; + + case DrawableSpinner _: + requiresHold = true; + break; + } } if (requiresHit) From cd2d1b06697d5b49fda11240425b8982d2af66b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 17:00:55 +0900 Subject: [PATCH 0471/1142] Fix 2B maps not playing correctly with relax mod enabled --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 7ebb6fd76d..d971e777ec 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -43,15 +43,15 @@ namespace osu.Game.Rulesets.Osu.Mods switch (h) { - case DrawableHitCircle _: - if (!h.IsHovered) - break; - - Debug.Assert(h.HitObject.HitWindows != null); - requiresHit |= h.HitObject.HitWindows.CanBeHit(time - h.HitObject.StartTime); + case DrawableHitCircle circle: + handleHitCircle(circle); break; case DrawableSlider slider: + // Handles cases like "2B" beatmaps, where sliders may be overlapping and simply holding is not enough. + if (!slider.HeadCircle.IsHit) + handleHitCircle(slider.HeadCircle); + requiresHold |= slider.Ball.IsHovered || h.IsHovered; break; @@ -68,6 +68,15 @@ namespace osu.Game.Rulesets.Osu.Mods } addAction(requiresHold); + + void handleHitCircle(DrawableHitCircle circle) + { + if (!circle.IsHovered) + return; + + Debug.Assert(circle.HitObject.HitWindows != null); + requiresHit |= circle.HitObject.HitWindows.CanBeHit(time - circle.HitObject.StartTime); + } } private bool wasHit; From 4ce687d608badbf3828992852e4070dcfb978cf4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 17:03:23 +0900 Subject: [PATCH 0472/1142] Move public methods up --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index d971e777ec..f874bc271f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -24,6 +24,18 @@ namespace osu.Game.Rulesets.Osu.Mods /// private const float relax_leniency = 3; + private bool wasHit; + private bool wasLeft; + + private OsuInputManager osuInputManager; + + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + // grab the input manager for future use. + osuInputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager; + osuInputManager.AllowUserPresses = false; + } + public void Update(Playfield playfield) { bool requiresHold = false; @@ -79,11 +91,6 @@ namespace osu.Game.Rulesets.Osu.Mods } } - private bool wasHit; - private bool wasLeft; - - private OsuInputManager osuInputManager; - private void addAction(bool hitting) { if (wasHit == hitting) @@ -104,12 +111,5 @@ namespace osu.Game.Rulesets.Osu.Mods state.Apply(osuInputManager.CurrentState, osuInputManager); } - - public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) - { - // grab the input manager for future use. - osuInputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager; - osuInputManager.AllowUserPresses = false; - } } } From 61a7f04efb7036a9998160b73d3f6166a671005c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 17:13:50 +0900 Subject: [PATCH 0473/1142] Add a sane key up delay to relax mod --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 50 +++++++++++++--------- osu.Game/Rulesets/Replays/AutoGenerator.cs | 2 +- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index f874bc271f..6286c80d7c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -9,6 +9,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.UI; using static osu.Game.Input.Handlers.ReplayInputHandler; @@ -24,11 +25,14 @@ namespace osu.Game.Rulesets.Osu.Mods ///
private const float relax_leniency = 3; - private bool wasHit; + private bool isDownState; private bool wasLeft; private OsuInputManager osuInputManager; + private ReplayState state; + private double lastStateChangeTime; + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { // grab the input manager for future use. @@ -75,11 +79,14 @@ namespace osu.Game.Rulesets.Osu.Mods if (requiresHit) { - addAction(false); - addAction(true); + changeState(false); + changeState(true); } - addAction(requiresHold); + if (requiresHold) + changeState(true); + else if (isDownState && time - lastStateChangeTime > AutoGenerator.KEY_UP_DELAY) + changeState(false); void handleHitCircle(DrawableHitCircle circle) { @@ -89,27 +96,28 @@ namespace osu.Game.Rulesets.Osu.Mods Debug.Assert(circle.HitObject.HitWindows != null); requiresHit |= circle.HitObject.HitWindows.CanBeHit(time - circle.HitObject.StartTime); } - } - private void addAction(bool hitting) - { - if (wasHit == hitting) - return; - - wasHit = hitting; - - var state = new ReplayState + void changeState(bool down) { - PressedActions = new List() - }; + if (isDownState == down) + return; - if (hitting) - { - state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton); - wasLeft = !wasLeft; + isDownState = down; + lastStateChangeTime = time; + + state = new ReplayState + { + PressedActions = new List() + }; + + if (down) + { + state.PressedActions.Add(wasLeft ? OsuAction.LeftButton : OsuAction.RightButton); + wasLeft = !wasLeft; + } + + state?.Apply(osuInputManager.CurrentState, osuInputManager); } - - state.Apply(osuInputManager.CurrentState, osuInputManager); } } } diff --git a/osu.Game/Rulesets/Replays/AutoGenerator.cs b/osu.Game/Rulesets/Replays/AutoGenerator.cs index 3319f30a6f..b3c609f2f4 100644 --- a/osu.Game/Rulesets/Replays/AutoGenerator.cs +++ b/osu.Game/Rulesets/Replays/AutoGenerator.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Replays #region Constants // Shared amongst all modes - protected const double KEY_UP_DELAY = 50; + public const double KEY_UP_DELAY = 50; #endregion From 5ec9f454d5f5caf792d287bf34e1524b6410123e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 17:20:38 +0900 Subject: [PATCH 0474/1142] Implement the match beatmap detail area --- .../TestSceneMatchBeatmapDetailArea.cs | 67 +++++++++++++ .../Multiplayer/TestSceneMatchSongSelect.cs | 37 +++++++ .../BeatmapDetailAreaPlaylistTabItem.cs | 12 +++ .../Components/MatchBeatmapDetailArea.cs | 98 +++++++++++++++++++ osu.Game/Screens/Select/MatchSongSelect.cs | 3 +- 5 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs create mode 100644 osu.Game/Screens/Multi/Components/BeatmapDetailAreaPlaylistTabItem.cs create mode 100644 osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs new file mode 100644 index 0000000000..09d882a265 --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs @@ -0,0 +1,67 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Utils; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Screens.Multi.Components; +using osuTK; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneMatchBeatmapDetailArea : MultiplayerTestScene + { + [Resolved] + private BeatmapManager beatmapManager { get; set; } + + [Resolved] + + private RulesetStore rulesetStore { get; set; } + + private MatchBeatmapDetailArea detailArea; + + [SetUp] + public void Setup() => Schedule(() => + { + Room.Playlist.Clear(); + + Child = detailArea = new MatchBeatmapDetailArea + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(500), + CreateNewItem = createNewItem + }; + }); + + private void createNewItem() + { + var set = beatmapManager.GetAllUsableBeatmapSetsEnumerable().First(); + var rulesets = rulesetStore.AvailableRulesets.ToList(); + + var beatmap = set.Beatmaps[RNG.Next(0, set.Beatmaps.Count)]; + + beatmap.BeatmapSet = set; + beatmap.Metadata = set.Metadata; + + Room.Playlist.Add(new PlaylistItem + { + ID = Room.Playlist.Count, + Beatmap = { Value = beatmap }, + Ruleset = { Value = rulesets[RNG.Next(0, rulesets.Count)] }, + RequiredMods = + { + new OsuModHardRock(), + new OsuModDoubleTime(), + new OsuModAutoplay() + } + }); + } + } +} diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs new file mode 100644 index 0000000000..f6e4715182 --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.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 System; +using System.Collections.Generic; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Screens.Multi.Components; +using osu.Game.Screens.Select; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneMatchSongSelect : MultiplayerTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(MatchSongSelect), + typeof(MatchBeatmapDetailArea), + }; + + [Resolved] + private BeatmapManager beatmapManager { get; set; } + + [SetUp] + public void Setup() => Schedule(() => + { + Room.Playlist.Clear(); + }); + + [Test] + public void TestLoadSongSelect() + { + AddStep("create song select", () => LoadScreen(new MatchSongSelect())); + } + } +} diff --git a/osu.Game/Screens/Multi/Components/BeatmapDetailAreaPlaylistTabItem.cs b/osu.Game/Screens/Multi/Components/BeatmapDetailAreaPlaylistTabItem.cs new file mode 100644 index 0000000000..3f2ab28f1a --- /dev/null +++ b/osu.Game/Screens/Multi/Components/BeatmapDetailAreaPlaylistTabItem.cs @@ -0,0 +1,12 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Screens.Select; + +namespace osu.Game.Screens.Multi.Components +{ + public class BeatmapDetailAreaPlaylistTabItem : BeatmapDetailAreaTabItem + { + public override string Name => "Playlist"; + } +} diff --git a/osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs b/osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs new file mode 100644 index 0000000000..8e085d6979 --- /dev/null +++ b/osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs @@ -0,0 +1,98 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Multiplayer; +using osu.Game.Screens.Select; +using osuTK; + +namespace osu.Game.Screens.Multi.Components +{ + public class MatchBeatmapDetailArea : BeatmapDetailArea + { + public Action CreateNewItem; + + public readonly Bindable SelectedItem = new Bindable(); + + [Resolved(typeof(Room))] + protected BindableList Playlist { get; private set; } + + private readonly Drawable playlistArea; + private readonly DrawableRoomPlaylist playlist; + + public MatchBeatmapDetailArea() + { + Add(playlistArea = new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Vertical = 10 }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Bottom = 10 }, + Child = playlist = new DrawableRoomPlaylist(true, false) + { + RelativeSizeAxes = Axes.Both, + } + } + }, + new Drawable[] + { + new TriangleButton + { + Text = "create new item", + RelativeSizeAxes = Axes.Both, + Size = Vector2.One, + Action = () => CreateNewItem?.Invoke() + } + }, + }, + RowDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.Absolute, 50), + } + } + }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + playlist.Items.BindTo(Playlist); + playlist.SelectedItem.BindTo(SelectedItem); + } + + protected override void OnTabChanged(BeatmapDetailAreaTabItem tab, bool selectedMods) + { + base.OnTabChanged(tab, selectedMods); + + switch (tab) + { + case BeatmapDetailAreaPlaylistTabItem _: + playlistArea.Show(); + break; + + default: + playlistArea.Hide(); + break; + } + } + + protected override BeatmapDetailAreaTabItem[] CreateTabItems() => base.CreateTabItems().Prepend(new BeatmapDetailAreaPlaylistTabItem()).ToArray(); + } +} diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 826677ee30..94d65889d1 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -12,6 +12,7 @@ using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi; +using osu.Game.Screens.Multi.Components; namespace osu.Game.Screens.Select { @@ -35,7 +36,7 @@ namespace osu.Game.Screens.Select Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING }; } - protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea(); // Todo: Temporary + protected override BeatmapDetailArea CreateBeatmapDetailArea() => new MatchBeatmapDetailArea(); protected override bool OnStart() { From 66910f1ee3489ed83890b772599e6ce02475a30e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 17:50:53 +0900 Subject: [PATCH 0475/1142] Remove unnecessary bindable setter --- osu.Game/Screens/Select/BeatmapDetailArea.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapDetailArea.cs b/osu.Game/Screens/Select/BeatmapDetailArea.cs index 1aae0cc243..2e78b1aed2 100644 --- a/osu.Game/Screens/Select/BeatmapDetailArea.cs +++ b/osu.Game/Screens/Select/BeatmapDetailArea.cs @@ -28,11 +28,7 @@ namespace osu.Game.Screens.Select public readonly BeatmapDetails Details; - protected Bindable CurrentTab - { - get => tabControl.Current; - set => tabControl.Current = value; - } + protected Bindable CurrentTab => tabControl.Current; private readonly Container content; protected override Container Content => content; From f0f739707f2e9a91cc4d64096afe4aae1e8a5ab0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 17:51:42 +0900 Subject: [PATCH 0476/1142] Add playlist support to match song select --- .../Multiplayer/TestSceneMatchSongSelect.cs | 101 +++++++++++++++++- osu.Game/Screens/Select/MatchSongSelect.cs | 42 +++----- 2 files changed, 114 insertions(+), 29 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs index f6e4715182..434b265f9c 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs @@ -3,9 +3,19 @@ using System; using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Extensions; +using osu.Framework.Platform; +using osu.Framework.Screens; +using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Select; @@ -22,6 +32,72 @@ namespace osu.Game.Tests.Visual.Multiplayer [Resolved] private BeatmapManager beatmapManager { get; set; } + private BeatmapManager manager; + + private RulesetStore rulesets; + + private TestMatchSongSelect songSelect; + + [BackgroundDependencyLoader] + private void load(GameHost host, AudioManager audio) + { + Dependencies.Cache(rulesets = new RulesetStore(ContextFactory)); + Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default)); + + var beatmaps = new List(); + + for (int i = 0; i < 6; i++) + { + int beatmapId = 10 * 10 + i; + + int length = RNG.Next(30000, 200000); + double bpm = RNG.NextSingle(80, 200); + + beatmaps.Add(new BeatmapInfo + { + Ruleset = new OsuRuleset().RulesetInfo, + OnlineBeatmapID = beatmapId, + Path = "normal.osu", + Version = $"{beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})", + Length = length, + BPM = bpm, + BaseDifficulty = new BeatmapDifficulty + { + OverallDifficulty = 3.5f, + }, + }); + } + + manager.Import(new BeatmapSetInfo + { + OnlineBeatmapSetID = 10, + Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + Metadata = new BeatmapMetadata + { + // Create random metadata, then we can check if sorting works based on these + Artist = "Some Artist " + RNG.Next(0, 9), + Title = $"Some Song (set id 10), max bpm {beatmaps.Max(b => b.BPM):0.#})", + AuthorString = "Some Guy " + RNG.Next(0, 9), + }, + Beatmaps = beatmaps, + DateAdded = DateTimeOffset.UtcNow, + }).Wait(); + } + + public override void SetUpSteps() + { + base.SetUpSteps(); + + AddStep("reset", () => + { + Ruleset.Value = new OsuRuleset().RulesetInfo; + Beatmap.SetDefault(); + }); + + AddStep("create song select", () => LoadScreen(songSelect = new TestMatchSongSelect())); + AddUntilStep("wait for present", () => songSelect.IsCurrentScreen()); + } + [SetUp] public void Setup() => Schedule(() => { @@ -29,9 +105,30 @@ namespace osu.Game.Tests.Visual.Multiplayer }); [Test] - public void TestLoadSongSelect() + public void TestItemAddedIfEmptyOnStart() { - AddStep("create song select", () => LoadScreen(new MatchSongSelect())); + AddStep("finalise selection", () => songSelect.FinaliseSelection()); + AddAssert("playlist has 1 item", () => Room.Playlist.Count == 1); + } + + [Test] + public void TestItemAddedWhenCreateNewItemClicked() + { + AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem()); + AddAssert("playlist has 1 item", () => Room.Playlist.Count == 1); + } + + [Test] + public void TestItemNotAddedIfExistingOnStart() + { + AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem()); + AddStep("finalise selection", () => songSelect.FinaliseSelection()); + AddAssert("playlist has 1 item", () => Room.Playlist.Count == 1); + } + + private class TestMatchSongSelect : MatchSongSelect + { + public new MatchBeatmapDetailArea BeatmapDetails => (MatchBeatmapDetailArea)base.BeatmapDetails; } } } diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 94d65889d1..4edc968e8a 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Linq; using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -10,7 +9,6 @@ using osu.Framework.Graphics; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi; using osu.Game.Screens.Multi.Components; @@ -36,42 +34,32 @@ namespace osu.Game.Screens.Select Padding = new MarginPadding { Horizontal = HORIZONTAL_OVERFLOW_PADDING }; } - protected override BeatmapDetailArea CreateBeatmapDetailArea() => new MatchBeatmapDetailArea(); + protected override BeatmapDetailArea CreateBeatmapDetailArea() => new MatchBeatmapDetailArea + { + CreateNewItem = createNewItem + }; protected override bool OnStart() { - var item = new PlaylistItem - { - Beatmap = { Value = Beatmap.Value.BeatmapInfo }, - Ruleset = { Value = Ruleset.Value }, - RulesetID = Ruleset.Value.ID ?? 0 - }; + if (Playlist.Count == 0) + createNewItem(); - item.RequiredMods.AddRange(Mods.Value); - - Selected?.Invoke(item); - - if (this.IsCurrentScreen()) - this.Exit(); + this.Exit(); return true; } - public override bool OnExiting(IScreen next) + private void createNewItem() { - if (base.OnExiting(next)) - return true; - - var firstItem = Playlist.FirstOrDefault(); - - if (firstItem != null) + PlaylistItem item = new PlaylistItem { - Ruleset.Value = firstItem.Ruleset.Value; - Beatmap.Value = beatmaps.GetWorkingBeatmap(firstItem.Beatmap.Value); - Mods.Value = firstItem.RequiredMods?.ToArray() ?? Array.Empty(); - } + Beatmap = { Value = Beatmap.Value.BeatmapInfo }, + Ruleset = { Value = Ruleset.Value } + }; - return false; + item.RequiredMods.AddRange(Mods.Value); + + Playlist.Add(item); } } } From 32fd713a9d4c4d40a5066e155efc463c207e3701 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 17:57:25 +0900 Subject: [PATCH 0477/1142] Use test beatmap instead of beatmap manager --- .../Multiplayer/TestSceneDrawableRoomPlaylist.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index c93d59acdf..4ba802730f 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -9,14 +9,15 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; -using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Multi; +using osu.Game.Tests.Beatmaps; using osuTK; using osuTK.Input; @@ -218,22 +219,13 @@ namespace osu.Game.Tests.Visual.Multiplayer Size = new Vector2(500, 300) }; - var beatmapSets = beatmapManager.GetAllUsableBeatmapSets(); - var rulesets = rulesetStore.AvailableRulesets.ToList(); - for (int i = 0; i < 20; i++) { - var set = beatmapSets[RNG.Next(0, beatmapSets.Count)]; - var beatmap = set.Beatmaps[RNG.Next(0, set.Beatmaps.Count)]; - - beatmap.BeatmapSet = set; - beatmap.Metadata = set.Metadata; - playlist.Items.Add(new PlaylistItem { ID = i, - Beatmap = { Value = beatmap }, - Ruleset = { Value = rulesets[RNG.Next(0, rulesets.Count)] }, + Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo }, RequiredMods = { new OsuModHardRock(), From de646649def7d7ca2d0322ab925f386c46343e63 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 17:59:14 +0900 Subject: [PATCH 0478/1142] Use test beatmap instead of beatmap manager --- .../TestSceneMatchBeatmapDetailArea.cs | 30 ++++--------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs index 09d882a265..13fcc18e56 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs @@ -1,37 +1,25 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Utils; -using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Multi.Components; +using osu.Game.Tests.Beatmaps; using osuTK; namespace osu.Game.Tests.Visual.Multiplayer { public class TestSceneMatchBeatmapDetailArea : MultiplayerTestScene { - [Resolved] - private BeatmapManager beatmapManager { get; set; } - - [Resolved] - - private RulesetStore rulesetStore { get; set; } - - private MatchBeatmapDetailArea detailArea; - [SetUp] public void Setup() => Schedule(() => { Room.Playlist.Clear(); - Child = detailArea = new MatchBeatmapDetailArea + Child = new MatchBeatmapDetailArea { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -42,19 +30,11 @@ namespace osu.Game.Tests.Visual.Multiplayer private void createNewItem() { - var set = beatmapManager.GetAllUsableBeatmapSetsEnumerable().First(); - var rulesets = rulesetStore.AvailableRulesets.ToList(); - - var beatmap = set.Beatmaps[RNG.Next(0, set.Beatmaps.Count)]; - - beatmap.BeatmapSet = set; - beatmap.Metadata = set.Metadata; - Room.Playlist.Add(new PlaylistItem { ID = Room.Playlist.Count, - Beatmap = { Value = beatmap }, - Ruleset = { Value = rulesets[RNG.Next(0, rulesets.Count)] }, + Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo }, RequiredMods = { new OsuModHardRock(), From fbc5ffbadbd27e5856b8c94c6d046a3513b5df16 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 17:59:47 +0900 Subject: [PATCH 0479/1142] Remove now unused members --- .../Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index 4ba802730f..d2d02412cd 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -5,15 +5,12 @@ using System; using System.Collections.Generic; using System.Linq; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Testing; -using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; -using osu.Game.Rulesets; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Multi; @@ -31,12 +28,6 @@ namespace osu.Game.Tests.Visual.Multiplayer typeof(DrawableRoomPlaylistItem) }; - [Resolved] - private BeatmapManager beatmapManager { get; set; } - - [Resolved] - private RulesetStore rulesetStore { get; set; } - private DrawableRoomPlaylist playlist; [Test] From be30ef3cca69c1b00beebdf1a579edc5f47f84f9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 18:13:52 +0900 Subject: [PATCH 0480/1142] Move BeatmapMetadataDisplay to its own class --- .../Screens/Play/BeatmapMetadataDisplay.cs | 180 ++++++++++++++++++ osu.Game/Screens/Play/PlayerLoader.cs | 163 ---------------- 2 files changed, 180 insertions(+), 163 deletions(-) create mode 100644 osu.Game/Screens/Play/BeatmapMetadataDisplay.cs diff --git a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs new file mode 100644 index 0000000000..074341226e --- /dev/null +++ b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs @@ -0,0 +1,180 @@ +// 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.Generic; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Localisation; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Play.HUD; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Play +{ + /// + /// Displays beatmap metadata inside + /// + public class BeatmapMetadataDisplay : Container + { + private class MetadataLine : Container + { + public MetadataLine(string left, string right) + { + AutoSizeAxes = Axes.Both; + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopRight, + Margin = new MarginPadding { Right = 5 }, + Colour = OsuColour.Gray(0.8f), + Text = left, + }, + new OsuSpriteText + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopLeft, + Margin = new MarginPadding { Left = 5 }, + Text = string.IsNullOrEmpty(right) ? @"-" : right, + } + }; + } + } + + private readonly WorkingBeatmap beatmap; + private readonly Bindable> mods; + private readonly Drawable facade; + private LoadingAnimation loading; + private Sprite backgroundSprite; + + public IBindable> Mods => mods; + + public bool Loading + { + set + { + if (value) + { + loading.Show(); + backgroundSprite.FadeColour(OsuColour.Gray(0.5f), 400, Easing.OutQuint); + } + else + { + loading.Hide(); + backgroundSprite.FadeColour(Color4.White, 400, Easing.OutQuint); + } + } + } + + public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Bindable> mods, Drawable facade) + { + this.beatmap = beatmap; + this.facade = facade; + + this.mods = new Bindable>(); + this.mods.BindTo(mods); + } + + [BackgroundDependencyLoader] + private void load() + { + var metadata = beatmap.BeatmapInfo?.Metadata ?? new BeatmapMetadata(); + + AutoSizeAxes = Axes.Both; + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Direction = FillDirection.Vertical, + Children = new[] + { + facade.With(d => + { + d.Anchor = Anchor.TopCentre; + d.Origin = Anchor.TopCentre; + }), + new OsuSpriteText + { + Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)), + Font = OsuFont.GetFont(size: 36, italics: true), + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Margin = new MarginPadding { Top = 15 }, + }, + new OsuSpriteText + { + Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist)), + Font = OsuFont.GetFont(size: 26, italics: true), + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + }, + new Container + { + Size = new Vector2(300, 60), + Margin = new MarginPadding(10), + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + CornerRadius = 10, + Masking = true, + Children = new Drawable[] + { + backgroundSprite = new Sprite + { + RelativeSizeAxes = Axes.Both, + Texture = beatmap?.Background, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + FillMode = FillMode.Fill, + }, + loading = new LoadingAnimation { Scale = new Vector2(1.3f) } + } + }, + new OsuSpriteText + { + Text = beatmap?.BeatmapInfo?.Version, + Font = OsuFont.GetFont(size: 26, italics: true), + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + Margin = new MarginPadding + { + Bottom = 40 + }, + }, + new MetadataLine("Source", metadata.Source) + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + }, + new MetadataLine("Mapper", metadata.AuthorString) + { + Origin = Anchor.TopCentre, + Anchor = Anchor.TopCentre, + }, + new ModDisplay + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Top = 20 }, + Current = mods + } + }, + } + }; + + Loading = true; + } + } +} diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index f37faac988..ebc2422dc5 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; @@ -12,21 +11,15 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input; -using osu.Framework.Localisation; using osu.Framework.Screens; using osu.Framework.Threading; -using osu.Game.Beatmaps; using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Input; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; -using osu.Game.Rulesets.Mods; using osu.Game.Screens.Menu; -using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.PlayerSettings; using osu.Game.Users; using osuTK; @@ -350,162 +343,6 @@ namespace osu.Game.Screens.Play } } - protected class BeatmapMetadataDisplay : Container - { - private class MetadataLine : Container - { - public MetadataLine(string left, string right) - { - AutoSizeAxes = Axes.Both; - Children = new Drawable[] - { - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopRight, - Margin = new MarginPadding { Right = 5 }, - Colour = OsuColour.Gray(0.8f), - Text = left, - }, - new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopLeft, - Margin = new MarginPadding { Left = 5 }, - Text = string.IsNullOrEmpty(right) ? @"-" : right, - } - }; - } - } - - private readonly WorkingBeatmap beatmap; - private readonly Bindable> mods; - private readonly Drawable facade; - private LoadingAnimation loading; - private Sprite backgroundSprite; - - public IBindable> Mods => mods; - - public bool Loading - { - set - { - if (value) - { - loading.Show(); - backgroundSprite.FadeColour(OsuColour.Gray(0.5f), 400, Easing.OutQuint); - } - else - { - loading.Hide(); - backgroundSprite.FadeColour(Color4.White, 400, Easing.OutQuint); - } - } - } - - public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Bindable> mods, Drawable facade) - { - this.beatmap = beatmap; - this.facade = facade; - - this.mods = new Bindable>(); - this.mods.BindTo(mods); - } - - [BackgroundDependencyLoader] - private void load() - { - var metadata = beatmap.BeatmapInfo?.Metadata ?? new BeatmapMetadata(); - - AutoSizeAxes = Axes.Both; - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Direction = FillDirection.Vertical, - Children = new[] - { - facade.With(d => - { - d.Anchor = Anchor.TopCentre; - d.Origin = Anchor.TopCentre; - }), - new OsuSpriteText - { - Text = new LocalisedString((metadata.TitleUnicode, metadata.Title)), - Font = OsuFont.GetFont(size: 36, italics: true), - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Margin = new MarginPadding { Top = 15 }, - }, - new OsuSpriteText - { - Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist)), - Font = OsuFont.GetFont(size: 26, italics: true), - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - }, - new Container - { - Size = new Vector2(300, 60), - Margin = new MarginPadding(10), - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - CornerRadius = 10, - Masking = true, - Children = new Drawable[] - { - backgroundSprite = new Sprite - { - RelativeSizeAxes = Axes.Both, - Texture = beatmap?.Background, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - FillMode = FillMode.Fill, - }, - loading = new LoadingAnimation { Scale = new Vector2(1.3f) } - } - }, - new OsuSpriteText - { - Text = beatmap?.BeatmapInfo?.Version, - Font = OsuFont.GetFont(size: 26, italics: true), - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Margin = new MarginPadding - { - Bottom = 40 - }, - }, - new MetadataLine("Source", metadata.Source) - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - }, - new MetadataLine("Mapper", metadata.AuthorString) - { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - }, - new ModDisplay - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = 20 }, - Current = mods - } - }, - } - }; - - Loading = true; - } - } - private class MutedNotification : SimpleNotification { public MutedNotification() From b69d1ad678b9052091777aad6669ac4e643d3513 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 18:22:57 +0900 Subject: [PATCH 0481/1142] Reorder and clean up PlayerLoader --- osu.Game/Screens/Play/PlayerLoader.cs | 308 +++++++++++++------------- 1 file changed, 158 insertions(+), 150 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index ebc2422dc5..6e968de397 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -31,30 +31,60 @@ namespace osu.Game.Screens.Play { protected const float BACKGROUND_BLUR = 15; + public override bool HideOverlaysOnEnter => hideOverlays; + + public override bool DisallowExternalBeatmapRulesetChanges => true; + + // Here because IsHovered will not update unless we do so. + public override bool HandlePositionalInput => true; + + // We show the previous screen status + protected override UserActivity InitialActivity => null; + + protected override bool PlayResumeSound => false; + + protected BeatmapMetadataDisplay MetadataInfo; + + protected VisualSettings VisualSettings; + + protected Task LoadTask { get; private set; } + + protected Task DisposalTask { get; private set; } + + private bool backgroundBrightnessReduction; + + protected bool BackgroundBrightnessReduction + { + set + { + if (value == backgroundBrightnessReduction) + return; + + backgroundBrightnessReduction = value; + + Background.FadeColour(OsuColour.Gray(backgroundBrightnessReduction ? 0.8f : 1), 200); + } + } + + private bool readyForPush => + player.LoadState == LoadState.Ready && (IsHovered || idleTracker.IsIdle.Value) && inputManager?.DraggedDrawable == null; + private readonly Func createPlayer; private Player player; private LogoTrackingContainer content; - protected BeatmapMetadataDisplay MetadataInfo; - private bool hideOverlays; - public override bool HideOverlaysOnEnter => hideOverlays; - - protected override UserActivity InitialActivity => null; //shows the previous screen status - - public override bool DisallowExternalBeatmapRulesetChanges => true; - - protected override bool PlayResumeSound => false; - - protected Task LoadTask { get; private set; } - - protected Task DisposalTask { get; private set; } private InputManager inputManager; + private IdleTracker idleTracker; + private Bindable muteWarningShownOnce; + + private ScheduledDelegate scheduledPushPlayer; + [Resolved(CanBeNull = true)] private NotificationOverlay notificationOverlay { get; set; } @@ -64,19 +94,11 @@ namespace osu.Game.Screens.Play [Resolved] private AudioManager audioManager { get; set; } - private Bindable muteWarningShownOnce; - public PlayerLoader(Func createPlayer) { this.createPlayer = createPlayer; } - private void restartRequested() - { - hideOverlays = true; - ValidForResume = true; - } - [BackgroundDependencyLoader] private void load(SessionStatics sessionStatics) { @@ -124,7 +146,7 @@ namespace osu.Game.Screens.Play { base.OnEntering(last); - loadNewPlayer(); + prepareNewPlayer(); content.ScaleTo(0.7f); Background?.FadeColour(Color4.White, 800, Easing.OutQuint); @@ -153,36 +175,32 @@ namespace osu.Game.Screens.Play MetadataInfo.Loading = true; - //we will only be resumed if the player has requested a re-run (see ValidForResume setting above) - loadNewPlayer(); + // we will only be resumed if the player has requested a re-run (see restartRequested). + prepareNewPlayer(); this.Delay(400).Schedule(pushWhenLoaded); } - private void loadNewPlayer() + public override void OnSuspending(IScreen next) { - var restartCount = player?.RestartCount + 1 ?? 0; + base.OnSuspending(next); - player = createPlayer(); - player.RestartCount = restartCount; - player.RestartRequested = restartRequested; + cancelLoad(); - LoadTask = LoadComponentAsync(player, _ => MetadataInfo.Loading = false); + BackgroundBrightnessReduction = false; } - private void contentIn() + public override bool OnExiting(IScreen next) { - content.ScaleTo(1, 650, Easing.OutQuint); - content.FadeInFromZero(400); - } + cancelLoad(); - private void contentOut() - { - // Ensure the logo is no longer tracking before we scale the content - content.StopTracking(); + content.ScaleTo(0.7f, 150, Easing.InQuint); + this.FadeOut(150); - content.ScaleTo(0.7f, 300, Easing.InQuint); - content.FadeOut(250); + Background.EnableUserDim.Value = false; + BackgroundBrightnessReduction = false; + + return base.OnExiting(next); } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -191,10 +209,7 @@ namespace osu.Game.Screens.Play const double duration = 300; - if (!resuming) - { - logo.MoveTo(new Vector2(0.5f), duration, Easing.In); - } + if (!resuming) logo.MoveTo(new Vector2(0.5f), duration, Easing.In); logo.ScaleTo(new Vector2(0.15f), duration, Easing.In); logo.FadeIn(350); @@ -212,110 +227,6 @@ namespace osu.Game.Screens.Play content.StopTracking(); } - private ScheduledDelegate pushDebounce; - protected VisualSettings VisualSettings; - - // Here because IsHovered will not update unless we do so. - public override bool HandlePositionalInput => true; - - private bool readyForPush => player.LoadState == LoadState.Ready && (IsHovered || idleTracker.IsIdle.Value) && inputManager?.DraggedDrawable == null; - - private void pushWhenLoaded() - { - if (!this.IsCurrentScreen()) return; - - try - { - if (!readyForPush) - { - // as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce - // if we become unready for push during the delay. - cancelLoad(); - return; - } - - if (pushDebounce != null) - return; - - pushDebounce = Scheduler.AddDelayed(() => - { - contentOut(); - - this.Delay(250).Schedule(() => - { - if (!this.IsCurrentScreen()) return; - - LoadTask = null; - - //By default, we want to load the player and never be returned to. - //Note that this may change if the player we load requested a re-run. - ValidForResume = false; - - if (player.LoadedBeatmapSuccessfully) - this.Push(player); - else - this.Exit(); - }); - }, 500); - } - finally - { - Schedule(pushWhenLoaded); - } - } - - private void cancelLoad() - { - pushDebounce?.Cancel(); - pushDebounce = null; - } - - public override void OnSuspending(IScreen next) - { - BackgroundBrightnessReduction = false; - base.OnSuspending(next); - cancelLoad(); - } - - public override bool OnExiting(IScreen next) - { - content.ScaleTo(0.7f, 150, Easing.InQuint); - this.FadeOut(150); - cancelLoad(); - - Background.EnableUserDim.Value = false; - BackgroundBrightnessReduction = false; - - return base.OnExiting(next); - } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (isDisposing) - { - // if the player never got pushed, we should explicitly dispose it. - DisposalTask = LoadTask?.ContinueWith(_ => player.Dispose()); - } - } - - private bool backgroundBrightnessReduction; - - protected bool BackgroundBrightnessReduction - { - get => backgroundBrightnessReduction; - set - { - if (value == backgroundBrightnessReduction) - return; - - backgroundBrightnessReduction = value; - - Background.FadeColour(OsuColour.Gray(backgroundBrightnessReduction ? 0.8f : 1), 200); - } - } - protected override void Update() { base.Update(); @@ -343,15 +254,112 @@ namespace osu.Game.Screens.Play } } + private void prepareNewPlayer() + { + var restartCount = player?.RestartCount + 1 ?? 0; + + player = createPlayer(); + player.RestartCount = restartCount; + player.RestartRequested = restartRequested; + + LoadTask = LoadComponentAsync(player, _ => MetadataInfo.Loading = false); + } + + private void restartRequested() + { + hideOverlays = true; + ValidForResume = true; + } + + private void contentIn() + { + content.ScaleTo(1, 650, Easing.OutQuint); + content.FadeInFromZero(400); + } + + private void contentOut() + { + // Ensure the logo is no longer tracking before we scale the content + content.StopTracking(); + + content.ScaleTo(0.7f, 300, Easing.InQuint); + content.FadeOut(250); + } + + private void pushWhenLoaded() + { + if (!this.IsCurrentScreen()) return; + + try + { + if (!readyForPush) + { + // as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce + // if we become unready for push during the delay. + cancelLoad(); + return; + } + + if (scheduledPushPlayer != null) + return; + + scheduledPushPlayer = Scheduler.AddDelayed(() => + { + contentOut(); + + this.Delay(250).Schedule(() => + { + if (!this.IsCurrentScreen()) return; + + LoadTask = null; + + //By default, we want to load the player and never be returned to. + //Note that this may change if the player we load requested a re-run. + ValidForResume = false; + + if (player.LoadedBeatmapSuccessfully) + this.Push(player); + else + this.Exit(); + }); + }, 500); + } + finally + { + Schedule(pushWhenLoaded); + } + } + + private void cancelLoad() + { + scheduledPushPlayer?.Cancel(); + scheduledPushPlayer = null; + } + + #region Disposal + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (isDisposing) + { + // if the player never got pushed, we should explicitly dispose it. + DisposalTask = LoadTask?.ContinueWith(_ => player.Dispose()); + } + } + + #endregion + private class MutedNotification : SimpleNotification { + public override bool IsImportant => true; + public MutedNotification() { Text = "Your music volume is set to 0%! Click here to restore it."; } - public override bool IsImportant => true; - [BackgroundDependencyLoader] private void load(OsuColour colours, AudioManager audioManager, NotificationOverlay notificationOverlay, VolumeOverlay volumeOverlay) { From 2808f8167dd40866481315156fd3b1954614f6ef Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 18:28:58 +0900 Subject: [PATCH 0482/1142] Use more regions --- osu.Game/Screens/Play/PlayerLoader.cs | 35 ++++++++++++++++++--------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 6e968de397..01873f7114 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -81,8 +81,6 @@ namespace osu.Game.Screens.Play private IdleTracker idleTracker; - private Bindable muteWarningShownOnce; - private ScheduledDelegate scheduledPushPlayer; [Resolved(CanBeNull = true)] @@ -142,6 +140,8 @@ namespace osu.Game.Screens.Play inputManager = GetContainingInputManager(); } + #region Screen handling + public override void OnEntering(IScreen last) { base.OnEntering(last); @@ -156,15 +156,7 @@ namespace osu.Game.Screens.Play MetadataInfo.Delay(750).FadeIn(500); this.Delay(1800).Schedule(pushWhenLoaded); - if (!muteWarningShownOnce.Value) - { - //Checks if the notification has not been shown yet and also if master volume is muted, track/music volume is muted or if the whole game is muted. - if (volumeOverlay?.IsMuted.Value == true || audioManager.Volume.Value <= audioManager.Volume.MinValue || audioManager.VolumeTrack.Value <= audioManager.VolumeTrack.MinValue) - { - notificationOverlay?.Post(new MutedNotification()); - muteWarningShownOnce.Value = true; - } - } + showMuteWarningIfNeeded(); } public override void OnResuming(IScreen last) @@ -227,6 +219,8 @@ namespace osu.Game.Screens.Play content.StopTracking(); } + #endregion + protected override void Update() { base.Update(); @@ -351,6 +345,23 @@ namespace osu.Game.Screens.Play #endregion + #region Mute warning + + private Bindable muteWarningShownOnce; + + private void showMuteWarningIfNeeded() + { + if (!muteWarningShownOnce.Value) + { + //Checks if the notification has not been shown yet and also if master volume is muted, track/music volume is muted or if the whole game is muted. + if (volumeOverlay?.IsMuted.Value == true || audioManager.Volume.Value <= audioManager.Volume.MinValue || audioManager.VolumeTrack.Value <= audioManager.VolumeTrack.MinValue) + { + notificationOverlay?.Post(new MutedNotification()); + muteWarningShownOnce.Value = true; + } + } + } + private class MutedNotification : SimpleNotification { public override bool IsImportant => true; @@ -378,5 +389,7 @@ namespace osu.Game.Screens.Play }; } } + + #endregion } } From 47325601f42a293d6b259e27489cfedf7b72e807 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 19:02:11 +0900 Subject: [PATCH 0483/1142] Add failing test --- .../Visual/Gameplay/TestScenePlayerLoader.cs | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 33ecbed62e..4f19067126 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -91,9 +91,44 @@ namespace osu.Game.Tests.Visual.Gameplay { AddStep("load dummy beatmap", () => ResetPlayer(false)); AddUntilStep("wait for current", () => loader.IsCurrentScreen()); - AddRepeatStep("move mouse", () => InputManager.MoveMouseTo(loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft + (loader.VisualSettings.ScreenSpaceDrawQuad.BottomRight - loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft) * RNG.NextSingle()), 20); + + AddUntilStep("wait for load ready", () => + { + moveMouse(); + return player.LoadState == LoadState.Ready; + }); + AddRepeatStep("move mouse", moveMouse, 20); + AddAssert("loader still active", () => loader.IsCurrentScreen()); AddUntilStep("loads after idle", () => !loader.IsCurrentScreen()); + + void moveMouse() + { + InputManager.MoveMouseTo( + loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft + + (loader.VisualSettings.ScreenSpaceDrawQuad.BottomRight - loader.VisualSettings.ScreenSpaceDrawQuad.TopLeft) + * RNG.NextSingle()); + } + } + + [Test] + public void TestBlockLoadViaFocus() + { + OsuFocusedOverlayContainer overlay = null; + + AddStep("load dummy beatmap", () => ResetPlayer(false)); + AddUntilStep("wait for current", () => loader.IsCurrentScreen()); + + AddStep("show focused overlay", () => { container.Add(overlay = new ChangelogOverlay { State = { Value = Visibility.Visible } }); }); + AddUntilStep("overlay visible", () => overlay.IsPresent); + + AddUntilStep("wait for load ready", () => player.LoadState == LoadState.Ready); + AddRepeatStep("twiddle thumbs", () => { }, 20); + + AddAssert("loader still active", () => loader.IsCurrentScreen()); + + AddStep("hide overlay", () => overlay.Hide()); + AddUntilStep("loads after idle", () => !loader.IsCurrentScreen()); } [Test] From 4d4ec3515d50bb184d33ab053d06b5d0ff17ca36 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 19:02:37 +0900 Subject: [PATCH 0484/1142] Fix player loading sequence continuing even when a priority overlay is visible --- osu.Game/Screens/Play/PlayerLoader.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 01873f7114..c0d88feda2 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -67,7 +67,14 @@ namespace osu.Game.Screens.Play } private bool readyForPush => - player.LoadState == LoadState.Ready && (IsHovered || idleTracker.IsIdle.Value) && inputManager?.DraggedDrawable == null; + // don't push unless the player is completely loaded + player.LoadState == LoadState.Ready + // don't push if the user is hovering one of the panes, unless they are idle. + && (IsHovered || idleTracker.IsIdle.Value) + // don't push if the user is dragging a slider or otherwise. + && inputManager?.DraggedDrawable == null + // don't push if a focused overlay is visible, like settings. + && inputManager?.FocusedDrawable == null; private readonly Func createPlayer; From 05c48cd92950b604cff21490f2ead15a91b15c78 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 19:27:32 +0900 Subject: [PATCH 0485/1142] Fix volume mute tests regressing --- .../Visual/Gameplay/TestScenePlayerLoader.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 4f19067126..100f99d130 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -194,13 +194,22 @@ namespace osu.Game.Tests.Visual.Gameplay } [Test] - public void TestMutedNotificationMasterVolume() => addVolumeSteps("master volume", () => audioManager.Volume.Value = 0, null, () => audioManager.Volume.IsDefault); + public void TestMutedNotificationMasterVolume() + { + addVolumeSteps("master volume", () => audioManager.Volume.Value = 0, null, () => audioManager.Volume.IsDefault); + } [Test] - public void TestMutedNotificationTrackVolume() => addVolumeSteps("music volume", () => audioManager.VolumeTrack.Value = 0, null, () => audioManager.VolumeTrack.IsDefault); + public void TestMutedNotificationTrackVolume() + { + addVolumeSteps("music volume", () => audioManager.VolumeTrack.Value = 0, null, () => audioManager.VolumeTrack.IsDefault); + } [Test] - public void TestMutedNotificationMuteButton() => addVolumeSteps("mute button", null, () => container.VolumeOverlay.IsMuted.Value = true, () => !container.VolumeOverlay.IsMuted.Value); + public void TestMutedNotificationMuteButton() + { + addVolumeSteps("mute button", null, () => container.VolumeOverlay.IsMuted.Value = true, () => !container.VolumeOverlay.IsMuted.Value); + } /// /// Created for avoiding copy pasting code for the same steps. @@ -214,7 +223,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("reset notification lock", () => sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce).Value = false); AddStep("load player", () => ResetPlayer(false, beforeLoad, afterLoad)); - AddUntilStep("wait for player", () => player.IsLoaded); + AddUntilStep("wait for player", () => player.LoadState == LoadState.Ready); AddAssert("check for notification", () => container.NotificationOverlay.UnreadCount.Value == 1); AddStep("click notification", () => @@ -228,6 +237,8 @@ namespace osu.Game.Tests.Visual.Gameplay }); AddAssert("check " + volumeName, assert); + + AddUntilStep("wait for player load", () => player.IsLoaded); } private class TestPlayerLoaderContainer : Container From f31220c1ee7aaf3f559b73248961d79208a089d8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 19:56:01 +0900 Subject: [PATCH 0486/1142] Fix exception when adding duplicate items --- .../Visual/Multiplayer/TestSceneMatchSongSelect.cs | 8 ++++++++ osu.Game/Screens/Select/MatchSongSelect.cs | 2 ++ 2 files changed, 10 insertions(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs index 434b265f9c..5820da811d 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSongSelect.cs @@ -126,6 +126,14 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("playlist has 1 item", () => Room.Playlist.Count == 1); } + [Test] + public void TestAddSameItemMultipleTimes() + { + AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem()); + AddStep("create new item", () => songSelect.BeatmapDetails.CreateNewItem()); + AddAssert("playlist has 2 items", () => Room.Playlist.Count == 2); + } + private class TestMatchSongSelect : MatchSongSelect { public new MatchBeatmapDetailArea BeatmapDetails => (MatchBeatmapDetailArea)base.BeatmapDetails; diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 4edc968e8a..cb0d09b6bb 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Linq; using Humanizer; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -53,6 +54,7 @@ namespace osu.Game.Screens.Select { PlaylistItem item = new PlaylistItem { + ID = (Playlist.LastOrDefault()?.ID + 1) ?? 0, Beatmap = { Value = Beatmap.Value.BeatmapInfo }, Ruleset = { Value = Ruleset.Value } }; From 1e80facfe8e67c03d83c3a0ca7c78e152097f3aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:03:37 +0900 Subject: [PATCH 0487/1142] Add subscreen test scene --- .../Multiplayer/TestSceneMatchSubScreen.cs | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs new file mode 100644 index 0000000000..76d950b847 --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs @@ -0,0 +1,87 @@ +// 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.Bindables; +using osu.Game.Beatmaps; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets; +using osu.Game.Screens.Multi.Match; +using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Screens.Select; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneMatchSubScreen : ScreenTestScene + { + protected override bool UseOnlineAPI => true; + + public override IReadOnlyList RequiredTypes => new[] + { + typeof(Screens.Multi.Multiplayer), + typeof(MatchSubScreen), + typeof(Header), + typeof(Footer) + }; + + [Cached] + private readonly Bindable currentRoom = new Bindable(); + + [Resolved] + private BeatmapManager beatmaps { get; set; } + + [Resolved] + private RulesetStore rulesets { get; set; } + + public TestSceneMatchSubScreen() + { + currentRoom.Value = new Room(); + } + + [Test] + public void TestShowRoom() + { + AddStep(@"show", () => + { + currentRoom.Value.RoomID.Value = 1; + currentRoom.Value.Availability.Value = RoomAvailability.Public; + currentRoom.Value.Duration.Value = TimeSpan.FromHours(24); + currentRoom.Value.Host.Value = new User { Username = "peppy", Id = 2 }; + currentRoom.Value.Name.Value = "super secret room"; + currentRoom.Value.Participants.AddRange(new[] + { + new User { Username = "peppy", Id = 2 }, + new User { Username = "smoogipoo", Id = 1040328 } + }); + currentRoom.Value.Playlist.Add(new PlaylistItem + { + Beatmap = { Value = beatmaps.GetAllUsableBeatmapSets()[0].Beatmaps[0] }, + Ruleset = { Value = rulesets.GetRuleset(2) }, + }); + + LoadScreen(new MatchSubScreen(currentRoom.Value)); + }); + } + + [Test] + public void TestShowSettings() + { + AddStep(@"show", () => + { + currentRoom.Value.RoomID.Value = null; + LoadScreen(new MatchSubScreen(currentRoom.Value)); + }); + } + + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new CachedModelDependencyContainer(base.CreateChildDependencies(parent)); + dependencies.Model.BindTo(currentRoom); + return dependencies; + } + } +} From b0793b06edd594f452dbc2b788f8105927884f28 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:07:52 +0900 Subject: [PATCH 0488/1142] Re-implement the match header --- .../Multiplayer/TestSceneMatchBeatmapPanel.cs | 41 ----- .../Multiplayer/TestSceneMatchHeader.cs | 5 +- .../Visual/Multiplayer/TestSceneMatchInfo.cs | 84 --------- .../Screens/Multi/Match/Components/Header.cs | 174 +++++------------- .../Match/Components/MatchBeatmapPanel.cs | 67 ------- .../Multi/Match/Components/MatchPage.cs | 28 --- .../Multi/Match/Components/MatchTabControl.cs | 66 ------- .../Screens/Multi/Match/MatchSubScreen.cs | 24 --- 8 files changed, 44 insertions(+), 445 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs delete mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs delete mode 100644 osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs delete mode 100644 osu.Game/Screens/Multi/Match/Components/MatchPage.cs delete mode 100644 osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs deleted file mode 100644 index f014b08325..0000000000 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapPanel.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using osu.Game.Beatmaps; -using osu.Game.Online.Multiplayer; -using osu.Game.Screens.Multi.Match.Components; -using osu.Framework.Graphics; -using osu.Game.Audio; -using osu.Framework.Allocation; - -namespace osu.Game.Tests.Visual.Multiplayer -{ - [Cached(typeof(IPreviewTrackOwner))] - public class TestSceneMatchBeatmapPanel : MultiplayerTestScene, IPreviewTrackOwner - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(MatchBeatmapPanel) - }; - - [Resolved] - private PreviewTrackManager previewTrackManager { get; set; } - - public TestSceneMatchBeatmapPanel() - { - Add(new MatchBeatmapPanel - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - }); - - Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 1763072 } } }); - Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 2101557 } } }); - Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 1973466 } } }); - Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 2109801 } } }); - Room.Playlist.Add(new PlaylistItem { Beatmap = { Value = new BeatmapInfo { OnlineBeatmapID = 1922035 } } }); - } - } -} diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs index 7d7e7f85db..cf40995fc0 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHeader.cs @@ -5,10 +5,10 @@ using System; using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; -using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Mods; using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Users; namespace osu.Game.Tests.Visual.Multiplayer { @@ -45,7 +45,8 @@ namespace osu.Game.Tests.Visual.Multiplayer } }); - Room.Type.Value = new GameTypeTimeshift(); + Room.Name.Value = "A very awesome room"; + Room.Host.Value = new User { Id = 2, Username = "peppy" }; Child = new Header(); } diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs deleted file mode 100644 index 6ee9ceb2dd..0000000000 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchInfo.cs +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Game.Beatmaps; -using osu.Game.Online.Multiplayer; -using osu.Game.Online.Multiplayer.RoomStatuses; -using osu.Game.Rulesets; -using osu.Game.Screens.Multi.Match.Components; - -namespace osu.Game.Tests.Visual.Multiplayer -{ - [TestFixture] - public class TestSceneMatchInfo : MultiplayerTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(Info), - typeof(HeaderButton), - typeof(ReadyButton), - typeof(MatchBeatmapPanel) - }; - - [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) - { - Add(new Info()); - - AddStep(@"set name", () => Room.Name.Value = @"Room Name?"); - AddStep(@"set availability", () => Room.Availability.Value = RoomAvailability.FriendsOnly); - AddStep(@"set status", () => Room.Status.Value = new RoomStatusPlaying()); - AddStep(@"set beatmap", () => - { - Room.Playlist.Clear(); - Room.Playlist.Add(new PlaylistItem - { - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 2.4, - Ruleset = rulesets.GetRuleset(0), - Metadata = new BeatmapMetadata - { - Title = @"My Song", - Artist = @"VisualTests", - AuthorString = @"osu!lazer", - }, - } - } - }); - }); - - AddStep(@"change name", () => Room.Name.Value = @"Room Name!"); - AddStep(@"change availability", () => Room.Availability.Value = RoomAvailability.InviteOnly); - AddStep(@"change status", () => Room.Status.Value = new RoomStatusOpen()); - AddStep(@"null beatmap", () => Room.Playlist.Clear()); - AddStep(@"change beatmap", () => - { - Room.Playlist.Clear(); - Room.Playlist.Add(new PlaylistItem - { - Beatmap = - { - Value = new BeatmapInfo - { - StarDifficulty = 4.2, - Ruleset = rulesets.GetRuleset(3), - Metadata = new BeatmapMetadata - { - Title = @"Your Song", - Artist = @"Tester", - AuthorString = @"Someone", - }, - } - } - }); - }); - } - } -} diff --git a/osu.Game/Screens/Multi/Match/Components/Header.cs b/osu.Game/Screens/Multi/Match/Components/Header.cs index cf1eb6b6ed..ddbaab1706 100644 --- a/osu.Game/Screens/Multi/Match/Components/Header.cs +++ b/osu.Game/Screens/Multi/Match/Components/Header.cs @@ -1,39 +1,23 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; -using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Online.Multiplayer; -using osu.Game.Overlays.SearchableList; -using osu.Game.Rulesets.Mods; -using osu.Game.Screens.Multi.Components; -using osu.Game.Screens.Play.HUD; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Users.Drawables; using osuTK; -using osuTK.Graphics; namespace osu.Game.Screens.Multi.Match.Components { public class Header : MultiplayerComposite { - public const float HEIGHT = 200; + public const float HEIGHT = 50; - public readonly BindableBool ShowBeatmapPanel = new BindableBool(); - - public MatchTabControl Tabs { get; private set; } - - public Action RequestBeatmapSelection; - - private MatchBeatmapPanel beatmapPanel; - private ModDisplay modDisplay; + private UpdateableAvatar avatar; + private LinkFlowContainer hostText; public Header() { @@ -44,128 +28,52 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load(OsuColour colours) { - BeatmapSelectButton beatmapButton; - - InternalChildren = new Drawable[] + InternalChild = new FillFlowContainer { - new Container + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new Drawable[] + avatar = new UpdateableAvatar { - new HeaderBackgroundSprite { RelativeSizeAxes = Axes.Both }, - new Box + Size = new Vector2(50), + Masking = true, + CornerRadius = 10, + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.7f), Color4.Black.Opacity(0.8f)), - }, - beatmapPanel = new MatchBeatmapPanel - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Margin = new MarginPadding { Right = 100 }, + new OsuSpriteText + { + Font = OsuFont.GetFont(size: 30), + Current = { BindTarget = RoomName } + }, + hostText = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 20, weight: FontWeight.SemiBold)) + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + } } } - }, - new Box - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Height = 1, - Colour = colours.Yellow - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 20 }, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new BeatmapTypeInfo(), - modDisplay = new ModDisplay - { - Scale = new Vector2(0.75f), - DisplayUnrankedText = false - }, - } - }, - new Container - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.Y, - Width = 200, - Padding = new MarginPadding { Vertical = 10 }, - Child = beatmapButton = new BeatmapSelectButton - { - RelativeSizeAxes = Axes.Both, - Height = 1, - }, - }, - Tabs = new MatchTabControl - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X - }, - }, - }, + } }; - beatmapButton.Action = () => RequestBeatmapSelection?.Invoke(); - - Playlist.ItemsAdded += _ => updateMods(); - Playlist.ItemsRemoved += _ => updateMods(); - - updateMods(); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - ShowBeatmapPanel.BindValueChanged(value => beatmapPanel.FadeTo(value.NewValue ? 1 : 0, 200, Easing.OutQuint), true); - } - - private void updateMods() - { - var item = Playlist.FirstOrDefault(); - - modDisplay.Current.Value = item?.RequiredMods?.ToArray() ?? Array.Empty(); - } - - private class BeatmapSelectButton : HeaderButton - { - [Resolved(typeof(Room), nameof(Room.RoomID))] - private Bindable roomId { get; set; } - - public BeatmapSelectButton() + Host.BindValueChanged(host => { - Text = "Select beatmap"; - } + avatar.User = host.NewValue; - [BackgroundDependencyLoader] - private void load() - { - roomId.BindValueChanged(id => this.FadeTo(id.NewValue.HasValue ? 0 : 1), true); - } - } + hostText.Clear(); - private class HeaderBackgroundSprite : MultiplayerBackgroundSprite - { - protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both }; - - private class BackgroundSprite : UpdateableBeatmapBackgroundSprite - { - protected override double TransformDuration => 200; - } + if (host.NewValue != null) + { + hostText.AddText("hosted by "); + hostText.AddUserLink(host.NewValue); + } + }, true); } } } diff --git a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs b/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs deleted file mode 100644 index c8de066caa..0000000000 --- a/osu.Game/Screens/Multi/Match/Components/MatchBeatmapPanel.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Linq; -using System.Threading; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests; -using osu.Game.Overlays.Direct; -using osu.Game.Rulesets; - -namespace osu.Game.Screens.Multi.Match.Components -{ - public class MatchBeatmapPanel : MultiplayerComposite - { - [Resolved] - private IAPIProvider api { get; set; } - - [Resolved] - private RulesetStore rulesets { get; set; } - - private CancellationTokenSource loadCancellation; - private GetBeatmapSetRequest request; - private DirectGridPanel panel; - - public MatchBeatmapPanel() - { - AutoSizeAxes = Axes.Both; - } - - [BackgroundDependencyLoader] - private void load() - { - Playlist.ItemsAdded += _ => loadNewPanel(); - Playlist.ItemsRemoved += _ => loadNewPanel(); - - loadNewPanel(); - } - - private void loadNewPanel() - { - loadCancellation?.Cancel(); - request?.Cancel(); - - panel?.FadeOut(200); - panel?.Expire(); - panel = null; - - var beatmap = Playlist.FirstOrDefault()?.Beatmap.Value; - - if (beatmap?.OnlineBeatmapID == null) - return; - - loadCancellation = new CancellationTokenSource(); - - request = new GetBeatmapSetRequest(beatmap.OnlineBeatmapID.Value, BeatmapSetLookupType.BeatmapId); - request.Success += res => Schedule(() => - { - panel = new DirectGridPanel(res.ToBeatmapSet(rulesets)); - LoadComponentAsync(panel, AddInternal, loadCancellation.Token); - }); - - api.Queue(request); - } - } -} diff --git a/osu.Game/Screens/Multi/Match/Components/MatchPage.cs b/osu.Game/Screens/Multi/Match/Components/MatchPage.cs deleted file mode 100644 index fc98db157b..0000000000 --- a/osu.Game/Screens/Multi/Match/Components/MatchPage.cs +++ /dev/null @@ -1,28 +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.Bindables; - -namespace osu.Game.Screens.Multi.Match.Components -{ - public abstract class MatchPage - { - public abstract string Name { get; } - - public readonly BindableBool Enabled = new BindableBool(true); - - public override string ToString() => Name; - public override int GetHashCode() => GetType().GetHashCode(); - public override bool Equals(object obj) => GetType() == obj?.GetType(); - } - - public class SettingsMatchPage : MatchPage - { - public override string Name => "Settings"; - } - - public class RoomMatchPage : MatchPage - { - public override string Name => "Room"; - } -} diff --git a/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs b/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs deleted file mode 100644 index c700d7b88a..0000000000 --- a/osu.Game/Screens/Multi/Match/Components/MatchTabControl.cs +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Input.Events; -using osu.Game.Graphics.UserInterface; -using osu.Game.Online.Multiplayer; -using osuTK.Graphics; - -namespace osu.Game.Screens.Multi.Match.Components -{ - public class MatchTabControl : PageTabControl - { - [Resolved(typeof(Room), nameof(Room.RoomID))] - private Bindable roomId { get; set; } - - public MatchTabControl() - { - AddItem(new RoomMatchPage()); - AddItem(new SettingsMatchPage()); - } - - [BackgroundDependencyLoader] - private void load() - { - roomId.BindValueChanged(id => - { - if (id.NewValue.HasValue) - { - Items.ForEach(t => t.Enabled.Value = !(t is SettingsMatchPage)); - Current.Value = new RoomMatchPage(); - } - else - { - Items.ForEach(t => t.Enabled.Value = t is SettingsMatchPage); - Current.Value = new SettingsMatchPage(); - } - }, true); - } - - protected override TabItem CreateTabItem(MatchPage value) => new TabItem(value); - - private class TabItem : PageTabItem - { - private readonly IBindable enabled = new BindableBool(); - - public TabItem(MatchPage value) - : base(value) - { - enabled.BindTo(value.Enabled); - enabled.BindValueChanged(enabled => Colour = enabled.NewValue ? Color4.White : Color4.Gray, true); - } - - protected override bool OnClick(ClickEvent e) - { - if (!enabled.Value) - return true; - - return base.OnClick(e); - } - } - } -} diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 890664e99b..ed1cb987c2 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -15,7 +15,6 @@ using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; -using osu.Game.Screens.Select; using PlaylistItem = osu.Game.Online.Multiplayer.PlaylistItem; namespace osu.Game.Screens.Multi.Match @@ -78,17 +77,6 @@ namespace osu.Game.Screens.Multi.Match header = new Components.Header { Depth = -1, - RequestBeatmapSelection = () => - { - this.Push(new MatchSongSelect - { - Selected = item => - { - Playlist.Clear(); - Playlist.Add(item); - } - }); - } } }, new Drawable[] { info = new Info { OnStart = onStart } }, @@ -145,18 +133,6 @@ namespace osu.Game.Screens.Multi.Match }, }; - header.Tabs.Current.BindValueChanged(tab => - { - const float fade_duration = 500; - - var settingsDisplayed = tab.NewValue is SettingsMatchPage; - - header.ShowBeatmapPanel.Value = !settingsDisplayed; - settings.State.Value = settingsDisplayed ? Visibility.Visible : Visibility.Hidden; - info.FadeTo(settingsDisplayed ? 0 : 1, fade_duration, Easing.OutQuint); - bottomRow.FadeTo(settingsDisplayed ? 0 : 1, fade_duration, Easing.OutQuint); - }, true); - beatmapManager.ItemAdded += beatmapAdded; } From 73621e41fd7b4f4164d5a316ca0d13b5cf267229 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Feb 2020 20:12:23 +0900 Subject: [PATCH 0489/1142] Forcefully hide mute notification for navigation tests --- osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index 8d2e4a614d..70d71d0952 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -117,6 +117,8 @@ namespace osu.Game.Tests.Visual.Navigation { base.LoadComplete(); API.Login("Rhythm Champion", "osu!"); + + Dependencies.Get().Set(Static.MutedAudioNotificationShownOnce, true); } } From c0dba632787246a7ef98b56fcf561dc827eb885f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:14:25 +0900 Subject: [PATCH 0490/1142] Remove match info --- .../Multiplayer/TestSceneMatchHostInfo.cs | 35 ------ .../Multiplayer/TestSceneMatchParticipants.cs | 52 --------- .../Multi/Match/Components/HeaderButton.cs | 47 -------- .../Multi/Match/Components/HostInfo.cs | 61 ---------- .../Screens/Multi/Match/Components/Info.cs | 107 ------------------ .../Multi/Match/Components/Participants.cs | 77 ------------- .../Multi/Match/Components/ReadyButton.cs | 3 +- .../Screens/Multi/Match/MatchSubScreen.cs | 2 - 8 files changed, 2 insertions(+), 382 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHostInfo.cs delete mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchParticipants.cs delete mode 100644 osu.Game/Screens/Multi/Match/Components/HeaderButton.cs delete mode 100644 osu.Game/Screens/Multi/Match/Components/HostInfo.cs delete mode 100644 osu.Game/Screens/Multi/Match/Components/Info.cs delete mode 100644 osu.Game/Screens/Multi/Match/Components/Participants.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHostInfo.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHostInfo.cs deleted file mode 100644 index 808a45cdf0..0000000000 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchHostInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Collections.Generic; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Game.Screens.Multi.Match.Components; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual.Multiplayer -{ - public class TestSceneMatchHostInfo : OsuTestScene - { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(HostInfo) - }; - - private readonly Bindable host = new Bindable(new User { Username = "SomeHost" }); - - public TestSceneMatchHostInfo() - { - HostInfo hostInfo; - - Child = hostInfo = new HostInfo - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre - }; - - hostInfo.Host.BindTo(host); - } - } -} diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchParticipants.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchParticipants.cs deleted file mode 100644 index a6f47961e9..0000000000 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchParticipants.cs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using NUnit.Framework; -using osu.Framework.Graphics; -using osu.Game.Screens.Multi.Match.Components; -using osu.Game.Users; - -namespace osu.Game.Tests.Visual.Multiplayer -{ - [TestFixture] - public class TestSceneMatchParticipants : MultiplayerTestScene - { - public TestSceneMatchParticipants() - { - Add(new Participants { RelativeSizeAxes = Axes.Both }); - - AddStep(@"set max to null", () => Room.MaxParticipants.Value = null); - AddStep(@"set users", () => Room.Participants.AddRange(new[] - { - new User - { - Username = @"Feppla", - Id = 4271601, - Country = new Country { FlagName = @"SE" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg", - IsSupporter = true, - }, - new User - { - Username = @"Xilver", - Id = 3099689, - Country = new Country { FlagName = @"IL" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c2.jpg", - IsSupporter = true, - }, - new User - { - Username = @"Wucki", - Id = 5287410, - Country = new Country { FlagName = @"FI" }, - CoverUrl = @"https://assets.ppy.sh/user-profile-covers/5287410/5cfeaa9dd41cbce038ecdc9d781396ed4b0108089170bf7f50492ef8eadeb368.jpeg", - IsSupporter = true, - }, - })); - - AddStep(@"set max", () => Room.MaxParticipants.Value = 10); - AddStep(@"clear users", () => Room.Participants.Clear()); - AddStep(@"set max to null", () => Room.MaxParticipants.Value = null); - } - } -} diff --git a/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs b/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs deleted file mode 100644 index de6ece6a05..0000000000 --- a/osu.Game/Screens/Multi/Match/Components/HeaderButton.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; - -namespace osu.Game.Screens.Multi.Match.Components -{ - public class HeaderButton : TriangleButton - { - [BackgroundDependencyLoader] - private void load() - { - BackgroundColour = OsuColour.FromHex(@"1187aa"); - - Triangles.ColourLight = OsuColour.FromHex(@"277b9c"); - Triangles.ColourDark = OsuColour.FromHex(@"1f6682"); - Triangles.TriangleScale = 1.5f; - - Add(new Container - { - RelativeSizeAxes = Axes.Both, - Alpha = 1f, - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0.15f, - Blending = BlendingParameters.Additive, - }, - }); - } - - protected override SpriteText CreateText() => new OsuSpriteText - { - Depth = -1, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Font = OsuFont.GetFont(weight: FontWeight.Light, size: 30), - }; - } -} diff --git a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs b/osu.Game/Screens/Multi/Match/Components/HostInfo.cs deleted file mode 100644 index 8851a96605..0000000000 --- a/osu.Game/Screens/Multi/Match/Components/HostInfo.cs +++ /dev/null @@ -1,61 +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.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Users; -using osu.Game.Users.Drawables; -using osuTK; - -namespace osu.Game.Screens.Multi.Match.Components -{ - public class HostInfo : CompositeDrawable - { - public readonly IBindable Host = new Bindable(); - - private readonly LinkFlowContainer linkContainer; - private readonly UpdateableAvatar avatar; - - public HostInfo() - { - AutoSizeAxes = Axes.X; - Height = 50; - - InternalChild = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5, 0), - Children = new Drawable[] - { - avatar = new UpdateableAvatar { Size = new Vector2(50) }, - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Child = linkContainer = new LinkFlowContainer { AutoSizeAxes = Axes.Both } - } - } - }; - - Host.BindValueChanged(host => updateHost(host.NewValue)); - } - - private void updateHost(User host) - { - avatar.User = host; - - if (host != null) - { - linkContainer.AddText("hosted by"); - linkContainer.NewLine(); - linkContainer.AddUserLink(host, s => s.Font = s.Font.With(Typeface.Exo, weight: FontWeight.Bold, italics: true)); - } - } - } -} diff --git a/osu.Game/Screens/Multi/Match/Components/Info.cs b/osu.Game/Screens/Multi/Match/Components/Info.cs deleted file mode 100644 index a320b08cc4..0000000000 --- a/osu.Game/Screens/Multi/Match/Components/Info.cs +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using System.Linq; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Overlays.SearchableList; -using osu.Game.Screens.Multi.Components; -using osuTK; - -namespace osu.Game.Screens.Multi.Match.Components -{ - public class Info : MultiplayerComposite - { - public Action OnStart; - - private ReadyButton readyButton; - - public Info() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - } - - [BackgroundDependencyLoader] - private void load() - { - HostInfo hostInfo; - - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"28242d"), - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 10), - Padding = new MarginPadding { Vertical = 20 }, - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - new OsuSpriteText - { - Font = OsuFont.GetFont(size: 30), - Current = RoomName - }, - new RoomStatusInfo(), - } - }, - hostInfo = new HostInfo(), - }, - }, - new FillFlowContainer - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - AutoSizeAxes = Axes.X, - Height = 70, - Spacing = new Vector2(10, 0), - Direction = FillDirection.Horizontal, - Children = new Drawable[] - { - readyButton = new ReadyButton - { - Action = () => OnStart?.Invoke() - } - } - } - }, - }, - }; - - hostInfo.Host.BindTo(Host); - - Playlist.ItemsAdded += _ => updateBeatmap(); - Playlist.ItemsRemoved += _ => updateBeatmap(); - - updateBeatmap(); - } - - private void updateBeatmap() - { - readyButton.Beatmap.Value = Playlist.FirstOrDefault()?.Beatmap.Value; - } - } -} diff --git a/osu.Game/Screens/Multi/Match/Components/Participants.cs b/osu.Game/Screens/Multi/Match/Components/Participants.cs deleted file mode 100644 index 00d2f3e150..0000000000 --- a/osu.Game/Screens/Multi/Match/Components/Participants.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System.Linq; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics.Containers; -using osu.Game.Overlays.SearchableList; -using osu.Game.Screens.Multi.Components; -using osu.Game.Users; -using osuTK; - -namespace osu.Game.Screens.Multi.Match.Components -{ - public class Participants : MultiplayerComposite - { - [BackgroundDependencyLoader] - private void load() - { - FillFlowContainer usersFlow; - - InternalChild = new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, - Children = new Drawable[] - { - new OsuScrollContainer - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 10 }, - Children = new Drawable[] - { - new ParticipantCountDisplay - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - }, - usersFlow = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(5), - Padding = new MarginPadding { Top = 40 }, - LayoutDuration = 200, - LayoutEasing = Easing.OutQuint, - }, - }, - }, - }, - }; - - Participants.ItemsAdded += users => - { - usersFlow.AddRange(users.Select(u => - { - var panel = new UserPanel(u) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Width = 300, - }; - - panel.OnLoadComplete += d => d.FadeInFromZero(60); - - return panel; - }).ToList()); - }; - - Participants.ItemsRemoved += users => - { - usersFlow.RemoveAll(p => users.Contains(p.User)); - }; - } - } -} diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index 8ab0b8f61f..cec5b2f855 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -7,12 +7,13 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osuTK; namespace osu.Game.Screens.Multi.Match.Components { - public class ReadyButton : HeaderButton + public class ReadyButton : OsuButton { public readonly Bindable Beatmap = new Bindable(); diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index ed1cb987c2..07da707724 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -61,7 +61,6 @@ namespace osu.Game.Screens.Multi.Match private void load() { Components.Header header; - Info info; GridContainer bottomRow; MatchSettingsOverlay settings; @@ -79,7 +78,6 @@ namespace osu.Game.Screens.Multi.Match Depth = -1, } }, - new Drawable[] { info = new Info { OnStart = onStart } }, new Drawable[] { bottomRow = new GridContainer From 80fd9485a9681b5c092860be6625c7495b111f22 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:18:53 +0900 Subject: [PATCH 0491/1142] Refactor ready button to support selected playlist item --- .../Multi/Match/Components/ReadyButton.cs | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index cec5b2f855..a62572a851 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Screens.Multi.Match.Components { public class ReadyButton : OsuButton { - public readonly Bindable Beatmap = new Bindable(); + public readonly Bindable SelectedItem = new Bindable(); [Resolved(typeof(Room), nameof(Room.EndDate))] private Bindable endDate { get; set; } @@ -42,31 +42,37 @@ namespace osu.Game.Screens.Multi.Match.Components beatmaps.ItemAdded += beatmapAdded; beatmaps.ItemRemoved += beatmapRemoved; - Beatmap.BindValueChanged(b => updateBeatmap(b.NewValue), true); + SelectedItem.BindValueChanged(item => updateSelectedItem(item.NewValue), true); } - private void updateBeatmap(BeatmapInfo beatmap) + private void updateSelectedItem(PlaylistItem item) { hasBeatmap = false; - if (beatmap?.OnlineBeatmapID == null) + int? beatmapId = SelectedItem.Value?.Beatmap.Value?.OnlineBeatmapID; + if (beatmapId == null) return; - hasBeatmap = beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID) != null; + hasBeatmap = beatmaps.QueryBeatmap(b => b.OnlineBeatmapID == beatmapId) != null; } private void beatmapAdded(BeatmapSetInfo model) { - if (model.Beatmaps.Any(b => b.OnlineBeatmapID == Beatmap.Value.OnlineBeatmapID)) + int? beatmapId = SelectedItem.Value?.Beatmap.Value?.OnlineBeatmapID; + if (beatmapId == null) + return; + + if (model.Beatmaps.Any(b => b.OnlineBeatmapID == beatmapId)) Schedule(() => hasBeatmap = true); } private void beatmapRemoved(BeatmapSetInfo model) { - if (Beatmap.Value == null) + int? beatmapId = SelectedItem.Value?.Beatmap.Value?.OnlineBeatmapID; + if (beatmapId == null) return; - if (model.OnlineBeatmapSetID == Beatmap.Value.BeatmapSet.OnlineBeatmapSetID) + if (model.Beatmaps.Any(b => b.OnlineBeatmapID == beatmapId)) Schedule(() => hasBeatmap = false); } @@ -79,7 +85,7 @@ namespace osu.Game.Screens.Multi.Match.Components private void updateEnabledState() { - if (gameBeatmap.Value == null) + if (gameBeatmap.Value == null || SelectedItem.Value == null) { Enabled.Value = false; return; @@ -95,7 +101,10 @@ namespace osu.Game.Screens.Multi.Match.Components base.Dispose(isDisposing); if (beatmaps != null) + { beatmaps.ItemAdded -= beatmapAdded; + beatmaps.ItemRemoved -= beatmapRemoved; + } } } } From c75a7742977122303c59de7bc036b7310238fec9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:27:37 +0900 Subject: [PATCH 0492/1142] Extract participants list from the room inspector --- .../Multiplayer/TestSceneParticipantsList.cs | 20 +++ .../Multi/Components/ParticipantsList.cs | 119 ++++++++++++++++++ .../Multi/Lounge/Components/RoomInspector.cs | 113 +---------------- 3 files changed, 142 insertions(+), 110 deletions(-) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneParticipantsList.cs create mode 100644 osu.Game/Screens/Multi/Components/ParticipantsList.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneParticipantsList.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneParticipantsList.cs new file mode 100644 index 0000000000..9c4c45f94a --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneParticipantsList.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Screens.Multi.Components; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneParticipantsList : MultiplayerTestScene + { + protected override bool UseOnlineAPI => true; + + public TestSceneParticipantsList() + { + Room.RoomID.Value = 7; + + Add(new ParticipantsList { RelativeSizeAxes = Axes.Both }); + } + } +} diff --git a/osu.Game/Screens/Multi/Components/ParticipantsList.cs b/osu.Game/Screens/Multi/Components/ParticipantsList.cs new file mode 100644 index 0000000000..2ef36b2795 --- /dev/null +++ b/osu.Game/Screens/Multi/Components/ParticipantsList.cs @@ -0,0 +1,119 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; +using osu.Game.Users; +using osu.Game.Users.Drawables; +using osuTK; + +namespace osu.Game.Screens.Multi.Components +{ + public class ParticipantsList : MultiplayerComposite + { + private readonly FillFlowContainer fill; + + public ParticipantsList() + { + InternalChild = new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + Child = fill = new FillFlowContainer + { + Spacing = new Vector2(10), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Full, + } + }; + } + + [BackgroundDependencyLoader] + private void load() + { + RoomID.BindValueChanged(_ => updateParticipants(), true); + } + + [Resolved] + private IAPIProvider api { get; set; } + + private GetRoomScoresRequest request; + + private void updateParticipants() + { + var roomId = RoomID.Value ?? 0; + + request?.Cancel(); + + // nice little progressive fade + int time = 500; + + foreach (var c in fill.Children) + { + c.Delay(500 - time).FadeOut(time, Easing.Out); + time = Math.Max(20, time - 20); + c.Expire(); + } + + if (roomId == 0) return; + + request = new GetRoomScoresRequest(roomId); + request.Success += scores => Schedule(() => + { + if (roomId != RoomID.Value) + return; + + fill.Clear(); + foreach (var s in scores) + fill.Add(new UserTile(s.User)); + + fill.FadeInFromZero(1000, Easing.OutQuint); + }); + + api.Queue(request); + } + + protected override void Dispose(bool isDisposing) + { + request?.Cancel(); + base.Dispose(isDisposing); + } + + private class UserTile : CompositeDrawable, IHasTooltip + { + private readonly User user; + + public string TooltipText => user.Username; + + public UserTile(User user) + { + this.user = user; + Size = new Vector2(70f); + CornerRadius = 5f; + Masking = true; + + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"27252d"), + }, + new UpdateableAvatar + { + RelativeSizeAxes = Axes.Both, + User = user, + }, + }; + } + } + } +} diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index 5030d8cb50..cb6bbf6731 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -1,25 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Components; -using osu.Game.Users; -using osu.Game.Users.Drawables; using osuTK; using osuTK.Graphics; @@ -160,9 +153,11 @@ namespace osu.Game.Screens.Multi.Lounge.Components }, new Drawable[] { - new MatchParticipants + new Container { RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 10 }, + Child = new ParticipantsList { RelativeSizeAxes = Axes.Both } } } } @@ -219,107 +214,5 @@ namespace osu.Game.Screens.Multi.Lounge.Components status.BindValueChanged(s => Text = s.NewValue.Message, true); } } - - private class MatchParticipants : MultiplayerComposite - { - private readonly FillFlowContainer fill; - - public MatchParticipants() - { - Padding = new MarginPadding { Horizontal = 10 }; - - InternalChild = new OsuScrollContainer - { - RelativeSizeAxes = Axes.Both, - Child = fill = new FillFlowContainer - { - Spacing = new Vector2(10), - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Full, - } - }; - } - - [BackgroundDependencyLoader] - private void load() - { - RoomID.BindValueChanged(_ => updateParticipants(), true); - } - - [Resolved] - private IAPIProvider api { get; set; } - - private GetRoomScoresRequest request; - - private void updateParticipants() - { - var roomId = RoomID.Value ?? 0; - - request?.Cancel(); - - // nice little progressive fade - int time = 500; - - foreach (var c in fill.Children) - { - c.Delay(500 - time).FadeOut(time, Easing.Out); - time = Math.Max(20, time - 20); - c.Expire(); - } - - if (roomId == 0) return; - - request = new GetRoomScoresRequest(roomId); - request.Success += scores => - { - if (roomId != RoomID.Value) - return; - - fill.Clear(); - foreach (var s in scores) - fill.Add(new UserTile(s.User)); - - fill.FadeInFromZero(1000, Easing.OutQuint); - }; - - api.Queue(request); - } - - protected override void Dispose(bool isDisposing) - { - request?.Cancel(); - base.Dispose(isDisposing); - } - - private class UserTile : CompositeDrawable, IHasTooltip - { - private readonly User user; - - public string TooltipText => user.Username; - - public UserTile(User user) - { - this.user = user; - Size = new Vector2(70f); - CornerRadius = 5f; - Masking = true; - - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"27252d"), - }, - new UpdateableAvatar - { - RelativeSizeAxes = Axes.Both, - User = user, - }, - }; - } - } - } } } From d5496321e2cf8dfaf0c254460786d25d0bacac8b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:31:55 +0900 Subject: [PATCH 0493/1142] Implement leaderboard chat display --- .../TestSceneMatchLeaderboardChatDisplay.cs | 39 +++++++ .../Components/LeaderboardChatDisplay.cs | 100 ++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboardChatDisplay.cs create mode 100644 osu.Game/Screens/Multi/Match/Components/LeaderboardChatDisplay.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboardChatDisplay.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboardChatDisplay.cs new file mode 100644 index 0000000000..e46386b263 --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchLeaderboardChatDisplay.cs @@ -0,0 +1,39 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Screens.Multi.Match.Components; +using osuTK; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneMatchLeaderboardChatDisplay : MultiplayerTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(LeaderboardChatDisplay) + }; + + protected override bool UseOnlineAPI => true; + + public TestSceneMatchLeaderboardChatDisplay() + { + Room.RoomID.Value = 7; + + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(500), + Child = new LeaderboardChatDisplay + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }); + } + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/LeaderboardChatDisplay.cs b/osu.Game/Screens/Multi/Match/Components/LeaderboardChatDisplay.cs new file mode 100644 index 0000000000..de02b7f605 --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/LeaderboardChatDisplay.cs @@ -0,0 +1,100 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.UserInterface; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class LeaderboardChatDisplay : MultiplayerComposite + { + private const double fade_duration = 100; + + private readonly OsuTabControl tabControl; + private readonly MatchLeaderboard leaderboard; + private readonly MatchChatDisplay chat; + + public LeaderboardChatDisplay() + { + RelativeSizeAxes = Axes.Both; + + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + tabControl = new DisplayModeTabControl + { + RelativeSizeAxes = Axes.X, + Height = 24, + } + }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 10 }, + Children = new Drawable[] + { + leaderboard = new MatchLeaderboard { RelativeSizeAxes = Axes.Both }, + chat = new MatchChatDisplay + { + RelativeSizeAxes = Axes.Both, + Alpha = 0 + } + } + } + }, + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + tabControl.AccentColour = colours.Yellow; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + tabControl.Current.BindValueChanged(changeTab); + } + + public void RefreshScores() => leaderboard.RefreshScores(); + + private void changeTab(ValueChangedEvent mode) + { + chat.FadeTo(mode.NewValue == DisplayMode.Chat ? 1 : 0, fade_duration); + leaderboard.FadeTo(mode.NewValue == DisplayMode.Leaderboard ? 1 : 0, fade_duration); + } + + private class DisplayModeTabControl : OsuTabControl + { + protected override TabItem CreateTabItem(DisplayMode value) => base.CreateTabItem(value).With(d => + { + d.Anchor = Anchor.Centre; + d.Origin = Anchor.Centre; + }); + } + + private enum DisplayMode + { + Leaderboard, + Chat, + } + } +} From d0b7b7f53a2892571f25c0daee83e229e40420a9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:34:15 +0900 Subject: [PATCH 0494/1142] Re-layout match settings overlay --- .../Match/Components/MatchSettingsOverlay.cs | 58 +++++++++++++++---- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 410aaed788..776de424ab 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -25,6 +25,8 @@ namespace osu.Game.Screens.Multi.Match.Components private const float transition_duration = 350; private const float field_padding = 45; + public Action EditPlaylist; + protected MatchSettings Settings { get; private set; } [BackgroundDependencyLoader] @@ -35,7 +37,8 @@ namespace osu.Game.Screens.Multi.Match.Components Child = Settings = new MatchSettings { RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.Y + RelativePositionAxes = Axes.Y, + EditPlaylist = () => EditPlaylist?.Invoke() }; } @@ -53,6 +56,8 @@ namespace osu.Game.Screens.Multi.Match.Components { private const float disabled_alpha = 0.2f; + public Action EditPlaylist; + public OsuTextBox NameField, MaxParticipantsField; public OsuDropdown DurationField; public RoomAvailabilityPicker AvailabilityPicker; @@ -63,6 +68,7 @@ namespace osu.Game.Screens.Multi.Match.Components private OsuSpriteText typeLabel; private ProcessingOverlay processingOverlay; + private DrawableRoomPlaylist playlist; [Resolved(CanBeNull = true)] private IRoomManager manager { get; set; } @@ -155,15 +161,6 @@ namespace osu.Game.Screens.Multi.Match.Components }, }, }, - }, - }, - new SectionContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Padding = new MarginPadding { Left = field_padding / 2 }, - Children = new[] - { new Section("Max participants") { Alpha = disabled_alpha, @@ -208,6 +205,45 @@ namespace osu.Game.Screens.Multi.Match.Components }, }, }, + new SectionContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Padding = new MarginPadding { Left = field_padding / 2 }, + Children = new[] + { + new Section("Playlist") + { + Child = new GridContainer + { + RelativeSizeAxes = Axes.X, + Height = 300, + Content = new[] + { + new Drawable[] + { + playlist = new DrawableRoomPlaylist(true, true) { RelativeSizeAxes = Axes.Both } + }, + new Drawable[] + { + new OsuButton + { + RelativeSizeAxes = Axes.X, + Height = 40, + Text = "Edit playlist", + Action = () => EditPlaylist?.Invoke() + } + } + }, + RowDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + } + } + }, + }, + }, }, } }, @@ -271,6 +307,8 @@ namespace osu.Game.Screens.Multi.Match.Components Type.BindValueChanged(type => TypePicker.Current.Value = type.NewValue, true); MaxParticipants.BindValueChanged(count => MaxParticipantsField.Text = count.NewValue?.ToString(), true); Duration.BindValueChanged(duration => DurationField.Current.Value = duration.NewValue, true); + + playlist.Items.BindTo(Playlist); } protected override void Update() From 929eb4f035d00a0d7b32b602c266685dec374afc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:35:52 +0900 Subject: [PATCH 0495/1142] Add match footer --- .../Multiplayer/TestSceneMatchSubScreen.cs | 1 - .../Screens/Multi/Match/Components/Footer.cs | 53 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/Multi/Match/Components/Footer.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs index 76d950b847..61def4be1a 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs @@ -11,7 +11,6 @@ using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; using osu.Game.Screens.Multi.Match; using osu.Game.Screens.Multi.Match.Components; -using osu.Game.Screens.Select; using osu.Game.Users; namespace osu.Game.Tests.Visual.Multiplayer diff --git a/osu.Game/Screens/Multi/Match/Components/Footer.cs b/osu.Game/Screens/Multi/Match/Components/Footer.cs new file mode 100644 index 0000000000..93430d9131 --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/Footer.cs @@ -0,0 +1,53 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.Multiplayer; +using osuTK; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class Footer : CompositeDrawable + { + public const float HEIGHT = 100; + + public Action OnStart; + public readonly Bindable SelectedItem = new Bindable(); + + private readonly Drawable background; + private readonly OsuButton startButton; + + public Footer() + { + RelativeSizeAxes = Axes.X; + Height = HEIGHT; + + InternalChildren = new[] + { + background = new Box { RelativeSizeAxes = Axes.Both }, + startButton = new ReadyButton + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(600, 50), + SelectedItem = { BindTarget = SelectedItem }, + Action = () => OnStart?.Invoke() + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = OsuColour.FromHex(@"28242d"); + startButton.BackgroundColour = colours.Green; + } + } +} From 6d87d22a84abb31ac09aa0d311b2dc2c84616486 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Fri, 14 Feb 2020 18:40:58 +0700 Subject: [PATCH 0496/1142] Remove duplicated dependency on AudioManager --- osu.Game/Screens/Menu/IntroTriangles.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 50cfe23481..4deaa68467 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Menu private SampleChannel welcome; [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load() { if (MenuVoice.Value && !MenuMusic.Value) welcome = audio.Samples.Get(@"welcome"); From b762e5e8a5f48ce0d098ba79d2b6e50ec5946186 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:42:14 +0900 Subject: [PATCH 0497/1142] Implement overlined components --- .../TestSceneOverlinedParticipants.cs | 28 ++++++ .../Multiplayer/TestSceneOverlinedPlaylist.cs | 39 +++++++++ .../Match/Components/OverlinedDisplay.cs | 87 +++++++++++++++++++ .../Match/Components/OverlinedParticipants.cs | 29 +++++++ .../Match/Components/OverlinedPlaylist.cs | 33 +++++++ 5 files changed, 216 insertions(+) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs create mode 100644 osu.Game/Screens/Multi/Match/Components/OverlinedDisplay.cs create mode 100644 osu.Game/Screens/Multi/Match/Components/OverlinedParticipants.cs create mode 100644 osu.Game/Screens/Multi/Match/Components/OverlinedPlaylist.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs new file mode 100644 index 0000000000..e07ebc1454 --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs @@ -0,0 +1,28 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Screens.Multi.Match.Components; +using osuTK; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneOverlinedParticipants : MultiplayerTestScene + { + protected override bool UseOnlineAPI => true; + + public TestSceneOverlinedParticipants() + { + Room.RoomID.Value = 7; + + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(500), + Child = new OverlinedParticipants() + }); + } + } +} diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs new file mode 100644 index 0000000000..cf4897be50 --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Online.Multiplayer; +using osu.Game.Rulesets.Osu; +using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Tests.Beatmaps; +using osuTK; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneOverlinedPlaylist : MultiplayerTestScene + { + protected override bool UseOnlineAPI => true; + + public TestSceneOverlinedPlaylist() + { + for (int i = 0; i < 10; i++) + { + Room.Playlist.Add(new PlaylistItem + { + ID = i, + Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo } + }); + } + + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(500), + Child = new OverlinedPlaylist(false) + }); + } + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/OverlinedDisplay.cs b/osu.Game/Screens/Multi/Match/Components/OverlinedDisplay.cs new file mode 100644 index 0000000000..854877bd1c --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/OverlinedDisplay.cs @@ -0,0 +1,87 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public abstract class OverlinedDisplay : MultiplayerComposite + { + protected readonly Container Content; + + protected string Details + { + set => details.Text = value; + } + + private readonly Circle line; + private readonly OsuSpriteText details; + + protected OverlinedDisplay(string title) + { + RelativeSizeAxes = Axes.Both; + + InternalChild = new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + line = new Circle + { + RelativeSizeAxes = Axes.X, + Height = 2, + Margin = new MarginPadding { Bottom = 2 } + }, + }, + new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Margin = new MarginPadding { Top = 5 }, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new OsuSpriteText + { + Text = title, + Font = OsuFont.GetFont(size: 14) + }, + details = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) }, + } + }, + }, + new Drawable[] + { + Content = new Container + { + Margin = new MarginPadding { Top = 5 }, + RelativeSizeAxes = Axes.Both + } + } + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + line.Colour = colours.Yellow; + details.Colour = colours.Yellow; + } + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/OverlinedParticipants.cs b/osu.Game/Screens/Multi/Match/Components/OverlinedParticipants.cs new file mode 100644 index 0000000000..7a4290a9a1 --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/OverlinedParticipants.cs @@ -0,0 +1,29 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Screens.Multi.Components; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class OverlinedParticipants : OverlinedDisplay + { + public OverlinedParticipants() + : base("Participants") + { + Content.Add(new ParticipantsList { RelativeSizeAxes = Axes.Both }); + } + + [BackgroundDependencyLoader] + private void load() + { + ParticipantCount.BindValueChanged(_ => setParticipantCount()); + MaxParticipants.BindValueChanged(_ => setParticipantCount()); + + setParticipantCount(); + } + + private void setParticipantCount() => Details = MaxParticipants.Value != null ? $"{ParticipantCount.Value}/{MaxParticipants.Value}" : ParticipantCount.Value.ToString(); + } +} diff --git a/osu.Game/Screens/Multi/Match/Components/OverlinedPlaylist.cs b/osu.Game/Screens/Multi/Match/Components/OverlinedPlaylist.cs new file mode 100644 index 0000000000..eea85d9d64 --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/OverlinedPlaylist.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Online.Multiplayer; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class OverlinedPlaylist : OverlinedDisplay + { + public readonly Bindable SelectedItem = new Bindable(); + + private readonly DrawableRoomPlaylist playlist; + + public OverlinedPlaylist(bool allowSelection) + : base("Playlist") + { + Content.Add(playlist = new DrawableRoomPlaylist(false, allowSelection) + { + RelativeSizeAxes = Axes.Both, + SelectedItem = { BindTarget = SelectedItem } + }); + } + + [BackgroundDependencyLoader] + private void load() + { + playlist.Items.BindTo(Playlist); + } + } +} From 2ea8c47c83a084bf3bc67ebe527c5bebfe12dc00 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:44:41 +0900 Subject: [PATCH 0498/1142] Fix incorrect footer button size --- osu.Game/Screens/Multi/Match/Components/ReadyButton.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index a62572a851..d39217db5d 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -5,11 +5,9 @@ using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; -using osuTK; namespace osu.Game.Screens.Multi.Match.Components { @@ -30,9 +28,6 @@ namespace osu.Game.Screens.Multi.Match.Components public ReadyButton() { - RelativeSizeAxes = Axes.Y; - Size = new Vector2(200, 1); - Text = "Start"; } From b92f1ad68dc57c67b33fe8bf180419b6118c93d7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 20:48:09 +0900 Subject: [PATCH 0499/1142] Implement match subscreen re-design --- .../TestSceneMatchBeatmapDetailArea.cs | 4 +- .../Screens/Multi/Match/MatchSubScreen.cs | 223 ++++++++++-------- 2 files changed, 125 insertions(+), 102 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs index 09d882a265..5c7ad7616d 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchBeatmapDetailArea.cs @@ -24,14 +24,12 @@ namespace osu.Game.Tests.Visual.Multiplayer private RulesetStore rulesetStore { get; set; } - private MatchBeatmapDetailArea detailArea; - [SetUp] public void Setup() => Schedule(() => { Room.Playlist.Clear(); - Child = detailArea = new MatchBeatmapDetailArea + Child = new MatchBeatmapDetailArea { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 07da707724..44fccdaa13 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -5,17 +5,23 @@ using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Audio; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; -using PlaylistItem = osu.Game.Online.Multiplayer.PlaylistItem; +using osu.Game.Screens.Select; +using osuTK.Graphics; +using Footer = osu.Game.Screens.Multi.Match.Components.Footer; namespace osu.Game.Screens.Multi.Match { @@ -31,26 +37,21 @@ namespace osu.Game.Screens.Multi.Match [Resolved(typeof(Room), nameof(Room.RoomID))] private Bindable roomId { get; set; } - [Resolved(typeof(Room), nameof(Room.Name))] - private Bindable name { get; set; } - [Resolved(typeof(Room), nameof(Room.Type))] private Bindable type { get; set; } - [Resolved(typeof(Room))] - protected BindableList Playlist { get; private set; } + [Resolved(typeof(Room), nameof(Room.Playlist))] + private BindableList playlist { get; set; } [Resolved] private BeatmapManager beatmapManager { get; set; } - [Resolved] - private PreviewTrackManager previewTrackManager { get; set; } - - [Resolved(CanBeNull = true)] - private OsuGame game { get; set; } + [Resolved(canBeNull: true)] + private Multiplayer multiplayer { get; set; } private readonly Bindable selectedItem = new Bindable(); - private MatchLeaderboard leaderboard; + private LeaderboardChatDisplay leaderboardChatDisplay; + private MatchSettingsOverlay settingsOverlay; public MatchSubScreen(Room room) { @@ -60,12 +61,14 @@ namespace osu.Game.Screens.Multi.Match [BackgroundDependencyLoader] private void load() { - Components.Header header; - GridContainer bottomRow; - MatchSettingsOverlay settings; - InternalChildren = new Drawable[] { + new HeaderBackgroundSprite + { + RelativeSizeAxes = Axes.X, + Height = 200, + Colour = ColourInfo.GradientVertical(Color4.White.Opacity(0.4f), Color4.White.Opacity(0)) + }, new GridContainer { RelativeSizeAxes = Axes.Both, @@ -73,143 +76,155 @@ namespace osu.Game.Screens.Multi.Match { new Drawable[] { - header = new Components.Header + new Container { - Depth = -1, + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding + { + Horizontal = 105, + Vertical = 20 + }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] { new Components.Header() }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Top = 65 }, + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Right = 5 }, + Child = new OverlinedParticipants() + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Horizontal = 5 }, + Child = new OverlinedPlaylist(true) // Temporarily always allow selection + { + SelectedItem = { BindTarget = selectedItem } + } + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = 5 }, + Child = leaderboardChatDisplay = new LeaderboardChatDisplay() + } + }, + } + } + } + } + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(), + } + } } }, new Drawable[] { - bottomRow = new GridContainer + new Footer { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - leaderboard = new MatchLeaderboard - { - Padding = new MarginPadding - { - Left = 10 + HORIZONTAL_OVERFLOW_PADDING, - Right = 10, - Vertical = 10, - }, - RelativeSizeAxes = Axes.Both - }, - new Container - { - Padding = new MarginPadding - { - Left = 10, - Right = 10 + HORIZONTAL_OVERFLOW_PADDING, - Vertical = 10, - }, - RelativeSizeAxes = Axes.Both, - Child = new MatchChatDisplay - { - RelativeSizeAxes = Axes.Both - } - }, - }, - }, + OnStart = onStart, + SelectedItem = { BindTarget = selectedItem } } - }, + } }, RowDimensions = new[] { + new Dimension(), new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Distributed), } }, - new Container + settingsOverlay = new MatchSettingsOverlay { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = Components.Header.HEIGHT }, - Child = settings = new MatchSettingsOverlay { RelativeSizeAxes = Axes.Both }, - }, + EditPlaylist = () => this.Push(new MatchSongSelect()), + State = { Value = roomId.Value == null ? Visibility.Visible : Visibility.Hidden } + } }; - - beatmapManager.ItemAdded += beatmapAdded; } protected override void LoadComplete() { base.LoadComplete(); - Playlist.ItemsAdded += _ => updateSelectedItem(); - Playlist.ItemsRemoved += _ => updateSelectedItem(); + roomId.BindValueChanged(id => + { + if (id.NewValue == null) + settingsOverlay.Show(); + else + settingsOverlay.Hide(); + }, true); - updateSelectedItem(); - } + selectedItem.BindValueChanged(selectedItemChanged); + selectedItem.Value = playlist.FirstOrDefault(); - private void updateSelectedItem() - { - selectedItem.Value = Playlist.FirstOrDefault(); - currentItemChanged(); + beatmapManager.ItemAdded += beatmapAdded; } public override bool OnExiting(IScreen next) { RoomManager?.PartRoom(); Mods.Value = Array.Empty(); - previewTrackManager.StopAnyPlaying(this); return base.OnExiting(next); } - /// - /// Handles propagation of the current playlist item's content to game-wide mechanisms. - /// - private void currentItemChanged() + private void selectedItemChanged(ValueChangedEvent e) { - var item = selectedItem.Value; + updateWorkingBeatmap(); - // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info - var localBeatmap = item?.Beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == item.Beatmap.Value.OnlineBeatmapID); + Mods.Value = e.NewValue?.RequiredMods?.ToArray() ?? Array.Empty(); - Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); - Mods.Value = item?.RequiredMods?.ToArray() ?? Array.Empty(); - - if (item?.Ruleset != null) - Ruleset.Value = item.Ruleset.Value; - - previewTrackManager.StopAnyPlaying(this); + if (e.NewValue?.Ruleset != null) + Ruleset.Value = e.NewValue.Ruleset.Value; + } + + private void updateWorkingBeatmap() + { + var beatmap = selectedItem.Value?.Beatmap.Value; + + // Retrieve the corresponding local beatmap, since we can't directly use the playlist's beatmap info + var localBeatmap = beatmap == null ? null : beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == beatmap.OnlineBeatmapID); + + Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); } - /// - /// Handle the case where a beatmap is imported (and can be used by this match). - /// private void beatmapAdded(BeatmapSetInfo model) => Schedule(() => { if (Beatmap.Value != beatmapManager.DefaultBeatmap) return; - if (selectedItem.Value == null) - return; - - // Try to retrieve the corresponding local beatmap - var localBeatmap = beatmapManager.QueryBeatmap(b => b.OnlineBeatmapID == selectedItem.Value.Beatmap.Value.OnlineBeatmapID); - - if (localBeatmap != null) - Beatmap.Value = beatmapManager.GetWorkingBeatmap(localBeatmap); + updateWorkingBeatmap(); }); - [Resolved(canBeNull: true)] - private Multiplayer multiplayer { get; set; } - private void onStart() { - previewTrackManager.StopAnyPlaying(this); - switch (type.Value) { default: case GameTypeTimeshift _: multiplayer?.Start(() => new TimeshiftPlayer(selectedItem.Value) { - Exited = () => leaderboard.RefreshScores() + Exited = () => leaderboardChatDisplay.RefreshScores() }); break; } @@ -222,5 +237,15 @@ namespace osu.Game.Screens.Multi.Match if (beatmapManager != null) beatmapManager.ItemAdded -= beatmapAdded; } + + private class HeaderBackgroundSprite : MultiplayerBackgroundSprite + { + protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both }; + + private class BackgroundSprite : UpdateableBeatmapBackgroundSprite + { + protected override double TransformDuration => 200; + } + } } } From 9eaf37258794cdec6c0bc6c9dedad6713551d54e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 21:17:07 +0900 Subject: [PATCH 0500/1142] Immediately update selected state --- osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs index b1e69e4c4f..1c35d8a53f 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs @@ -76,7 +76,7 @@ namespace osu.Game.Screens.Multi { base.LoadComplete(); - SelectedItem.BindValueChanged(selected => maskingContainer.BorderThickness = selected.NewValue == Model ? 5 : 0); + SelectedItem.BindValueChanged(selected => maskingContainer.BorderThickness = selected.NewValue == Model ? 5 : 0, true); beatmap.BindValueChanged(_ => scheduleRefresh()); ruleset.BindValueChanged(_ => scheduleRefresh()); From c753cb46c50d48107fb58ebdd93f8ae4c54e542f Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Fri, 14 Feb 2020 20:14:00 +0700 Subject: [PATCH 0501/1142] Use [Resolved] wherever possible --- osu.Game/Audio/PreviewTrackManager.cs | 15 +++++---------- osu.Game/Graphics/ScreenshotManager.cs | 12 +++++++----- osu.Game/Graphics/UserInterface/DownloadButton.cs | 7 +++---- .../Graphics/UserInterface/ExternalLinkButton.cs | 7 ++++--- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 7 +++---- .../Graphics/UserInterface/OsuPasswordTextBox.cs | 9 ++------- osu.Game/Online/Chat/ChannelManager.cs | 9 ++------- osu.Game/Online/Chat/ExternalLinkOpener.cs | 12 +++++++----- osu.Game/Online/DownloadTrackingComposite.cs | 7 +++---- osu.Game/Online/Leaderboards/Leaderboard.cs | 8 ++++---- osu.Game/OsuGame.cs | 7 +++---- osu.Game/Overlays/AccountCreation/ScreenEntry.cs | 13 +++++++------ .../Overlays/AccountCreation/ScreenWarning.cs | 8 ++++---- osu.Game/Overlays/BeatmapSetOverlay.cs | 7 +++---- osu.Game/Overlays/ChatOverlay.cs | 7 +++---- osu.Game/Overlays/Direct/PlayButton.cs | 7 +++---- osu.Game/Overlays/DirectOverlay.cs | 12 ++++++------ osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 7 +++---- osu.Game/Overlays/Music/PlaylistOverlay.cs | 7 ++++--- .../Sections/Audio/AudioDevicesSettings.cs | 9 ++------- .../Settings/Sections/General/LoginSettings.cs | 15 ++++++++------- .../Settings/Sections/Graphics/LayoutSettings.cs | 8 ++++---- .../Overlays/Settings/Sections/SkinSection.cs | 7 +++---- osu.Game/Rulesets/Judgements/DrawableJudgement.cs | 7 +++---- .../Screens/Edit/Components/PlaybackControl.cs | 7 +++---- .../Screens/Edit/Components/TimeInfoContainer.cs | 9 ++------- .../Edit/Compose/Components/Timeline/Timeline.cs | 7 +++---- osu.Game/Screens/Menu/IntroTriangles.cs | 7 +++---- .../Multi/Ranking/Pages/RoomLeaderboardPage.cs | 8 ++++---- osu.Game/Screens/Play/Player.cs | 7 +++---- osu.Game/Screens/Select/BeatmapDetails.cs | 9 ++------- .../Select/Carousel/DrawableCarouselBeatmap.cs | 7 +++---- .../Select/Carousel/DrawableCarouselBeatmapSet.cs | 6 +++--- osu.Game/Skinning/SkinnableSound.cs | 9 ++------- osu.Game/Updater/SimpleUpdateManager.cs | 7 ++++--- 35 files changed, 128 insertions(+), 169 deletions(-) diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs index 6f0b62543d..862be41c1a 100644 --- a/osu.Game/Audio/PreviewTrackManager.cs +++ b/osu.Game/Audio/PreviewTrackManager.cs @@ -19,13 +19,15 @@ namespace osu.Game.Audio { private readonly BindableDouble muteBindable = new BindableDouble(); - private AudioManager audio; + [Resolved] + private AudioManager audio { get; set; } + private PreviewTrackStore trackStore; protected TrackManagerPreviewTrack CurrentTrack; [BackgroundDependencyLoader] - private void load(AudioManager audio) + private void load() { // this is a temporary solution to get around muting ourselves. // todo: update this once we have a BackgroundTrackManager or similar. @@ -33,8 +35,6 @@ namespace osu.Game.Audio audio.AddItem(trackStore); trackStore.AddAdjustment(AdjustableProperty.Volume, audio.VolumeTrack); - - this.audio = audio; } /// @@ -90,6 +90,7 @@ namespace osu.Game.Audio public class TrackManagerPreviewTrack : PreviewTrack { + [Resolved] public IPreviewTrackOwner Owner { get; private set; } private readonly BeatmapSetInfo beatmapSetInfo; @@ -101,12 +102,6 @@ namespace osu.Game.Audio this.trackManager = trackManager; } - [BackgroundDependencyLoader] - private void load(IPreviewTrackOwner owner) - { - Owner = owner; - } - protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3"); } diff --git a/osu.Game/Graphics/ScreenshotManager.cs b/osu.Game/Graphics/ScreenshotManager.cs index e21545688b..9804aefce8 100644 --- a/osu.Game/Graphics/ScreenshotManager.cs +++ b/osu.Game/Graphics/ScreenshotManager.cs @@ -35,18 +35,20 @@ namespace osu.Game.Graphics private Bindable screenshotFormat; private Bindable captureMenuCursor; - private GameHost host; + [Resolved] + private GameHost host { get; set; } + private Storage storage; - private NotificationOverlay notificationOverlay; + + [Resolved] + private NotificationOverlay notificationOverlay { get; set; } private SampleChannel shutter; [BackgroundDependencyLoader] - private void load(GameHost host, OsuConfigManager config, Storage storage, NotificationOverlay notificationOverlay, AudioManager audio) + private void load(OsuConfigManager config, Storage storage, AudioManager audio) { - this.host = host; this.storage = storage.GetStorageForDirectory(@"screenshots"); - this.notificationOverlay = notificationOverlay; screenshotFormat = config.GetBindable(OsuSetting.ScreenshotFormat); captureMenuCursor = config.GetBindable(OsuSetting.ScreenshotCaptureMenuCursor); diff --git a/osu.Game/Graphics/UserInterface/DownloadButton.cs b/osu.Game/Graphics/UserInterface/DownloadButton.cs index 41b90d3802..86a5cb9aa6 100644 --- a/osu.Game/Graphics/UserInterface/DownloadButton.cs +++ b/osu.Game/Graphics/UserInterface/DownloadButton.cs @@ -19,7 +19,8 @@ namespace osu.Game.Graphics.UserInterface private readonly SpriteIcon checkmark; private readonly Box background; - private OsuColour colours; + [Resolved] + private OsuColour colours { get; set; } public DownloadButton() { @@ -49,10 +50,8 @@ namespace osu.Game.Graphics.UserInterface } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - this.colours = colours; - State.BindValueChanged(updateState, true); } diff --git a/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs b/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs index 7225dbc66f..5a1eb53fe1 100644 --- a/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs +++ b/osu.Game/Graphics/UserInterface/ExternalLinkButton.cs @@ -18,7 +18,9 @@ namespace osu.Game.Graphics.UserInterface public string Link { get; set; } private Color4 hoverColour; - private GameHost host; + + [Resolved] + private GameHost host { get; set; } public ExternalLinkButton(string link = null) { @@ -32,10 +34,9 @@ namespace osu.Game.Graphics.UserInterface } [BackgroundDependencyLoader] - private void load(OsuColour colours, GameHost host) + private void load(OsuColour colours) { hoverColour = colours.Yellow; - this.host = host; } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index e59353a480..8977f014b6 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -36,13 +36,12 @@ namespace osu.Game.Graphics.UserInterface } } - private GameHost host; + [Resolved] + private GameHost host { get; set; } [BackgroundDependencyLoader] - private void load(GameHost host) + private void load() { - this.host = host; - BackgroundUnfocused = new Color4(10, 10, 10, 255); BackgroundFocused = new Color4(10, 10, 10, 255); } diff --git a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs index e4a4b1c50e..e7699e5255 100644 --- a/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs +++ b/osu.Game/Graphics/UserInterface/OsuPasswordTextBox.cs @@ -24,7 +24,8 @@ namespace osu.Game.Graphics.UserInterface private readonly CapsWarning warning; - private GameHost host; + [Resolved] + private GameHost host { get; set; } public OsuPasswordTextBox() { @@ -38,12 +39,6 @@ namespace osu.Game.Graphics.UserInterface }); } - [BackgroundDependencyLoader] - private void load(GameHost host) - { - this.host = host; - } - protected override bool OnKeyDown(KeyDownEvent e) { if (e.Key == Key.CapsLock) diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs index 4b5ec1cad0..2c37216fd6 100644 --- a/osu.Game/Online/Chat/ChannelManager.cs +++ b/osu.Game/Online/Chat/ChannelManager.cs @@ -48,7 +48,8 @@ namespace osu.Game.Online.Chat /// public IBindableList AvailableChannels => availableChannels; - private IAPIProvider api; + [Resolved] + private IAPIProvider api { get; set; } public readonly BindableBool HighPollRate = new BindableBool(); @@ -466,12 +467,6 @@ namespace osu.Game.Online.Chat api.Queue(req); } - - [BackgroundDependencyLoader] - private void load(IAPIProvider api) - { - this.api = api; - } } /// diff --git a/osu.Game/Online/Chat/ExternalLinkOpener.cs b/osu.Game/Online/Chat/ExternalLinkOpener.cs index 495f1ac0b0..da90ea6845 100644 --- a/osu.Game/Online/Chat/ExternalLinkOpener.cs +++ b/osu.Game/Online/Chat/ExternalLinkOpener.cs @@ -13,15 +13,17 @@ namespace osu.Game.Online.Chat { public class ExternalLinkOpener : Component { - private GameHost host; - private DialogOverlay dialogOverlay; + [Resolved] + private GameHost host { get; set; } + + [Resolved] + private DialogOverlay dialogOverlay { get; set; } + private Bindable externalLinkWarning; [BackgroundDependencyLoader(true)] - private void load(GameHost host, DialogOverlay dialogOverlay, OsuConfigManager config) + private void load(OsuConfigManager config) { - this.host = host; - this.dialogOverlay = dialogOverlay; externalLinkWarning = config.GetBindable(OsuSetting.ExternalLinkWarning); } diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 9a0e112727..9eb5f36729 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -19,7 +19,8 @@ namespace osu.Game.Online { protected readonly Bindable Model = new Bindable(); - private TModelManager manager; + [Resolved] + private TModelManager manager { get; set; } /// /// Holds the current download state of the , whether is has already been downloaded, is in progress, or is not downloaded. @@ -34,10 +35,8 @@ namespace osu.Game.Online } [BackgroundDependencyLoader(true)] - private void load(TModelManager manager) + private void load() { - this.manager = manager; - Model.BindValueChanged(modelInfo => { if (modelInfo.NewValue == null) diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index 87c747675a..71859d3aeb 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -217,14 +217,14 @@ namespace osu.Game.Online.Leaderboards Scores = null; } - private IAPIProvider api; + [Resolved(CanBeNull = true)] + private IAPIProvider api { get; set; } private ScheduledDelegate pendingUpdateScores; - [BackgroundDependencyLoader(true)] - private void load(IAPIProvider api) + [BackgroundDependencyLoader] + private void load() { - this.api = api; api?.Register(this); } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e7fffd49b4..100730d40d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -150,10 +150,8 @@ namespace osu.Game dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfig) + private void load() { - this.frameworkConfig = frameworkConfig; - if (!Host.IsPrimaryInstance && !DebugUtils.IsDebugBuild) { Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error); @@ -881,7 +879,8 @@ namespace osu.Game private Container topMostOverlayContent; - private FrameworkConfigManager frameworkConfig; + [Resolved] + private FrameworkConfigManager frameworkConfig { get; set; } private ScalingContainer screenContainer; diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index 7067e02cd2..be3a84ca00 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -33,20 +33,21 @@ namespace osu.Game.Overlays.AccountCreation private OsuTextBox emailTextBox; private OsuPasswordTextBox passwordTextBox; - private IAPIProvider api; + [Resolved] + private IAPIProvider api { get; set; } + private ShakeContainer registerShake; private IEnumerable characterCheckText; private OsuTextBox[] textboxes; private ProcessingOverlay processingOverlay; - private GameHost host; + + [Resolved] + private GameHost host { get; set; } [BackgroundDependencyLoader] - private void load(OsuColour colours, IAPIProvider api, GameHost host) + private void load(OsuColour colours) { - this.api = api; - this.host = host; - InternalChildren = new Drawable[] { new FillFlowContainer diff --git a/osu.Game/Overlays/AccountCreation/ScreenWarning.cs b/osu.Game/Overlays/AccountCreation/ScreenWarning.cs index f91d2e3323..3c3c27ab6f 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenWarning.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenWarning.cs @@ -22,7 +22,9 @@ namespace osu.Game.Overlays.AccountCreation { private OsuTextFlowContainer multiAccountExplanationText; private LinkFlowContainer furtherAssistance; - private IAPIProvider api; + + [Resolved] + private IAPIProvider api { get; set; } private const string help_centre_url = "/help/wiki/Help_Centre#login"; @@ -39,10 +41,8 @@ namespace osu.Game.Overlays.AccountCreation } [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, IAPIProvider api, OsuGame game, TextureStore textures) + private void load(OsuColour colours, OsuGame game, TextureStore textures) { - this.api = api; - if (string.IsNullOrEmpty(api.ProvidedUsername)) return; diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 7624351e41..d29997f7e5 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -25,7 +25,8 @@ namespace osu.Game.Overlays public const float RIGHT_WIDTH = 275; protected readonly Header Header; - private RulesetStore rulesets; + [Resolved] + private RulesetStore rulesets { get; set; } private readonly Bindable beatmapSet = new Bindable(); @@ -90,10 +91,8 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(RulesetStore rulesets) + private void load() { - this.rulesets = rulesets; - background.Colour = ColourProvider.Background6; } diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index f2aef0995f..bdc241a437 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -30,7 +30,8 @@ namespace osu.Game.Overlays private const float textbox_height = 60; private const float channel_selection_min_height = 0.3f; - private ChannelManager channelManager; + [Resolved] + private ChannelManager channelManager { get; set; } private Container currentChannelContainer; @@ -72,7 +73,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, OsuColour colours, ChannelManager channelManager) + private void load(OsuConfigManager config, OsuColour colours) { const float padding = 5; @@ -209,8 +210,6 @@ namespace osu.Game.Overlays chatBackground.Colour = colours.ChatBlue; - this.channelManager = channelManager; - loading.Show(); // This is a relatively expensive (and blocking) operation. diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 2a77e7ca26..10abe15177 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -85,13 +85,12 @@ namespace osu.Game.Overlays.Direct Playing.ValueChanged += playingStateChanged; } - private PreviewTrackManager previewTrackManager; + [Resolved] + private PreviewTrackManager previewTrackManager { get; set; } [BackgroundDependencyLoader] - private void load(OsuColour colour, PreviewTrackManager previewTrackManager) + private void load(OsuColour colour) { - this.previewTrackManager = previewTrackManager; - hoverColour = colour.Yellow; } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index e4cef319fe..6cc48f09bd 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -27,7 +27,8 @@ namespace osu.Game.Overlays { private const float panel_padding = 10f; - private RulesetStore rulesets; + [Resolved] + private RulesetStore rulesets { get; set; } private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; @@ -155,11 +156,8 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuColour colours, RulesetStore rulesets, PreviewTrackManager previewTrackManager) + private void load(OsuColour colours) { - this.rulesets = rulesets; - this.previewTrackManager = previewTrackManager; - resultCountsContainer.Colour = colours.Yellow; } @@ -228,7 +226,9 @@ namespace osu.Game.Overlays private readonly Bindable currentQuery = new Bindable(string.Empty); private ScheduledDelegate queryChangedDebounce; - private PreviewTrackManager previewTrackManager; + + [Resolved] + private PreviewTrackManager previewTrackManager { get; set; } private void queueUpdateSearch(bool queryTextChanged = false) { diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index d2fcc2652a..58ca2143f9 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -66,13 +66,12 @@ namespace osu.Game.Overlays.KeyBinding CornerRadius = padding; } - private KeyBindingStore store; + [Resolved] + private KeyBindingStore store { get; set; } [BackgroundDependencyLoader] - private void load(OsuColour colours, KeyBindingStore store) + private void load(OsuColour colours) { - this.store = store; - EdgeEffect = new EdgeEffectParameters { Radius = 2, diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 7c391e27f9..8f753fd3aa 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -26,16 +26,17 @@ namespace osu.Game.Overlays.Music private readonly BindableList beatmapSets = new BindableList(); private readonly Bindable beatmap = new Bindable(); - private BeatmapManager beatmaps; + + [Resolved] + private BeatmapManager beatmaps { get; set; } private FilterControl filter; private Playlist list; [BackgroundDependencyLoader] - private void load(OsuColour colours, Bindable beatmap, BeatmapManager beatmaps) + private void load(OsuColour colours, Bindable beatmap) { this.beatmap.BindTo(beatmap); - this.beatmaps = beatmaps; Children = new Drawable[] { diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index 0612f028bc..3cc233ef73 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -14,15 +14,10 @@ namespace osu.Game.Overlays.Settings.Sections.Audio { protected override string Header => "Devices"; - private AudioManager audio; + [Resolved] + private AudioManager audio { get; set; } private SettingsDropdown dropdown; - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - this.audio = audio; - } - protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs index e485aa5ea9..b41c7d5afb 100644 --- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs @@ -29,7 +29,9 @@ namespace osu.Game.Overlays.Settings.Sections.General { private bool bounding = true; private LoginForm form; - private OsuColour colours; + + [Resolved] + private OsuColour colours { get; set; } private UserPanel panel; private UserDropdown dropdown; @@ -60,10 +62,8 @@ namespace osu.Game.Overlays.Settings.Sections.General } [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, IAPIProvider api) + private void load(IAPIProvider api) { - this.colours = colours; - api?.Register(this); } @@ -201,7 +201,9 @@ namespace osu.Game.Overlays.Settings.Sections.General private TextBox username; private TextBox password; private ShakeContainer shakeSignIn; - private IAPIProvider api; + + [Resolved] + private IAPIProvider api { get; set; } public Action RequestHide; @@ -214,9 +216,8 @@ namespace osu.Game.Overlays.Settings.Sections.General } [BackgroundDependencyLoader(permitNulls: true)] - private void load(IAPIProvider api, OsuConfigManager config, AccountCreationOverlay accountCreation) + private void load(OsuConfigManager config, AccountCreationOverlay accountCreation) { - this.api = api; Direction = FillDirection.Vertical; Spacing = new Vector2(0, 5); AutoSizeAxes = Axes.Y; diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index efbb08b7df..b73c8f7622 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -29,7 +29,9 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics private Bindable sizeFullscreen; private readonly IBindableList windowModes = new BindableList(); - private OsuGameBase game; + [Resolved] + private OsuGameBase game { get; set; } + private SettingsDropdown resolutionDropdown; private SettingsDropdown windowModeDropdown; @@ -41,10 +43,8 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics private const int transition_duration = 400; [BackgroundDependencyLoader] - private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, OsuGameBase game, GameHost host) + private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, GameHost host) { - this.game = game; - scalingMode = osuConfig.GetBindable(OsuSetting.Scaling); sizeFullscreen = config.GetBindable(FrameworkSetting.SizeFullscreen); scalingSizeX = osuConfig.GetBindable(OsuSetting.ScalingSizeX); diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index d3029d8ab9..b229014c84 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -24,13 +24,12 @@ namespace osu.Game.Overlays.Settings.Sections private readonly Bindable dropdownBindable = new Bindable { Default = SkinInfo.Default }; private readonly Bindable configBindable = new Bindable(); - private SkinManager skins; + [Resolved] + private SkinManager skins { get; set; } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, SkinManager skins) + private void load(OsuConfigManager config) { - this.skins = skins; - FlowContent.Spacing = new Vector2(0, 5); Children = new Drawable[] { diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 8289ca175d..960585b968 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -23,7 +23,8 @@ namespace osu.Game.Rulesets.Judgements { private const float judgement_size = 128; - private OsuColour colours; + [Resolved] + private OsuColour colours { get; set; } protected readonly JudgementResult Result; @@ -56,10 +57,8 @@ namespace osu.Game.Rulesets.Judgements } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - this.colours = colours; - InternalChild = JudgementBody = new Container { Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs index 66df68418a..897c6ec531 100644 --- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs +++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs @@ -25,15 +25,14 @@ namespace osu.Game.Screens.Edit.Components { private IconButton playButton; - private IAdjustableClock adjustableClock; + [Resolved] + private IAdjustableClock adjustableClock { get; set; } private readonly BindableNumber tempo = new BindableDouble(1); [BackgroundDependencyLoader] - private void load(IAdjustableClock adjustableClock) + private void load() { - this.adjustableClock = adjustableClock; - Children = new Drawable[] { playButton = new IconButton diff --git a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs index 0391074b11..4bf21d240a 100644 --- a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs +++ b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs @@ -14,7 +14,8 @@ namespace osu.Game.Screens.Edit.Components { private readonly OsuSpriteText trackTimer; - private IAdjustableClock adjustableClock; + [Resolved] + private IAdjustableClock adjustableClock { get; set; } public TimeInfoContainer() { @@ -30,12 +31,6 @@ namespace osu.Game.Screens.Edit.Components }; } - [BackgroundDependencyLoader] - private void load(IAdjustableClock adjustableClock) - { - this.adjustableClock = adjustableClock; - } - protected override void Update() { base.Update(); diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 0475e68e42..ddca5e42c2 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -24,7 +24,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public readonly Bindable WaveformVisible = new Bindable(); public readonly IBindable Beatmap = new Bindable(); - private IAdjustableClock adjustableClock; + [Resolved] + private IAdjustableClock adjustableClock { get; set; } public Timeline() { @@ -36,10 +37,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline private WaveformGraph waveform; [BackgroundDependencyLoader] - private void load(IBindable beatmap, IAdjustableClock adjustableClock, OsuColour colours) + private void load(IBindable beatmap, OsuColour colours) { - this.adjustableClock = adjustableClock; - Add(waveform = new WaveformGraph { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 4deaa68467..29f32406e8 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -102,13 +102,12 @@ namespace osu.Game.Screens.Menu this.background = background; } - private OsuGameBase game; + [Resolved] + private OsuGameBase game { get; set; } [BackgroundDependencyLoader] - private void load(TextureStore textures, OsuGameBase game) + private void load(TextureStore textures) { - this.game = game; - InternalChildren = new Drawable[] { triangles = new GlitchingTriangles diff --git a/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs index ff5471cf4a..f8fb192b5c 100644 --- a/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs +++ b/osu.Game/Screens/Multi/Ranking/Pages/RoomLeaderboardPage.cs @@ -23,7 +23,9 @@ namespace osu.Game.Screens.Multi.Ranking.Pages { public class RoomLeaderboardPage : ResultsPage { - private OsuColour colours; + [Resolved] + private OsuColour colours { get; set; } + private TextFlowContainer rankText; [Resolved(typeof(Room), nameof(Room.Name))] @@ -35,10 +37,8 @@ namespace osu.Game.Screens.Multi.Ranking.Pages } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - this.colours = colours; - MatchLeaderboard leaderboard; Children = new Drawable[] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9bfdcd79fe..bd43b23a9f 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -65,7 +65,8 @@ namespace osu.Game.Screens.Play private Ruleset ruleset; - private IAPIProvider api; + [Resolved] + private IAPIProvider api { get; set; } private SampleChannel sampleRestart; @@ -118,10 +119,8 @@ namespace osu.Game.Screens.Play => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); [BackgroundDependencyLoader] - private void load(AudioManager audio, IAPIProvider api, OsuConfigManager config) + private void load(AudioManager audio, OsuConfigManager config) { - this.api = api; - Mods.Value = base.Mods.Value.Select(m => m.CreateCopy()).ToArray(); if (Beatmap.Value is DummyWorkingBeatmap) diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 577d999388..85b892336a 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -37,7 +37,8 @@ namespace osu.Game.Screens.Select private readonly FailRetryGraph failRetryGraph; private readonly DimmedLoadingLayer loading; - private IAPIProvider api; + [Resolved] + private IAPIProvider api { get; set; } private ScheduledDelegate pendingBeatmapSwitch; @@ -160,12 +161,6 @@ namespace osu.Game.Screens.Select }; } - [BackgroundDependencyLoader] - private void load(IAPIProvider api) - { - this.api = api; - } - protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index fba7a328c1..31aca11b86 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -37,7 +37,8 @@ namespace osu.Game.Screens.Select.Carousel private Triangles triangles; private StarCounter starCounter; - private BeatmapSetOverlay beatmapOverlay; + [Resolved] + private BeatmapSetOverlay beatmapOverlay { get; set; } public DrawableCarouselBeatmap(CarouselBeatmap panel) : base(panel) @@ -47,10 +48,8 @@ namespace osu.Game.Screens.Select.Carousel } [BackgroundDependencyLoader(true)] - private void load(SongSelect songSelect, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay) + private void load(SongSelect songSelect, BeatmapManager manager) { - this.beatmapOverlay = beatmapOverlay; - if (songSelect != null) { startRequested = b => songSelect.FinaliseSelection(b); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 699e01bca7..db59d8a4de 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -30,7 +30,8 @@ namespace osu.Game.Screens.Select.Carousel private Action restoreHiddenRequested; private Action viewDetails; - private DialogOverlay dialogOverlay; + [Resolved] + private DialogOverlay dialogOverlay { get; set; } private readonly BeatmapSetInfo beatmapSet; public DrawableCarouselBeatmapSet(CarouselBeatmapSet set) @@ -40,10 +41,9 @@ namespace osu.Game.Screens.Select.Carousel } [BackgroundDependencyLoader(true)] - private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) + private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay) { restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); - dialogOverlay = overlay; if (beatmapOverlay != null) viewDetails = beatmapOverlay.FetchAndShowBeatmapSet; diff --git a/osu.Game/Skinning/SkinnableSound.cs b/osu.Game/Skinning/SkinnableSound.cs index fc6afd0b27..a78c04ecd4 100644 --- a/osu.Game/Skinning/SkinnableSound.cs +++ b/osu.Game/Skinning/SkinnableSound.cs @@ -21,7 +21,8 @@ namespace osu.Game.Skinning private SampleChannel[] channels; - private ISampleStore samples; + [Resolved] + private ISampleStore samples { get; set; } public SkinnableSound(IEnumerable hitSamples) { @@ -33,12 +34,6 @@ namespace osu.Game.Skinning this.hitSamples = new[] { hitSamples }; } - [BackgroundDependencyLoader] - private void load(ISampleStore samples) - { - this.samples = samples; - } - private bool looping; public bool Looping diff --git a/osu.Game/Updater/SimpleUpdateManager.cs b/osu.Game/Updater/SimpleUpdateManager.cs index 5412b11b33..e490ac14e9 100644 --- a/osu.Game/Updater/SimpleUpdateManager.cs +++ b/osu.Game/Updater/SimpleUpdateManager.cs @@ -20,12 +20,13 @@ namespace osu.Game.Updater public class SimpleUpdateManager : UpdateManager { private string version; - private GameHost host; + + [Resolved] + private GameHost host { get; set; } [BackgroundDependencyLoader] - private void load(OsuGameBase game, GameHost host) + private void load(OsuGameBase game) { - this.host = host; version = game.Version; if (game.IsDeployedBuild) From a7c2fd078f03bc9c1c808c54e3a5d2d8a6ae61cc Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Fri, 14 Feb 2020 20:27:21 +0700 Subject: [PATCH 0502/1142] Fix remaining cases --- osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 6 +++--- osu.Game/Online/API/APIAccess.cs | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs index a3128e36c4..8a0d981e49 100644 --- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs +++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs @@ -150,12 +150,12 @@ namespace osu.Game.Beatmaps.Drawables }; } - private OsuColour colours; + [Resolved] + private OsuColour colours { get; set; } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - this.colours = colours; background.Colour = colours.Gray3; } diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 23c931d161..ab87607112 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -9,6 +9,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json.Linq; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Extensions.ExceptionExtensions; using osu.Framework.Graphics; @@ -21,7 +22,9 @@ namespace osu.Game.Online.API { public class APIAccess : Component, IAPIProvider { - private readonly OsuConfigManager config; + [Resolved] + private OsuConfigManager config { get; set; } + private readonly OAuth authentication; public string Endpoint => @"https://osu.ppy.sh"; From 10798aeab3ec493cec17daab1746e23a609c8cc2 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Fri, 14 Feb 2020 20:30:27 +0700 Subject: [PATCH 0503/1142] Fix code formatting --- osu.Game/Overlays/DirectOverlay.cs | 2 +- .../Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs | 1 + osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 6cc48f09bd..a6f8b65a0d 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -226,7 +226,7 @@ namespace osu.Game.Overlays private readonly Bindable currentQuery = new Bindable(string.Empty); private ScheduledDelegate queryChangedDebounce; - + [Resolved] private PreviewTrackManager previewTrackManager { get; set; } diff --git a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs index 3cc233ef73..3da64e0de4 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/AudioDevicesSettings.cs @@ -16,6 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio [Resolved] private AudioManager audio { get; set; } + private SettingsDropdown dropdown; protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index db59d8a4de..bf7329b305 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -32,6 +32,7 @@ namespace osu.Game.Screens.Select.Carousel [Resolved] private DialogOverlay dialogOverlay { get; set; } + private readonly BeatmapSetInfo beatmapSet; public DrawableCarouselBeatmapSet(CarouselBeatmapSet set) From c46d8287164a88c70703598c169531684a89e596 Mon Sep 17 00:00:00 2001 From: recapitalverb <41869184+recapitalverb@users.noreply.github.com> Date: Fri, 14 Feb 2020 20:59:51 +0700 Subject: [PATCH 0504/1142] Preserve permitNulls --- osu.Game/Online/Chat/ExternalLinkOpener.cs | 4 ++-- osu.Game/Online/DownloadTrackingComposite.cs | 2 +- osu.Game/Overlays/AccountCreation/ScreenWarning.cs | 2 +- osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs | 2 +- .../Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/Chat/ExternalLinkOpener.cs b/osu.Game/Online/Chat/ExternalLinkOpener.cs index da90ea6845..a5958d38cb 100644 --- a/osu.Game/Online/Chat/ExternalLinkOpener.cs +++ b/osu.Game/Online/Chat/ExternalLinkOpener.cs @@ -13,10 +13,10 @@ namespace osu.Game.Online.Chat { public class ExternalLinkOpener : Component { - [Resolved] + [Resolved(CanBeNull = true)] private GameHost host { get; set; } - [Resolved] + [Resolved(CanBeNull = true)] private DialogOverlay dialogOverlay { get; set; } private Bindable externalLinkWarning; diff --git a/osu.Game/Online/DownloadTrackingComposite.cs b/osu.Game/Online/DownloadTrackingComposite.cs index 9eb5f36729..6e7ef99c6d 100644 --- a/osu.Game/Online/DownloadTrackingComposite.cs +++ b/osu.Game/Online/DownloadTrackingComposite.cs @@ -19,7 +19,7 @@ namespace osu.Game.Online { protected readonly Bindable Model = new Bindable(); - [Resolved] + [Resolved(CanBeNull = true)] private TModelManager manager { get; set; } /// diff --git a/osu.Game/Overlays/AccountCreation/ScreenWarning.cs b/osu.Game/Overlays/AccountCreation/ScreenWarning.cs index 3c3c27ab6f..5375476c9e 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenWarning.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenWarning.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.AccountCreation private OsuTextFlowContainer multiAccountExplanationText; private LinkFlowContainer furtherAssistance; - [Resolved] + [Resolved(CanBeNull = true)] private IAPIProvider api { get; set; } private const string help_centre_url = "/help/wiki/Help_Centre#login"; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs index 31aca11b86..d9eeec9f85 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs @@ -37,7 +37,7 @@ namespace osu.Game.Screens.Select.Carousel private Triangles triangles; private StarCounter starCounter; - [Resolved] + [Resolved(CanBeNull = true)] private BeatmapSetOverlay beatmapOverlay { get; set; } public DrawableCarouselBeatmap(CarouselBeatmap panel) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index bf7329b305..997f2382fc 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Select.Carousel private Action restoreHiddenRequested; private Action viewDetails; - [Resolved] + [Resolved(CanBeNull = true)] private DialogOverlay dialogOverlay { get; set; } private readonly BeatmapSetInfo beatmapSet; From 61d539dc6794b1108aeab5e065a322f7e7b53795 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 14 Feb 2020 23:39:39 +0900 Subject: [PATCH 0505/1142] Fix first playlist item not getting selected --- .../Multiplayer/TestSceneMatchSubScreen.cs | 99 +++++++++++++------ .../Screens/Multi/Match/MatchSubScreen.cs | 21 ++-- 2 files changed, 81 insertions(+), 39 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs index 61def4be1a..7f79e306ad 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMatchSubScreen.cs @@ -3,19 +3,28 @@ using System; using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Screens; +using osu.Framework.Testing; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu; +using osu.Game.Screens.Multi; using osu.Game.Screens.Multi.Match; using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Tests.Beatmaps; using osu.Game.Users; +using osuTK.Input; +using Header = osu.Game.Screens.Multi.Match.Components.Header; namespace osu.Game.Tests.Visual.Multiplayer { - public class TestSceneMatchSubScreen : ScreenTestScene + public class TestSceneMatchSubScreen : MultiplayerTestScene { protected override bool UseOnlineAPI => true; @@ -27,8 +36,8 @@ namespace osu.Game.Tests.Visual.Multiplayer typeof(Footer) }; - [Cached] - private readonly Bindable currentRoom = new Bindable(); + [Cached(typeof(IRoomManager))] + private readonly TestRoomManager roomManager = new TestRoomManager(); [Resolved] private BeatmapManager beatmaps { get; set; } @@ -36,51 +45,77 @@ namespace osu.Game.Tests.Visual.Multiplayer [Resolved] private RulesetStore rulesets { get; set; } - public TestSceneMatchSubScreen() + private TestMatchSubScreen match; + + [SetUp] + public void Setup() => Schedule(() => { - currentRoom.Value = new Room(); + Room.CopyFrom(new Room()); + }); + + [SetUpSteps] + public void SetupSteps() + { + AddStep("load match", () => LoadScreen(match = new TestMatchSubScreen(Room))); + AddUntilStep("wait for load", () => match.IsCurrentScreen()); } [Test] - public void TestShowRoom() + public void TestPlaylistItemSelectedOnCreate() { - AddStep(@"show", () => + AddStep("set room properties", () => { - currentRoom.Value.RoomID.Value = 1; - currentRoom.Value.Availability.Value = RoomAvailability.Public; - currentRoom.Value.Duration.Value = TimeSpan.FromHours(24); - currentRoom.Value.Host.Value = new User { Username = "peppy", Id = 2 }; - currentRoom.Value.Name.Value = "super secret room"; - currentRoom.Value.Participants.AddRange(new[] + Room.Name.Value = "my awesome room"; + Room.Host.Value = new User { Id = 2, Username = "peppy" }; + Room.Playlist.Add(new PlaylistItem { - new User { Username = "peppy", Id = 2 }, - new User { Username = "smoogipoo", Id = 1040328 } + Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo } }); - currentRoom.Value.Playlist.Add(new PlaylistItem - { - Beatmap = { Value = beatmaps.GetAllUsableBeatmapSets()[0].Beatmaps[0] }, - Ruleset = { Value = rulesets.GetRuleset(2) }, - }); - - LoadScreen(new MatchSubScreen(currentRoom.Value)); }); + + AddStep("move mouse to create button", () => + { + var footer = match.ChildrenOfType