From c06e558f874fe975502894658617d00214731777 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 15 Dec 2019 18:12:37 +0800 Subject: [PATCH 001/240] add setting to start fully wounded --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index 133f9ceb39..d21990ae91 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -23,6 +23,9 @@ namespace osu.Game.Rulesets.Mods [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } + [SettingSource("Start wounded", "Start at 100% of the final rate")] + public BindableBool Reverse { get; } = new BindableBool(); + private double finalRateTime; private double beginRampTime; @@ -61,7 +64,10 @@ namespace osu.Game.Rulesets.Mods public virtual void Update(Playfield playfield) { - applyAdjustment((track.CurrentTime - beginRampTime) / finalRateTime); + if (!Reverse.Value) + applyAdjustment((track.CurrentTime - beginRampTime) / finalRateTime); + else + applyAdjustment(1 - ((track.CurrentTime - beginRampTime) / finalRateTime)); } /// From b3d32710df2cf43bc3a969f88ea43b6cc7a5ed30 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Sun, 29 Dec 2019 00:19:51 +0100 Subject: [PATCH 002/240] Centered button mods by adding padding to FillFlowContainer --- osu.Game/Screens/Select/FooterButtonMods.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 8419ee0c2a..bb733f10ed 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -54,11 +54,10 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), - Margin = new MarginPadding { Right = 10 } } }, AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Left = 70 } + Margin = new MarginPadding { Left = 70, Right = 15 } }); } From bf463fe5e0c13f2d07b257a2a21060620cb672b5 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Sun, 29 Dec 2019 08:57:14 +0100 Subject: [PATCH 003/240] adjusted the margin values --- .../Visual/UserInterface/TestSceneFooterButtonMods.cs | 7 +++++++ osu.Game/Screens/Select/FooterButtonMods.cs | 1 + 2 files changed, 8 insertions(+) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs index 6eb621ca3b..de67968fbc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs @@ -45,6 +45,13 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep(@"Add multiple Mods", () => changeMods(mutlipleIncrementMods)); AddAssert(@"Check multiple mod multiplier", () => assertModsMultiplier(mutlipleIncrementMods)); } + + [Test] + public void Temporary() + { + var hiddenMod = new Mod[] { new OsuModRelax() }; + AddStep(@"Add Hidden", () => changeMods(hiddenMod)); + } [Test] public void TestDecrementMultiplier() diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index bb733f10ed..d533d5444c 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -54,6 +54,7 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), + Margin = new MarginPadding { Right = 6 } } }, AutoSizeAxes = Axes.Both, From 875a25c5297b0797b84af4974c2bf5e0d68ed6c6 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Sun, 29 Dec 2019 08:57:14 +0100 Subject: [PATCH 004/240] adjusted the margin values --- osu.Game/Screens/Select/FooterButtonMods.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index bb733f10ed..d533d5444c 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -54,6 +54,7 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), + Margin = new MarginPadding { Right = 6 } } }, AutoSizeAxes = Axes.Both, From e85910c4e465ab174ee8d328b75442d8886c8cb9 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Sun, 29 Dec 2019 09:18:27 +0100 Subject: [PATCH 005/240] removed unnecessary test code --- .../Visual/UserInterface/TestSceneFooterButtonMods.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs index de67968fbc..6eb621ca3b 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs @@ -45,13 +45,6 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep(@"Add multiple Mods", () => changeMods(mutlipleIncrementMods)); AddAssert(@"Check multiple mod multiplier", () => assertModsMultiplier(mutlipleIncrementMods)); } - - [Test] - public void Temporary() - { - var hiddenMod = new Mod[] { new OsuModRelax() }; - AddStep(@"Add Hidden", () => changeMods(hiddenMod)); - } [Test] public void TestDecrementMultiplier() From b0bcbf8b93ab24b96a2fe3f73491c2703b31675b Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Mon, 30 Dec 2019 21:55:09 +0100 Subject: [PATCH 006/240] Adjusted margin to fix the 1 px increase --- osu.Game/Screens/Select/FooterButtonMods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index d533d5444c..a0e34a7f87 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Select } }, AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Left = 70, Right = 15 } + Margin = new MarginPadding { Left = 70, Right = 14 } }); } From f40ebc83caea08d02810065d7150c30c8fe60ffb Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Mon, 30 Dec 2019 23:58:49 +0100 Subject: [PATCH 007/240] Begun refractorization process of wrapping Button text in a FillFlowContainer --- .../TestSceneFooterButtonMods.cs | 3 +- osu.Game/Screens/Select/FooterButton.cs | 23 +++++++---- osu.Game/Screens/Select/FooterButtonMods.cs | 38 +++++++------------ 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs index 6eb621ca3b..63197ed26a 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs @@ -16,7 +16,8 @@ namespace osu.Game.Tests.Visual.UserInterface { public override IReadOnlyList RequiredTypes => new[] { - typeof(FooterButtonMods) + typeof(FooterButtonMods), + typeof(FooterButton) }; private readonly TestFooterButtonMods footerButtonMods; diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index b77da36748..18c9d1091c 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Select } } - protected readonly Container TextContainer; + protected FillFlowContainer TextContainer; protected readonly SpriteText SpriteText; private readonly Box box; private readonly Box light; @@ -80,15 +80,24 @@ namespace osu.Game.Screens.Select EdgeSmoothness = new Vector2(2, 0), RelativeSizeAxes = Axes.X, }, - TextContainer = new Container + TextContainer = new FillFlowContainer { - Size = new Vector2(100 - SHEAR_WIDTH, 50), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, Shear = -SHEAR, - Child = SpriteText = new OsuSpriteText + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } + SpriteText = new OsuSpriteText + { + Size = new Vector2(100 - SHEAR_WIDTH, 50), + Shear = -SHEAR, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }, + AutoSizeAxes = Axes.Both, + // Margin = new MarginPadding { Left = 70, Right = 14 } }, }; } diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index a0e34a7f87..2141c04cd6 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -3,7 +3,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; +// using osu.Framework.Graphics.Containers; using osu.Game.Screens.Play.HUD; using osu.Game.Rulesets.Mods; using System.Collections.Generic; @@ -34,31 +34,19 @@ namespace osu.Game.Screens.Select public FooterButtonMods() { - Add(new FillFlowContainer + TextContainer.Add(modDisplay = new FooterModDisplay { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Shear = -SHEAR, - Children = new Drawable[] - { - modDisplay = new FooterModDisplay - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - DisplayUnrankedText = false, - Scale = new Vector2(0.8f) - }, - MultiplierText = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = OsuFont.GetFont(weight: FontWeight.Bold), - Margin = new MarginPadding { Right = 6 } - } - }, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Left = 70, Right = 14 } + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + DisplayUnrankedText = false, + Scale = new Vector2(0.8f) + }); + TextContainer.Add(MultiplierText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(weight: FontWeight.Bold), + Margin = new MarginPadding { Right = 6 } }); } From 8695e57f627aa2dc6da22c4eb53836265328cc30 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Tue, 31 Dec 2019 12:21:55 +0100 Subject: [PATCH 008/240] Hides mod display when no mods are active to fix issue of invisible margin --- osu.Game/Screens/Select/FooterButton.cs | 2 +- osu.Game/Screens/Select/FooterButtonMods.cs | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 18c9d1091c..7acb2fd221 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -91,7 +91,7 @@ namespace osu.Game.Screens.Select SpriteText = new OsuSpriteText { Size = new Vector2(100 - SHEAR_WIDTH, 50), - Shear = -SHEAR, + Shear = SHEAR, Anchor = Anchor.Centre, Origin = Anchor.Centre, } diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 2141c04cd6..a3453fee05 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), - Margin = new MarginPadding { Right = 6 } + // Margin = new MarginPadding { Right = 6 } }); } @@ -80,6 +80,11 @@ namespace osu.Game.Screens.Select MultiplierText.FadeColour(lowMultiplierColour, 200); else MultiplierText.FadeColour(Color4.White, 200); + + if (Current.Value?.Count > 0) + modDisplay.FadeIn(0); + else + modDisplay.FadeOut(0); } private class FooterModDisplay : ModDisplay From ddec59ec9158c0f88ca9a35048de161f232c5bd6 Mon Sep 17 00:00:00 2001 From: Viktor Rosvall Date: Wed, 1 Jan 2020 12:22:19 +0100 Subject: [PATCH 009/240] Further refactoring. I think this may have polluted the FooterButton too much. Not sure what to do about the centering. --- osu.Game/Screens/Select/FooterButton.cs | 40 +++++++++++++-------- osu.Game/Screens/Select/FooterButtonMods.cs | 6 ++-- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 7acb2fd221..869e9e8aa4 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -56,7 +56,8 @@ namespace osu.Game.Screens.Select } } - protected FillFlowContainer TextContainer; + protected FillFlowContainer ButtonContentContainer; + protected readonly Container TextContainer; protected readonly SpriteText SpriteText; private readonly Box box; private readonly Box light; @@ -80,24 +81,35 @@ namespace osu.Game.Screens.Select EdgeSmoothness = new Vector2(2, 0), RelativeSizeAxes = Axes.X, }, - TextContainer = new FillFlowContainer + new Container { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Direction = FillDirection.Horizontal, - Shear = -SHEAR, + AutoSizeAxes = Axes.Both, Children = new Drawable[] { - SpriteText = new OsuSpriteText + ButtonContentContainer = new FillFlowContainer { - Size = new Vector2(100 - SHEAR_WIDTH, 50), - Shear = SHEAR, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - } + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Direction = FillDirection.Horizontal, + Shear = -SHEAR, + AutoSizeAxes = Axes.Both, + Margin = new MarginPadding { Horizontal = SHEAR_WIDTH / 4 }, + Children = new Drawable[] + { + TextContainer = new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(100 - SHEAR_WIDTH, 50), + Child = SpriteText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }, + }, + }, }, - AutoSizeAxes = Axes.Both, - // Margin = new MarginPadding { Left = 70, Right = 14 } }, }; } diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index a3453fee05..67b491cf9e 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -34,19 +34,19 @@ namespace osu.Game.Screens.Select public FooterButtonMods() { - TextContainer.Add(modDisplay = new FooterModDisplay + ButtonContentContainer.Add(modDisplay = new FooterModDisplay { Anchor = Anchor.Centre, Origin = Anchor.Centre, DisplayUnrankedText = false, Scale = new Vector2(0.8f) }); - TextContainer.Add(MultiplierText = new OsuSpriteText + ButtonContentContainer.Add(MultiplierText = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), - // Margin = new MarginPadding { Right = 6 } + Margin = new MarginPadding { Right = 10 } }); } From af248457b02b9380c49dc09d8dd2085b9ebe7766 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 1 Jan 2020 22:49:04 +0300 Subject: [PATCH 010/240] 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 011/240] 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 012/240] 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 013/240] 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 014/240] 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 015/240] 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 016/240] 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 017/240] 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 018/240] 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 019/240] 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 020/240] 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 021/240] 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 90e4def4bd0d782f24b4d987639f33a1388fe621 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 14 Jan 2020 07:07:21 +0300 Subject: [PATCH 022/240] 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 023/240] 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 024/240] 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 025/240] 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 026/240] 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 027/240] 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 028/240] 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 59cb93321fbdffaf271021a8b6ede430e0eee10d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 18 Jan 2020 01:36:14 +0300 Subject: [PATCH 029/240] Implement ProfileItemBackground component --- .../Historical/DrawableMostPlayedBeatmap.cs | 81 +++++++++---------- .../Profile/Sections/ProfileItemBackground.cs | 49 +++++++++++ 2 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Sections/ProfileItemBackground.cs diff --git a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs index 0206c4e13b..9040af3384 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs @@ -4,7 +4,6 @@ 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.Framework.Localisation; using osu.Game.Beatmaps; @@ -13,32 +12,25 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osuTK; -using System.Collections.Generic; using osu.Framework.Graphics.Cursor; namespace osu.Game.Overlays.Profile.Sections.Historical { - public class DrawableMostPlayedBeatmap : OsuHoverContainer + public class DrawableMostPlayedBeatmap : CompositeDrawable { private const int cover_width = 100; private const int corner_radius = 6; - private const int height = 50; private readonly BeatmapInfo beatmap; private readonly int playCount; - private Box background; - - protected override IEnumerable EffectTargets => new[] { background }; - public DrawableMostPlayedBeatmap(BeatmapInfo beatmap, int playCount) { this.beatmap = beatmap; this.playCount = playCount; - Enabled.Value = true; //manually enabled, because we have no action RelativeSizeAxes = Axes.X; - Height = height; + Height = 50; Masking = true; CornerRadius = corner_radius; @@ -47,10 +39,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical [BackgroundDependencyLoader] private void load(OsuColour colours) { - IdleColour = colours.GreySeafoam; - HoverColour = colours.GreySeafoamLight; - - Children = new Drawable[] + AddRangeInternal(new Drawable[] { new UpdateableBeatmapSetCover { @@ -72,46 +61,48 @@ namespace osu.Game.Overlays.Profile.Sections.Historical CornerRadius = corner_radius, Children = new Drawable[] { - background = new Box { RelativeSizeAxes = Axes.Both }, - new Container + new ProfileItemBackground { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding(10), - Children = new Drawable[] + Child = new Container { - new FillFlowContainer + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding(10), + Children = new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new FillFlowContainer { - new MostPlayedBeatmapMetadataContainer(beatmap), - new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular)) + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Colour = colours.GreySeafoamLighter - }.With(d => - { - d.AddText("mapped by "); - d.AddUserLink(beatmap.Metadata.Author); - }), - } - }, - new PlayCountText(playCount) - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight - }, - } - }, + new MostPlayedBeatmapMetadataContainer(beatmap), + new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular)) + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Colour = colours.GreySeafoamLighter + }.With(d => + { + d.AddText("mapped by "); + d.AddUserLink(beatmap.Metadata.Author); + }), + } + }, + new PlayCountText(playCount) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight + }, + } + }, + } } } } } - }; + }); } private class MostPlayedBeatmapMetadataContainer : BeatmapMetadataContainer diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemBackground.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemBackground.cs new file mode 100644 index 0000000000..4f8630c92d --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemBackground.cs @@ -0,0 +1,49 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.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 System.Collections.Generic; + +namespace osu.Game.Overlays.Profile.Sections +{ + public class ProfileItemBackground : OsuHoverContainer + { + protected override IEnumerable EffectTargets => new[] { background }; + protected override Container Content => content; + + private readonly Box background; + private readonly Container content; + + public ProfileItemBackground() + { + RelativeSizeAxes = Axes.Both; + Enabled.Value = true; //manually enabled, because we have no action + Masking = true; + CornerRadius = 6; + + base.Content.AddRange(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + content = new Container + { + RelativeSizeAxes = Axes.Both, + } + }); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + IdleColour = colours.GreySeafoam; + HoverColour = colours.GreySeafoamLight; + } + } +} From 4cdaebb42bf681a04e2e4043fd18f204c928fa6e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 18 Jan 2020 02:58:10 +0300 Subject: [PATCH 030/240] Implement ProfileScore component --- .../Online/TestSceneUserProfileScores.cs | 82 ++++++ osu.Game/Graphics/DrawableDate.cs | 4 +- .../Profile/Sections/Ranks/ProfileScore.cs | 242 ++++++++++++++++++ 3 files changed, 326 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs create mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs new file mode 100644 index 0000000000..f8e3da5241 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs @@ -0,0 +1,82 @@ +// 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.Profile.Sections; +using osu.Game.Overlays.Profile.Sections.Ranks; +using osu.Framework.Graphics; +using osu.Game.Scoring; +using osu.Framework.Graphics.Containers; +using osuTK; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneUserProfileScores : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ProfileScore), + typeof(ProfileItemBackground), + }; + + public TestSceneUserProfileScores() + { + var score = new ScoreInfo + { + PP = 134.32, + Rank = ScoreRank.A, + Beatmap = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Title = "Triumph & Regret", + Artist = "typeMARS" + }, + Version = "[4K] Regret" + }, + Date = DateTimeOffset.Now, + Mods = new Mod[] + { + new OsuModHardRock(), + new OsuModDoubleTime(), + }, + Accuracy = 0.998546 + }; + + var noPPScore = new ScoreInfo + { + Rank = ScoreRank.B, + Beatmap = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + Title = "C18H27NO3(extend)", + Artist = "Team Grimoire" + }, + Version = "[4K] Cataclysmic Hypernova" + }, + Date = DateTimeOffset.Now, + Accuracy = 0.55879 + }; + + Add(new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new[] + { + new ProfileScore(score), + new ProfileScore(noPPScore), + } + }); + } + } +} diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 533f02af7b..925c7981e0 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) + public DrawableDate(DateTimeOffset date, float textSize = OsuFont.DEFAULT_FONT_SIZE) { - Font = OsuFont.GetFont(weight: FontWeight.Regular, italics: true); + Font = OsuFont.GetFont(weight: FontWeight.Regular, size: textSize, italics: true); Date = date; } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs new file mode 100644 index 0000000000..c30c13d52e --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs @@ -0,0 +1,242 @@ +// 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.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Localisation; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +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 ProfileScore : CompositeDrawable + { + private const int performance_width = 80; + private const int content_padding = 10; + + protected readonly ScoreInfo Score; + + [Resolved] + private OsuColour colours { get; set; } + + public ProfileScore(ScoreInfo score) + { + Score = score; + + RelativeSizeAxes = Axes.X; + Height = 40; + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(new ProfileItemBackground + { + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = content_padding, Right = performance_width + content_padding }, + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(8, 0), + Children = new Drawable[] + { + new UpdateableRank(Score.Rank) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(50, 20), + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 2), + Children = new Drawable[] + { + new ScoreBeatmapMetadataContainer(Score.Beatmap), + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Children = new Drawable[] + { + new OsuSpriteText + { + Text = $"{Score.Beatmap.Version}", + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular), + Colour = colours.Yellow + }, + new DrawableDate(Score.Date, 12) + { + Colour = colours.GreySeafoamLighter + } + } + } + } + } + } + }, + new FillFlowContainer + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10), + Children = new Drawable[] + { + CreateRightContent().With(c => + { + c.Anchor = Anchor.CentreRight; + c.Origin = Anchor.CentreRight; + }), + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(2), + Children = Score.Mods.Select(mod => new ModIcon(mod) + { + Scale = new Vector2(0.35f) + }).ToList(), + } + } + } + } + }, + new Container + { + RelativeSizeAxes = Axes.Y, + Width = performance_width, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1, 0.5f), + Colour = Color4.Black.Opacity(0.5f), + Shear = new Vector2(-0.45f, 0), + EdgeSmoothness = new Vector2(2, 0), + }, + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Y, + Size = new Vector2(1, -0.5f), + Position = new Vector2(0, 1), + Colour = Color4.Black.Opacity(0.5f), + Shear = new Vector2(0.45f, 0), + EdgeSmoothness = new Vector2(2, 0), + }, + createDrawablePerformance().With(d => + { + d.Anchor = Anchor.Centre; + d.Origin = Anchor.Centre; + }) + } + } + } + }); + } + + protected virtual Drawable CreateRightContent() => CreateDrawableAccuracy(); + + protected OsuSpriteText CreateDrawableAccuracy(float textSize = 16) => new OsuSpriteText + { + Text = $"{Score.Accuracy:P2}", + Font = OsuFont.GetFont(size: textSize, weight: FontWeight.Bold, italics: true), + Colour = colours.Yellow, + }; + + private Drawable createDrawablePerformance() + { + if (Score.PP.HasValue) + { + return new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Children = new[] + { + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(weight: FontWeight.Bold), + Text = $"{Score.PP:0}", + Colour = colours.GreenLight + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Text = "pp", + Colour = colours.Green + } + } + }; + } + + return new OsuSpriteText + { + Font = OsuFont.GetFont(weight: FontWeight.Bold), + Text = "-", + Colour = colours.GreenLight + }; + } + + private class ScoreBeatmapMetadataContainer : BeatmapMetadataContainer + { + public ScoreBeatmapMetadataContainer(BeatmapInfo beatmap) + : base(beatmap) + { + } + + protected override Drawable[] CreateText(BeatmapInfo beatmap) => new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = new LocalisedString(( + $"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} ", + $"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} ")), + Font = OsuFont.GetFont(weight: FontWeight.SemiBold, italics: true) + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = "by " + new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)), + Font = OsuFont.GetFont(size: 14, italics: true) + }, + }; + } + } +} From 4964505c3e3bbbf037dad273b6d1ee1cacd382f4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 18 Jan 2020 03:19:28 +0300 Subject: [PATCH 031/240] Implement ProfileWeightedScore component --- .../Online/TestSceneUserProfileScores.cs | 2 + .../Profile/Sections/Ranks/ProfileScore.cs | 9 ++- .../Sections/Ranks/ProfileWeightedScore.cs | 70 +++++++++++++++++++ 3 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs index f8e3da5241..4af024052e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs @@ -20,6 +20,7 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { typeof(ProfileScore), + typeof(ProfileWeightedScore), typeof(ProfileItemBackground), }; @@ -75,6 +76,7 @@ namespace osu.Game.Tests.Visual.Online { new ProfileScore(score), new ProfileScore(noPPScore), + new ProfileWeightedScore(score, 0.85), } }); } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs index c30c13d52e..bd49c59523 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -104,7 +105,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(10), + Spacing = new Vector2(15), Children = new Drawable[] { CreateRightContent().With(c => @@ -165,12 +166,13 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks }); } + [NotNull] protected virtual Drawable CreateRightContent() => CreateDrawableAccuracy(); - protected OsuSpriteText CreateDrawableAccuracy(float textSize = 16) => new OsuSpriteText + protected OsuSpriteText CreateDrawableAccuracy() => new OsuSpriteText { Text = $"{Score.Accuracy:P2}", - Font = OsuFont.GetFont(size: textSize, weight: FontWeight.Bold, italics: true), + Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), Colour = colours.Yellow, }; @@ -181,6 +183,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks return new FillFlowContainer { AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, Children = new[] { new OsuSpriteText diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs new file mode 100644 index 0000000000..aaf3664403 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs @@ -0,0 +1,70 @@ +// 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.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Scoring; +using osuTK; + +namespace osu.Game.Overlays.Profile.Sections.Ranks +{ + public class ProfileWeightedScore : ProfileScore + { + private readonly double weight; + + public ProfileWeightedScore(ScoreInfo score, double weight) + : base(score) + { + this.weight = weight; + } + + protected override Drawable CreateRightContent() => new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 2), + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(15, 0), + Children = new Drawable[] + { + CreateDrawableAccuracy(), + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new[] + { + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), + Text = $"{Score.PP * weight:0}", + }, + new OsuSpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), + Text = "pp", + } + } + } + } + }, + new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Text = $@"weighted {weight:P0}" + } + } + }; + } +} From 6e776d02f817563ad9299dd204e03dcecb937e70 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 18 Jan 2020 03:33:02 +0300 Subject: [PATCH 032/240] Refactor PaginatedScoreContainer to use new components --- .../Profile/Sections/Ranks/PaginatedScoreContainer.cs | 10 ++++------ .../Profile/Sections/Ranks/ProfileWeightedScore.cs | 7 ++++++- osu.Game/Overlays/Profile/Sections/RanksSection.cs | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index e0f1c935da..ad6621696d 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -15,14 +15,12 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { public class PaginatedScoreContainer : PaginatedContainer { - private readonly bool includeWeight; private readonly ScoreType type; - public PaginatedScoreContainer(ScoreType type, Bindable user, string header, string missing, bool includeWeight = false) + public PaginatedScoreContainer(ScoreType type, Bindable user, string header, string missing) : base(user, header, missing) { this.type = type; - this.includeWeight = includeWeight; ItemsPerPage = 5; @@ -43,10 +41,10 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks switch (type) { default: - return new DrawablePerformanceScore(model.CreateScoreInfo(Rulesets), includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); + return new ProfileScore(model.CreateScoreInfo(Rulesets)); - case ScoreType.Recent: - return new DrawableTotalScore(model.CreateScoreInfo(Rulesets)); + case ScoreType.Best: + return new ProfileWeightedScore(model.CreateScoreInfo(Rulesets), Math.Pow(0.95, ItemsContainer.Count)); } } } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs index aaf3664403..5f080f2589 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs @@ -34,7 +34,12 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Spacing = new Vector2(15, 0), Children = new Drawable[] { - CreateDrawableAccuracy(), + new Container + { + AutoSizeAxes = Axes.Y, + Width = 60, + Child = CreateDrawableAccuracy() + }, new FillFlowContainer { AutoSizeAxes = Axes.Both, diff --git a/osu.Game/Overlays/Profile/Sections/RanksSection.cs b/osu.Game/Overlays/Profile/Sections/RanksSection.cs index c4b933593e..dbdff3a273 100644 --- a/osu.Game/Overlays/Profile/Sections/RanksSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RanksSection.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedScoreContainer(ScoreType.Best, User, "Best Performance", "No performance records. :(", true), + new PaginatedScoreContainer(ScoreType.Best, User, "Best Performance", "No performance records. :("), new PaginatedScoreContainer(ScoreType.Firsts, User, "First Place Ranks", "No awesome performance records yet. :("), }; } From d5a3d8dbaa9f21d75a46150f55b048a0972c76cb Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 18 Jan 2020 03:35:47 +0300 Subject: [PATCH 033/240] Remove no longer used components --- .../Visual/Online/TestSceneUserRanks.cs | 7 +- .../Ranks/DrawablePerformanceScore.cs | 47 --------- .../Sections/Ranks/DrawableProfileScore.cs | 96 ------------------- .../Sections/Ranks/DrawableTotalScore.cs | 31 ------ 4 files changed, 6 insertions(+), 175 deletions(-) delete mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/DrawablePerformanceScore.cs delete mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs delete mode 100644 osu.Game/Overlays/Profile/Sections/Ranks/DrawableTotalScore.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 2951f6b63e..9779343c07 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -20,7 +20,12 @@ namespace osu.Game.Tests.Visual.Online { protected override bool UseOnlineAPI => true; - public override IReadOnlyList RequiredTypes => new[] { typeof(DrawableProfileScore), typeof(RanksSection) }; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ProfileScore), + typeof(ProfileWeightedScore), + typeof(RanksSection) + }; public TestSceneUserRanks() { diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePerformanceScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePerformanceScore.cs deleted file mode 100644 index 843f9b7ef2..0000000000 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawablePerformanceScore.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.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Scoring; - -namespace osu.Game.Overlays.Profile.Sections.Ranks -{ - public class DrawablePerformanceScore : DrawableProfileScore - { - private readonly double? weight; - - public DrawablePerformanceScore(ScoreInfo score, double? weight = null) - : base(score) - { - this.weight = weight; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colour) - { - double pp = Score.PP ?? 0; - RightFlowContainer.Add(new OsuSpriteText - { - Text = $"{pp:0}pp", - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) - }); - - if (weight.HasValue) - { - RightFlowContainer.Add(new OsuSpriteText - { - Text = $"weighted: {pp * weight:0}pp ({weight:P0})", - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Colour = colour.GrayA, - Font = OsuFont.GetFont(size: 11, weight: FontWeight.Regular, italics: true) - }); - } - } - } -} diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs deleted file mode 100644 index 6362d3dfb0..0000000000 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ /dev/null @@ -1,96 +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 osuTK; -using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Online.Leaderboards; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.UI; -using osu.Game.Scoring; -using osu.Game.Beatmaps; -using osu.Framework.Localisation; -using osu.Framework.Graphics.Containers; - -namespace osu.Game.Overlays.Profile.Sections.Ranks -{ - public abstract class DrawableProfileScore : DrawableProfileRow - { - private readonly FillFlowContainer modsContainer; - protected readonly ScoreInfo Score; - - protected DrawableProfileScore(ScoreInfo score) - { - Score = score; - - RelativeSizeAxes = Axes.X; - Height = 60; - Children = new Drawable[] - { - modsContainer = new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - Spacing = new Vector2(1), - Margin = new MarginPadding { Right = 160 } - } - }; - } - - [BackgroundDependencyLoader(true)] - private void load(OsuColour colour) - { - var text = new OsuSpriteText - { - Text = $"accuracy: {Score.Accuracy:P2}", - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Colour = colour.GrayA, - Font = OsuFont.GetFont(size: 11, weight: FontWeight.Regular, italics: true) - }; - - RightFlowContainer.Insert(1, text); - - LeftFlowContainer.Add(new ProfileScoreBeatmapMetadataContainer(Score.Beatmap)); - LeftFlowContainer.Add(new DrawableDate(Score.Date)); - - foreach (Mod mod in Score.Mods) - modsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.5f) }); - } - - protected override Drawable CreateLeftVisual() => new UpdateableRank(Score.Rank) - { - RelativeSizeAxes = Axes.Y, - Width = 60, - FillMode = FillMode.Fit, - }; - - private class ProfileScoreBeatmapMetadataContainer : BeatmapMetadataContainer - { - public ProfileScoreBeatmapMetadataContainer(BeatmapInfo beatmap) - : base(beatmap) - { - } - - protected override Drawable[] CreateText(BeatmapInfo beatmap) => new Drawable[] - { - new OsuSpriteText - { - Text = new LocalisedString(( - $"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} [{beatmap.Version}] ", - $"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} [{beatmap.Version}] ")), - Font = OsuFont.GetFont(size: 15, weight: FontWeight.SemiBold, italics: true) - }, - new OsuSpriteText - { - Text = new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)), - Padding = new MarginPadding { Top = 3 }, - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular, italics: true) - }, - }; - } - } -} diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableTotalScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableTotalScore.cs deleted file mode 100644 index 8bfca08fe7..0000000000 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableTotalScore.cs +++ /dev/null @@ -1,31 +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.Game.Graphics; -using osu.Game.Graphics.Sprites; -using osu.Game.Scoring; - -namespace osu.Game.Overlays.Profile.Sections.Ranks -{ - public class DrawableTotalScore : DrawableProfileScore - { - public DrawableTotalScore(ScoreInfo score) - : base(score) - { - } - - [BackgroundDependencyLoader] - private void load() - { - RightFlowContainer.Add(new OsuSpriteText - { - Text = Score.TotalScore.ToString("#,###"), - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) - }); - } - } -} From 16cfb9310b4edda6055eea3079d7a60cb94b3c04 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 18 Jan 2020 03:40:31 +0300 Subject: [PATCH 034/240] Naming adjustments --- .../Visual/Online/TestSceneUserProfileScores.cs | 10 +++++----- osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs | 4 ++-- .../Ranks/{ProfileScore.cs => DrawableProfileScore.cs} | 4 ++-- ...eightedScore.cs => DrawableProfileWeightedScore.cs} | 4 ++-- .../Profile/Sections/Ranks/PaginatedScoreContainer.cs | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) rename osu.Game/Overlays/Profile/Sections/Ranks/{ProfileScore.cs => DrawableProfileScore.cs} (98%) rename osu.Game/Overlays/Profile/Sections/Ranks/{ProfileWeightedScore.cs => DrawableProfileWeightedScore.cs} (94%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs index 4af024052e..ff26611311 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs @@ -19,8 +19,8 @@ namespace osu.Game.Tests.Visual.Online { public override IReadOnlyList RequiredTypes => new[] { - typeof(ProfileScore), - typeof(ProfileWeightedScore), + typeof(DrawableProfileScore), + typeof(DrawableProfileWeightedScore), typeof(ProfileItemBackground), }; @@ -74,9 +74,9 @@ namespace osu.Game.Tests.Visual.Online Spacing = new Vector2(0, 10), Children = new[] { - new ProfileScore(score), - new ProfileScore(noPPScore), - new ProfileWeightedScore(score, 0.85), + new DrawableProfileScore(score), + new DrawableProfileScore(noPPScore), + new DrawableProfileWeightedScore(score, 0.85), } }); } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 9779343c07..5cbdfb561e 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs @@ -22,8 +22,8 @@ namespace osu.Game.Tests.Visual.Online public override IReadOnlyList RequiredTypes => new[] { - typeof(ProfileScore), - typeof(ProfileWeightedScore), + typeof(DrawableProfileScore), + typeof(DrawableProfileWeightedScore), typeof(RanksSection) }; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs similarity index 98% rename from osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs rename to osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index bd49c59523..13bdb523d2 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -20,7 +20,7 @@ using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Sections.Ranks { - public class ProfileScore : CompositeDrawable + public class DrawableProfileScore : CompositeDrawable { private const int performance_width = 80; private const int content_padding = 10; @@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [Resolved] private OsuColour colours { get; set; } - public ProfileScore(ScoreInfo score) + public DrawableProfileScore(ScoreInfo score) { Score = score; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs similarity index 94% rename from osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs rename to osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs index 5f080f2589..bacfc0fd83 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/ProfileWeightedScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs @@ -10,11 +10,11 @@ using osuTK; namespace osu.Game.Overlays.Profile.Sections.Ranks { - public class ProfileWeightedScore : ProfileScore + public class DrawableProfileWeightedScore : DrawableProfileScore { private readonly double weight; - public ProfileWeightedScore(ScoreInfo score, double weight) + public DrawableProfileWeightedScore(ScoreInfo score, double weight) : base(score) { this.weight = weight; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index ad6621696d..64494f9814 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -41,10 +41,10 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks switch (type) { default: - return new ProfileScore(model.CreateScoreInfo(Rulesets)); + return new DrawableProfileScore(model.CreateScoreInfo(Rulesets)); case ScoreType.Best: - return new ProfileWeightedScore(model.CreateScoreInfo(Rulesets), Math.Pow(0.95, ItemsContainer.Count)); + return new DrawableProfileWeightedScore(model.CreateScoreInfo(Rulesets), Math.Pow(0.95, ItemsContainer.Count)); } } } From bab67eb399149c5ed638fafff8118a971dd7f11e Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 18 Jan 2020 04:12:17 +0300 Subject: [PATCH 035/240] CI fix --- .../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 13bdb523d2..4d2334df5e 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -106,7 +106,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(15), - Children = new Drawable[] + Children = new[] { CreateRightContent().With(c => { From 8906416294b21aa72ac2a1c574ed165651a12de6 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 19 Jan 2020 22:48:11 +0300 Subject: [PATCH 036/240] ProfileItemBackground -> ProfileItemContainer --- osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs | 2 +- .../Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs | 2 +- .../{ProfileItemBackground.cs => ProfileItemContainer.cs} | 4 ++-- .../Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) rename osu.Game/Overlays/Profile/Sections/{ProfileItemBackground.cs => ProfileItemContainer.cs} (93%) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs index ff26611311..a303d88037 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Online { typeof(DrawableProfileScore), typeof(DrawableProfileWeightedScore), - typeof(ProfileItemBackground), + typeof(ProfileItemContainer), }; public TestSceneUserProfileScores() diff --git a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs index 9040af3384..e75ad2f161 100644 --- a/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs +++ b/osu.Game/Overlays/Profile/Sections/Historical/DrawableMostPlayedBeatmap.cs @@ -61,7 +61,7 @@ namespace osu.Game.Overlays.Profile.Sections.Historical CornerRadius = corner_radius, Children = new Drawable[] { - new ProfileItemBackground + new ProfileItemContainer { Child = new Container { diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemBackground.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs similarity index 93% rename from osu.Game/Overlays/Profile/Sections/ProfileItemBackground.cs rename to osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index 4f8630c92d..8b6d4ea97d 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemBackground.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs @@ -11,7 +11,7 @@ using System.Collections.Generic; namespace osu.Game.Overlays.Profile.Sections { - public class ProfileItemBackground : OsuHoverContainer + public class ProfileItemContainer : OsuHoverContainer { protected override IEnumerable EffectTargets => new[] { background }; protected override Container Content => content; @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Profile.Sections private readonly Box background; private readonly Container content; - public ProfileItemBackground() + public ProfileItemContainer() { RelativeSizeAxes = Axes.Both; Enabled.Value = true; //manually enabled, because we have no action diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 4d2334df5e..722b4d2dae 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -41,7 +41,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [BackgroundDependencyLoader] private void load() { - AddInternal(new ProfileItemBackground + AddInternal(new ProfileItemContainer { Children = new Drawable[] { From 5f11084aedc4a6896f50d0e5a32ca7cf8540e653 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sun, 19 Jan 2020 22:57:39 +0300 Subject: [PATCH 037/240] Refactor ProfileItemContainer to not use sounds --- .../Profile/Sections/ProfileItemContainer.cs | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index 8b6d4ea97d..99cad26a64 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs @@ -5,28 +5,31 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input.Events; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using System.Collections.Generic; +using osuTK.Graphics; namespace osu.Game.Overlays.Profile.Sections { - public class ProfileItemContainer : OsuHoverContainer + public class ProfileItemContainer : Container { - protected override IEnumerable EffectTargets => new[] { background }; + private const int hover_duration = 200; + protected override Container Content => content; + private Color4 idleColour; + private Color4 hoverColour; + private readonly Box background; private readonly Container content; public ProfileItemContainer() { RelativeSizeAxes = Axes.Both; - Enabled.Value = true; //manually enabled, because we have no action Masking = true; CornerRadius = 6; - base.Content.AddRange(new Drawable[] + AddRangeInternal(new Drawable[] { background = new Box { @@ -42,8 +45,20 @@ namespace osu.Game.Overlays.Profile.Sections [BackgroundDependencyLoader] private void load(OsuColour colours) { - IdleColour = colours.GreySeafoam; - HoverColour = colours.GreySeafoamLight; + background.Colour = idleColour = colours.GreySeafoam; + hoverColour = colours.GreySeafoamLight; + } + + protected override bool OnHover(HoverEvent e) + { + background.FadeColour(hoverColour, hover_duration, Easing.OutQuint); + return base.OnHover(e); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + background.FadeColour(idleColour, hover_duration, 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 038/240] 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 039/240] 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 7f538cfa747f069fada8354d4999dfc67f51a45a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 27 Jan 2020 07:56:18 +0800 Subject: [PATCH 040/240] allow setting initial rate instead of reversing --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 14 ++++++-------- osu.Game/Rulesets/Mods/ModWindDown.cs | 10 ++++++++++ osu.Game/Rulesets/Mods/ModWindUp.cs | 10 ++++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index d21990ae91..a9330f9287 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -20,12 +20,12 @@ namespace osu.Game.Rulesets.Mods /// private const double final_rate_progress = 0.75f; + [SettingSource("Initial rate", "The starting speed of the track")] + public abstract BindableNumber InitialRate { get; } + [SettingSource("Final rate", "The final speed to ramp to")] public abstract BindableNumber FinalRate { get; } - [SettingSource("Start wounded", "Start at 100% of the final rate")] - public BindableBool Reverse { get; } = new BindableBool(); - private double finalRateTime; private double beginRampTime; @@ -64,10 +64,7 @@ namespace osu.Game.Rulesets.Mods public virtual void Update(Playfield playfield) { - if (!Reverse.Value) - applyAdjustment((track.CurrentTime - beginRampTime) / finalRateTime); - else - applyAdjustment(1 - ((track.CurrentTime - beginRampTime) / finalRateTime)); + applyAdjustment((track.CurrentTime - beginRampTime) / finalRateTime); } /// @@ -75,6 +72,7 @@ namespace osu.Game.Rulesets.Mods /// /// The amount of adjustment to apply (from 0..1). private void applyAdjustment(double amount) => - SpeedChange.Value = 1 + (FinalRate.Value - 1) * Math.Clamp(amount, 0, 1); + // SpeedChange.Value = 1 + (FinalRate.Value - 1) * Math.Clamp(amount, 0, 1); + SpeedChange.Value = InitialRate.Value + (FinalRate.Value - InitialRate.Value) * Math.Clamp(amount, 0, 1); } } diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index da3bd75b44..939766fee5 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -17,6 +17,16 @@ namespace osu.Game.Rulesets.Mods public override IconUsage? Icon => FontAwesome.Solid.ChevronCircleDown; public override double ScoreMultiplier => 1.0; + [SettingSource("Initial rate", "The starting speed of the track")] + public override BindableNumber InitialRate { get; } = new BindableDouble + { + MinValue = 1, + MaxValue = 1.5, + Default = 1, + Value = 1, + Precision = 0.01, + }; + [SettingSource("Final rate", "The speed increase to ramp towards")] public override BindableNumber FinalRate { get; } = new BindableDouble { diff --git a/osu.Game/Rulesets/Mods/ModWindUp.cs b/osu.Game/Rulesets/Mods/ModWindUp.cs index 3f456a42a5..74c6fc22d3 100644 --- a/osu.Game/Rulesets/Mods/ModWindUp.cs +++ b/osu.Game/Rulesets/Mods/ModWindUp.cs @@ -17,6 +17,16 @@ namespace osu.Game.Rulesets.Mods public override IconUsage? Icon => FontAwesome.Solid.ChevronCircleUp; public override double ScoreMultiplier => 1.0; + [SettingSource("Initial rate", "The starting speed of the track")] + public override BindableNumber InitialRate { get; } = new BindableDouble + { + MinValue = 0.5, + MaxValue = 1, + Default = 1, + Value = 1, + Precision = 0.01, + }; + [SettingSource("Final rate", "The speed increase to ramp towards")] public override BindableNumber FinalRate { get; } = new BindableDouble { From 508b92e611c3c20ffa4a7bbdecd64b2f3db42586 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 15:57:55 +0900 Subject: [PATCH 041/240] Update beat divisor colours to be more distinguishable Close to osu-stable --- osu.Game/Screens/Edit/BindableBeatDivisor.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs index ce95d81f54..e8f7c75cc1 100644 --- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs +++ b/osu.Game/Screens/Edit/BindableBeatDivisor.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; @@ -52,29 +52,32 @@ namespace osu.Game.Screens.Edit { switch (beatDivisor) { + case 1: + return Color4.White; + case 2: - return colours.BlueLight; + return colours.Red; case 4: return colours.Blue; case 8: - return colours.BlueDarker; + return colours.Yellow; case 16: return colours.PurpleDark; case 3: - return colours.YellowLight; + return colours.Purple; case 6: - return colours.Yellow; + return colours.YellowDark; case 12: return colours.YellowDarker; default: - return Color4.White; + return Color4.Red; } } } From df665c3a3cd98744c5381282c124148b60d83cdc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 16:00:51 +0900 Subject: [PATCH 042/240] Move beat index colour retrieval to static function --- osu.Game/Screens/Edit/BindableBeatDivisor.cs | 23 ++++++++++++++++++- .../Compose/Components/DistanceSnapGrid.cs | 14 +---------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs index e8f7c75cc1..be1e121a99 100644 --- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs +++ b/osu.Game/Screens/Edit/BindableBeatDivisor.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; @@ -80,5 +80,26 @@ namespace osu.Game.Screens.Edit return Color4.Red; } } + + /// + /// Retrieves the applicable divisor for a specific beat index. + /// + /// The 0-based beat index. + /// The beat divisor. + /// The applicable divisor. + public static int GetDivisorForBeatIndex(int index, int beatDivisor) + { + int beat = index % beatDivisor; + + for (int i = 0; i < BindableBeatDivisor.VALID_DIVISORS.Length; i++) + { + int divisor = BindableBeatDivisor.VALID_DIVISORS[i]; + + if ((beat * divisor) % beatDivisor == 0) + return divisor; + } + + return 0; + } } } diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 53c5cf97fa..3bbccd612b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -130,19 +130,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// The applicable colour. protected ColourInfo GetColourForBeatIndex(int index) { - int beat = (index + 1) % beatDivisor.Value; - ColourInfo colour = Colours.Gray5; - - for (int i = 0; i < BindableBeatDivisor.VALID_DIVISORS.Length; i++) - { - int divisor = BindableBeatDivisor.VALID_DIVISORS[i]; - - if ((beat * divisor) % beatDivisor.Value == 0) - { - colour = BindableBeatDivisor.GetColourFor(divisor, Colours); - break; - } - } + var colour = BindableBeatDivisor.GetColourFor(BindableBeatDivisor.GetDivisorForBeatIndex(index + 1, beatDivisor.Value), Colours); int repeatIndex = index / beatDivisor.Value; return colour.MultiplyAlpha(0.5f / (repeatIndex + 1)); From 03b7c6cfa7ed291dc9b9c2913d12c7b4378c65b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 16:54:36 +0900 Subject: [PATCH 043/240] Add base test scene for timeline --- .../TestSceneTimelineBlueprintContainer.cs | 135 +--------------- .../Visual/Editor/TimelineTestScene.cs | 148 ++++++++++++++++++ 2 files changed, 150 insertions(+), 133 deletions(-) create mode 100644 osu.Game.Tests/Visual/Editor/TimelineTestScene.cs diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs index e7b2508ac7..3c75fd5310 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBlueprintContainer.cs @@ -1,146 +1,15 @@ // 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.Audio; -using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -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; -using osuTK.Graphics; namespace osu.Game.Tests.Visual.Editor { [TestFixture] - public class TestSceneTimelineBlueprintContainer : EditorClockTestScene + public class TestSceneTimelineBlueprintContainer : TimelineTestScene { - public override IReadOnlyList RequiredTypes => new[] - { - typeof(TimelineArea), - typeof(Timeline), - typeof(TimelineButton), - typeof(CentreMarker) - }; - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - Beatmap.Value = new WaveformTestBeatmap(audio); - - var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap, BeatDivisor); - - Dependencies.Cache(editorBeatmap); - Dependencies.CacheAs(editorBeatmap); - - Children = new Drawable[] - { - new FillFlowContainer - { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), - Children = new Drawable[] - { - new StartStopButton(), - new AudioVisualiser(), - } - }, - new TimelineArea - { - Child = new TimelineBlueprintContainer(), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.X, - Size = new Vector2(0.8f, 100) - } - }; - } - - private class AudioVisualiser : CompositeDrawable - { - private readonly Drawable marker; - - [Resolved] - private IBindable beatmap { get; set; } - - [Resolved] - private IAdjustableClock adjustableClock { get; set; } - - public AudioVisualiser() - { - Size = new Vector2(250, 25); - - InternalChildren = new[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0.25f, - }, - marker = new Box - { - RelativePositionAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Width = 2, - } - }; - } - - protected override void Update() - { - base.Update(); - - if (beatmap.Value.Track.IsLoaded) - marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length); - } - } - - private class StartStopButton : OsuButton - { - private IAdjustableClock adjustableClock; - private bool started; - - public StartStopButton() - { - BackgroundColour = Color4.SlateGray; - Size = new Vector2(100, 50); - Text = "Start"; - - Action = onClick; - } - - [BackgroundDependencyLoader] - private void load(IAdjustableClock adjustableClock) - { - this.adjustableClock = adjustableClock; - } - - private void onClick() - { - if (started) - { - adjustableClock.Stop(); - Text = "Start"; - } - else - { - adjustableClock.Start(); - Text = "Stop"; - } - - started = !started; - } - } + public override Drawable CreateTestComponent() => new TimelineBlueprintContainer(); } } diff --git a/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs new file mode 100644 index 0000000000..b5e526d3c2 --- /dev/null +++ b/osu.Game.Tests/Visual/Editor/TimelineTestScene.cs @@ -0,0 +1,148 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +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; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.Editor +{ + public abstract class TimelineTestScene : EditorClockTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(TimelineArea), + typeof(Timeline), + typeof(TimelineButton), + typeof(CentreMarker) + }; + + protected TimelineArea TimelineArea { get; private set; } + + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + Beatmap.Value = new WaveformTestBeatmap(audio); + + var editorBeatmap = new EditorBeatmap((Beatmap)Beatmap.Value.Beatmap, BeatDivisor); + + Dependencies.Cache(editorBeatmap); + Dependencies.CacheAs(editorBeatmap); + + AddRange(new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + new StartStopButton(), + new AudioVisualiser(), + } + }, + TimelineArea = new TimelineArea + { + Child = CreateTestComponent(), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Size = new Vector2(0.8f, 100), + } + }); + } + + public abstract Drawable CreateTestComponent(); + + private class AudioVisualiser : CompositeDrawable + { + private readonly Drawable marker; + + [Resolved] + private IBindable beatmap { get; set; } + + [Resolved] + private IAdjustableClock adjustableClock { get; set; } + + public AudioVisualiser() + { + Size = new Vector2(250, 25); + + InternalChildren = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.25f, + }, + marker = new Box + { + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Width = 2, + } + }; + } + + protected override void Update() + { + base.Update(); + + if (beatmap.Value.Track.IsLoaded) + marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length); + } + } + + private class StartStopButton : OsuButton + { + private IAdjustableClock adjustableClock; + private bool started; + + public StartStopButton() + { + BackgroundColour = Color4.SlateGray; + Size = new Vector2(100, 50); + Text = "Start"; + + Action = onClick; + } + + [BackgroundDependencyLoader] + private void load(IAdjustableClock adjustableClock) + { + this.adjustableClock = adjustableClock; + } + + private void onClick() + { + if (started) + { + adjustableClock.Stop(); + Text = "Start"; + } + else + { + adjustableClock.Start(); + Text = "Stop"; + } + + started = !started; + } + } + } +} From e24c4ab90101ed2c53035db225a5c85339dc6183 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 16:54:57 +0900 Subject: [PATCH 044/240] Adjust zoom defaults for timeline to be more useful --- .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 96395696c3..5b2dd343e6 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -30,7 +30,10 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { ZoomDuration = 200; ZoomEasing = Easing.OutQuint; - Zoom = 10; + + Zoom = 60; + MaxZoom = 240; + ScrollbarVisible = false; } From 084fa2f04a8fa8b1d6a3c34b7744c590c0256f75 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 17:34:25 +0900 Subject: [PATCH 045/240] Add timeline beat display --- .../TestSceneTimelineBeatLineDisplay.cs | 32 +++++++ .../Visualisations/PointVisualisation.cs | 2 +- .../Timeline/TimelineBeatLineDisplay.cs | 90 +++++++++++++++++++ .../Screens/Edit/EditorScreenWithTimeline.cs | 6 +- 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs create mode 100644 osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBeatLineDisplay.cs diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs new file mode 100644 index 0000000000..50a33852be --- /dev/null +++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs @@ -0,0 +1,32 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Screens.Edit.Compose.Components; +using osu.Game.Screens.Edit.Compose.Components.Timeline; +using osuTK; + +namespace osu.Game.Tests.Visual.Editor +{ + [TestFixture] + public class TestSceneTimelineBeatLineDisplay : TimelineTestScene + { + public override Drawable CreateTestComponent() => new TimelineBeatLineDisplay(); + + [BackgroundDependencyLoader] + private void load() + { + BeatDivisor.Value = 4; + + Add(new BeatDivisorControl(BeatDivisor) + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Margin = new MarginPadding(30), + Size = new Vector2(90) + }); + } + } +} diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs index 9c00cce57a..1ac960039e 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Visualisations/PointVisualisation.cs @@ -12,7 +12,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations /// public class PointVisualisation : Box { - protected PointVisualisation(double startTime) + public PointVisualisation(double startTime) { Origin = Anchor.TopCentre; diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBeatLineDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBeatLineDisplay.cs new file mode 100644 index 0000000000..0a6fa2be66 --- /dev/null +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBeatLineDisplay.cs @@ -0,0 +1,90 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Screens.Edit.Components.Timelines.Summary.Parts; +using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; + +namespace osu.Game.Screens.Edit.Compose.Components.Timeline +{ + public class TimelineBeatLineDisplay : TimelinePart + { + [Resolved] + private EditorBeatmap beatmap { get; set; } + + [Resolved] + private Bindable working { get; set; } + + [Resolved] + private BindableBeatDivisor beatDivisor { get; set; } + + [Resolved] + private OsuColour colours { get; set; } + + public TimelineBeatLineDisplay() + { + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load() + { + beatDivisor.BindValueChanged(_ => createLines(), true); + } + + private void createLines() + { + Clear(); + + 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; + + int beat = 0; + + for (double t = point.Time; t < until; t += point.BeatLength / beatDivisor.Value) + { + var indexInBeat = beat % beatDivisor.Value; + + if (indexInBeat == 0) + { + Add(new PointVisualisation(t) + { + Colour = BindableBeatDivisor.GetColourFor(1, colours), + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + }); + } + else + { + var divisor = BindableBeatDivisor.GetDivisorForBeatIndex(beat, beatDivisor.Value); + var colour = BindableBeatDivisor.GetColourFor(divisor, colours); + var height = 0.1f - (float)divisor / BindableBeatDivisor.VALID_DIVISORS.Last() * 0.08f; + + Add(new PointVisualisation(t) + { + Colour = colour, + Height = height, + }); + + Add(new PointVisualisation(t) + { + Colour = colour, + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Height = height, + }); + } + + beat++; + } + } + } + } +} diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs index 8967f24185..0f81194894 100644 --- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs +++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs @@ -102,7 +102,11 @@ namespace osu.Game.Screens.Edit LoadComponentAsync(new TimelineArea { RelativeSizeAxes = Axes.Both, - Child = CreateTimelineContent() + Children = new[] + { + new TimelineBeatLineDisplay(), + CreateTimelineContent(), + } }, timelineContainer.Add); }); } From 493390b75088993c67d6c6c8d662b366483cb622 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 18:07:46 +0900 Subject: [PATCH 046/240] Rename class to TimelineTickDisplay --- .../Visual/Editor/TestSceneTimelineBeatLineDisplay.cs | 2 +- .../{TimelineBeatLineDisplay.cs => TimelineTickDisplay.cs} | 4 ++-- osu.Game/Screens/Edit/EditorScreenWithTimeline.cs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Screens/Edit/Compose/Components/Timeline/{TimelineBeatLineDisplay.cs => TimelineTickDisplay.cs} (96%) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs index 50a33852be..3b04496792 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Visual.Editor [TestFixture] public class TestSceneTimelineBeatLineDisplay : TimelineTestScene { - public override Drawable CreateTestComponent() => new TimelineBeatLineDisplay(); + public override Drawable CreateTestComponent() => new TimelineTickDisplay(); [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBeatLineDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs similarity index 96% rename from osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBeatLineDisplay.cs rename to osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index 0a6fa2be66..03fb1fdba1 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBeatLineDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -12,7 +12,7 @@ using osu.Game.Screens.Edit.Components.Timelines.Summary.Visualisations; namespace osu.Game.Screens.Edit.Compose.Components.Timeline { - public class TimelineBeatLineDisplay : TimelinePart + public class TimelineTickDisplay : TimelinePart { [Resolved] private EditorBeatmap beatmap { get; set; } @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline [Resolved] private OsuColour colours { get; set; } - public TimelineBeatLineDisplay() + public TimelineTickDisplay() { RelativeSizeAxes = Axes.Both; } diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs index 0f81194894..7ee1005add 100644 --- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs +++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Edit RelativeSizeAxes = Axes.Both, Children = new[] { - new TimelineBeatLineDisplay(), + new TimelineTickDisplay(), CreateTimelineContent(), } }, timelineContainer.Add); From d5fda053f4333bd6c68715c3cc077412d5607b57 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 18:08:30 +0900 Subject: [PATCH 047/240] Use centre origin/anchors --- .../Edit/Compose/Components/Timeline/TimelineTickDisplay.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs index 03fb1fdba1..f9b92c0504 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineTickDisplay.cs @@ -57,8 +57,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Add(new PointVisualisation(t) { Colour = BindableBeatDivisor.GetColourFor(1, colours), - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, + Origin = Anchor.TopCentre, }); } else @@ -71,13 +70,14 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { Colour = colour, Height = height, + Origin = Anchor.TopCentre, }); Add(new PointVisualisation(t) { Colour = colour, Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, + Origin = Anchor.BottomCentre, Height = height, }); } From 9a2867d3d97e8becceffa5d7b6866ae336758cdb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 27 Jan 2020 18:10:42 +0900 Subject: [PATCH 048/240] Rename test class --- ...melineBeatLineDisplay.cs => TestSceneTimelineTickDisplay.cs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename osu.Game.Tests/Visual/Editor/{TestSceneTimelineBeatLineDisplay.cs => TestSceneTimelineTickDisplay.cs} (92%) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs b/osu.Game.Tests/Visual/Editor/TestSceneTimelineTickDisplay.cs similarity index 92% rename from osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs rename to osu.Game.Tests/Visual/Editor/TestSceneTimelineTickDisplay.cs index 3b04496792..43a3cd6122 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneTimelineBeatLineDisplay.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneTimelineTickDisplay.cs @@ -11,7 +11,7 @@ using osuTK; namespace osu.Game.Tests.Visual.Editor { [TestFixture] - public class TestSceneTimelineBeatLineDisplay : TimelineTestScene + public class TestSceneTimelineTickDisplay : TimelineTestScene { public override Drawable CreateTestComponent() => new TimelineTickDisplay(); From 79cdfc6dc211ec3086843d8bfddb998df80db4ed Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 27 Jan 2020 12:55:19 +0300 Subject: [PATCH 049/240] Use OverlayColourProvider --- .../Online/TestSceneUserProfileScores.cs | 23 ++++++++++++++++--- .../Visual/Online/TestSceneUserRanks.cs | 5 ++++ .../Profile/Sections/ProfileItemContainer.cs | 7 +++--- .../Sections/Ranks/DrawableProfileScore.cs | 11 +++++---- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs index a303d88037..19b72e7071 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileScores.cs @@ -12,6 +12,8 @@ using osuTK; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Overlays; +using osu.Framework.Allocation; namespace osu.Game.Tests.Visual.Online { @@ -74,11 +76,26 @@ namespace osu.Game.Tests.Visual.Online Spacing = new Vector2(0, 10), Children = new[] { - new DrawableProfileScore(score), - new DrawableProfileScore(noPPScore), - new DrawableProfileWeightedScore(score, 0.85), + new ColourProvidedContainer(OverlayColourScheme.Green, new DrawableProfileScore(score)), + new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileScore(noPPScore)), + new ColourProvidedContainer(OverlayColourScheme.Pink, new DrawableProfileWeightedScore(score, 0.85)) } }); } + + private class ColourProvidedContainer : Container + { + [Cached] + private readonly OverlayColourProvider colourProvider; + + public ColourProvidedContainer(OverlayColourScheme colourScheme, DrawableProfileScore score) + { + colourProvider = new OverlayColourProvider(colourScheme); + + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + Add(score); + } + } } } diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs index 5cbdfb561e..c8e94b2915 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneUserRanks.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserRanks.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.Containers; +using osu.Game.Overlays; using osu.Game.Overlays.Profile.Sections; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Users; @@ -27,6 +29,9 @@ namespace osu.Game.Tests.Visual.Online typeof(RanksSection) }; + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green); + public TestSceneUserRanks() { RanksSection ranks; diff --git a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs index 99cad26a64..717ec4fb1a 100644 --- a/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/ProfileItemContainer.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.Profile.Sections @@ -43,10 +42,10 @@ namespace osu.Game.Overlays.Profile.Sections } [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) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 722b4d2dae..9145ce6894 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -30,6 +30,9 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [Resolved] private OsuColour colours { get; set; } + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + public DrawableProfileScore(ScoreInfo score) { Score = score; @@ -91,7 +94,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks }, new DrawableDate(Score.Date, 12) { - Colour = colours.GreySeafoamLighter + Colour = colourProvider.Foreground1 } } } @@ -192,7 +195,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.BottomLeft, Font = OsuFont.GetFont(weight: FontWeight.Bold), Text = $"{Score.PP:0}", - Colour = colours.GreenLight + Colour = colourProvider.Highlight1 }, new OsuSpriteText { @@ -200,7 +203,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Origin = Anchor.BottomLeft, Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), Text = "pp", - Colour = colours.Green + Colour = colourProvider.Light3 } } }; @@ -210,7 +213,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { Font = OsuFont.GetFont(weight: FontWeight.Bold), Text = "-", - Colour = colours.GreenLight + Colour = colourProvider.Highlight1 }; } From d9e21a572fba46f991a7ca94a218e8655bca9d47 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Jan 2020 07:13:28 +0800 Subject: [PATCH 050/240] remove unecessary comment --- osu.Game/Rulesets/Mods/ModTimeRamp.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModTimeRamp.cs b/osu.Game/Rulesets/Mods/ModTimeRamp.cs index a9330f9287..9e63142b42 100644 --- a/osu.Game/Rulesets/Mods/ModTimeRamp.cs +++ b/osu.Game/Rulesets/Mods/ModTimeRamp.cs @@ -72,7 +72,6 @@ namespace osu.Game.Rulesets.Mods /// /// The amount of adjustment to apply (from 0..1). private void applyAdjustment(double amount) => - // SpeedChange.Value = 1 + (FinalRate.Value - 1) * Math.Clamp(amount, 0, 1); SpeedChange.Value = InitialRate.Value + (FinalRate.Value - InitialRate.Value) * Math.Clamp(amount, 0, 1); } } From 29daabb40a42856de7fd6a709ee938b17bedf152 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 11:59:21 +0900 Subject: [PATCH 051/240] Fix distance snap grid showing incorrect colouring Now matches timeline colours (based on timing point). --- .../Editor/TestSceneDistanceSnapGrid.cs | 36 +++++++++---------- .../Components/CircularDistanceSnapGrid.cs | 14 ++++---- .../Compose/Components/DistanceSnapGrid.cs | 15 ++++---- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs b/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs index 847d168e51..f49256a633 100644 --- a/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs +++ b/osu.Game.Tests/Visual/Editor/TestSceneDistanceSnapGrid.cs @@ -85,64 +85,64 @@ namespace osu.Game.Tests.Visual.Editor { } - protected override void CreateContent(Vector2 startPosition) + protected override void CreateContent() { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(5), - Position = startPosition + Position = StartPosition }); - int beatIndex = 0; + int indexFromPlacement = 0; - for (float s = startPosition.X + DistanceSpacing; s <= DrawWidth && beatIndex < MaxIntervals; s += DistanceSpacing, beatIndex++) + for (float s = StartPosition.X + DistanceSpacing; s <= DrawWidth && indexFromPlacement < MaxIntervals; s += DistanceSpacing, indexFromPlacement++) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(5, 10), - Position = new Vector2(s, startPosition.Y), - Colour = GetColourForBeatIndex(beatIndex) + Position = new Vector2(s, StartPosition.Y), + Colour = GetColourForIndexFromPlacement(indexFromPlacement) }); } - beatIndex = 0; + indexFromPlacement = 0; - for (float s = startPosition.X - DistanceSpacing; s >= 0 && beatIndex < MaxIntervals; s -= DistanceSpacing, beatIndex++) + for (float s = StartPosition.X - DistanceSpacing; s >= 0 && indexFromPlacement < MaxIntervals; s -= DistanceSpacing, indexFromPlacement++) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(5, 10), - Position = new Vector2(s, startPosition.Y), - Colour = GetColourForBeatIndex(beatIndex) + Position = new Vector2(s, StartPosition.Y), + Colour = GetColourForIndexFromPlacement(indexFromPlacement) }); } - beatIndex = 0; + indexFromPlacement = 0; - for (float s = startPosition.Y + DistanceSpacing; s <= DrawHeight && beatIndex < MaxIntervals; s += DistanceSpacing, beatIndex++) + for (float s = StartPosition.Y + DistanceSpacing; s <= DrawHeight && indexFromPlacement < MaxIntervals; s += DistanceSpacing, indexFromPlacement++) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(10, 5), - Position = new Vector2(startPosition.X, s), - Colour = GetColourForBeatIndex(beatIndex) + Position = new Vector2(StartPosition.X, s), + Colour = GetColourForIndexFromPlacement(indexFromPlacement) }); } - beatIndex = 0; + indexFromPlacement = 0; - for (float s = startPosition.Y - DistanceSpacing; s >= 0 && beatIndex < MaxIntervals; s -= DistanceSpacing, beatIndex++) + for (float s = StartPosition.Y - DistanceSpacing; s >= 0 && indexFromPlacement < MaxIntervals; s -= DistanceSpacing, indexFromPlacement++) { AddInternal(new Circle { Origin = Anchor.Centre, Size = new Vector2(10, 5), - Position = new Vector2(startPosition.X, s), - Colour = GetColourForBeatIndex(beatIndex) + Position = new Vector2(StartPosition.X, s), + Colour = GetColourForIndexFromPlacement(indexFromPlacement) }); } } diff --git a/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs index 23ed10b92d..730f482f83 100644 --- a/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/CircularDistanceSnapGrid.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens.Edit.Compose.Components { } - protected override void CreateContent(Vector2 startPosition) + protected override void CreateContent() { const float crosshair_thickness = 1; const float crosshair_max_size = 10; @@ -26,7 +26,7 @@ namespace osu.Game.Screens.Edit.Compose.Components new Box { Origin = Anchor.Centre, - Position = startPosition, + Position = StartPosition, Width = crosshair_thickness, EdgeSmoothness = new Vector2(1), Height = Math.Min(crosshair_max_size, DistanceSpacing * 2), @@ -34,15 +34,15 @@ namespace osu.Game.Screens.Edit.Compose.Components new Box { Origin = Anchor.Centre, - Position = startPosition, + Position = StartPosition, EdgeSmoothness = new Vector2(1), Width = Math.Min(crosshair_max_size, DistanceSpacing * 2), Height = crosshair_thickness, } }); - float dx = Math.Max(startPosition.X, DrawWidth - startPosition.X); - float dy = Math.Max(startPosition.Y, DrawHeight - startPosition.Y); + float dx = Math.Max(StartPosition.X, DrawWidth - StartPosition.X); + float dy = Math.Max(StartPosition.Y, DrawHeight - StartPosition.Y); float maxDistance = new Vector2(dx, dy).Length; int requiredCircles = Math.Min(MaxIntervals, (int)(maxDistance / DistanceSpacing)); @@ -53,11 +53,11 @@ namespace osu.Game.Screens.Edit.Compose.Components AddInternal(new CircularProgress { Origin = Anchor.Centre, - Position = startPosition, + Position = StartPosition, Current = { Value = 1 }, Size = new Vector2(radius), InnerRadius = 4 * 1f / radius, - Colour = GetColourForBeatIndex(i) + Colour = GetColourForIndexFromPlacement(i) }); } } diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index 3bbccd612b..bce8878766 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Graphics; @@ -106,7 +107,7 @@ namespace osu.Game.Screens.Edit.Compose.Components if (!gridCache.IsValid) { ClearInternal(); - CreateContent(StartPosition); + CreateContent(); gridCache.Validate(); } } @@ -114,7 +115,7 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Creates the content which visualises the grid ticks. /// - protected abstract void CreateContent(Vector2 startPosition); + protected abstract void CreateContent(); /// /// Snaps a position to this grid. @@ -126,13 +127,15 @@ namespace osu.Game.Screens.Edit.Compose.Components /// /// Retrieves the applicable colour for a beat index. /// - /// The 0-based beat index. + /// The 0-based beat index from the point of placement. /// The applicable colour. - protected ColourInfo GetColourForBeatIndex(int index) + protected ColourInfo GetColourForIndexFromPlacement(int placementIndex) { - var colour = BindableBeatDivisor.GetColourFor(BindableBeatDivisor.GetDivisorForBeatIndex(index + 1, beatDivisor.Value), Colours); + var timingPoint = beatmap.ControlPointInfo.TimingPointAt(StartTime); + var beatIndex = (int)Math.Round((StartTime - timingPoint.Time) / timingPoint.BeatLength * beatDivisor.Value); + var colour = BindableBeatDivisor.GetColourFor(BindableBeatDivisor.GetDivisorForBeatIndex(beatIndex + placementIndex + 1, beatDivisor.Value), Colours); - int repeatIndex = index / beatDivisor.Value; + int repeatIndex = placementIndex / beatDivisor.Value; return colour.MultiplyAlpha(0.5f / (repeatIndex + 1)); } } From 58654f28b67e4ce29d50125237e075007f0ec7ff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 12:48:24 +0900 Subject: [PATCH 052/240] Fix beat snap implementation being incorrect --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 4 ++-- osu.Game/Rulesets/Edit/IBeatSnapProvider.cs | 8 ++++---- .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Edit/EditorBeatmap.cs | 8 +++++--- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 9ee3bacf9b..252b418523 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -275,10 +275,10 @@ namespace osu.Game.Rulesets.Edit } public override double GetSnappedDurationFromDistance(double referenceTime, float distance) - => beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance)); + => beatSnapProvider.SnapTime(referenceTime + DistanceToDuration(referenceTime, distance), referenceTime) - referenceTime; public override float GetSnappedDistanceFromDistance(double referenceTime, float distance) - => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(referenceTime, DistanceToDuration(referenceTime, distance))); + => DurationToDistance(referenceTime, beatSnapProvider.SnapTime(DistanceToDuration(referenceTime, distance), referenceTime)); protected override void Dispose(bool isDisposing) { diff --git a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs index e1daafaebe..616f854cd7 100644 --- a/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IBeatSnapProvider.cs @@ -8,10 +8,10 @@ namespace osu.Game.Rulesets.Edit /// /// Snaps a duration to the closest beat of a timing point applicable at the reference time. /// - /// The time of the timing point which resides in. - /// The duration to snap. - /// A value that represents snapped to the closest beat of the timing point. - double SnapTime(double referenceTime, double duration); + /// The time to snap. + /// An optional reference point to use for timing point lookup. + /// A value that represents snapped to the closest beat of the timing point. + double SnapTime(double time, double? referenceTime = null); /// /// Get the most appropriate beat length at a given time. diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 96395696c3..2dd7ad79ba 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -177,7 +177,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline public (Vector2 position, double time) GetSnappedPosition(Vector2 position, double time) { var targetTime = (position.X / Content.DrawWidth) * track.Length; - return (position, beatSnapProvider.SnapTime(targetTime, targetTime)); + return (position, beatSnapProvider.SnapTime(targetTime)); } public float GetBeatSnapDistanceAt(double referenceTime) => throw new NotImplementedException(); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index eae94a3c8e..8c7270d3a2 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -348,7 +348,7 @@ namespace osu.Game.Screens.Edit beatmapManager.Export(Beatmap.Value.BeatmapSetInfo); } - public double SnapTime(double referenceTime, double duration) => editorBeatmap.SnapTime(referenceTime, duration); + public double SnapTime(double time, double? referenceTime) => editorBeatmap.SnapTime(time, referenceTime); public double GetBeatLengthAtTime(double referenceTime) => editorBeatmap.GetBeatLengthAtTime(referenceTime); diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 9c75d40bec..2d3ecf583e 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -128,12 +128,14 @@ namespace osu.Game.Screens.Edit return list.Count - 1; } - public double SnapTime(double referenceTime, double duration) + public double SnapTime(double time, double? referenceTime) { - double beatLength = GetBeatLengthAtTime(referenceTime); + var timingPoint = ControlPointInfo.TimingPointAt(referenceTime ?? time); + + var beatLength = timingPoint.BeatLength / BeatDivisor; // A 1ms offset prevents rounding errors due to minute variations in duration - return (int)((duration + 1) / beatLength) * beatLength; + return timingPoint.Time + (int)Math.Round(((time - timingPoint.Time) + 1) / beatLength) * beatLength; } public double GetBeatLengthAtTime(double referenceTime) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor; From 4bb33046ca3b4237c3227c3bbba4c60c6084971a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 13:02:29 +0900 Subject: [PATCH 053/240] Standardise editor timeline zoom across maps of all lengths --- .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 7 ++++++- .../Components/Timeline/ZoomableScrollContainer.cs | 8 ++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 96395696c3..b4baa64086 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -30,7 +30,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { ZoomDuration = 200; ZoomEasing = Easing.OutQuint; - Zoom = 10; ScrollbarVisible = false; } @@ -61,9 +60,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { waveform.Waveform = b.NewValue.Waveform; track = b.NewValue.Track; + + MinZoom = getZoomLevelForVisibleMilliseconds(10000); + MaxZoom = getZoomLevelForVisibleMilliseconds(500); + Zoom = getZoomLevelForVisibleMilliseconds(2000); }, true); } + private float getZoomLevelForVisibleMilliseconds(double milliseconds) => (float)(track.Length / milliseconds); + /// /// The timeline's scroll position in the last frame. /// diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index 9aa527667b..7ce8a751e0 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -36,12 +36,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); } - private int minZoom = 1; + private float minZoom = 1; /// /// The minimum zoom level allowed. /// - public int MinZoom + public float MinZoom { get => minZoom; set @@ -56,12 +56,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline } } - private int maxZoom = 60; + private float maxZoom = 60; /// /// The maximum zoom level allowed. /// - public int MaxZoom + public float MaxZoom { get => maxZoom; set From aa264cd2a8c89f77c966471661e6b76d781e27bf Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Jan 2020 12:32:30 +0800 Subject: [PATCH 054/240] allow tooltip to show as percentage as needed --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 8 ++++++-- .../Settings/Sections/Audio/VolumeSettings.cs | 8 ++++---- .../Settings/Sections/Gameplay/GeneralSettings.cs | 6 ++++-- .../Settings/Sections/Graphics/LayoutSettings.cs | 12 ++++++++---- osu.Game/Overlays/Settings/SettingsSlider.cs | 6 ++++++ .../Screens/Play/PlayerSettings/VisualSettings.cs | 10 ++++++++-- 6 files changed, 36 insertions(+), 14 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 2112aac6a3..1058595232 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -35,6 +35,7 @@ namespace osu.Game.Graphics.UserInterface private readonly Container nubContainer; public virtual string TooltipText { get; private set; } + public bool DisplayAsPercentage { get; set; } private Color4 accentColour; @@ -172,8 +173,11 @@ namespace osu.Game.Graphics.UserInterface double floatMinValue = CurrentNumber.MinValue.ToDouble(NumberFormatInfo.InvariantInfo); double floatMaxValue = CurrentNumber.MaxValue.ToDouble(NumberFormatInfo.InvariantInfo); - if (floatMaxValue == 1 && floatMinValue >= -1) - TooltipText = floatValue.ToString("P0"); + if (DisplayAsPercentage) + { + double percentage = floatValue / floatMaxValue; + TooltipText = percentage.ToString("P0"); + } else { var decimalPrecision = normalise(CurrentNumber.Precision.ToDecimal(NumberFormatInfo.InvariantInfo), max_decimal_digits); diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index 0124f7090e..fe7f4c4908 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -17,10 +17,10 @@ namespace osu.Game.Overlays.Settings.Sections.Audio { Children = new Drawable[] { - new SettingsSlider { LabelText = "Master", Bindable = audio.Volume, KeyboardStep = 0.01f }, - new SettingsSlider { LabelText = "Master (window inactive)", Bindable = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.01f }, - new SettingsSlider { LabelText = "Effect", Bindable = audio.VolumeSample, KeyboardStep = 0.01f }, - new SettingsSlider { LabelText = "Music", Bindable = audio.VolumeTrack, KeyboardStep = 0.01f }, + new SettingsSlider { LabelText = "Master", Bindable = audio.Volume, KeyboardStep = 0.01f, DisplayAsPercentage = true }, + new SettingsSlider { LabelText = "Master (window inactive)", Bindable = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.01f, DisplayAsPercentage = true }, + new SettingsSlider { LabelText = "Effect", Bindable = audio.VolumeSample, KeyboardStep = 0.01f, DisplayAsPercentage = true }, + new SettingsSlider { LabelText = "Music", Bindable = audio.VolumeTrack, KeyboardStep = 0.01f, DisplayAsPercentage = true }, }; } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 08bc67e43e..2d2cd42213 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -21,13 +21,15 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { LabelText = "Background dim", Bindable = config.GetBindable(OsuSetting.DimLevel), - KeyboardStep = 0.01f + KeyboardStep = 0.01f, + DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Background blur", Bindable = config.GetBindable(OsuSetting.BlurLevel), - KeyboardStep = 0.01f + KeyboardStep = 0.01f, + DisplayAsPercentage = true }, new SettingsCheckbox { diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs index 02b9edd975..efbb08b7df 100644 --- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs @@ -98,25 +98,29 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics { LabelText = "Horizontal position", Bindable = scalingPositionX, - KeyboardStep = 0.01f + KeyboardStep = 0.01f, + DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Vertical position", Bindable = scalingPositionY, - KeyboardStep = 0.01f + KeyboardStep = 0.01f, + DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Horizontal scale", Bindable = scalingSizeX, - KeyboardStep = 0.01f + KeyboardStep = 0.01f, + DisplayAsPercentage = true }, new SettingsSlider { LabelText = "Vertical scale", Bindable = scalingSizeY, - KeyboardStep = 0.01f + KeyboardStep = 0.01f, + DisplayAsPercentage = true }, } }, diff --git a/osu.Game/Overlays/Settings/SettingsSlider.cs b/osu.Game/Overlays/Settings/SettingsSlider.cs index 96c0279a7b..a7485f77cd 100644 --- a/osu.Game/Overlays/Settings/SettingsSlider.cs +++ b/osu.Game/Overlays/Settings/SettingsSlider.cs @@ -33,5 +33,11 @@ namespace osu.Game.Overlays.Settings get => ((TSlider)Control).KeyboardStep; set => ((TSlider)Control).KeyboardStep = value; } + + public bool DisplayAsPercentage + { + get => ((TSlider)Control).DisplayAsPercentage; + set => ((TSlider)Control).DisplayAsPercentage = value; + } } } diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index ff64f35a18..9db3a587fa 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -27,12 +27,18 @@ namespace osu.Game.Screens.Play.PlayerSettings { Text = "Background dim:" }, - dimSliderBar = new PlayerSliderBar(), + dimSliderBar = new PlayerSliderBar + { + DisplayAsPercentage = true + }, new OsuSpriteText { Text = "Background blur:" }, - blurSliderBar = new PlayerSliderBar(), + blurSliderBar = new PlayerSliderBar + { + DisplayAsPercentage = true + }, new OsuSpriteText { Text = "Toggles:" From a3cfeb08d41d3b4b8235b6422fc35c8d5cf16b0d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Jan 2020 12:34:17 +0800 Subject: [PATCH 055/240] remove unused assignment --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 1058595232..d908f046bd 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -170,7 +170,6 @@ namespace osu.Game.Graphics.UserInterface else { double floatValue = value.ToDouble(NumberFormatInfo.InvariantInfo); - double floatMinValue = CurrentNumber.MinValue.ToDouble(NumberFormatInfo.InvariantInfo); double floatMaxValue = CurrentNumber.MaxValue.ToDouble(NumberFormatInfo.InvariantInfo); if (DisplayAsPercentage) From 596a01661cfed0e2dc275c105754fb6c4304adb1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 13:42:22 +0900 Subject: [PATCH 056/240] Remove 1ms offset and update tests --- ...tSceneHitObjectComposerDistanceSnapping.cs | 30 ++++++++++--------- osu.Game/Screens/Edit/EditorBeatmap.cs | 2 +- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs index e825df5a3f..5a4e76d586 100644 --- a/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs +++ b/osu.Game.Tests/Editor/TestSceneHitObjectComposerDistanceSnapping.cs @@ -118,17 +118,19 @@ namespace osu.Game.Tests.Editor [Test] public void TestGetSnappedDurationFromDistance() { - assertSnappedDuration(50, 0); + assertSnappedDuration(0, 0); + assertSnappedDuration(50, 1000); assertSnappedDuration(100, 1000); - assertSnappedDuration(150, 1000); + assertSnappedDuration(150, 2000); assertSnappedDuration(200, 2000); - assertSnappedDuration(250, 2000); + assertSnappedDuration(250, 3000); AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier = 2); + assertSnappedDuration(0, 0); assertSnappedDuration(50, 0); - assertSnappedDuration(100, 0); - assertSnappedDuration(150, 0); + assertSnappedDuration(100, 1000); + assertSnappedDuration(150, 1000); assertSnappedDuration(200, 1000); assertSnappedDuration(250, 1000); @@ -139,8 +141,8 @@ namespace osu.Game.Tests.Editor }); assertSnappedDuration(50, 0); - assertSnappedDuration(100, 0); - assertSnappedDuration(150, 0); + assertSnappedDuration(100, 500); + assertSnappedDuration(150, 500); assertSnappedDuration(200, 500); assertSnappedDuration(250, 500); assertSnappedDuration(400, 1000); @@ -149,17 +151,17 @@ namespace osu.Game.Tests.Editor [Test] public void GetSnappedDistanceFromDistance() { - assertSnappedDistance(50, 0); + assertSnappedDistance(50, 100); assertSnappedDistance(100, 100); - assertSnappedDistance(150, 100); + assertSnappedDistance(150, 200); assertSnappedDistance(200, 200); - assertSnappedDistance(250, 200); + assertSnappedDistance(250, 300); AddStep("set slider multiplier = 2", () => composer.EditorBeatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier = 2); assertSnappedDistance(50, 0); - assertSnappedDistance(100, 0); - assertSnappedDistance(150, 0); + assertSnappedDistance(100, 200); + assertSnappedDistance(150, 200); assertSnappedDistance(200, 200); assertSnappedDistance(250, 200); @@ -170,8 +172,8 @@ namespace osu.Game.Tests.Editor }); assertSnappedDistance(50, 0); - assertSnappedDistance(100, 0); - assertSnappedDistance(150, 0); + assertSnappedDistance(100, 200); + assertSnappedDistance(150, 200); assertSnappedDistance(200, 200); assertSnappedDistance(250, 200); assertSnappedDistance(400, 400); diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 2d3ecf583e..385afc2392 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -135,7 +135,7 @@ namespace osu.Game.Screens.Edit var beatLength = timingPoint.BeatLength / BeatDivisor; // A 1ms offset prevents rounding errors due to minute variations in duration - return timingPoint.Time + (int)Math.Round(((time - timingPoint.Time) + 1) / beatLength) * beatLength; + return timingPoint.Time + (int)Math.Round((time - timingPoint.Time) / beatLength, MidpointRounding.AwayFromZero) * beatLength; } public double GetBeatLengthAtTime(double referenceTime) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor; From e81d3c51edb0f4ca502409593d03d34c0b523a1a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 15:00:45 +0900 Subject: [PATCH 057/240] Move select tool to an actual tool implementation Also tidies up radio button action firing so calling Select actually fires the associated action in all cases. --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 14 ++++---- .../Edit/Tools/HitObjectCompositionTool.cs | 2 ++ osu.Game/Rulesets/Edit/Tools/SelectTool.cs | 15 +++++++++ .../RadioButtons/DrawableRadioButton.cs | 18 ++--------- .../Components/RadioButtons/RadioButton.cs | 32 +++++++++++-------- 5 files changed, 44 insertions(+), 37 deletions(-) create mode 100644 osu.Game/Rulesets/Edit/Tools/SelectTool.cs diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 9ee3bacf9b..c413d25f09 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -137,12 +137,12 @@ namespace osu.Game.Rulesets.Edit } }; - toolboxCollection.Items = - CompositionTools.Select(t => new RadioButton(t.Name, () => selectTool(t))) - .Prepend(new RadioButton("Select", () => selectTool(null))) - .ToList(); + toolboxCollection.Items = CompositionTools + .Prepend(new SelectTool()) + .Select(t => new RadioButton(t.Name, () => toolSelected(t))) + .ToList(); - toolboxCollection.Items[0].Select(); + toolboxCollection.Items.First().Select(); blueprintContainer.SelectionChanged += selectionChanged; } @@ -187,11 +187,11 @@ namespace osu.Game.Rulesets.Edit showGridFor(hitObjects); } - private void selectTool(HitObjectCompositionTool tool) + private void toolSelected(HitObjectCompositionTool tool) { blueprintContainer.CurrentTool = tool; - if (tool == null) + if (tool is SelectTool) distanceSnapGridContainer.Hide(); else showGridFor(Enumerable.Empty()); diff --git a/osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs b/osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs index 825c63e6ee..0631031302 100644 --- a/osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs +++ b/osu.Game/Rulesets/Edit/Tools/HitObjectCompositionTool.cs @@ -13,5 +13,7 @@ namespace osu.Game.Rulesets.Edit.Tools } public abstract PlacementBlueprint CreatePlacementBlueprint(); + + public override string ToString() => Name; } } diff --git a/osu.Game/Rulesets/Edit/Tools/SelectTool.cs b/osu.Game/Rulesets/Edit/Tools/SelectTool.cs new file mode 100644 index 0000000000..b96eeb0790 --- /dev/null +++ b/osu.Game/Rulesets/Edit/Tools/SelectTool.cs @@ -0,0 +1,15 @@ +// 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.Rulesets.Edit.Tools +{ + public class SelectTool : HitObjectCompositionTool + { + public SelectTool() + : base("Select") + { + } + + public override PlacementBlueprint CreatePlacementBlueprint() => null; + } +} diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs index 5854d66aa8..7be91f4e8e 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/DrawableRadioButton.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -37,8 +36,8 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons { this.button = button; - Text = button.Text; - Action = button.Action; + Text = button.Item.ToString(); + Action = button.Select; RelativeSizeAxes = Axes.X; @@ -100,19 +99,6 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons bubble.Colour = button.Selected.Value ? selectedBubbleColour : defaultBubbleColour; } - protected override bool OnClick(ClickEvent e) - { - if (button.Selected.Value) - return true; - - if (!Enabled.Value) - return true; - - button.Selected.Value = true; - - return base.OnClick(e); - } - protected override SpriteText CreateText() => new OsuSpriteText { Depth = -1, diff --git a/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs b/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs index 3692c0437b..b515d7c8bd 100644 --- a/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs +++ b/osu.Game/Screens/Edit/Components/RadioButtons/RadioButton.cs @@ -15,33 +15,37 @@ namespace osu.Game.Screens.Edit.Components.RadioButtons public readonly BindableBool Selected; /// - /// The text that should be displayed in this button. + /// The item related to this button. /// - public string Text; + public object Item; - /// - /// The that should be invoked when this button is selected. - /// - public Action Action; + private readonly Action action; - public RadioButton(string text, Action action) + public RadioButton(object item, Action action) { - Text = text; - Action = action; + Item = item; + this.action = action; Selected = new BindableBool(); } - public RadioButton(string text) - : this(text, null) + public RadioButton(string item) + : this(item, null) { - Text = text; - Action = null; + Item = item; + action = null; } /// /// Selects this . /// - public void Select() => Selected.Value = true; + public void Select() + { + if (!Selected.Value) + { + Selected.Value = true; + action?.Invoke(); + } + } /// /// Deselects this . From 7e0c45de6dfb736d749f3606b8c33eded764c432 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 15:08:02 +0900 Subject: [PATCH 058/240] Allow selecting composition tools using 1-4 keys --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index c413d25f09..82e0905bd8 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -9,6 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; 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; @@ -25,6 +26,7 @@ using osu.Game.Screens.Edit.Components.RadioButtons; using osu.Game.Screens.Edit.Compose; using osu.Game.Screens.Edit.Compose.Components; using osuTK; +using Key = osuTK.Input.Key; namespace osu.Game.Rulesets.Edit { @@ -58,6 +60,8 @@ namespace osu.Game.Rulesets.Edit private InputManager inputManager; + private RadioButtonCollection toolboxCollection; + protected HitObjectComposer(Ruleset ruleset) { Ruleset = ruleset; @@ -100,7 +104,6 @@ namespace osu.Game.Rulesets.Edit layerContainers.Add(layerBelowRuleset); layerContainers.Add(layerAboveRuleset); - RadioButtonCollection toolboxCollection; InternalChild = new GridContainer { RelativeSizeAxes = Axes.Both, @@ -147,6 +150,22 @@ namespace osu.Game.Rulesets.Edit blueprintContainer.SelectionChanged += selectionChanged; } + protected override bool OnKeyDown(KeyDownEvent e) + { + if (e.Key >= Key.Number1 && e.Key <= Key.Number9) + { + var item = toolboxCollection.Items.Skip(e.Key - Key.Number1).FirstOrDefault(); + + if (item != null) + { + item.Select(); + return true; + } + } + + return base.OnKeyDown(e); + } + protected override void LoadComplete() { base.LoadComplete(); From 8e2159e4eba213a624dbb759bd5ff130207590b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 15:07:37 +0900 Subject: [PATCH 059/240] Ensure selection tool correctly matches selection state - When a selection is made (via the timeline) the selection tool should become the select tool. - When the selection tool is changed to anything *but* the select tool, the selection should be cleared. --- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 21 ++++++++++++++----- .../Compose/Components/BlueprintContainer.cs | 8 +++---- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index c413d25f09..1d97567b39 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -58,6 +58,8 @@ namespace osu.Game.Rulesets.Edit private InputManager inputManager; + private RadioButtonCollection toolboxCollection; + protected HitObjectComposer(Ruleset ruleset) { Ruleset = ruleset; @@ -100,7 +102,6 @@ namespace osu.Game.Rulesets.Edit layerContainers.Add(layerBelowRuleset); layerContainers.Add(layerAboveRuleset); - RadioButtonCollection toolboxCollection; InternalChild = new GridContainer { RelativeSizeAxes = Axes.Both, @@ -142,7 +143,7 @@ namespace osu.Game.Rulesets.Edit .Select(t => new RadioButton(t.Name, () => toolSelected(t))) .ToList(); - toolboxCollection.Items.First().Select(); + setSelectTool(); blueprintContainer.SelectionChanged += selectionChanged; } @@ -181,12 +182,19 @@ namespace osu.Game.Rulesets.Edit { var hitObjects = selectedHitObjects.ToArray(); - if (!hitObjects.Any()) - distanceSnapGridContainer.Hide(); - else + if (hitObjects.Any()) + { + // ensure in selection mode if a selection is made. + setSelectTool(); + showGridFor(hitObjects); + } + else + distanceSnapGridContainer.Hide(); } + private void setSelectTool() => toolboxCollection.Items.First().Select(); + private void toolSelected(HitObjectCompositionTool tool) { blueprintContainer.CurrentTool = tool; @@ -194,7 +202,10 @@ namespace osu.Game.Rulesets.Edit if (tool is SelectTool) distanceSnapGridContainer.Hide(); else + { + EditorBeatmap.SelectedHitObjects.Clear(); showGridFor(Enumerable.Empty()); + } } private void showGridFor(IEnumerable selectedHitObjects) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index 6b21f56567..675b2b648d 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -74,12 +74,16 @@ namespace osu.Game.Screens.Edit.Compose.Components { foreach (var o in objects) selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Select(); + + SelectionChanged?.Invoke(selectedHitObjects); }; selectedHitObjects.ItemsRemoved += objects => { foreach (var o in objects) selectionBlueprints.FirstOrDefault(b => b.HitObject == o)?.Deselect(); + + SelectionChanged?.Invoke(selectedHitObjects); }; } @@ -332,8 +336,6 @@ namespace osu.Game.Screens.Edit.Compose.Components selectionHandler.HandleSelected(blueprint); selectionBlueprints.ChangeChildDepth(blueprint, 1); beatmap.SelectedHitObjects.Add(blueprint.HitObject); - - SelectionChanged?.Invoke(selectionHandler.SelectedHitObjects); } private void onBlueprintDeselected(SelectionBlueprint blueprint) @@ -341,8 +343,6 @@ namespace osu.Game.Screens.Edit.Compose.Components selectionHandler.HandleDeselected(blueprint); selectionBlueprints.ChangeChildDepth(blueprint, 0); beatmap.SelectedHitObjects.Remove(blueprint.HitObject); - - SelectionChanged?.Invoke(selectionHandler.SelectedHitObjects); } #endregion From a6cac072ee7f4376238094fcee94ef926162dab6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 15:17:50 +0900 Subject: [PATCH 060/240] Change default method style for better IDE autocompletion --- .editorconfig | 2 +- osu.sln.DotSettings | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.editorconfig b/.editorconfig index 8cdb92d11c..67f98f94eb 100644 --- a/.editorconfig +++ b/.editorconfig @@ -135,7 +135,7 @@ csharp_preferred_modifier_order = public,private,protected,internal,new,abstract csharp_style_expression_bodied_accessors = true:warning csharp_style_expression_bodied_constructors = false:none csharp_style_expression_bodied_indexers = true:warning -csharp_style_expression_bodied_methods = true:silent +csharp_style_expression_bodied_methods = false:silent csharp_style_expression_bodied_operators = true:warning csharp_style_expression_bodied_properties = true:warning csharp_style_expression_bodied_local_functions = true:silent diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 6d131bf423..e3b64c03b9 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -1,4 +1,4 @@ - + True True True @@ -245,7 +245,7 @@ RequiredForMultiline Explicit ExpressionBody - ExpressionBody + BlockBody True NEXT_LINE True From 40379a5e225eb8b2b8f13a1214858e5dedf059e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 16:04:13 +0900 Subject: [PATCH 061/240] Use foreach --- osu.Game/Screens/Edit/BindableBeatDivisor.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/BindableBeatDivisor.cs b/osu.Game/Screens/Edit/BindableBeatDivisor.cs index be1e121a99..d9477dd4bc 100644 --- a/osu.Game/Screens/Edit/BindableBeatDivisor.cs +++ b/osu.Game/Screens/Edit/BindableBeatDivisor.cs @@ -91,10 +91,8 @@ namespace osu.Game.Screens.Edit { int beat = index % beatDivisor; - for (int i = 0; i < BindableBeatDivisor.VALID_DIVISORS.Length; i++) + foreach (var divisor in BindableBeatDivisor.VALID_DIVISORS) { - int divisor = BindableBeatDivisor.VALID_DIVISORS[i]; - if ((beat * divisor) % beatDivisor == 0) return divisor; } From 12ff51f686cfd884200dabed1f2ef87dc7f08d91 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 17:21:24 +0900 Subject: [PATCH 062/240] Fix key count being incorrectly adjusted by hard/easy mods --- .../Screens/Select/Details/AdvancedStats.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index b7f60a8370..56c400e869 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -117,9 +117,20 @@ namespace osu.Game.Screens.Select.Details mod.ApplyToDifficulty(adjustedDifficulty); } - // Account for mania differences - firstValue.Title = (Beatmap?.Ruleset?.ID ?? 0) == 3 ? "Key Amount" : "Circle Size"; - firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); + switch (Beatmap?.Ruleset?.ID ?? 0) + { + 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); + break; + + default: + firstValue.Title = "Circle Size"; + firstValue.Value = (baseDifficulty?.CircleSize ?? 0, adjustedDifficulty?.CircleSize); + break; + } starDifficulty.Value = ((float)(Beatmap?.StarDifficulty ?? 0), null); From 894642d5883d75dcd9c1b294c6edde806994a06c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 28 Jan 2020 18:04:00 +0800 Subject: [PATCH 063/240] add xmldoc and formatting --- .../Graphics/UserInterface/OsuSliderBar.cs | 4 +++ .../Settings/Sections/Audio/VolumeSettings.cs | 32 ++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index d908f046bd..2db1c881c0 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -35,6 +35,10 @@ namespace osu.Game.Graphics.UserInterface private readonly Container nubContainer; public virtual string TooltipText { get; private set; } + + /// + /// Whether to format the tooltip as a percentage or the actual value. + /// public bool DisplayAsPercentage { get; set; } private Color4 accentColour; diff --git a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs index fe7f4c4908..bda677ecd6 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/VolumeSettings.cs @@ -17,10 +17,34 @@ namespace osu.Game.Overlays.Settings.Sections.Audio { Children = new Drawable[] { - new SettingsSlider { LabelText = "Master", Bindable = audio.Volume, KeyboardStep = 0.01f, DisplayAsPercentage = true }, - new SettingsSlider { LabelText = "Master (window inactive)", Bindable = config.GetBindable(OsuSetting.VolumeInactive), KeyboardStep = 0.01f, DisplayAsPercentage = true }, - new SettingsSlider { LabelText = "Effect", Bindable = audio.VolumeSample, KeyboardStep = 0.01f, DisplayAsPercentage = true }, - new SettingsSlider { LabelText = "Music", Bindable = audio.VolumeTrack, KeyboardStep = 0.01f, DisplayAsPercentage = true }, + new SettingsSlider + { + LabelText = "Master", + Bindable = audio.Volume, + KeyboardStep = 0.01f, + DisplayAsPercentage = true + }, + new SettingsSlider + { + LabelText = "Master (window inactive)", + Bindable = config.GetBindable(OsuSetting.VolumeInactive), + KeyboardStep = 0.01f, + DisplayAsPercentage = true + }, + new SettingsSlider + { + LabelText = "Effect", + Bindable = audio.VolumeSample, + KeyboardStep = 0.01f, + DisplayAsPercentage = true + }, + new SettingsSlider + { + LabelText = "Music", + Bindable = audio.VolumeTrack, + KeyboardStep = 0.01f, + DisplayAsPercentage = true + }, }; } } From 0e0c730095e11e4320c50d4934d0ad60df6f5af8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 19:44:32 +0900 Subject: [PATCH 064/240] Add a method to recycle test storage between runs --- .../Visual/Menus/TestSceneScreenNavigation.cs | 2 ++ osu.Game/Tests/Visual/OsuTestScene.cs | 33 +++++++++++-------- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs index 471f67b7b6..f3c5d2a7ef 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs @@ -65,6 +65,8 @@ namespace osu.Game.Tests.Visual.Menus game.Dispose(); } + RecycleLocalStorage(); + game = new TestOsuGame(LocalStorage, API); game.SetHost(host); diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 8926c76018..41ab7fce99 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -36,7 +36,7 @@ namespace osu.Game.Tests.Visual protected new OsuScreenDependencies Dependencies { get; private set; } - private readonly Lazy localStorage; + private Lazy localStorage; protected Storage LocalStorage => localStorage.Value; private readonly Lazy contextFactory; @@ -91,7 +91,7 @@ namespace osu.Game.Tests.Visual protected OsuTestScene() { - localStorage = new Lazy(() => new NativeStorage($"{GetType().Name}-{Guid.NewGuid()}")); + RecycleLocalStorage(); contextFactory = new Lazy(() => { var factory = new DatabaseContextFactory(LocalStorage); @@ -104,6 +104,23 @@ namespace osu.Game.Tests.Visual base.Content.Add(content = new DrawSizePreservingFillContainer()); } + public void RecycleLocalStorage() + { + if (localStorage?.IsValueCreated == true) + { + try + { + localStorage.Value.DeleteDirectory("."); + } + catch + { + // we don't really care if this fails; it will just leave folders lying around from test runs. + } + } + + localStorage = new Lazy(() => new NativeStorage($"{GetType().Name}-{Guid.NewGuid()}")); + } + [Resolved] protected AudioManager Audio { get; private set; } @@ -131,17 +148,7 @@ namespace osu.Game.Tests.Visual if (contextFactory.IsValueCreated) contextFactory.Value.ResetDatabase(); - if (localStorage.IsValueCreated) - { - try - { - localStorage.Value.DeleteDirectory("."); - } - catch - { - // we don't really care if this fails; it will just leave folders lying around from test runs. - } - } + RecycleLocalStorage(); } protected override ITestSceneTestRunner CreateRunner() => new OsuTestSceneTestRunner(); From 2498709d0626c388c0a1d4801db7c743585a6618 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 28 Jan 2020 19:46:57 +0900 Subject: [PATCH 065/240] Fix navigation test crashing when raw input is disabled --- osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs index 471f67b7b6..0908e527a6 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Bindables; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -65,10 +66,14 @@ namespace osu.Game.Tests.Visual.Menus game.Dispose(); } + // see MouseSettings + var frameworkConfig = host.Dependencies.Get(); + frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity).Disabled = false; + game = new TestOsuGame(LocalStorage, API); game.SetHost(host); - // todo: this can be removed once we can run audio trakcs without a device present + // todo: this can be removed once we can run audio tracks without a device present // see https://github.com/ppy/osu/issues/1302 game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles); From b947e89a6b11946110ec66709657fc70bfbe73ec Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 28 Jan 2020 16:53:22 +0300 Subject: [PATCH 066/240] 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 067/240] 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 e7964023aed0a6d8eeebd6762de8e6e6aff04ad1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:22:08 +0300 Subject: [PATCH 068/240] 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 069/240] 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 cfc4eaff59c72c41e41f2b16485429b581dfa134 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 12:50:21 +0900 Subject: [PATCH 070/240] Fix display being incorrect when MaxValue is not 1 --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 2db1c881c0..5c6c7aeafd 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -174,12 +174,10 @@ namespace osu.Game.Graphics.UserInterface else { double floatValue = value.ToDouble(NumberFormatInfo.InvariantInfo); - double floatMaxValue = CurrentNumber.MaxValue.ToDouble(NumberFormatInfo.InvariantInfo); if (DisplayAsPercentage) { - double percentage = floatValue / floatMaxValue; - TooltipText = percentage.ToString("P0"); + TooltipText = floatValue.ToString("P0"); } else { From aa597c193468b5b2f4c798412b41f003ad5e1e2d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 12:55:07 +0900 Subject: [PATCH 071/240] Copy documentation across to SettingsSlider --- osu.Game/Overlays/Settings/SettingsSlider.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Overlays/Settings/SettingsSlider.cs b/osu.Game/Overlays/Settings/SettingsSlider.cs index a7485f77cd..9fc3379b94 100644 --- a/osu.Game/Overlays/Settings/SettingsSlider.cs +++ b/osu.Game/Overlays/Settings/SettingsSlider.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Graphics; +using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Settings @@ -22,18 +23,28 @@ namespace osu.Game.Overlays.Settings RelativeSizeAxes = Axes.X }; + /// + /// When set, value changes based on user input are only transferred to any bound control's Current on commit. + /// This is useful if the UI interaction could be adversely affected by the value changing, such as the position of the on the screen. + /// public bool TransferValueOnCommit { get => ((TSlider)Control).TransferValueOnCommit; set => ((TSlider)Control).TransferValueOnCommit = value; } + /// + /// A custom step value for each key press which actuates a change on this control. + /// public float KeyboardStep { get => ((TSlider)Control).KeyboardStep; set => ((TSlider)Control).KeyboardStep = value; } + /// + /// Whether to format the tooltip as a percentage or the actual value. + /// public bool DisplayAsPercentage { get => ((TSlider)Control).DisplayAsPercentage; From 5fcda013469f133efb573496fd0a398c65621785 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 06:58:53 +0300 Subject: [PATCH 072/240] 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 f457ecaf83968ce794e42bb6f8198c842b738aac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 29 Jan 2020 13:54:12 +0900 Subject: [PATCH 073/240] Fix random test failures --- osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 98b8e3c5d6..fc06780431 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -118,6 +118,7 @@ namespace osu.Game.Tests.Visual.SongSelect InputManager.ReleaseKey(Key.Enter); }); + AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen()); AddAssert("ensure selection changed", () => selected != Beatmap.Value); AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen()); @@ -145,6 +146,7 @@ namespace osu.Game.Tests.Visual.SongSelect InputManager.ReleaseKey(Key.Down); }); + 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()); @@ -176,6 +178,7 @@ namespace osu.Game.Tests.Visual.SongSelect InputManager.ReleaseKey(Key.Enter); }); + AddUntilStep("wait for not current", () => !songSelect.IsCurrentScreen()); AddAssert("ensure selection changed", () => selected != Beatmap.Value); AddUntilStep("wait for return to song select", () => songSelect.IsCurrentScreen()); @@ -208,6 +211,7 @@ namespace osu.Game.Tests.Visual.SongSelect InputManager.ReleaseButton(MouseButton.Left); }); + 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()); From 9a47428bfd9fa68fd1ba9924d579f28260bec861 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 29 Jan 2020 14:40:42 +0900 Subject: [PATCH 074/240] Remove out of date comment --- osu.Game/Screens/Edit/EditorBeatmap.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 385afc2392..6edd62fa67 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -131,10 +131,8 @@ namespace osu.Game.Screens.Edit public double SnapTime(double time, double? referenceTime) { var timingPoint = ControlPointInfo.TimingPointAt(referenceTime ?? time); - var beatLength = timingPoint.BeatLength / BeatDivisor; - // A 1ms offset prevents rounding errors due to minute variations in duration return timingPoint.Time + (int)Math.Round((time - timingPoint.Time) / beatLength, MidpointRounding.AwayFromZero) * beatLength; } From 391681b7afaf17d14178d975c4292689fa37d4f9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 29 Jan 2020 15:16:48 +0900 Subject: [PATCH 075/240] Separate calculation to follow other examples --- osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs index bce8878766..479de64eab 100644 --- a/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs +++ b/osu.Game/Screens/Edit/Compose/Components/DistanceSnapGrid.cs @@ -132,7 +132,9 @@ namespace osu.Game.Screens.Edit.Compose.Components protected ColourInfo GetColourForIndexFromPlacement(int placementIndex) { var timingPoint = beatmap.ControlPointInfo.TimingPointAt(StartTime); - var beatIndex = (int)Math.Round((StartTime - timingPoint.Time) / timingPoint.BeatLength * beatDivisor.Value); + var beatLength = timingPoint.BeatLength / beatDivisor.Value; + var beatIndex = (int)Math.Round((StartTime - timingPoint.Time) / beatLength); + var colour = BindableBeatDivisor.GetColourFor(BindableBeatDivisor.GetDivisorForBeatIndex(beatIndex + placementIndex + 1, beatDivisor.Value), Colours); int repeatIndex = placementIndex / beatDivisor.Value; From 17294b1b09719724a8694b38aa374b15ebbc6501 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 29 Jan 2020 15:34:36 +0900 Subject: [PATCH 076/240] Make wind down max value 200% --- osu.Game/Rulesets/Mods/ModWindDown.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModWindDown.cs b/osu.Game/Rulesets/Mods/ModWindDown.cs index 939766fee5..5e634ac434 100644 --- a/osu.Game/Rulesets/Mods/ModWindDown.cs +++ b/osu.Game/Rulesets/Mods/ModWindDown.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mods public override BindableNumber InitialRate { get; } = new BindableDouble { MinValue = 1, - MaxValue = 1.5, + MaxValue = 2, Default = 1, Value = 1, Precision = 0.01, From 6e8bd35373701f7758e302010b5d994655e1afdd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 14:23:23 +0900 Subject: [PATCH 077/240] Move navigation / game test scenes to new namespace --- .../Visual/Navigation/OsuGameTestScene.cs | 122 ++++++++++++++++ .../TestSceneScreenNavigation.cs | 132 +++--------------- 2 files changed, 139 insertions(+), 115 deletions(-) create mode 100644 osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs rename osu.Game.Tests/Visual/{Menus => Navigation}/TestSceneScreenNavigation.cs (54%) diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs new file mode 100644 index 0000000000..662d9977ba --- /dev/null +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -0,0 +1,122 @@ +// 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.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Platform; +using osu.Framework.Screens; +using osu.Framework.Testing; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online.API; +using osu.Game.Overlays; +using osu.Game.Rulesets; +using osu.Game.Screens; +using osu.Game.Screens.Menu; +using osuTK.Graphics; +using IntroSequence = osu.Game.Configuration.IntroSequence; + +namespace osu.Game.Tests.Visual.Navigation +{ + /// + /// A scene which tests full game flow. + /// + public abstract class OsuGameTestScene : ManualInputManagerTestScene + { + private GameHost host; + + protected TestOsuGame Game; + + [BackgroundDependencyLoader] + private void load(GameHost host) + { + this.host = host; + + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + }; + } + + [SetUpSteps] + public void SetUpSteps() + { + AddStep("Create new game instance", () => + { + if (Game != null) + { + Remove(Game); + Game.Dispose(); + } + + RecycleLocalStorage(); + + // see MouseSettings + var frameworkConfig = host.Dependencies.Get(); + frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity).Disabled = false; + + Game = new TestOsuGame(LocalStorage, API); + Game.SetHost(host); + + // todo: this can be removed once we can run audio tracks without a device present + // see https://github.com/ppy/osu/issues/1302 + Game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles); + + Add(Game); + }); + + AddUntilStep("Wait for load", () => Game.IsLoaded); + AddUntilStep("Wait for intro", () => Game.ScreenStack.CurrentScreen is IntroScreen); + + ConfirmAtMainMenu(); + } + + protected void ConfirmAtMainMenu() => AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded); + + public class TestOsuGame : OsuGame + { + public new ScreenStack ScreenStack => base.ScreenStack; + + public new BackButton BackButton => base.BackButton; + + public new BeatmapManager BeatmapManager => base.BeatmapManager; + + public new SettingsPanel Settings => base.Settings; + + public new OsuConfigManager LocalConfig => base.LocalConfig; + + public new Bindable Beatmap => base.Beatmap; + + public new Bindable Ruleset => base.Ruleset; + + protected override Loader CreateLoader() => new TestLoader(); + + public TestOsuGame(Storage storage, IAPIProvider api) + { + Storage = storage; + API = api; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + API.Login("Rhythm Champion", "osu!"); + } + } + + public class TestLoader : Loader + { + protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(); + + private class TestShaderPrecompiler : ShaderPrecompiler + { + protected override bool AllLoaded => true; + } + } + } +} diff --git a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs similarity index 54% rename from osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs rename to osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index c4307a3ad3..d706d47384 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -6,85 +6,26 @@ using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Track; -using osu.Framework.Bindables; -using osu.Framework.Configuration; -using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Platform; using osu.Framework.Screens; -using osu.Framework.Testing; using osu.Game.Beatmaps; -using osu.Game.Configuration; -using osu.Game.Graphics.UserInterface; -using osu.Game.Online.API; using osu.Game.Overlays; using osu.Game.Overlays.Mods; -using osu.Game.Screens; -using osu.Game.Screens.Menu; using osu.Game.Screens.Play; using osu.Game.Screens.Select; using osu.Game.Tests.Beatmaps.IO; using osuTK; -using osuTK.Graphics; using osuTK.Input; -using IntroSequence = osu.Game.Configuration.IntroSequence; -namespace osu.Game.Tests.Visual.Menus +namespace osu.Game.Tests.Visual.Navigation { - public class TestSceneScreenNavigation : ManualInputManagerTestScene + public class TestSceneScreenNavigation : OsuGameTestScene { private const float click_padding = 25; - private GameHost host; - private TestOsuGame game; + private Vector2 backButtonPosition => Game.ToScreenSpace(new Vector2(click_padding, Game.LayoutRectangle.Bottom - click_padding)); - private Vector2 backButtonPosition => game.ToScreenSpace(new Vector2(click_padding, game.LayoutRectangle.Bottom - click_padding)); - - private Vector2 optionsButtonPosition => game.ToScreenSpace(new Vector2(click_padding, click_padding)); - - [BackgroundDependencyLoader] - private void load(GameHost host) - { - this.host = host; - - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - }; - } - - [SetUpSteps] - public void SetUpSteps() - { - AddStep("Create new game instance", () => - { - if (game != null) - { - Remove(game); - game.Dispose(); - } - - RecycleLocalStorage(); - - // see MouseSettings - var frameworkConfig = host.Dependencies.Get(); - frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity).Disabled = false; - - game = new TestOsuGame(LocalStorage, API); - game.SetHost(host); - - // todo: this can be removed once we can run audio tracks without a device present - // see https://github.com/ppy/osu/issues/1302 - game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles); - - Add(game); - }); - AddUntilStep("Wait for load", () => game.IsLoaded); - AddUntilStep("Wait for intro", () => game.ScreenStack.CurrentScreen is IntroScreen); - confirmAtMainMenu(); - } + private Vector2 optionsButtonPosition => Game.ToScreenSpace(new Vector2(click_padding, click_padding)); [Test] public void TestExitSongSelectWithEscape() @@ -105,21 +46,21 @@ namespace osu.Game.Tests.Visual.Menus { Player player = null; - WorkingBeatmap beatmap() => game.Beatmap.Value; + WorkingBeatmap beatmap() => Game.Beatmap.Value; Track track() => beatmap().Track; pushAndConfirm(() => new TestSongSelect()); - AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(game, virtualTrack: true).Wait()); + AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait()); - AddUntilStep("wait for selected", () => !game.Beatmap.IsDefault); + AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault); if (withUserPause) - AddStep("pause", () => game.Dependencies.Get().Stop()); + AddStep("pause", () => Game.Dependencies.Get().Stop()); AddStep("press enter", () => pressAndRelease(Key.Enter)); - AddUntilStep("wait for player", () => (player = game.ScreenStack.CurrentScreen as Player) != null); + AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null); AddUntilStep("wait for fail", () => player.HasFailed); AddUntilStep("wait for track stop", () => !track().IsRunning); @@ -142,7 +83,7 @@ namespace osu.Game.Tests.Visual.Menus AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition)); // BackButton handles hover using its child button, so this checks whether or not any of BackButton's children are hovered. - AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == game.BackButton)); + AddUntilStep("Back button is hovered", () => InputManager.HoveredDrawables.Any(d => d.Parent == Game.BackButton)); AddStep("Click back button", () => InputManager.Click(MouseButton.Left)); AddUntilStep("Overlay was hidden", () => songSelect.ModSelectOverlay.State.Value == Visibility.Hidden); @@ -166,20 +107,20 @@ namespace osu.Game.Tests.Visual.Menus [Test] public void TestOpenOptionsAndExitWithEscape() { - AddUntilStep("Wait for options to load", () => game.Settings.IsLoaded); + AddUntilStep("Wait for options to load", () => Game.Settings.IsLoaded); AddStep("Enter menu", () => pressAndRelease(Key.Enter)); AddStep("Move mouse to options overlay", () => InputManager.MoveMouseTo(optionsButtonPosition)); AddStep("Click options overlay", () => InputManager.Click(MouseButton.Left)); - AddAssert("Options overlay was opened", () => game.Settings.State.Value == Visibility.Visible); + AddAssert("Options overlay was opened", () => Game.Settings.State.Value == Visibility.Visible); AddStep("Hide options overlay using escape", () => pressAndRelease(Key.Escape)); - AddAssert("Options overlay was closed", () => game.Settings.State.Value == Visibility.Hidden); + 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); + AddStep("Push new screen", () => Game.ScreenStack.Push(screen = newScreen())); + AddUntilStep("Wait for new screen", () => Game.ScreenStack.CurrentScreen == screen && screen.IsLoaded); } private void pushEscape() => @@ -188,64 +129,25 @@ namespace osu.Game.Tests.Visual.Menus private void exitViaEscapeAndConfirm() { pushEscape(); - confirmAtMainMenu(); + ConfirmAtMainMenu(); } private void exitViaBackButtonAndConfirm() { AddStep("Move mouse to backButton", () => InputManager.MoveMouseTo(backButtonPosition)); AddStep("Click back button", () => InputManager.Click(MouseButton.Left)); - confirmAtMainMenu(); + ConfirmAtMainMenu(); } - private void confirmAtMainMenu() => AddUntilStep("Wait for main menu", () => game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded); - private void pressAndRelease(Key key) { InputManager.PressKey(key); InputManager.ReleaseKey(key); } - private class TestOsuGame : OsuGame - { - public new ScreenStack ScreenStack => base.ScreenStack; - - public new BackButton BackButton => base.BackButton; - - public new SettingsPanel Settings => base.Settings; - - public new OsuConfigManager LocalConfig => base.LocalConfig; - - public new Bindable Beatmap => base.Beatmap; - - protected override Loader CreateLoader() => new TestLoader(); - - public TestOsuGame(Storage storage, IAPIProvider api) - { - Storage = storage; - API = api; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - API.Login("Rhythm Champion", "osu!"); - } - } - private class TestSongSelect : PlaySongSelect { public ModSelectOverlay ModSelectOverlay => ModSelect; } - - private class TestLoader : Loader - { - protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(); - - private class TestShaderPrecompiler : ShaderPrecompiler - { - protected override bool AllLoaded => true; - } - } } } From 1db353558bf0b4f09a58e0079be1e0ee5a6839f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 14:23:31 +0900 Subject: [PATCH 078/240] Add present beatmap tests --- .../Navigation/TestScenePresentBeatmap.cs | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs new file mode 100644 index 0000000000..909409835c --- /dev/null +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -0,0 +1,110 @@ +// 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.Screens; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Mania; +using osu.Game.Rulesets.Osu; +using osu.Game.Screens.Menu; + +namespace osu.Game.Tests.Visual.Navigation +{ + public class TestScenePresentBeatmap : OsuGameTestScene + { + [Test] + public void TestFromMainMenu() + { + var firstImport = importBeatmap(1); + presentAndConfirm(firstImport); + + AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit()); + AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu); + + var secondimport = importBeatmap(2); + presentAndConfirm(secondimport); + } + + [Test] + public void TestFromMainMenuDifferentRuleset() + { + var firstImport = importBeatmap(1); + presentAndConfirm(firstImport); + + AddStep("return to menu", () => Game.ScreenStack.CurrentScreen.Exit()); + AddUntilStep("wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu); + + var secondimport = importBeatmap(2, new ManiaRuleset().RulesetInfo); + presentAndConfirm(secondimport); + } + + [Test] + public void TestFromSongSelect() + { + var firstImport = importBeatmap(1); + presentAndConfirm(firstImport); + + var secondimport = importBeatmap(2); + presentAndConfirm(secondimport); + } + + [Test] + public void TestFromSongSelectDifferentRuleset() + { + var firstImport = importBeatmap(1); + presentAndConfirm(firstImport); + + var secondimport = importBeatmap(2, new ManiaRuleset().RulesetInfo); + presentAndConfirm(secondimport); + } + + private Func importBeatmap(int i, RulesetInfo ruleset = null) + { + BeatmapSetInfo imported = null; + AddStep($"import beatmap {i}", () => + { + var difficulty = new BeatmapDifficulty(); + var metadata = new BeatmapMetadata + { + Artist = "SomeArtist", + AuthorString = "SomeAuthor", + Title = $"import {i}" + }; + + imported = Game.BeatmapManager.Import(new BeatmapSetInfo + { + Hash = Guid.NewGuid().ToString(), + OnlineBeatmapSetID = i, + Metadata = metadata, + Beatmaps = new List + { + new BeatmapInfo + { + OnlineBeatmapID = i * 1024, + Metadata = metadata, + BaseDifficulty = difficulty, + Ruleset = ruleset ?? new OsuRuleset().RulesetInfo + }, + } + }).Result; + }); + + AddAssert($"import {i} succeeded", () => imported != null); + + return () => imported; + } + + private void presentAndConfirm(Func getImport) + { + AddStep("present beatmap", () => Game.PresentBeatmap(getImport())); + + AddUntilStep("wait for song select", () => Game.ScreenStack.CurrentScreen is Screens.Select.SongSelect); + AddUntilStep("correct beatmap displayed", () => Game.Beatmap.Value.BeatmapSetInfo.ID == getImport().ID); + AddAssert("correct ruleset selected", () => Game.Ruleset.Value.ID == getImport().Beatmaps.First().Ruleset.ID); + } + } +} From 77c06b1c6eb7f20d0e6f9ae3fc248ed2680cf3fe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 16:51:14 +0900 Subject: [PATCH 079/240] Fix beatmap carousel potentially missing beatmap imports --- osu.Game/Screens/Select/BeatmapCarousel.cs | 27 +++++++++++++++++++++- osu.Game/Screens/Select/SongSelect.cs | 27 ++++------------------ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 2bb5ba612e..592e26adc2 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -68,6 +68,7 @@ namespace osu.Game.Screens.Select private IEnumerable beatmapSets => root.Children.OfType(); + // todo: only used for testing, maybe remove. public IEnumerable BeatmapSets { get => beatmapSets.Select(g => g.BeatmapSet); @@ -133,8 +134,11 @@ namespace osu.Game.Screens.Select }; } + [Resolved] + private BeatmapManager beatmaps { get; set; } + [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuConfigManager config, BeatmapManager beatmaps) + private void load(OsuConfigManager config) { config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm); config.BindWith(OsuSetting.SongSelectRightMouseScroll, RightClickScrollingEnabled); @@ -142,6 +146,11 @@ namespace osu.Game.Screens.Select RightClickScrollingEnabled.ValueChanged += enabled => scroll.RightMouseScrollbar = enabled.NewValue; RightClickScrollingEnabled.TriggerChange(); + beatmaps.ItemAdded += beatmapAdded; + beatmaps.ItemRemoved += beatmapRemoved; + beatmaps.BeatmapHidden += beatmapHidden; + beatmaps.BeatmapRestored += beatmapRestored; + loadBeatmapSets(beatmaps.GetAllUsableBeatmapSetsEnumerable()); } @@ -535,11 +544,27 @@ namespace osu.Game.Screens.Select { base.Dispose(isDisposing); + if (beatmaps != null) + { + beatmaps.ItemAdded -= beatmapAdded; + beatmaps.ItemRemoved -= beatmapRemoved; + beatmaps.BeatmapHidden -= beatmapHidden; + beatmaps.BeatmapRestored -= beatmapRestored; + } + // aggressively dispose "off-screen" items to reduce GC pressure. foreach (var i in Items) i.Dispose(); } + private void beatmapRemoved(BeatmapSetInfo item) => RemoveBeatmapSet(item); + + private void beatmapAdded(BeatmapSetInfo item) => UpdateBeatmapSet(item); + + private void beatmapRestored(BeatmapInfo b) => UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); + + private void beatmapHidden(BeatmapInfo b) => UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); + private CarouselBeatmapSet createCarouselSet(BeatmapSetInfo beatmapSet) { if (beatmapSet.Beatmaps.All(b => b.Hidden)) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 1a29f336ea..a5352c4eeb 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -72,7 +72,9 @@ namespace osu.Game.Screens.Select private BeatmapInfoWedge beatmapInfoWedge; private DialogOverlay dialogOverlay; - private BeatmapManager beatmaps; + + [Resolved] + private BeatmapManager beatmaps { get; set; } protected ModSelectOverlay ModSelect { get; private set; } @@ -89,7 +91,7 @@ namespace osu.Game.Screens.Select private MusicController music { get; set; } [BackgroundDependencyLoader(true)] - private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, ScoreManager scores) + private void load(AudioManager audio, DialogOverlay dialog, OsuColour colours, SkinManager skins, ScoreManager scores) { // initial value transfer is required for FilterControl (it uses our re-cached bindables in its async load for the initial filter). transferRulesetValue(); @@ -247,14 +249,6 @@ namespace osu.Game.Screens.Select BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.Solid.Trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo), Key.Number3); } - if (this.beatmaps == null) - this.beatmaps = beatmaps; - - this.beatmaps.ItemAdded += onBeatmapSetAdded; - this.beatmaps.ItemRemoved += onBeatmapSetRemoved; - this.beatmaps.BeatmapHidden += onBeatmapHidden; - this.beatmaps.BeatmapRestored += onBeatmapRestored; - dialogOverlay = dialog; sampleChangeDifficulty = audio.Samples.Get(@"SongSelect/select-difficulty"); @@ -563,14 +557,6 @@ namespace osu.Game.Screens.Select base.Dispose(isDisposing); decoupledRuleset.UnbindAll(); - - if (beatmaps != null) - { - beatmaps.ItemAdded -= onBeatmapSetAdded; - beatmaps.ItemRemoved -= onBeatmapSetRemoved; - beatmaps.BeatmapHidden -= onBeatmapHidden; - beatmaps.BeatmapRestored -= onBeatmapRestored; - } } /// @@ -617,11 +603,6 @@ namespace osu.Game.Screens.Select lastTrack.SetTarget(track); } - private void onBeatmapSetAdded(BeatmapSetInfo s) => Carousel.UpdateBeatmapSet(s); - private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s); - private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); - private void onBeatmapHidden(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); - private void carouselBeatmapsLoaded() { bindBindables(); From c003ae63d5afa9fd9d32eacbc884b0692e241151 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 17:17:10 +0900 Subject: [PATCH 080/240] Ignore failing test for now --- osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs index 909409835c..de330004c2 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePresentBeatmap.cs @@ -30,6 +30,7 @@ namespace osu.Game.Tests.Visual.Navigation } [Test] + [Ignore("will be fixed soon")] public void TestFromMainMenuDifferentRuleset() { var firstImport = importBeatmap(1); From d908bc269345c13a7a1f282418faa29fb79204d6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 29 Jan 2020 18:44:30 +0900 Subject: [PATCH 081/240] Remove unnecessary extra spritetext --- .../Ranks/DrawableProfileWeightedScore.cs | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs index bacfc0fd83..1b77e8e4fb 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs @@ -40,28 +40,13 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Width = 60, Child = CreateDrawableAccuracy() }, - new FillFlowContainer + new OsuSpriteText { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new[] - { - new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), - Text = $"{Score.PP * weight:0}", - }, - new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), - Text = "pp", - } - } - } + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), + Text = $"{Score.PP * weight:0}pp", + }, } }, new OsuSpriteText From 7f946047f9ab1b064a27901eea7a171a864c06ee Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 29 Jan 2020 18:51:20 +0900 Subject: [PATCH 082/240] Adjust styling to closer match osu-web --- .../Profile/Sections/Ranks/DrawableProfileScore.cs | 8 ++++---- .../Sections/Ranks/DrawableProfileWeightedScore.cs | 11 +++-------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 9145ce6894..5196bef48d 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -174,8 +174,8 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks protected OsuSpriteText CreateDrawableAccuracy() => new OsuSpriteText { - Text = $"{Score.Accuracy:P2}", - Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), + Text = $"{Score.Accuracy:0.00%}", + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), Colour = colours.Yellow, }; @@ -233,14 +233,14 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks Text = new LocalisedString(( $"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} ", $"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} ")), - Font = OsuFont.GetFont(weight: FontWeight.SemiBold, italics: true) + Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true) }, new OsuSpriteText { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Text = "by " + new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)), - Font = OsuFont.GetFont(size: 14, italics: true) + Font = OsuFont.GetFont(size: 12, italics: true) }, }; } diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs index 1b77e8e4fb..e741c88aeb 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileWeightedScore.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Scoring; -using osuTK; namespace osu.Game.Overlays.Profile.Sections.Ranks { @@ -24,14 +23,12 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks { AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 2), Children = new Drawable[] { new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(15, 0), Children = new Drawable[] { new Container @@ -42,17 +39,15 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks }, new OsuSpriteText { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true), Text = $"{Score.PP * weight:0}pp", }, } }, new OsuSpriteText { - Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), - Text = $@"weighted {weight:P0}" + Font = OsuFont.GetFont(size: 12), + Text = $@"weighted {weight:0%}" } } }; From 7588c574a21e7a0a54a509f4c50013714769f810 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 29 Jan 2020 19:37:54 +0900 Subject: [PATCH 083/240] 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 76af8bea5dd13d940d021ed6328f7d77c99bcf20 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 29 Jan 2020 19:51:24 +0900 Subject: [PATCH 084/240] Fix percentage-formatted displays containing a space --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 2 +- osu.Game/Online/Leaderboards/LeaderboardScore.cs | 2 +- osu.Game/Overlays/BeatmapSet/SuccessRate.cs | 2 +- .../Screens/Multi/Match/Components/MatchLeaderboardScore.cs | 2 +- osu.Game/Screens/Select/LocalScoreDeleteDialog.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 5c6c7aeafd..d0356e77c7 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -177,7 +177,7 @@ namespace osu.Game.Graphics.UserInterface if (DisplayAsPercentage) { - TooltipText = floatValue.ToString("P0"); + TooltipText = floatValue.ToString("0%"); } else { diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index 9c7324d913..c8b2f2327b 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:P0}" : @"{0:P2}", model.Accuracy)) + new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:0%}" : @"{0:0.00%}", model.Accuracy)) }; protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs index 0258a0301a..cd81013c30 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("P0"); + successPercent.Text = rate.ToString("0%"); successRate.Length = rate; percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic); diff --git a/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs b/osu.Game/Screens/Multi/Match/Components/MatchLeaderboardScore.cs index aa92451c77..bab9672d65 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:P0}" : @"{0:P2}", model.Accuracy)), + new LeaderboardScoreStatistic(FontAwesome.Solid.Crosshairs, "Accuracy", string.Format(model.Accuracy % 1 == 0 ? @"{0:0%}" : @"{0:0.00%}", model.Accuracy)), 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/Select/LocalScoreDeleteDialog.cs b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs index 97df40fa6d..99e76124e8 100644 --- a/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs +++ b/osu.Game/Screens/Select/LocalScoreDeleteDialog.cs @@ -32,7 +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:P0}" : "{0:P2}", score.Accuracy); + string accuracy = string.Format(score.Accuracy == 1 ? "{0:0%}" : "{0:0.00%}", score.Accuracy); BodyText = $"{score.User} ({accuracy}, {score.Rank})"; Icon = FontAwesome.Regular.TrashAlt; From 3d6e00095edc737f247b6a93e20b4608d0206b7b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 14:08:10 +0300 Subject: [PATCH 085/240] 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 086/240] 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 087/240] 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 c9dda78ded008337b45b1b4190dce7ea70751613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 29 Jan 2020 18:59:51 +0100 Subject: [PATCH 088/240] Refactor drawable hierarchy to center properly * Use FillFlowContainer.Spacing instead of manually applying margins. * Use Update() for calculating button padding to preserve it after mod button expansion and adjust FooterButtonRandom to use this method while avoiding flickering. * Expose mod display margin to clear it in the footer button. --- osu.Game/Screens/Play/HUD/ModDisplay.cs | 16 +++++++------- osu.Game/Screens/Select/FooterButton.cs | 21 ++++++++++++++++--- osu.Game/Screens/Select/FooterButtonMods.cs | 2 +- osu.Game/Screens/Select/FooterButtonRandom.cs | 5 ++++- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/ModDisplay.cs b/osu.Game/Screens/Play/HUD/ModDisplay.cs index 0f3c92a962..00edd4db99 100644 --- a/osu.Game/Screens/Play/HUD/ModDisplay.cs +++ b/osu.Game/Screens/Play/HUD/ModDisplay.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Play.HUD } } - private readonly FillFlowContainer iconsContainer; + protected readonly FillFlowContainer IconsContainer; private readonly OsuSpriteText unrankedText; public ModDisplay() @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play.HUD Children = new Drawable[] { - iconsContainer = new ReverseChildIDFillFlowContainer + IconsContainer = new ReverseChildIDFillFlowContainer { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -69,11 +69,11 @@ namespace osu.Game.Screens.Play.HUD Current.ValueChanged += mods => { - iconsContainer.Clear(); + IconsContainer.Clear(); foreach (Mod mod in mods.NewValue) { - iconsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.6f) }); + IconsContainer.Add(new ModIcon(mod) { Scale = new Vector2(0.6f) }); } if (IsLoaded) @@ -92,7 +92,7 @@ namespace osu.Game.Screens.Play.HUD base.LoadComplete(); appearTransform(); - iconsContainer.FadeInFromZero(fade_duration, Easing.OutQuint); + IconsContainer.FadeInFromZero(fade_duration, Easing.OutQuint); } private void appearTransform() @@ -104,17 +104,17 @@ namespace osu.Game.Screens.Play.HUD expand(); - using (iconsContainer.BeginDelayedSequence(1200)) + using (IconsContainer.BeginDelayedSequence(1200)) contract(); } private void expand() { if (AllowExpand) - iconsContainer.TransformSpacingTo(new Vector2(5, 0), 500, Easing.OutQuint); + IconsContainer.TransformSpacingTo(new Vector2(5, 0), 500, Easing.OutQuint); } - private void contract() => iconsContainer.TransformSpacingTo(new Vector2(-25, 0), 500, Easing.OutQuint); + private void contract() => IconsContainer.TransformSpacingTo(new Vector2(-25, 0), 500, Easing.OutQuint); protected override bool OnHover(HoverEvent e) { diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index 869e9e8aa4..cebc73d70d 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -92,15 +92,17 @@ namespace osu.Game.Screens.Select Origin = Anchor.CentreLeft, Direction = FillDirection.Horizontal, Shear = -SHEAR, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Horizontal = SHEAR_WIDTH / 4 }, + AutoSizeAxes = Axes.X, + Height = 50, + Margin = new MarginPadding { Right = -SHEAR_WIDTH / 2 }, + Spacing = new Vector2(15, 0), Children = new Drawable[] { TextContainer = new Container { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(100 - SHEAR_WIDTH, 50), + AutoSizeAxes = Axes.Both, Child = SpriteText = new OsuSpriteText { Anchor = Anchor.Centre, @@ -118,6 +120,19 @@ namespace osu.Game.Screens.Select public Action HoverLost; public Key? Hotkey; + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + float horizontalMargin = (100 - TextContainer.Width) / 2; + ButtonContentContainer.Padding = new MarginPadding + { + Left = horizontalMargin, + // right side margin offset to compensate for shear + Right = horizontalMargin - SHEAR_WIDTH / 2 + }; + } + protected override bool OnHover(HoverEvent e) { Hovered?.Invoke(); diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 67b491cf9e..a98f3d6c5e 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -46,7 +46,6 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(weight: FontWeight.Bold), - Margin = new MarginPadding { Right = 10 } }); } @@ -94,6 +93,7 @@ namespace osu.Game.Screens.Select public FooterModDisplay() { AllowExpand = false; + IconsContainer.Margin = new MarginPadding(); } } } diff --git a/osu.Game/Screens/Select/FooterButtonRandom.cs b/osu.Game/Screens/Select/FooterButtonRandom.cs index 14c9eb2035..990b9a52fb 100644 --- a/osu.Game/Screens/Select/FooterButtonRandom.cs +++ b/osu.Game/Screens/Select/FooterButtonRandom.cs @@ -24,8 +24,11 @@ namespace osu.Game.Screens.Select Anchor = Anchor.Centre, Origin = Anchor.Centre, Text = @"rewind", - Alpha = 0 + Alpha = 0, }); + + // force both text sprites to always be present to avoid width flickering while they're being swapped out + SpriteText.AlwaysPresent = secondaryText.AlwaysPresent = true; } [BackgroundDependencyLoader] From 786ed038683f49ebd105b7668da9b95007c4e6d1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 29 Jan 2020 21:01:40 +0300 Subject: [PATCH 089/240] 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 f130e48c9e05ba37d348feac2a541edfff533f14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 29 Jan 2020 19:17:07 +0100 Subject: [PATCH 090/240] Remove leftover negative margin --- osu.Game/Screens/Select/FooterButton.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Select/FooterButton.cs b/osu.Game/Screens/Select/FooterButton.cs index cebc73d70d..3517ab4c3c 100644 --- a/osu.Game/Screens/Select/FooterButton.cs +++ b/osu.Game/Screens/Select/FooterButton.cs @@ -94,7 +94,6 @@ namespace osu.Game.Screens.Select Shear = -SHEAR, AutoSizeAxes = Axes.X, Height = 50, - Margin = new MarginPadding { Right = -SHEAR_WIDTH / 2 }, Spacing = new Vector2(15, 0), Children = new Drawable[] { From 65f71b8c12757a1085d971d77fcd65c2fca23e9c Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 29 Jan 2020 21:23:19 +0100 Subject: [PATCH 091/240] 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 092/240] 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 093/240] 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 094/240] 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 095/240] 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 096/240] 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 097/240] 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 098/240] 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 099/240] 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 100/240] 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 101/240] 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 102/240] 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 103/240] 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 104/240] 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 105/240] 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 37ecf8a060fc37743dfc72b7bf4d7e1ad2a363b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 10:50:48 +0900 Subject: [PATCH 106/240] Remove commented line --- osu.Game/Screens/Select/FooterButtonMods.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index a98f3d6c5e..965be10219 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -3,7 +3,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; -// using osu.Framework.Graphics.Containers; using osu.Game.Screens.Play.HUD; using osu.Game.Rulesets.Mods; using System.Collections.Generic; From f72de235cc9ad05ab9f76cc874fc118aabc5f358 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 11:00:14 +0900 Subject: [PATCH 107/240] Remove unnecessary length specifications --- osu.Game/Screens/Select/FooterButtonMods.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs index 965be10219..4f2369847f 100644 --- a/osu.Game/Screens/Select/FooterButtonMods.cs +++ b/osu.Game/Screens/Select/FooterButtonMods.cs @@ -80,9 +80,9 @@ namespace osu.Game.Screens.Select MultiplierText.FadeColour(Color4.White, 200); if (Current.Value?.Count > 0) - modDisplay.FadeIn(0); + modDisplay.FadeIn(); else - modDisplay.FadeOut(0); + modDisplay.FadeOut(); } private class FooterModDisplay : ModDisplay From ebdb425c508c34894048e40a66c84b8cd1aacea7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 11:17:26 +0900 Subject: [PATCH 108/240] 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 109/240] 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 110/240] 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 111/240] 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 112/240] 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 113/240] 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 114/240] 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 115/240] 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 116/240] 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 117/240] 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 118/240] 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 119/240] 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 120/240] 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 121/240] 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 122/240] 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 123/240] 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 124/240] 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 125/240] 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 126/240] 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 127/240] 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 a7a3372a984bd9ad79c3414a4e75d16d883df2b5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 30 Jan 2020 13:01:40 +0300 Subject: [PATCH 128/240] 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 8e966624e02345c593501f69cabd8c78b34ec384 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 30 Jan 2020 19:55:25 +0900 Subject: [PATCH 129/240] 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 130/240] 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 131/240] 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 132/240] 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 133/240] 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 134/240] 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 135/240] 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 136/240] 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 137/240] 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 138/240] 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 139/240] 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 140/240] 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 141/240] 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 142/240] 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 143/240] 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 144/240] 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 145/240] 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 146/240] 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 147/240] 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 148/240] 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 149/240] 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 150/240] 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 151/240] 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 152/240] 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 153/240] 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 154/240] 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 155/240] 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 156/240] 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 157/240] 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 158/240] 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 159/240] 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 160/240] 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 161/240] 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 162/240] 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 163/240] 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 164/240] 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 165/240] 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 166/240] 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 167/240] 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 168/240] 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 169/240] 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 170/240] 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 171/240] 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 172/240] 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 173/240] 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 174/240] 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 175/240] 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 176/240] 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 177/240] 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 178/240] 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 179/240] 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 180/240] 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 181/240] 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 182/240] 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 183/240] 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 184/240] 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 185/240] 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 186/240] 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 187/240] 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 188/240] 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 189/240] 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 190/240] 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 191/240] 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 192/240] 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 193/240] 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 194/240] 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 195/240] 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 196/240] 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 197/240] 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 198/240] 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 199/240] 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 200/240] 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 201/240] 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 202/240] 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 203/240] 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 204/240] 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 205/240] 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 206/240] 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 207/240] 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 208/240] 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 209/240] 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 210/240] 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 211/240] 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 212/240] 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 213/240] 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 214/240] 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 215/240] 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 216/240] 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 217/240] 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 218/240] 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 219/240] 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 220/240] 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 221/240] 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 222/240] 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 223/240] 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 224/240] 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 225/240] 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 226/240] 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 227/240] 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 228/240] 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 4abd9cb89ae3fc3c5bf13a633a35a622a67656c5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 3 Feb 2020 21:45:10 +0300 Subject: [PATCH 229/240] 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 26a9d60437d706ab993354d4a39630548a3d5c38 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Mon, 3 Feb 2020 23:17:10 +0300 Subject: [PATCH 230/240] 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 231/240] 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 232/240] 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 233/240] 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 234/240] 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 235/240] 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 236/240] 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 237/240] 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 238/240] 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 239/240] 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 240/240] 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}%"; + } +}