From b45f1ef99a6489984534cf86ac219469b6d0265f Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Sun, 9 Feb 2020 22:27:37 +0100 Subject: [PATCH 001/127] make timestamps hoverable --- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index 096e91b65b..485ca100c6 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -50,7 +51,7 @@ namespace osu.Game.Overlays.BeatmapSet fields.Children = new Drawable[] { new Field("mapped by", BeatmapSet.Metadata.Author.Username, OsuFont.GetFont(weight: FontWeight.Regular, italics: true)), - new Field("submitted on", online.Submitted.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold)) + new Field("submitted", online.Submitted, OsuFont.GetFont(weight: FontWeight.Bold)) { Margin = new MarginPadding { Top = 5 }, }, @@ -58,11 +59,11 @@ namespace osu.Game.Overlays.BeatmapSet if (online.Ranked.HasValue) { - fields.Add(new Field("ranked on", online.Ranked.Value.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold))); + fields.Add(new Field("ranked", online.Ranked.Value, OsuFont.GetFont(weight: FontWeight.Bold))); } else if (online.LastUpdated.HasValue) { - fields.Add(new Field("last updated on", online.LastUpdated.Value.ToString(@"MMMM d, yyyy"), OsuFont.GetFont(weight: FontWeight.Bold))); + fields.Add(new Field("last updated", online.LastUpdated.Value, OsuFont.GetFont(weight: FontWeight.Bold))); } } @@ -126,6 +127,25 @@ namespace osu.Game.Overlays.BeatmapSet }, }; } + + public Field(string first, DateTimeOffset second, FontUsage secondFont) + { + AutoSizeAxes = Axes.Both; + Direction = FillDirection.Horizontal; + + Children = new[] + { + new OsuSpriteText + { + Text = $"{first} ", + Font = OsuFont.GetFont(size: 13) + }, + new DrawableDate(second) + { + Font = secondFont.With(size: 13) + } + }; + } } } } From 867c7338093934caf6164ba27029b3e65d006614 Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Sun, 9 Feb 2020 23:19:32 +0100 Subject: [PATCH 002/127] make score date hoverable --- .../BeatmapSet/Scores/TopScoreUserSection.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 72a7efd777..ba1db8ef03 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,7 +13,6 @@ using osu.Game.Graphics.Sprites; using osu.Game.Online.Leaderboards; using osu.Game.Scoring; using osu.Game.Users.Drawables; -using osu.Game.Utils; using osuTK; using osuTK.Graphics; @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly UpdateableRank rank; private readonly UpdateableAvatar avatar; private readonly LinkFlowContainer usernameText; - private readonly SpriteText date; + private readonly DrawableDate achievedOn; private readonly UpdateableFlag flag; public TopScoreUserSection() @@ -92,11 +92,24 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, }, - date = new OsuSpriteText + new FillFlowContainer() { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) + Children = new[] + { + new OsuSpriteText + { + Text = "achieved ", + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) + }, + achievedOn = new DrawableDate(DateTimeOffset.MinValue) + { + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold) + }, + } }, flag = new UpdateableFlag { @@ -125,7 +138,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { avatar.User = value.User; flag.Country = value.User.Country; - date.Text = $@"achieved {HumanizerUtils.Humanize(value.Date)}"; + achievedOn.Date = value.Date; usernameText.Clear(); usernameText.AddUserLink(value.User); @@ -134,4 +147,4 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } } -} +} \ No newline at end of file From 3e06324f61770bd6bcee4135c0573d5fc1720b0a Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Sun, 9 Feb 2020 23:39:34 +0100 Subject: [PATCH 003/127] fix formatting issue --- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index ba1db8ef03..6c33629c0e 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -92,7 +92,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, }, - new FillFlowContainer() + new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, From ed8cb1d6bf42b35b97370810216404532acb114a Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Sun, 9 Feb 2020 23:46:06 +0100 Subject: [PATCH 004/127] add missing eof newline --- osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 6c33629c0e..94a6334401 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -147,4 +147,4 @@ namespace osu.Game.Overlays.BeatmapSet.Scores } } } -} \ No newline at end of file +} From 627833844839dec52e21f1ad7bc00cd796933a9c Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Tue, 11 Feb 2020 14:21:12 +0100 Subject: [PATCH 005/127] implement custom tooltip for DrawableDate --- osu.Game/Graphics/DrawableDate.cs | 75 ++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index 0224c77ee8..dcbea96071 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -4,13 +4,16 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Sprites; using osu.Game.Utils; +using osuTK; namespace osu.Game.Graphics { - public class DrawableDate : OsuSpriteText, IHasTooltip + public class DrawableDate : OsuSpriteText, IHasCustomTooltip { private DateTimeOffset date; @@ -75,6 +78,74 @@ namespace osu.Game.Graphics private void updateTime() => Text = Format(); - public virtual string TooltipText => string.Format($"{Date:MMMM d, yyyy h:mm tt \"UTC\"z}"); + public ITooltip GetCustomTooltip() => new DateTooltip(); + + public object TooltipContent => Date; + + private class DateTooltip : VisibilityContainer, ITooltip + { + private readonly OsuSpriteText dateText, timeText; + private readonly Box background; + + public DateTooltip() + { + AutoSizeAxes = Axes.Both; + Masking = true; + CornerRadius = 5; + + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Padding = new MarginPadding(10), + Children = new Drawable[] + { + dateText = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + }, + timeText = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular), + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + } + } + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + // Temporary colour since it's currently impossible to change it without bugs (see https://github.com/ppy/osu-framework/issues/3231) + // If above is fixed, this should use OverlayColourProvider + background.Colour = colours.Gray1; + timeText.Colour = colours.GreyCyanLighter; + } + + protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); + protected override void PopOut() => this.FadeOut(200, Easing.OutQuint); + + public bool SetContent(object content) + { + if (!(content is DateTimeOffset date)) + return false; + + dateText.Text = string.Format($"{date:d MMMM yyyy}") + " "; + timeText.Text = string.Format($"{date:hh:mm:ss \"UTC\"z}"); + return true; + } + + public void Move(Vector2 pos) => Position = pos; + } } } From 482f622c94202a483092f8e6df306fbcc234af6a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 18:46:49 +0300 Subject: [PATCH 006/127] CommentEditor basic implementation --- .../UserInterface/TestSceneCommentEditor.cs | 43 ++++++++++++++ osu.Game/Overlays/Comments/CommentEditor.cs | 59 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs create mode 100644 osu.Game/Overlays/Comments/CommentEditor.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs new file mode 100644 index 0000000000..f349c81b38 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Overlays; +using osu.Game.Overlays.Comments; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneCommentEditor : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(CommentEditor), + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + + public TestSceneCommentEditor() + { + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Y, + Width = 800, + Child = new TestCommentEditor() + }); + } + + private class TestCommentEditor : CommentEditor + { + protected override string EmptyTextboxText() => @"This textbox is empty"; + + protected override string FooterText() => @"Footer text. And it is pretty long. Cool."; + } + } +} diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs new file mode 100644 index 0000000000..a1995530bb --- /dev/null +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -0,0 +1,59 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.Comments +{ + public abstract class CommentEditor : CompositeDrawable + { + private const int footer_height = 40; + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + RelativeSizeAxes = Axes.X; + Height = footer_height * 2; + Masking = true; + CornerRadius = 6; + + AddRangeInternal(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider.Background3 + }, + new Container + { + Name = "Footer", + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + RelativeSizeAxes = Axes.X, + Height = footer_height, + Padding = new MarginPadding { Horizontal = 8 }, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12), + Shadow = false, + Text = FooterText() + } + } + } + }); + } + + protected abstract string FooterText(); + + protected abstract string EmptyTextboxText(); + } +} From 829152c8e89444f3146f582509d8b9879a1b6ba3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 20:08:24 +0300 Subject: [PATCH 007/127] Implement EditorTextbox --- .../UserInterface/TestSceneCommentEditor.cs | 6 +- osu.Game/Overlays/Comments/CommentEditor.cs | 81 +++++++++++++++---- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index f349c81b38..a1f1999090 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -35,9 +35,11 @@ namespace osu.Game.Tests.Visual.UserInterface private class TestCommentEditor : CommentEditor { - protected override string EmptyTextboxText() => @"This textbox is empty"; + protected override string FooterText => @"Footer text. And it is pretty long. Cool."; - protected override string FooterText() => @"Footer text. And it is pretty long. Cool."; + protected override string CommitButtonText => @"Commit"; + + protected override string TextboxPlaceholderText => @"This textbox is empty"; } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index a1995530bb..9252194377 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -7,20 +7,32 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Graphics.Sprites; +using osuTK.Graphics; namespace osu.Game.Overlays.Comments { public abstract class CommentEditor : CompositeDrawable { private const int footer_height = 40; + private const int side_padding = 8; + + protected abstract string FooterText { get; } + + protected abstract string CommitButtonText { get; } + + protected abstract string TextboxPlaceholderText { get; } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { RelativeSizeAxes = Axes.X; - Height = footer_height * 2; + AutoSizeAxes = Axes.Y; Masking = true; CornerRadius = 6; + BorderThickness = 3; + BorderColour = colourProvider.Background3; AddRangeInternal(new Drawable[] { @@ -29,31 +41,70 @@ namespace osu.Game.Overlays.Comments RelativeSizeAxes = Axes.Both, Colour = colourProvider.Background3 }, - new Container + new FillFlowContainer { - Name = "Footer", - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, + AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Height = footer_height, - Padding = new MarginPadding { Horizontal = 8 }, + Direction = FillDirection.Vertical, Children = new Drawable[] { - new OsuSpriteText + new EditorTextbox { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 12), - Shadow = false, - Text = FooterText() + Height = footer_height, + RelativeSizeAxes = Axes.X, + PlaceholderText = TextboxPlaceholderText + }, + new Container + { + Name = "Footer", + RelativeSizeAxes = Axes.X, + Height = footer_height, + Padding = new MarginPadding { Horizontal = side_padding }, + Children = new Drawable[] + { + new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), + Text = FooterText + } + } } } } }); } - protected abstract string FooterText(); + private class EditorTextbox : BasicTextBox + { + protected override float LeftRightPadding => side_padding; - protected abstract string EmptyTextboxText(); + protected override Color4 SelectionColour => Color4.LightSkyBlue; + + private OsuSpriteText placeholder; + + public EditorTextbox() + { + Masking = false; + TextContainer.Height = 0.4f; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + BackgroundUnfocused = BackgroundFocused = colourProvider.Background5; + placeholder.Colour = colourProvider.Background3; + BackgroundCommit = Color4.LightSkyBlue; + } + + + protected override SpriteText CreatePlaceholder() => placeholder = new OsuSpriteText + { + Font = OsuFont.GetFont(weight: FontWeight.Regular), + }; + + protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) }; + } } } From 730c115f49fbb29b5f72f37ad0446e9f4174d939 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 20:11:22 +0300 Subject: [PATCH 008/127] Fix some size values --- osu.Game/Overlays/Comments/CommentEditor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 9252194377..4ad59ff754 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -15,7 +15,6 @@ namespace osu.Game.Overlays.Comments { public abstract class CommentEditor : CompositeDrawable { - private const int footer_height = 40; private const int side_padding = 8; protected abstract string FooterText { get; } @@ -50,7 +49,7 @@ namespace osu.Game.Overlays.Comments { new EditorTextbox { - Height = footer_height, + Height = 40, RelativeSizeAxes = Axes.X, PlaceholderText = TextboxPlaceholderText }, @@ -58,7 +57,7 @@ namespace osu.Game.Overlays.Comments { Name = "Footer", RelativeSizeAxes = Axes.X, - Height = footer_height, + Height = 35, Padding = new MarginPadding { Horizontal = side_padding }, Children = new Drawable[] { From c022cf72b58a8bd13861c8cde85eca6cc3484672 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 11 Feb 2020 20:47:51 +0300 Subject: [PATCH 009/127] Implement CancellableCommentEditor --- .../UserInterface/TestSceneCommentEditor.cs | 21 +++++- .../Comments/CancellableCommentEditor.cs | 71 +++++++++++++++++++ osu.Game/Overlays/Comments/CommentEditor.cs | 10 +++ osu.Game/Overlays/OverlayColourProvider.cs | 42 +++++------ 4 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 osu.Game/Overlays/Comments/CancellableCommentEditor.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index a1f1999090..86179886e5 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Overlays.Comments; +using osuTK; namespace osu.Game.Tests.Visual.UserInterface { @@ -16,6 +17,7 @@ namespace osu.Game.Tests.Visual.UserInterface public override IReadOnlyList RequiredTypes => new[] { typeof(CommentEditor), + typeof(CancellableCommentEditor), }; [Cached] @@ -23,13 +25,19 @@ namespace osu.Game.Tests.Visual.UserInterface public TestSceneCommentEditor() { - Add(new Container + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, AutoSizeAxes = Axes.Y, Width = 800, - Child = new TestCommentEditor() + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + new TestCommentEditor(), + new TestCancellableCommentEditor() + } }); } @@ -41,5 +49,14 @@ namespace osu.Game.Tests.Visual.UserInterface protected override string TextboxPlaceholderText => @"This textbox is empty"; } + + private class TestCancellableCommentEditor : CancellableCommentEditor + { + protected override string FooterText => @"Wow, another one. Sicc"; + + protected override string CommitButtonText => @"Save"; + + protected override string TextboxPlaceholderText => @"Miltiline textboxes soon"; + } } } diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs new file mode 100644 index 0000000000..ad5686910a --- /dev/null +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -0,0 +1,71 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; + +namespace osu.Game.Overlays.Comments +{ + public abstract class CancellableCommentEditor : CommentEditor + { + public Action OnCancel; + + [BackgroundDependencyLoader] + private void load() + { + ButtonsContainer.Add(new CancelButton + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Action = () => OnCancel?.Invoke() + }); + } + + private class CancelButton : OsuHoverContainer + { + protected override IEnumerable EffectTargets => new[] { background }; + + private readonly Box background; + + public CancelButton() + { + AutoSizeAxes = Axes.Both; + Child = new CircularContainer + { + Masking = true, + Height = 25, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Margin = new MarginPadding { Horizontal = 20 }, + Text = @"Cancel" + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + IdleColour = colourProvider.GetColour(0.5f, 0.45f); + HoverColour = colourProvider.GetColour(0.5f, 0.6f); + } + } + } +} diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 4ad59ff754..bb8ae7f114 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -23,6 +23,8 @@ namespace osu.Game.Overlays.Comments protected abstract string TextboxPlaceholderText { get; } + protected FillFlowContainer ButtonsContainer; + [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { @@ -67,6 +69,14 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.CentreLeft, Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold), Text = FooterText + }, + ButtonsContainer = new FillFlowContainer + { + Name = "Buttons", + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, } } } diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index 9816f313ad..c0984073e6 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -16,28 +16,28 @@ namespace osu.Game.Overlays this.colourScheme = colourScheme; } - public Color4 Highlight1 => getColour(1, 0.7f); - public Color4 Content1 => getColour(0.4f, 1); - public Color4 Content2 => getColour(0.4f, 0.9f); - public Color4 Light1 => getColour(0.4f, 0.8f); - public Color4 Light2 => getColour(0.4f, 0.75f); - public Color4 Light3 => getColour(0.4f, 0.7f); - public Color4 Light4 => getColour(0.4f, 0.5f); - public Color4 Dark1 => getColour(0.2f, 0.35f); - public Color4 Dark2 => getColour(0.2f, 0.3f); - public Color4 Dark3 => getColour(0.2f, 0.25f); - public Color4 Dark4 => getColour(0.2f, 0.2f); - public Color4 Dark5 => getColour(0.2f, 0.15f); - public Color4 Dark6 => getColour(0.2f, 0.1f); - public Color4 Foreground1 => getColour(0.1f, 0.6f); - public Color4 Background1 => getColour(0.1f, 0.4f); - public Color4 Background2 => getColour(0.1f, 0.3f); - public Color4 Background3 => getColour(0.1f, 0.25f); - public Color4 Background4 => getColour(0.1f, 0.2f); - public Color4 Background5 => getColour(0.1f, 0.15f); - public Color4 Background6 => getColour(0.1f, 0.1f); + public Color4 Highlight1 => GetColour(1, 0.7f); + public Color4 Content1 => GetColour(0.4f, 1); + public Color4 Content2 => GetColour(0.4f, 0.9f); + public Color4 Light1 => GetColour(0.4f, 0.8f); + public Color4 Light2 => GetColour(0.4f, 0.75f); + public Color4 Light3 => GetColour(0.4f, 0.7f); + public Color4 Light4 => GetColour(0.4f, 0.5f); + public Color4 Dark1 => GetColour(0.2f, 0.35f); + public Color4 Dark2 => GetColour(0.2f, 0.3f); + public Color4 Dark3 => GetColour(0.2f, 0.25f); + public Color4 Dark4 => GetColour(0.2f, 0.2f); + public Color4 Dark5 => GetColour(0.2f, 0.15f); + public Color4 Dark6 => GetColour(0.2f, 0.1f); + public Color4 Foreground1 => GetColour(0.1f, 0.6f); + public Color4 Background1 => GetColour(0.1f, 0.4f); + public Color4 Background2 => GetColour(0.1f, 0.3f); + public Color4 Background3 => GetColour(0.1f, 0.25f); + public Color4 Background4 => GetColour(0.1f, 0.2f); + public Color4 Background5 => GetColour(0.1f, 0.15f); + public Color4 Background6 => GetColour(0.1f, 0.1f); - private Color4 getColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); + public Color4 GetColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 private static float getBaseHue(OverlayColourScheme colourScheme) From 5a3daf1bd71939f6f1c4b34d1911d74b6789a6f1 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 00:57:06 +0300 Subject: [PATCH 010/127] Implement CommitButton --- .../Comments/CancellableCommentEditor.cs | 4 +- osu.Game/Overlays/Comments/CommentEditor.cs | 72 ++++++++++++++++++- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index ad5686910a..f58627efb3 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -22,8 +22,8 @@ namespace osu.Game.Overlays.Comments { ButtonsContainer.Add(new CancelButton { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, Action = () => OnCancel?.Invoke() }); } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index bb8ae7f114..624e15a047 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -10,6 +10,10 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; using osu.Framework.Graphics.Sprites; using osuTK.Graphics; +using osu.Game.Graphics.UserInterface; +using System.Collections.Generic; +using System; +using osuTK; namespace osu.Game.Overlays.Comments { @@ -17,6 +21,8 @@ namespace osu.Game.Overlays.Comments { private const int side_padding = 8; + public Action OnCommit; + protected abstract string FooterText { get; } protected abstract string CommitButtonText { get; } @@ -28,6 +34,9 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { + EditorTextbox textbox; + CommitButton commitButton; + RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; Masking = true; @@ -49,7 +58,7 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - new EditorTextbox + textbox = new EditorTextbox { Height = 40, RelativeSizeAxes = Axes.X, @@ -77,12 +86,21 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.CentreRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, + Spacing = new Vector2(5, 0), + Child = commitButton = new CommitButton(CommitButtonText) + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + Action = () => OnCommit?.Invoke(textbox.Text) + } } } } } } }); + + textbox.OnCommit += (u, v) => commitButton.Click(); } private class EditorTextbox : BasicTextBox @@ -107,7 +125,6 @@ namespace osu.Game.Overlays.Comments BackgroundCommit = Color4.LightSkyBlue; } - protected override SpriteText CreatePlaceholder() => placeholder = new OsuSpriteText { Font = OsuFont.GetFont(weight: FontWeight.Regular), @@ -115,5 +132,56 @@ namespace osu.Game.Overlays.Comments protected override Drawable GetDrawableCharacter(char c) => new OsuSpriteText { Text = c.ToString(), Font = OsuFont.GetFont(size: CalculatedTextSize) }; } + + private class CommitButton : LoadingButton + { + private const int duration = 200; + + protected override IEnumerable EffectTargets => new[] { background }; + + private OsuSpriteText drawableText; + private Box background; + + public CommitButton(string text) + { + AutoSizeAxes = Axes.Both; + LoadingAnimationSize = new Vector2(10); + + drawableText.Text = text; + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + IdleColour = colourProvider.GetColour(0.5f, 0.45f); + HoverColour = colourProvider.GetColour(0.5f, 0.6f); + } + + protected override Drawable CreateContent() => new CircularContainer + { + Masking = true, + Height = 25, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + drawableText = new OsuSpriteText + { + AlwaysPresent = true, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), + Margin = new MarginPadding { Horizontal = 20 } + } + } + }; + + protected override void OnLoadStarted() => drawableText.FadeOut(duration, Easing.OutQuint); + + protected override void OnLoadFinished() => drawableText.FadeIn(duration, Easing.OutQuint); + } } } From 53a2b65dbdffda9ee3f053108dd8080b9ed85a5f Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 01:35:08 +0300 Subject: [PATCH 011/127] Create dependency between textbox and commit button --- osu.Game/Overlays/Comments/CommentEditor.cs | 56 ++++++++++++++++++--- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 624e15a047..7adb33663c 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -14,6 +14,7 @@ using osu.Game.Graphics.UserInterface; using System.Collections.Generic; using System; using osuTK; +using osu.Framework.Bindables; namespace osu.Game.Overlays.Comments { @@ -31,11 +32,14 @@ namespace osu.Game.Overlays.Comments protected FillFlowContainer ButtonsContainer; + private readonly Bindable current = new Bindable(); + + private CommitButton commitButton; + [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { EditorTextbox textbox; - CommitButton commitButton; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -62,7 +66,8 @@ namespace osu.Game.Overlays.Comments { Height = 40, RelativeSizeAxes = Axes.X, - PlaceholderText = TextboxPlaceholderText + PlaceholderText = TextboxPlaceholderText, + Current = current }, new Container { @@ -91,7 +96,7 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Action = () => OnCommit?.Invoke(textbox.Text) + Action = () => OnCommit?.Invoke(current.Value) } } } @@ -100,14 +105,28 @@ namespace osu.Game.Overlays.Comments } }); - textbox.OnCommit += (u, v) => commitButton.Click(); + textbox.OnCommit += (u, v) => + { + if (!commitButton.IsReady.Value) + return; + + commitButton.Click(); + current.Value = string.Empty; + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + current.BindValueChanged(text => commitButton.IsReady.Value = !string.IsNullOrEmpty(text.NewValue), true); } private class EditorTextbox : BasicTextBox { protected override float LeftRightPadding => side_padding; - protected override Color4 SelectionColour => Color4.LightSkyBlue; + protected override Color4 SelectionColour => Color4.Gray; private OsuSpriteText placeholder; @@ -122,7 +141,7 @@ namespace osu.Game.Overlays.Comments { BackgroundUnfocused = BackgroundFocused = colourProvider.Background5; placeholder.Colour = colourProvider.Background3; - BackgroundCommit = Color4.LightSkyBlue; + BackgroundCommit = colourProvider.Background3; } protected override SpriteText CreatePlaceholder() => placeholder = new OsuSpriteText @@ -137,8 +156,15 @@ namespace osu.Game.Overlays.Comments { private const int duration = 200; + public readonly BindableBool IsReady = new BindableBool(); + + public override bool PropagatePositionalInputSubTree => IsReady.Value && base.PropagatePositionalInputSubTree; + protected override IEnumerable EffectTargets => new[] { background }; + [Resolved] + private OverlayColourProvider colourProvider { get; set; } + private OsuSpriteText drawableText; private Box background; @@ -151,12 +177,28 @@ namespace osu.Game.Overlays.Comments } [BackgroundDependencyLoader] - private void load(OverlayColourProvider colourProvider) + private void load() { IdleColour = colourProvider.GetColour(0.5f, 0.45f); HoverColour = colourProvider.GetColour(0.5f, 0.6f); } + protected override void LoadComplete() + { + base.LoadComplete(); + IsReady.BindValueChanged(onReadyStateChanged, true); + } + + private void onReadyStateChanged(ValueChangedEvent isReady) + { + drawableText.FadeColour(isReady.NewValue ? Color4.White : colourProvider.Foreground1, duration, Easing.OutQuint); + + if (isReady.NewValue) + background.FadeColour(IsHovered ? HoverColour : IdleColour, duration, Easing.OutQuint); + else + background.FadeColour(colourProvider.Background5, duration, Easing.OutQuint); + } + protected override Drawable CreateContent() => new CircularContainer { Masking = true, From 9ac6c271ac3331e390b8d00d168fee539e97c556 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 02:05:45 +0300 Subject: [PATCH 012/127] Naming adjustments --- .../UserInterface/TestSceneCommentEditor.cs | 36 +++++++++++++++++-- osu.Game/Overlays/Comments/CommentEditor.cs | 26 ++++++++------ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 86179886e5..e32bf05197 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -6,6 +6,8 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.Comments; using osuTK; @@ -23,8 +25,21 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + private readonly OsuSpriteText text; + private readonly TestCommentEditor commentEditor; + private readonly TestCancellableCommentEditor cancellableCommentEditor; + public TestSceneCommentEditor() { + Add(new Container + { + AutoSizeAxes = Axes.Both, + Child = text = new OsuSpriteText + { + Font = OsuFont.GetFont() + } + }); + Add(new FillFlowContainer { Anchor = Anchor.Centre, @@ -35,12 +50,29 @@ namespace osu.Game.Tests.Visual.UserInterface Spacing = new Vector2(0, 20), Children = new Drawable[] { - new TestCommentEditor(), - new TestCancellableCommentEditor() + commentEditor = new TestCommentEditor + { + OnCommit = onCommit + }, + cancellableCommentEditor = new TestCancellableCommentEditor + { + OnCommit = onCommit + } } }); } + private void onCommit(string value) + { + text.Text = $@"Invoked text: {value}"; + + Scheduler.AddDelayed(() => + { + commentEditor.IsLoading = false; + cancellableCommentEditor.IsLoading = false; + }, 500); + } + private class TestCommentEditor : CommentEditor { protected override string FooterText => @"Footer text. And it is pretty long. Cool."; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 7adb33663c..34aa036938 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -24,6 +24,12 @@ namespace osu.Game.Overlays.Comments public Action OnCommit; + public bool IsLoading + { + get => commitButton.IsLoading; + set => commitButton.IsLoading = value; + } + protected abstract string FooterText { get; } protected abstract string CommitButtonText { get; } @@ -107,7 +113,7 @@ namespace osu.Game.Overlays.Comments textbox.OnCommit += (u, v) => { - if (!commitButton.IsReady.Value) + if (commitButton.IsBlocked.Value) return; commitButton.Click(); @@ -119,7 +125,7 @@ namespace osu.Game.Overlays.Comments { base.LoadComplete(); - current.BindValueChanged(text => commitButton.IsReady.Value = !string.IsNullOrEmpty(text.NewValue), true); + current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } private class EditorTextbox : BasicTextBox @@ -156,9 +162,9 @@ namespace osu.Game.Overlays.Comments { private const int duration = 200; - public readonly BindableBool IsReady = new BindableBool(); + public readonly BindableBool IsBlocked = new BindableBool(); - public override bool PropagatePositionalInputSubTree => IsReady.Value && base.PropagatePositionalInputSubTree; + public override bool PropagatePositionalInputSubTree => !IsBlocked.Value && base.PropagatePositionalInputSubTree; protected override IEnumerable EffectTargets => new[] { background }; @@ -186,17 +192,17 @@ namespace osu.Game.Overlays.Comments protected override void LoadComplete() { base.LoadComplete(); - IsReady.BindValueChanged(onReadyStateChanged, true); + IsBlocked.BindValueChanged(onBlockedStateChanged, true); } - private void onReadyStateChanged(ValueChangedEvent isReady) + private void onBlockedStateChanged(ValueChangedEvent isBlocked) { - drawableText.FadeColour(isReady.NewValue ? Color4.White : colourProvider.Foreground1, duration, Easing.OutQuint); + drawableText.FadeColour(isBlocked.NewValue ? colourProvider.Foreground1 : Color4.White, duration, Easing.OutQuint); - if (isReady.NewValue) - background.FadeColour(IsHovered ? HoverColour : IdleColour, duration, Easing.OutQuint); - else + if (isBlocked.NewValue) background.FadeColour(colourProvider.Background5, duration, Easing.OutQuint); + else + background.FadeColour(IsHovered ? HoverColour : IdleColour, duration, Easing.OutQuint); } protected override Drawable CreateContent() => new CircularContainer From 2901ec9f261d8d9963f964ef114f5c3b06063267 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Tue, 11 Feb 2020 20:05:26 -0800 Subject: [PATCH 013/127] Select specific difficulties using their icons --- osu.Game/Screens/Select/BeatmapCarousel.cs | 7 ++++- .../Select/Carousel/CarouselBeatmapSet.cs | 5 +++- .../Carousel/DrawableCarouselBeatmapSet.cs | 28 +++++++++++++++++-- osu.Game/Screens/Select/SongSelect.cs | 1 + 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 592e26adc2..1777527ced 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -53,6 +53,11 @@ namespace osu.Game.Screens.Select /// public Action SelectionChanged; + /// + /// Raised when user finalises beatmap selection using + /// + public Action SelectionFinalised; + public override bool HandleNonPositionalInput => AllowSelection; public override bool HandlePositionalInput => AllowSelection; @@ -577,7 +582,7 @@ namespace osu.Game.Screens.Select b.Metadata = beatmapSet.Metadata; } - var set = new CarouselBeatmapSet(beatmapSet); + var set = new CarouselBeatmapSet(beatmapSet, this); foreach (var c in set.Beatmaps) { diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 301d0d4dae..66ee4d2aee 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -15,8 +15,9 @@ namespace osu.Game.Screens.Select.Carousel public IEnumerable Beatmaps => InternalChildren.OfType(); public BeatmapSetInfo BeatmapSet; + public BeatmapCarousel Carousel; - public CarouselBeatmapSet(BeatmapSetInfo beatmapSet) + public CarouselBeatmapSet(BeatmapSetInfo beatmapSet, BeatmapCarousel carousel) { BeatmapSet = beatmapSet ?? throw new ArgumentNullException(nameof(beatmapSet)); @@ -24,6 +25,8 @@ namespace osu.Game.Screens.Select.Carousel .Where(b => !b.Hidden) .Select(b => new CarouselBeatmap(b)) .ForEach(AddChild); + + Carousel = carousel; } protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmapSet(this); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 699e01bca7..536fca9e6f 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; @@ -33,10 +34,13 @@ namespace osu.Game.Screens.Select.Carousel private DialogOverlay dialogOverlay; private readonly BeatmapSetInfo beatmapSet; + private BeatmapCarousel carousel; + public DrawableCarouselBeatmapSet(CarouselBeatmapSet set) : base(set) { beatmapSet = set.BeatmapSet; + carousel = set.Carousel; } [BackgroundDependencyLoader(true)] @@ -117,7 +121,7 @@ namespace osu.Game.Screens.Select.Carousel return beatmaps.Count > maximum_difficulty_icons ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) - : beatmaps.Select(b => new FilterableDifficultyIcon(b)); + : beatmaps.Select(b => new FilterableDifficultyIcon(b, carousel)); } public MenuItem[] ContextMenuItems @@ -210,12 +214,32 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - public FilterableDifficultyIcon(CarouselBeatmap item) + private BeatmapCarousel carousel; + private BeatmapInfo info; + + public FilterableDifficultyIcon(CarouselBeatmap item, BeatmapCarousel carousel) : base(item.Beatmap) { filtered.BindTo(item.Filtered); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); + + this.carousel = carousel; + info = item.Beatmap; + } + + protected override bool OnClick(ClickEvent e) + { + if(e.AltPressed || carousel.SelectedBeatmap == info) + { + Schedule(() => carousel.SelectionFinalised?.Invoke(info)); + } + else + { + carousel.SelectBeatmap(info); + } + + return true; } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 5037081b5e..bfa693cf3d 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -155,6 +155,7 @@ namespace osu.Game.Screens.Select Origin = Anchor.CentreRight, RelativeSizeAxes = Axes.Both, SelectionChanged = updateSelectedBeatmap, + SelectionFinalised = beatmapInfo => { FinaliseSelection(beatmapInfo); }, BeatmapSetsChanged = carouselBeatmapsLoaded, }, } From ab7adb3a9798dd0c68cfd4dab5939c36918faf5a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 13:28:49 +0300 Subject: [PATCH 014/127] Adjust button colours --- .../Comments/CancellableCommentEditor.cs | 4 +- osu.Game/Overlays/Comments/CommentEditor.cs | 4 +- osu.Game/Overlays/OverlayColourProvider.cs | 42 +++++++++---------- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs index f58627efb3..c226b7f07f 100644 --- a/osu.Game/Overlays/Comments/CancellableCommentEditor.cs +++ b/osu.Game/Overlays/Comments/CancellableCommentEditor.cs @@ -63,8 +63,8 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - IdleColour = colourProvider.GetColour(0.5f, 0.45f); - HoverColour = colourProvider.GetColour(0.5f, 0.6f); + IdleColour = colourProvider.Light4; + HoverColour = colourProvider.Light3; } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 34aa036938..ac355e9c98 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -185,8 +185,8 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load() { - IdleColour = colourProvider.GetColour(0.5f, 0.45f); - HoverColour = colourProvider.GetColour(0.5f, 0.6f); + IdleColour = colourProvider.Light4; + HoverColour = colourProvider.Light3; } protected override void LoadComplete() diff --git a/osu.Game/Overlays/OverlayColourProvider.cs b/osu.Game/Overlays/OverlayColourProvider.cs index c0984073e6..9816f313ad 100644 --- a/osu.Game/Overlays/OverlayColourProvider.cs +++ b/osu.Game/Overlays/OverlayColourProvider.cs @@ -16,28 +16,28 @@ namespace osu.Game.Overlays this.colourScheme = colourScheme; } - public Color4 Highlight1 => GetColour(1, 0.7f); - public Color4 Content1 => GetColour(0.4f, 1); - public Color4 Content2 => GetColour(0.4f, 0.9f); - public Color4 Light1 => GetColour(0.4f, 0.8f); - public Color4 Light2 => GetColour(0.4f, 0.75f); - public Color4 Light3 => GetColour(0.4f, 0.7f); - public Color4 Light4 => GetColour(0.4f, 0.5f); - public Color4 Dark1 => GetColour(0.2f, 0.35f); - public Color4 Dark2 => GetColour(0.2f, 0.3f); - public Color4 Dark3 => GetColour(0.2f, 0.25f); - public Color4 Dark4 => GetColour(0.2f, 0.2f); - public Color4 Dark5 => GetColour(0.2f, 0.15f); - public Color4 Dark6 => GetColour(0.2f, 0.1f); - public Color4 Foreground1 => GetColour(0.1f, 0.6f); - public Color4 Background1 => GetColour(0.1f, 0.4f); - public Color4 Background2 => GetColour(0.1f, 0.3f); - public Color4 Background3 => GetColour(0.1f, 0.25f); - public Color4 Background4 => GetColour(0.1f, 0.2f); - public Color4 Background5 => GetColour(0.1f, 0.15f); - public Color4 Background6 => GetColour(0.1f, 0.1f); + public Color4 Highlight1 => getColour(1, 0.7f); + public Color4 Content1 => getColour(0.4f, 1); + public Color4 Content2 => getColour(0.4f, 0.9f); + public Color4 Light1 => getColour(0.4f, 0.8f); + public Color4 Light2 => getColour(0.4f, 0.75f); + public Color4 Light3 => getColour(0.4f, 0.7f); + public Color4 Light4 => getColour(0.4f, 0.5f); + public Color4 Dark1 => getColour(0.2f, 0.35f); + public Color4 Dark2 => getColour(0.2f, 0.3f); + public Color4 Dark3 => getColour(0.2f, 0.25f); + public Color4 Dark4 => getColour(0.2f, 0.2f); + public Color4 Dark5 => getColour(0.2f, 0.15f); + public Color4 Dark6 => getColour(0.2f, 0.1f); + public Color4 Foreground1 => getColour(0.1f, 0.6f); + public Color4 Background1 => getColour(0.1f, 0.4f); + public Color4 Background2 => getColour(0.1f, 0.3f); + public Color4 Background3 => getColour(0.1f, 0.25f); + public Color4 Background4 => getColour(0.1f, 0.2f); + public Color4 Background5 => getColour(0.1f, 0.15f); + public Color4 Background6 => getColour(0.1f, 0.1f); - public Color4 GetColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); + private Color4 getColour(float saturation, float lightness) => Color4.FromHsl(new Vector4(getBaseHue(colourScheme), saturation, lightness, 1)); // See https://github.com/ppy/osu-web/blob/4218c288292d7c810b619075471eaea8bbb8f9d8/app/helpers.php#L1463 private static float getBaseHue(OverlayColourScheme colourScheme) From 62051c036b1f90bd16f7972ca6b4d9dd13e8d6ce Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 12 Feb 2020 13:43:56 +0300 Subject: [PATCH 015/127] Small CommitButton improvements --- osu.Game/Overlays/Comments/CommentEditor.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index ac355e9c98..edd09cc95f 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -102,7 +102,11 @@ namespace osu.Game.Overlays.Comments { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, - Action = () => OnCommit?.Invoke(current.Value) + Action = () => + { + OnCommit?.Invoke(current.Value); + current.Value = string.Empty; + } } } } @@ -117,7 +121,6 @@ namespace osu.Game.Overlays.Comments return; commitButton.Click(); - current.Value = string.Empty; }; } @@ -173,6 +176,7 @@ namespace osu.Game.Overlays.Comments private OsuSpriteText drawableText; private Box background; + private Box blockedBackground; public CommitButton(string text) { @@ -187,6 +191,7 @@ namespace osu.Game.Overlays.Comments { IdleColour = colourProvider.Light4; HoverColour = colourProvider.Light3; + blockedBackground.Colour = colourProvider.Background5; } protected override void LoadComplete() @@ -198,11 +203,7 @@ namespace osu.Game.Overlays.Comments private void onBlockedStateChanged(ValueChangedEvent isBlocked) { drawableText.FadeColour(isBlocked.NewValue ? colourProvider.Foreground1 : Color4.White, duration, Easing.OutQuint); - - if (isBlocked.NewValue) - background.FadeColour(colourProvider.Background5, duration, Easing.OutQuint); - else - background.FadeColour(IsHovered ? HoverColour : IdleColour, duration, Easing.OutQuint); + background.FadeTo(isBlocked.NewValue ? 0 : 1, duration, Easing.OutQuint); } protected override Drawable CreateContent() => new CircularContainer @@ -212,6 +213,10 @@ namespace osu.Game.Overlays.Comments AutoSizeAxes = Axes.X, Children = new Drawable[] { + blockedBackground = new Box + { + RelativeSizeAxes = Axes.Both + }, background = new Box { RelativeSizeAxes = Axes.Both From c391a464a5ecffb8fda5ba27cabcc9aa733503fd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 13 Feb 2020 04:06:34 +0300 Subject: [PATCH 016/127] Add tests --- .../UserInterface/TestSceneCommentEditor.cs | 106 +++++++++++++++--- osu.Game/Overlays/Comments/CommentEditor.cs | 13 ++- 2 files changed, 96 insertions(+), 23 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index e32bf05197..a7888bb0b4 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -3,18 +3,19 @@ using System; using System.Collections.Generic; +using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; -using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.Comments; using osuTK; +using osuTK.Input; namespace osu.Game.Tests.Visual.UserInterface { - public class TestSceneCommentEditor : OsuTestScene + public class TestSceneCommentEditor : ManualInputManagerTestScene { public override IReadOnlyList RequiredTypes => new[] { @@ -25,20 +26,76 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); - private readonly OsuSpriteText text; - private readonly TestCommentEditor commentEditor; - private readonly TestCancellableCommentEditor cancellableCommentEditor; + private TestCommentEditor commentEditor; + private TestCancellableCommentEditor cancellableCommentEditor; + private string commitText; + private bool cancelActionFired; - public TestSceneCommentEditor() + [Test] + public void TestCommitViaKeyboard() { - Add(new Container + AddStep("Create", createEditors); + AddStep("Click on textbox", () => { - AutoSizeAxes = Axes.Both, - Child = text = new OsuSpriteText - { - Font = OsuFont.GetFont() - } + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); }); + AddStep("Write something", () => commentEditor.Current.Value = "text"); + AddStep("Click Enter", () => press(Key.Enter)); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Button is loading", () => commentEditor.IsLoading); + } + + [Test] + public void TestCommitViaKeyboardWhenEmpty() + { + AddStep("Create", createEditors); + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); + }); + AddStep("Click Enter", () => press(Key.Enter)); + AddAssert("Text not invoked", () => string.IsNullOrEmpty(commitText)); + AddAssert("Button is not loading", () => !commentEditor.IsLoading); + } + + [Test] + public void TestCommitViaButton() + { + AddStep("Create", createEditors); + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); + }); + AddStep("Write something", () => commentEditor.Current.Value = "text"); + AddStep("Click on button", () => + { + InputManager.MoveMouseTo(commentEditor.ButtonsContainer); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Button is loading", () => commentEditor.IsLoading); + } + + [Test] + public void TestCancelAction() + { + AddStep("Create", createEditors); + AddStep("Click on cancel button", () => + { + InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Cancel action is fired", () => cancelActionFired); + } + + private void createEditors() + { + Clear(); + commitText = string.Empty; + cancelActionFired = false; Add(new FillFlowContainer { @@ -52,11 +109,12 @@ namespace osu.Game.Tests.Visual.UserInterface { commentEditor = new TestCommentEditor { - OnCommit = onCommit + OnCommit = onCommit, }, cancellableCommentEditor = new TestCancellableCommentEditor { - OnCommit = onCommit + OnCommit = onCommit, + OnCancel = onCancel } } }); @@ -64,17 +122,29 @@ namespace osu.Game.Tests.Visual.UserInterface private void onCommit(string value) { - text.Text = $@"Invoked text: {value}"; + commitText = value; Scheduler.AddDelayed(() => { commentEditor.IsLoading = false; cancellableCommentEditor.IsLoading = false; - }, 500); + }, 1000); + } + + private void onCancel() => cancelActionFired = true; + + private void press(Key key) + { + InputManager.PressKey(key); + InputManager.ReleaseKey(key); } private class TestCommentEditor : CommentEditor { + public new Bindable Current => base.Current; + + public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; + protected override string FooterText => @"Footer text. And it is pretty long. Cool."; protected override string CommitButtonText => @"Commit"; @@ -84,6 +154,8 @@ namespace osu.Game.Tests.Visual.UserInterface private class TestCancellableCommentEditor : CancellableCommentEditor { + public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; + protected override string FooterText => @"Wow, another one. Sicc"; protected override string CommitButtonText => @"Save"; diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index edd09cc95f..765e5e228c 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Comments protected FillFlowContainer ButtonsContainer; - private readonly Bindable current = new Bindable(); + protected readonly Bindable Current = new Bindable(); private CommitButton commitButton; @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Comments Height = 40, RelativeSizeAxes = Axes.X, PlaceholderText = TextboxPlaceholderText, - Current = current + Current = Current }, new Container { @@ -104,8 +104,8 @@ namespace osu.Game.Overlays.Comments Origin = Anchor.CentreRight, Action = () => { - OnCommit?.Invoke(current.Value); - current.Value = string.Empty; + OnCommit?.Invoke(Current.Value); + Current.Value = string.Empty; } } } @@ -128,7 +128,7 @@ namespace osu.Game.Overlays.Comments { base.LoadComplete(); - current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); + Current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } private class EditorTextbox : BasicTextBox @@ -219,7 +219,8 @@ namespace osu.Game.Overlays.Comments }, background = new Box { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + Alpha = 0 }, drawableText = new OsuSpriteText { From b126c002924788acd7dd62cc410821db081da0fa Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Wed, 12 Feb 2020 19:05:08 -0800 Subject: [PATCH 017/127] Use dependency loader to get SongSelect instance --- osu.Game/Screens/Select/BeatmapCarousel.cs | 7 +---- .../Select/Carousel/CarouselBeatmapSet.cs | 5 +--- .../Carousel/DrawableCarouselBeatmapSet.cs | 27 ++++++++++--------- osu.Game/Screens/Select/SongSelect.cs | 3 +-- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 1777527ced..592e26adc2 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -53,11 +53,6 @@ namespace osu.Game.Screens.Select /// public Action SelectionChanged; - /// - /// Raised when user finalises beatmap selection using - /// - public Action SelectionFinalised; - public override bool HandleNonPositionalInput => AllowSelection; public override bool HandlePositionalInput => AllowSelection; @@ -582,7 +577,7 @@ namespace osu.Game.Screens.Select b.Metadata = beatmapSet.Metadata; } - var set = new CarouselBeatmapSet(beatmapSet, this); + var set = new CarouselBeatmapSet(beatmapSet); foreach (var c in set.Beatmaps) { diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs index 66ee4d2aee..301d0d4dae 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs @@ -15,9 +15,8 @@ namespace osu.Game.Screens.Select.Carousel public IEnumerable Beatmaps => InternalChildren.OfType(); public BeatmapSetInfo BeatmapSet; - public BeatmapCarousel Carousel; - public CarouselBeatmapSet(BeatmapSetInfo beatmapSet, BeatmapCarousel carousel) + public CarouselBeatmapSet(BeatmapSetInfo beatmapSet) { BeatmapSet = beatmapSet ?? throw new ArgumentNullException(nameof(beatmapSet)); @@ -25,8 +24,6 @@ namespace osu.Game.Screens.Select.Carousel .Where(b => !b.Hidden) .Select(b => new CarouselBeatmap(b)) .ForEach(AddChild); - - Carousel = carousel; } protected override DrawableCarouselItem CreateDrawableRepresentation() => new DrawableCarouselBeatmapSet(this); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 536fca9e6f..fd13bdc3eb 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -34,18 +34,20 @@ namespace osu.Game.Screens.Select.Carousel private DialogOverlay dialogOverlay; private readonly BeatmapSetInfo beatmapSet; - private BeatmapCarousel carousel; + private SongSelect songSelect; public DrawableCarouselBeatmapSet(CarouselBeatmapSet set) : base(set) { beatmapSet = set.BeatmapSet; - carousel = set.Carousel; } [BackgroundDependencyLoader(true)] - private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) + private void load(SongSelect songSelect, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) { + if(songSelect != null) + this.songSelect = songSelect; + restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); dialogOverlay = overlay; if (beatmapOverlay != null) @@ -121,7 +123,7 @@ namespace osu.Game.Screens.Select.Carousel return beatmaps.Count > maximum_difficulty_icons ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) - : beatmaps.Select(b => new FilterableDifficultyIcon(b, carousel)); + : beatmaps.Select(b => new FilterableDifficultyIcon(b, songSelect, songSelect.Carousel)); } public MenuItem[] ContextMenuItems @@ -214,32 +216,33 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); + private SongSelect songSelect; private BeatmapCarousel carousel; private BeatmapInfo info; - public FilterableDifficultyIcon(CarouselBeatmap item, BeatmapCarousel carousel) + public FilterableDifficultyIcon(CarouselBeatmap item, SongSelect songSelect, BeatmapCarousel carousel) : base(item.Beatmap) { filtered.BindTo(item.Filtered); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); + this.songSelect = songSelect; this.carousel = carousel; info = item.Beatmap; } protected override bool OnClick(ClickEvent e) { - if(e.AltPressed || carousel.SelectedBeatmap == info) + if(!filtered.Value) { - Schedule(() => carousel.SelectionFinalised?.Invoke(info)); - } - else - { - carousel.SelectBeatmap(info); + carousel?.SelectBeatmap(info); + + if (e.AltPressed) + songSelect?.FinaliseSelection(); } - return true; + return base.OnClick(e); } } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index bfa693cf3d..463a17989a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Select protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); - protected BeatmapCarousel Carousel { get; private set; } + public BeatmapCarousel Carousel { get; private set; } private BeatmapInfoWedge beatmapInfoWedge; private DialogOverlay dialogOverlay; @@ -155,7 +155,6 @@ namespace osu.Game.Screens.Select Origin = Anchor.CentreRight, RelativeSizeAxes = Axes.Both, SelectionChanged = updateSelectedBeatmap, - SelectionFinalised = beatmapInfo => { FinaliseSelection(beatmapInfo); }, BeatmapSetsChanged = carouselBeatmapsLoaded, }, } From f8b69fe63285186a2e6b661e875353696e86ce1f Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Wed, 12 Feb 2020 20:11:39 -0800 Subject: [PATCH 018/127] Remove unnecessary carousel variable, fix code formatting --- .../Carousel/DrawableCarouselBeatmapSet.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index fd13bdc3eb..80dae575ff 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Select.Carousel [BackgroundDependencyLoader(true)] private void load(SongSelect songSelect, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) { - if(songSelect != null) + if (songSelect != null) this.songSelect = songSelect; restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); @@ -123,7 +123,7 @@ namespace osu.Game.Screens.Select.Carousel return beatmaps.Count > maximum_difficulty_icons ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) - : beatmaps.Select(b => new FilterableDifficultyIcon(b, songSelect, songSelect.Carousel)); + : beatmaps.Select(b => new FilterableDifficultyIcon(b, songSelect)); } public MenuItem[] ContextMenuItems @@ -216,11 +216,10 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private SongSelect songSelect; - private BeatmapCarousel carousel; - private BeatmapInfo info; + private readonly SongSelect songSelect; + private readonly BeatmapInfo info; - public FilterableDifficultyIcon(CarouselBeatmap item, SongSelect songSelect, BeatmapCarousel carousel) + public FilterableDifficultyIcon(CarouselBeatmap item, SongSelect songSelect) : base(item.Beatmap) { filtered.BindTo(item.Filtered); @@ -228,15 +227,14 @@ namespace osu.Game.Screens.Select.Carousel filtered.TriggerChange(); this.songSelect = songSelect; - this.carousel = carousel; info = item.Beatmap; } protected override bool OnClick(ClickEvent e) { - if(!filtered.Value) + if (!filtered.Value) { - carousel?.SelectBeatmap(info); + songSelect?.Carousel.SelectBeatmap(info); if (e.AltPressed) songSelect?.FinaliseSelection(); From ad0de2796427ee9025d01afe82fe062d9a0a2b8e Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Wed, 12 Feb 2020 22:11:26 -0800 Subject: [PATCH 019/127] Safer dependency injection and accessibility levels --- osu.Game/OsuGame.cs | 47 +++++++++++-------- .../Carousel/DrawableCarouselBeatmapSet.cs | 26 +++++----- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index ff3dee55af..3d6b93c87d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -311,22 +311,12 @@ namespace osu.Game public void ShowBeatmap(int beatmapId) => waitForReady(() => beatmapSetOverlay, _ => beatmapSetOverlay.FetchAndShowBeatmap(beatmapId)); /// - /// Present a beatmap at song select immediately. + /// Present a specific beatmap difficulty at song select immediately. /// The user should have already requested this interactively. /// /// The beatmap to select. - public void PresentBeatmap(BeatmapSetInfo beatmap) + public void PresentBeatmap(BeatmapInfo beatmap) { - var databasedSet = beatmap.OnlineBeatmapSetID != null - ? BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID) - : BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmap.Hash); - - if (databasedSet == null) - { - Logger.Log("The requested beatmap could not be loaded.", LoggingTarget.Information); - return; - } - PerformFromScreen(screen => { // we might already be at song select, so a check is required before performing the load to solo. @@ -334,19 +324,36 @@ namespace osu.Game menuScreen.LoadToSolo(); // we might even already be at the song - if (Beatmap.Value.BeatmapSetInfo.Hash == databasedSet.Hash) - { + if (Beatmap.Value.BeatmapInfo.Hash == beatmap.Hash) return; - } - // Use first beatmap available for current ruleset, else switch ruleset. - var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); - - Ruleset.Value = first.Ruleset; - Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); + Ruleset.Value = beatmap.Ruleset; + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap); }, validScreens: new[] { typeof(PlaySongSelect) }); } + /// + /// + /// Instead of selecting a specific difficulty, this will select the first difficulty of the current ruleset in a beatmapset, + /// or the first difficulty of the set if there is none. + /// + /// The beatmapset to select. + public void PresentBeatmap(BeatmapSetInfo beatmapSet) + { + var databasedSet = beatmapSet.OnlineBeatmapSetID != null + ? BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmapSet.OnlineBeatmapSetID) + : BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmapSet.Hash); + + if (databasedSet == null) + { + Logger.Log("The requested beatmap could not be loaded.", LoggingTarget.Information); + return; + } + + var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); + PresentBeatmap(first); + } + /// /// Present a score's replay immediately. /// The user should have already requested this interactively. diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 80dae575ff..9e4f31b15b 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -34,8 +34,6 @@ namespace osu.Game.Screens.Select.Carousel private DialogOverlay dialogOverlay; private readonly BeatmapSetInfo beatmapSet; - private SongSelect songSelect; - public DrawableCarouselBeatmapSet(CarouselBeatmapSet set) : base(set) { @@ -43,11 +41,8 @@ namespace osu.Game.Screens.Select.Carousel } [BackgroundDependencyLoader(true)] - private void load(SongSelect songSelect, BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) + private void load(BeatmapManager manager, BeatmapSetOverlay beatmapOverlay, DialogOverlay overlay) { - if (songSelect != null) - this.songSelect = songSelect; - restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); dialogOverlay = overlay; if (beatmapOverlay != null) @@ -123,7 +118,7 @@ namespace osu.Game.Screens.Select.Carousel return beatmaps.Count > maximum_difficulty_icons ? (IEnumerable)beatmaps.GroupBy(b => b.Beatmap.Ruleset).Select(group => new FilterableGroupedDifficultyIcon(group.ToList(), group.Key)) - : beatmaps.Select(b => new FilterableDifficultyIcon(b, songSelect)); + : beatmaps.Select(b => new FilterableDifficultyIcon(b)); } public MenuItem[] ContextMenuItems @@ -216,17 +211,17 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private readonly SongSelect songSelect; + private OsuGame game; + private SongSelect songSelect; private readonly BeatmapInfo info; - public FilterableDifficultyIcon(CarouselBeatmap item, SongSelect songSelect) + public FilterableDifficultyIcon(CarouselBeatmap item) : base(item.Beatmap) { filtered.BindTo(item.Filtered); filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); - this.songSelect = songSelect; info = item.Beatmap; } @@ -234,7 +229,7 @@ namespace osu.Game.Screens.Select.Carousel { if (!filtered.Value) { - songSelect?.Carousel.SelectBeatmap(info); + game.PresentBeatmap(info); if (e.AltPressed) songSelect?.FinaliseSelection(); @@ -242,6 +237,15 @@ namespace osu.Game.Screens.Select.Carousel return base.OnClick(e); } + + [BackgroundDependencyLoader] + private void load(OsuGame game, SongSelect songSelect) + { + this.game = game; + + if (songSelect != null) + this.songSelect = songSelect; + } } public class FilterableGroupedDifficultyIcon : GroupedDifficultyIcon diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 463a17989a..5037081b5e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Select protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); - public BeatmapCarousel Carousel { get; private set; } + protected BeatmapCarousel Carousel { get; private set; } private BeatmapInfoWedge beatmapInfoWedge; private DialogOverlay dialogOverlay; From b2fbeab7732437b8671c512fe69eabeb6deefb47 Mon Sep 17 00:00:00 2001 From: Maximilian Junges Date: Thu, 13 Feb 2020 14:07:14 +0100 Subject: [PATCH 020/127] simplify string formatting and fix color --- osu.Game/Graphics/DrawableDate.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/DrawableDate.cs b/osu.Game/Graphics/DrawableDate.cs index dcbea96071..8c520f4e10 100644 --- a/osu.Game/Graphics/DrawableDate.cs +++ b/osu.Game/Graphics/DrawableDate.cs @@ -126,10 +126,8 @@ namespace osu.Game.Graphics [BackgroundDependencyLoader] private void load(OsuColour colours) { - // Temporary colour since it's currently impossible to change it without bugs (see https://github.com/ppy/osu-framework/issues/3231) - // If above is fixed, this should use OverlayColourProvider - background.Colour = colours.Gray1; - timeText.Colour = colours.GreyCyanLighter; + background.Colour = colours.GreySeafoamDarker; + timeText.Colour = colours.BlueLighter; } protected override void PopIn() => this.FadeIn(200, Easing.OutQuint); @@ -140,8 +138,8 @@ namespace osu.Game.Graphics if (!(content is DateTimeOffset date)) return false; - dateText.Text = string.Format($"{date:d MMMM yyyy}") + " "; - timeText.Text = string.Format($"{date:hh:mm:ss \"UTC\"z}"); + dateText.Text = $"{date:d MMMM yyyy} "; + timeText.Text = $"{date:hh:mm:ss \"UTC\"z}"; return true; } From cc625e3b897dd2669fe6300de9a6924082e97652 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Feb 2020 20:44:02 +0100 Subject: [PATCH 021/127] Move initialisation logic to [SetUp] --- .../UserInterface/TestSceneCommentEditor.cs | 122 +++++++++--------- 1 file changed, 59 insertions(+), 63 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index a7888bb0b4..aaf26f78a7 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -31,73 +31,13 @@ namespace osu.Game.Tests.Visual.UserInterface private string commitText; private bool cancelActionFired; - [Test] - public void TestCommitViaKeyboard() + [SetUp] + public void SetUp() { - AddStep("Create", createEditors); - AddStep("Click on textbox", () => - { - InputManager.MoveMouseTo(commentEditor); - InputManager.Click(MouseButton.Left); - }); - AddStep("Write something", () => commentEditor.Current.Value = "text"); - AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); - AddAssert("Button is loading", () => commentEditor.IsLoading); - } - - [Test] - public void TestCommitViaKeyboardWhenEmpty() - { - AddStep("Create", createEditors); - AddStep("Click on textbox", () => - { - InputManager.MoveMouseTo(commentEditor); - InputManager.Click(MouseButton.Left); - }); - AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text not invoked", () => string.IsNullOrEmpty(commitText)); - AddAssert("Button is not loading", () => !commentEditor.IsLoading); - } - - [Test] - public void TestCommitViaButton() - { - AddStep("Create", createEditors); - AddStep("Click on textbox", () => - { - InputManager.MoveMouseTo(commentEditor); - InputManager.Click(MouseButton.Left); - }); - AddStep("Write something", () => commentEditor.Current.Value = "text"); - AddStep("Click on button", () => - { - InputManager.MoveMouseTo(commentEditor.ButtonsContainer); - InputManager.Click(MouseButton.Left); - }); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); - AddAssert("Button is loading", () => commentEditor.IsLoading); - } - - [Test] - public void TestCancelAction() - { - AddStep("Create", createEditors); - AddStep("Click on cancel button", () => - { - InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); - InputManager.Click(MouseButton.Left); - }); - AddAssert("Cancel action is fired", () => cancelActionFired); - } - - private void createEditors() - { - Clear(); commitText = string.Empty; cancelActionFired = false; - Add(new FillFlowContainer + Schedule(() => Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -117,7 +57,63 @@ namespace osu.Game.Tests.Visual.UserInterface OnCancel = onCancel } } + })); + } + + [Test] + public void TestCommitViaKeyboard() + { + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); }); + AddStep("Write something", () => commentEditor.Current.Value = "text"); + AddStep("Click Enter", () => press(Key.Enter)); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Button is loading", () => commentEditor.IsLoading); + } + + [Test] + public void TestCommitViaKeyboardWhenEmpty() + { + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); + }); + AddStep("Click Enter", () => press(Key.Enter)); + AddAssert("Text not invoked", () => string.IsNullOrEmpty(commitText)); + AddAssert("Button is not loading", () => !commentEditor.IsLoading); + } + + [Test] + public void TestCommitViaButton() + { + AddStep("Click on textbox", () => + { + InputManager.MoveMouseTo(commentEditor); + InputManager.Click(MouseButton.Left); + }); + AddStep("Write something", () => commentEditor.Current.Value = "text"); + AddStep("Click on button", () => + { + InputManager.MoveMouseTo(commentEditor.ButtonsContainer); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Button is loading", () => commentEditor.IsLoading); + } + + [Test] + public void TestCancelAction() + { + AddStep("Click on cancel button", () => + { + InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); + InputManager.Click(MouseButton.Left); + }); + AddAssert("Cancel action is fired", () => cancelActionFired); } private void onCommit(string value) From 09b2e7beed1d317bfa0bce11f02b3dd7f86f35bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Feb 2020 20:56:34 +0100 Subject: [PATCH 022/127] Encapsulate test editors --- .../UserInterface/TestSceneCommentEditor.cs | 68 ++++++++----------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index aaf26f78a7..8005e9a2bc 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -28,16 +28,10 @@ namespace osu.Game.Tests.Visual.UserInterface private TestCommentEditor commentEditor; private TestCancellableCommentEditor cancellableCommentEditor; - private string commitText; - private bool cancelActionFired; [SetUp] - public void SetUp() - { - commitText = string.Empty; - cancelActionFired = false; - - Schedule(() => Add(new FillFlowContainer + public void SetUp() => Schedule(() => + Add(new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -47,18 +41,10 @@ namespace osu.Game.Tests.Visual.UserInterface Spacing = new Vector2(0, 20), Children = new Drawable[] { - commentEditor = new TestCommentEditor - { - OnCommit = onCommit, - }, - cancellableCommentEditor = new TestCancellableCommentEditor - { - OnCommit = onCommit, - OnCancel = onCancel - } + commentEditor = new TestCommentEditor(), + cancellableCommentEditor = new TestCancellableCommentEditor() } })); - } [Test] public void TestCommitViaKeyboard() @@ -70,7 +56,7 @@ namespace osu.Game.Tests.Visual.UserInterface }); AddStep("Write something", () => commentEditor.Current.Value = "text"); AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commentEditor.CommittedText)); AddAssert("Button is loading", () => commentEditor.IsLoading); } @@ -83,7 +69,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.Click(MouseButton.Left); }); AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text not invoked", () => string.IsNullOrEmpty(commitText)); + AddAssert("Text not invoked", () => string.IsNullOrEmpty(commentEditor.CommittedText)); AddAssert("Button is not loading", () => !commentEditor.IsLoading); } @@ -101,7 +87,7 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(commentEditor.ButtonsContainer); InputManager.Click(MouseButton.Left); }); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commitText)); + AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commentEditor.CommittedText)); AddAssert("Button is loading", () => commentEditor.IsLoading); } @@ -113,22 +99,9 @@ namespace osu.Game.Tests.Visual.UserInterface InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); InputManager.Click(MouseButton.Left); }); - AddAssert("Cancel action is fired", () => cancelActionFired); + AddAssert("Cancel action is fired", () => cancellableCommentEditor.Cancelled); } - private void onCommit(string value) - { - commitText = value; - - Scheduler.AddDelayed(() => - { - commentEditor.IsLoading = false; - cancellableCommentEditor.IsLoading = false; - }, 1000); - } - - private void onCancel() => cancelActionFired = true; - private void press(Key key) { InputManager.PressKey(key); @@ -138,24 +111,39 @@ namespace osu.Game.Tests.Visual.UserInterface private class TestCommentEditor : CommentEditor { public new Bindable Current => base.Current; - public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; + public string CommittedText { get; private set; } + + public TestCommentEditor() + { + OnCommit = onCommit; + } + + private void onCommit(string value) + { + CommittedText = value; + Scheduler.AddDelayed(() => IsLoading = false, 1000); + } + protected override string FooterText => @"Footer text. And it is pretty long. Cool."; - protected override string CommitButtonText => @"Commit"; - protected override string TextboxPlaceholderText => @"This textbox is empty"; } private class TestCancellableCommentEditor : CancellableCommentEditor { public new FillFlowContainer ButtonsContainer => base.ButtonsContainer; - protected override string FooterText => @"Wow, another one. Sicc"; - protected override string CommitButtonText => @"Save"; + public bool Cancelled { get; private set; } + public TestCancellableCommentEditor() + { + OnCancel = () => Cancelled = true; + } + + protected override string CommitButtonText => @"Save"; protected override string TextboxPlaceholderText => @"Miltiline textboxes soon"; } } From 5646083ed9ae4214e9f436b6ff1a7f0d8e107576 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Feb 2020 21:01:25 +0100 Subject: [PATCH 023/127] Adjust code style in test --- .../UserInterface/TestSceneCommentEditor.cs | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index 8005e9a2bc..a5ef8b046d 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -49,57 +49,64 @@ namespace osu.Game.Tests.Visual.UserInterface [Test] public void TestCommitViaKeyboard() { - AddStep("Click on textbox", () => + AddStep("click on text box", () => { InputManager.MoveMouseTo(commentEditor); InputManager.Click(MouseButton.Left); }); - AddStep("Write something", () => commentEditor.Current.Value = "text"); - AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commentEditor.CommittedText)); - AddAssert("Button is loading", () => commentEditor.IsLoading); + AddStep("enter text", () => commentEditor.Current.Value = "text"); + + AddStep("press Enter", () => press(Key.Enter)); + + AddAssert("text committed", () => commentEditor.CommittedText == "text"); + AddAssert("button is loading", () => commentEditor.IsLoading); } [Test] public void TestCommitViaKeyboardWhenEmpty() { - AddStep("Click on textbox", () => + AddStep("click on text box", () => { InputManager.MoveMouseTo(commentEditor); InputManager.Click(MouseButton.Left); }); - AddStep("Click Enter", () => press(Key.Enter)); - AddAssert("Text not invoked", () => string.IsNullOrEmpty(commentEditor.CommittedText)); - AddAssert("Button is not loading", () => !commentEditor.IsLoading); + + AddStep("press Enter", () => press(Key.Enter)); + + AddAssert("no text committed", () => commentEditor.CommittedText == null); + AddAssert("button is not loading", () => !commentEditor.IsLoading); } [Test] public void TestCommitViaButton() { - AddStep("Click on textbox", () => + AddStep("click on text box", () => { InputManager.MoveMouseTo(commentEditor); InputManager.Click(MouseButton.Left); }); - AddStep("Write something", () => commentEditor.Current.Value = "text"); - AddStep("Click on button", () => + AddStep("enter text", () => commentEditor.Current.Value = "some other text"); + + AddStep("click submit", () => { InputManager.MoveMouseTo(commentEditor.ButtonsContainer); InputManager.Click(MouseButton.Left); }); - AddAssert("Text has been invoked", () => !string.IsNullOrEmpty(commentEditor.CommittedText)); - AddAssert("Button is loading", () => commentEditor.IsLoading); + + AddAssert("text committed", () => commentEditor.CommittedText == "some other text"); + AddAssert("button is loading", () => commentEditor.IsLoading); } [Test] public void TestCancelAction() { - AddStep("Click on cancel button", () => + AddStep("click cancel button", () => { InputManager.MoveMouseTo(cancellableCommentEditor.ButtonsContainer); InputManager.Click(MouseButton.Left); }); - AddAssert("Cancel action is fired", () => cancellableCommentEditor.Cancelled); + + AddAssert("cancel action fired", () => cancellableCommentEditor.Cancelled); } private void press(Key key) @@ -128,7 +135,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override string FooterText => @"Footer text. And it is pretty long. Cool."; protected override string CommitButtonText => @"Commit"; - protected override string TextboxPlaceholderText => @"This textbox is empty"; + protected override string TextboxPlaceholderText => @"This text box is empty"; } private class TestCancellableCommentEditor : CancellableCommentEditor @@ -144,7 +151,7 @@ namespace osu.Game.Tests.Visual.UserInterface } protected override string CommitButtonText => @"Save"; - protected override string TextboxPlaceholderText => @"Miltiline textboxes soon"; + protected override string TextboxPlaceholderText => @"Multiline textboxes soon"; } } } From 0f25864faed05910713df23ecdf5d6310f295a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Feb 2020 21:04:53 +0100 Subject: [PATCH 024/127] Textbox -> TextBox rename pass --- .../Visual/UserInterface/TestSceneCommentEditor.cs | 4 ++-- osu.Game/Overlays/Comments/CommentEditor.cs | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs index a5ef8b046d..7b0b644dab 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneCommentEditor.cs @@ -135,7 +135,7 @@ namespace osu.Game.Tests.Visual.UserInterface protected override string FooterText => @"Footer text. And it is pretty long. Cool."; protected override string CommitButtonText => @"Commit"; - protected override string TextboxPlaceholderText => @"This text box is empty"; + protected override string TextBoxPlaceholder => @"This text box is empty"; } private class TestCancellableCommentEditor : CancellableCommentEditor @@ -151,7 +151,7 @@ namespace osu.Game.Tests.Visual.UserInterface } protected override string CommitButtonText => @"Save"; - protected override string TextboxPlaceholderText => @"Multiline textboxes soon"; + protected override string TextBoxPlaceholder => @"Multiline textboxes soon"; } } } diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index 765e5e228c..f7e53addbe 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -34,7 +34,7 @@ namespace osu.Game.Overlays.Comments protected abstract string CommitButtonText { get; } - protected abstract string TextboxPlaceholderText { get; } + protected abstract string TextBoxPlaceholder { get; } protected FillFlowContainer ButtonsContainer; @@ -45,7 +45,7 @@ namespace osu.Game.Overlays.Comments [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - EditorTextbox textbox; + EditorTextBox textBox; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -68,11 +68,11 @@ namespace osu.Game.Overlays.Comments Direction = FillDirection.Vertical, Children = new Drawable[] { - textbox = new EditorTextbox + textBox = new EditorTextBox { Height = 40, RelativeSizeAxes = Axes.X, - PlaceholderText = TextboxPlaceholderText, + PlaceholderText = TextBoxPlaceholder, Current = Current }, new Container @@ -115,7 +115,7 @@ namespace osu.Game.Overlays.Comments } }); - textbox.OnCommit += (u, v) => + textBox.OnCommit += (u, v) => { if (commitButton.IsBlocked.Value) return; @@ -131,7 +131,7 @@ namespace osu.Game.Overlays.Comments Current.BindValueChanged(text => commitButton.IsBlocked.Value = string.IsNullOrEmpty(text.NewValue), true); } - private class EditorTextbox : BasicTextBox + private class EditorTextBox : BasicTextBox { protected override float LeftRightPadding => side_padding; @@ -139,7 +139,7 @@ namespace osu.Game.Overlays.Comments private OsuSpriteText placeholder; - public EditorTextbox() + public EditorTextBox() { Masking = false; TextContainer.Height = 0.4f; From c871f07d2ef9f55d1c91f9ac6138fd2d162e7ed3 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Thu, 13 Feb 2020 17:14:46 -0800 Subject: [PATCH 025/127] Use CarouselBeatmap action to select beatmap --- osu.Game/OsuGame.cs | 55 ++++++++----------- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 + .../Select/Carousel/CarouselBeatmap.cs | 5 ++ .../Carousel/DrawableCarouselBeatmapSet.cs | 23 +------- 4 files changed, 34 insertions(+), 51 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3d6b93c87d..79616ef97c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -311,38 +311,15 @@ namespace osu.Game public void ShowBeatmap(int beatmapId) => waitForReady(() => beatmapSetOverlay, _ => beatmapSetOverlay.FetchAndShowBeatmap(beatmapId)); /// - /// Present a specific beatmap difficulty at song select immediately. + /// Present a beatmap at song select immediately. /// The user should have already requested this interactively. /// /// The beatmap to select. - public void PresentBeatmap(BeatmapInfo beatmap) + public void PresentBeatmap(BeatmapSetInfo beatmap) { - PerformFromScreen(screen => - { - // we might already be at song select, so a check is required before performing the load to solo. - if (screen is MainMenu) - menuScreen.LoadToSolo(); - - // we might even already be at the song - if (Beatmap.Value.BeatmapInfo.Hash == beatmap.Hash) - return; - - Ruleset.Value = beatmap.Ruleset; - Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap); - }, validScreens: new[] { typeof(PlaySongSelect) }); - } - - /// - /// - /// Instead of selecting a specific difficulty, this will select the first difficulty of the current ruleset in a beatmapset, - /// or the first difficulty of the set if there is none. - /// - /// The beatmapset to select. - public void PresentBeatmap(BeatmapSetInfo beatmapSet) - { - var databasedSet = beatmapSet.OnlineBeatmapSetID != null - ? BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmapSet.OnlineBeatmapSetID) - : BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmapSet.Hash); + var databasedSet = beatmap.OnlineBeatmapSetID != null + ? BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID) + : BeatmapManager.QueryBeatmapSet(s => s.Hash == beatmap.Hash); if (databasedSet == null) { @@ -350,8 +327,24 @@ namespace osu.Game return; } - var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); - PresentBeatmap(first); + PerformFromScreen(screen => + { + // we might already be at song select, so a check is required before performing the load to solo. + if (screen is MainMenu) + menuScreen.LoadToSolo(); + + // we might even already be at the song + if (Beatmap.Value.BeatmapSetInfo.Hash == databasedSet.Hash) + { + return; + } + + // Use first beatmap available for current ruleset, else switch ruleset. + var first = databasedSet.Beatmaps.Find(b => b.Ruleset.Equals(Ruleset.Value)) ?? databasedSet.Beatmaps.First(); + + Ruleset.Value = first.Ruleset; + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first); + }, validScreens: new[] { typeof(PlaySongSelect) }); } /// @@ -453,7 +446,7 @@ namespace osu.Game /// /// The action to perform once we are in the correct state. /// An optional collection of valid screen types. If any of these screens are already current we can perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. - protected void PerformFromScreen(Action action, IEnumerable validScreens = null) + public void PerformFromScreen(Action action, IEnumerable validScreens = null) { performFromMainMenuTask?.Cancel(); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 592e26adc2..f6e0e6bf70 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -592,6 +592,8 @@ namespace osu.Game.Screens.Select scrollPositionCache.Invalidate(); } }; + + c.Select = () => SelectBeatmap(c.Beatmap); } return set; diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 2ffb73f226..116053b4f2 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -13,6 +13,11 @@ namespace osu.Game.Screens.Select.Carousel { public readonly BeatmapInfo Beatmap; + /// + /// Select this beatmap on the carousel. + /// + public Action Select; + public CarouselBeatmap(BeatmapInfo beatmap) { Beatmap = beatmap; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 9e4f31b15b..5ef0e8a018 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -211,9 +211,7 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private OsuGame game; - private SongSelect songSelect; - private readonly BeatmapInfo info; + private readonly Action select; public FilterableDifficultyIcon(CarouselBeatmap item) : base(item.Beatmap) @@ -222,30 +220,15 @@ namespace osu.Game.Screens.Select.Carousel filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); - info = item.Beatmap; + select = item.Select; } protected override bool OnClick(ClickEvent e) { - if (!filtered.Value) - { - game.PresentBeatmap(info); - - if (e.AltPressed) - songSelect?.FinaliseSelection(); - } + select?.Invoke(); return base.OnClick(e); } - - [BackgroundDependencyLoader] - private void load(OsuGame game, SongSelect songSelect) - { - this.game = game; - - if (songSelect != null) - this.songSelect = songSelect; - } } public class FilterableGroupedDifficultyIcon : GroupedDifficultyIcon From 368e6f9579492d6321c89850cf4fe114a0337c83 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Thu, 13 Feb 2020 17:47:16 -0800 Subject: [PATCH 026/127] Use CarouselBeatmap.State to select --- osu.Game/OsuGame.cs | 2 +- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 -- osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs | 5 ----- .../Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs | 8 ++++---- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 79616ef97c..ff3dee55af 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -446,7 +446,7 @@ namespace osu.Game /// /// The action to perform once we are in the correct state. /// An optional collection of valid screen types. If any of these screens are already current we can perform the action immediately, else the first valid parent will be made current before performing the action. is used if not specified. - public void PerformFromScreen(Action action, IEnumerable validScreens = null) + protected void PerformFromScreen(Action action, IEnumerable validScreens = null) { performFromMainMenuTask?.Cancel(); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index f6e0e6bf70..592e26adc2 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -592,8 +592,6 @@ namespace osu.Game.Screens.Select scrollPositionCache.Invalidate(); } }; - - c.Select = () => SelectBeatmap(c.Beatmap); } return set; diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs index 116053b4f2..2ffb73f226 100644 --- a/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs +++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmap.cs @@ -13,11 +13,6 @@ namespace osu.Game.Screens.Select.Carousel { public readonly BeatmapInfo Beatmap; - /// - /// Select this beatmap on the carousel. - /// - public Action Select; - public CarouselBeatmap(BeatmapInfo beatmap) { Beatmap = beatmap; diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 5ef0e8a018..572580f7c1 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -211,7 +211,7 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private readonly Action select; + private readonly CarouselBeatmap item; public FilterableDifficultyIcon(CarouselBeatmap item) : base(item.Beatmap) @@ -220,14 +220,14 @@ namespace osu.Game.Screens.Select.Carousel filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); - select = item.Select; + this.item = item; } protected override bool OnClick(ClickEvent e) { - select?.Invoke(); + item.State.Value = CarouselItemState.Selected; - return base.OnClick(e); + return true; } } From 8e1ecddb1dbd05a81b71ef14f513bdd733fd2807 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Fri, 14 Feb 2020 17:23:24 -0800 Subject: [PATCH 027/127] Add testing --- .../SongSelect/TestScenePlaySongSelect.cs | 40 +++++++++++++++++++ .../Carousel/DrawableCarouselBeatmapSet.cs | 7 ++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 80192b9ebc..2b6d7cce58 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -463,6 +463,46 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("Selected beatmap has not changed", () => songSelect.Carousel.SelectedBeatmap.ID == previousID); } + [Test] + public void TestDifficultyIconSelecting() + { + int? previousID = null; + addRulesetImportStep(0); + createSongSelect(); + + AddStep("Store current ID", () => previousID = songSelect.Carousel.SelectedBeatmap.ID); + AddStep("Click on a difficulty", () => + { + InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType() + .First(icon => icon.Item.Beatmap != songSelect.Carousel.SelectedBeatmap)); + + InputManager.PressButton(MouseButton.Left); + InputManager.ReleaseButton(MouseButton.Left); + }); + AddAssert("Selected beatmap changed", () => songSelect.Carousel.SelectedBeatmap.ID != previousID); + + AddStep("Filter some difficulties", () => songSelect.Carousel.Filter(new FilterCriteria + { + BPM = new FilterCriteria.OptionalRange + { + Min = songSelect.Carousel.SelectedBeatmapSet.MaxBPM, + IsLowerInclusive = true + } + })); + AddUntilStep("Wait for filter", () => songSelect.Carousel.ChildrenOfType().Any(icon => icon.Item.Filtered.Value)); + + AddStep("Store current ID", () => previousID = songSelect.Carousel.SelectedBeatmap.ID); + AddStep("Click on a filtered difficulty", () => + { + InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType() + .First(icon => icon.Item.Filtered.Value)); + + InputManager.PressButton(MouseButton.Left); + InputManager.ReleaseButton(MouseButton.Left); + }); + AddAssert("Selected beatmap has not changed", () => songSelect.Carousel.SelectedBeatmap.ID == previousID); + } + private void addRulesetImportStep(int id) => AddStep($"import test map for ruleset {id}", () => importForRuleset(id)); private void importForRuleset(int id) => manager.Import(createTestBeatmapSet(getImportId(), rulesets.AvailableRulesets.Where(r => r.ID == id).ToArray())).Wait(); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 572580f7c1..4b98c4eeb2 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -211,7 +211,7 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - private readonly CarouselBeatmap item; + public readonly CarouselBeatmap Item; public FilterableDifficultyIcon(CarouselBeatmap item) : base(item.Beatmap) @@ -220,12 +220,13 @@ namespace osu.Game.Screens.Select.Carousel filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); - this.item = item; + Item = item; } protected override bool OnClick(ClickEvent e) { - item.State.Value = CarouselItemState.Selected; + if (!filtered.Value) + Item.State.Value = CarouselItemState.Selected; return true; } From 8c81f1e684ce4e4b32531f8fb4807b6cc087f002 Mon Sep 17 00:00:00 2001 From: voidedWarranties Date: Sat, 15 Feb 2020 17:51:55 -0800 Subject: [PATCH 028/127] Move CarouselBeatmap access to private, test using indices --- .../SongSelect/TestScenePlaySongSelect.cs | 44 +++++++++++++++---- .../Carousel/DrawableCarouselBeatmapSet.cs | 6 +-- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs index 2b6d7cce58..369ae346dc 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs @@ -466,36 +466,53 @@ namespace osu.Game.Tests.Visual.SongSelect [Test] public void TestDifficultyIconSelecting() { - int? previousID = null; addRulesetImportStep(0); createSongSelect(); - AddStep("Store current ID", () => previousID = songSelect.Carousel.SelectedBeatmap.ID); + DrawableCarouselBeatmapSet set = null; + AddStep("Find the DrawableCarouselBeatmapSet", () => + { + set = songSelect.Carousel.ChildrenOfType().First(); + }); + + DrawableCarouselBeatmapSet.FilterableDifficultyIcon difficultyIcon = null; + AddStep("Find an icon", () => + { + difficultyIcon = set.ChildrenOfType() + .First(icon => getDifficultyIconIndex(set, icon) != getCurrentBeatmapIndex()); + }); AddStep("Click on a difficulty", () => { - InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType() - .First(icon => icon.Item.Beatmap != songSelect.Carousel.SelectedBeatmap)); + InputManager.MoveMouseTo(difficultyIcon); InputManager.PressButton(MouseButton.Left); InputManager.ReleaseButton(MouseButton.Left); }); - AddAssert("Selected beatmap changed", () => songSelect.Carousel.SelectedBeatmap.ID != previousID); + AddAssert("Selected beatmap correct", () => getCurrentBeatmapIndex() == getDifficultyIconIndex(set, difficultyIcon)); + double? maxBPM = null; AddStep("Filter some difficulties", () => songSelect.Carousel.Filter(new FilterCriteria { BPM = new FilterCriteria.OptionalRange { - Min = songSelect.Carousel.SelectedBeatmapSet.MaxBPM, + Min = maxBPM = songSelect.Carousel.SelectedBeatmapSet.MaxBPM, IsLowerInclusive = true } })); - AddUntilStep("Wait for filter", () => songSelect.Carousel.ChildrenOfType().Any(icon => icon.Item.Filtered.Value)); + DrawableCarouselBeatmapSet.FilterableDifficultyIcon filteredIcon = null; + AddStep("Get filtered icon", () => + { + var filteredBeatmap = songSelect.Carousel.SelectedBeatmapSet.Beatmaps.Find(b => b.BPM < maxBPM); + int filteredBeatmapIndex = getBeatmapIndex(filteredBeatmap.BeatmapSet, filteredBeatmap); + filteredIcon = set.ChildrenOfType().ElementAt(filteredBeatmapIndex); + }); + + int? previousID = null; AddStep("Store current ID", () => previousID = songSelect.Carousel.SelectedBeatmap.ID); AddStep("Click on a filtered difficulty", () => { - InputManager.MoveMouseTo(songSelect.Carousel.ChildrenOfType() - .First(icon => icon.Item.Filtered.Value)); + InputManager.MoveMouseTo(filteredIcon); InputManager.PressButton(MouseButton.Left); InputManager.ReleaseButton(MouseButton.Left); @@ -503,6 +520,15 @@ namespace osu.Game.Tests.Visual.SongSelect AddAssert("Selected beatmap has not changed", () => songSelect.Carousel.SelectedBeatmap.ID == previousID); } + private int getBeatmapIndex(BeatmapSetInfo set, BeatmapInfo info) => set.Beatmaps.FindIndex(b => b == info); + + private int getCurrentBeatmapIndex() => getBeatmapIndex(songSelect.Carousel.SelectedBeatmapSet, songSelect.Carousel.SelectedBeatmap); + + private int getDifficultyIconIndex(DrawableCarouselBeatmapSet set, DrawableCarouselBeatmapSet.FilterableDifficultyIcon icon) + { + return set.ChildrenOfType().ToList().FindIndex(i => i == icon); + } + private void addRulesetImportStep(int id) => AddStep($"import test map for ruleset {id}", () => importForRuleset(id)); private void importForRuleset(int id) => manager.Import(createTestBeatmapSet(getImportId(), rulesets.AvailableRulesets.Where(r => r.ID == id).ToArray())).Wait(); diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index 4b98c4eeb2..3d958dc67f 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -211,7 +211,7 @@ namespace osu.Game.Screens.Select.Carousel { private readonly BindableBool filtered = new BindableBool(); - public readonly CarouselBeatmap Item; + private readonly CarouselBeatmap item; public FilterableDifficultyIcon(CarouselBeatmap item) : base(item.Beatmap) @@ -220,13 +220,13 @@ namespace osu.Game.Screens.Select.Carousel filtered.ValueChanged += isFiltered => Schedule(() => this.FadeTo(isFiltered.NewValue ? 0.1f : 1, 100)); filtered.TriggerChange(); - Item = item; + this.item = item; } protected override bool OnClick(ClickEvent e) { if (!filtered.Value) - Item.State.Value = CarouselItemState.Selected; + item.State.Value = CarouselItemState.Selected; return true; } From dd5e713c0c109a387307925aba91764c8f389282 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 16 Feb 2020 21:42:05 +0100 Subject: [PATCH 029/127] Adjust colours --- osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs index 16eecb7198..182ab055b3 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs @@ -50,7 +50,7 @@ namespace osu.Game.Beatmaps.Drawables Child = new Box { RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.2f), OsuColour.Gray(0.1f)), + Colour = OsuColour.Gray(0.2f), }; } From 8fcd5e93dd56db9116fd90cac4e8b2aa662e3375 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 16 Feb 2020 21:43:11 +0100 Subject: [PATCH 030/127] Adjust table layout to match osu-web --- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 43a45bd2fc..99b3870bc1 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; @@ -77,17 +77,20 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new TableColumn("rank", Anchor.CentreRight, new Dimension(GridSizeMode.AutoSize)), new TableColumn("", Anchor.Centre, new Dimension(GridSizeMode.Absolute, 70)), // grade new TableColumn("score", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), - new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 60, maxSize: 70)), - new TableColumn("player", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 150)), - new TableColumn("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 110)) + new TableColumn("accuracy", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, minSize: 60, maxSize: 70)), + new TableColumn("", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 25)), // flag + new TableColumn("player", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 125)), + new TableColumn("max combo", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 70, maxSize: 120)) }; - foreach (var statistic in score.SortedStatistics) - columns.Add(new TableColumn(statistic.Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 50, maxSize: 70))); + foreach (var statistic in score.SortedStatistics.Take(score.SortedStatistics.Count() - 1)) + columns.Add(new TableColumn(statistic.Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 35, maxSize: 60))); + + columns.Add(new TableColumn(score.SortedStatistics.LastOrDefault().Key.GetDescription(), Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 45, maxSize: 95))); columns.AddRange(new[] { - new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Distributed, minSize: 40, maxSize: 70)), + new TableColumn("pp", Anchor.CentreLeft, new Dimension(GridSizeMode.Absolute, 30)), new TableColumn("mods", Anchor.CentreLeft, new Dimension(GridSizeMode.AutoSize)), }); From 4d180a685a1070e3dc4ada778a3bf675208030e6 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 16 Feb 2020 21:43:33 +0100 Subject: [PATCH 031/127] Adjust font sizes and spacing in BeatmapSetOverlay --- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 8 ++-- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 11 +++--- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 38 +++++++++++-------- .../Buttons/HeaderDownloadButton.cs | 13 ++++--- osu.Game/Overlays/BeatmapSet/Details.cs | 2 +- osu.Game/Overlays/BeatmapSet/Header.cs | 7 +++- osu.Game/Overlays/BeatmapSet/Info.cs | 10 +++-- .../BeatmapSet/LeaderboardScopeSelector.cs | 1 - .../BeatmapSet/Scores/DrawableTopScore.cs | 4 +- .../Scores/NotSupporterPlaceholder.cs | 6 +-- .../Overlays/BeatmapSet/Scores/ScoreTable.cs | 38 ++++++------------- .../Scores/ScoreTableRowBackground.cs | 4 +- .../BeatmapSet/Scores/ScoresContainer.cs | 6 +-- .../Scores/TopScoreStatisticsSection.cs | 22 ++++++----- .../BeatmapSet/Scores/TopScoreUserSection.cs | 2 +- osu.Game/Overlays/BeatmapSet/SuccessRate.cs | 6 +-- .../Screens/Select/Details/AdvancedStats.cs | 8 ++-- .../Screens/Select/Details/UserRatings.cs | 13 ++++--- 18 files changed, 102 insertions(+), 97 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index 096e91b65b..a6ff0ebeb8 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -76,7 +76,7 @@ namespace osu.Game.Overlays.BeatmapSet new Container { AutoSizeAxes = Axes.Both, - CornerRadius = 3, + CornerRadius = 4, Masking = true, Child = avatar = new UpdateableAvatar { @@ -87,7 +87,7 @@ namespace osu.Game.Overlays.BeatmapSet { Colour = Color4.Black.Opacity(0.25f), Type = EdgeEffectType.Shadow, - Radius = 3, + Radius = 4, Offset = new Vector2(0f, 1f), }, }, @@ -117,12 +117,12 @@ namespace osu.Game.Overlays.BeatmapSet new OsuSpriteText { Text = $"{first} ", - Font = OsuFont.GetFont(size: 13) + Font = OsuFont.GetFont(size: 11) }, new OsuSpriteText { Text = second, - Font = secondFont.With(size: 13) + Font = secondFont.With(size: 11) }, }; } diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index 7092b860a0..ba0a62ec2f 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -105,7 +105,7 @@ namespace osu.Game.Overlays.BeatmapSet { TooltipText = name; RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; + Height = 24f; Children = new Drawable[] { @@ -113,7 +113,8 @@ namespace osu.Game.Overlays.BeatmapSet { Anchor = Anchor.Centre, Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, Children = new Drawable[] { new SpriteIcon @@ -121,7 +122,7 @@ namespace osu.Game.Overlays.BeatmapSet Anchor = Anchor.CentreLeft, Origin = Anchor.Centre, Icon = FontAwesome.Solid.Square, - Size = new Vector2(13), + Size = new Vector2(12), Rotation = 45, Colour = OsuColour.FromHex(@"441288"), }, @@ -130,7 +131,7 @@ namespace osu.Game.Overlays.BeatmapSet Anchor = Anchor.CentreLeft, Origin = Anchor.Centre, Icon = icon, - Size = new Vector2(13), + Size = new Vector2(12), Colour = OsuColour.FromHex(@"f7dd55"), Scale = new Vector2(0.8f), }, @@ -139,7 +140,7 @@ namespace osu.Game.Overlays.BeatmapSet Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, Margin = new MarginPadding { Left = 10 }, - Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold), + Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold), }, }, }, diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index bf2a92cd4f..265e2d32f9 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -34,7 +34,6 @@ namespace osu.Game.Overlays.BeatmapSet public readonly DifficultiesContainer Difficulties; public readonly Bindable Beatmap = new Bindable(); - private BeatmapSetInfo beatmapSet; public BeatmapSetInfo BeatmapSet @@ -67,7 +66,7 @@ namespace osu.Game.Overlays.BeatmapSet { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2) }, + Margin = new MarginPadding { Left = -(tile_icon_padding + tile_spacing / 2), Bottom = 10 }, OnLostHover = () => { showBeatmap(Beatmap.Value); @@ -77,7 +76,6 @@ namespace osu.Game.Overlays.BeatmapSet new FillFlowContainer { AutoSizeAxes = Axes.Both, - Margin = new MarginPadding { Top = 10 }, Spacing = new Vector2(5f), Children = new[] { @@ -85,13 +83,13 @@ namespace osu.Game.Overlays.BeatmapSet { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Font = OsuFont.GetFont(size: 20, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: 17, weight: FontWeight.Bold) }, starRating = new OsuSpriteText { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold), + Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold), Text = "Star Difficulty", Alpha = 0, Margin = new MarginPadding { Bottom = 1 }, @@ -192,9 +190,11 @@ namespace osu.Game.Overlays.BeatmapSet public class DifficultySelectorButton : OsuClickableContainer, IStateful { private const float transition_duration = 100; - private const float size = 52; + private const float size = 54; + private const float background_size = size - 2; - private readonly Container bg; + private readonly Container background; + private readonly Box backgroundBox; private readonly DifficultyIcon icon; public readonly BeatmapInfo Beatmap; @@ -230,16 +230,16 @@ namespace osu.Game.Overlays.BeatmapSet Children = new Drawable[] { - bg = new Container + background = new Container { - RelativeSizeAxes = Axes.Both, + Size = new Vector2(background_size), Masking = true, CornerRadius = 4, - Child = new Box + Child = backgroundBox = new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.5f), - }, + Alpha = 0.5f + } }, icon = new DifficultyIcon(beatmap, shouldShowTooltip: false) { @@ -273,15 +273,21 @@ namespace osu.Game.Overlays.BeatmapSet private void fadeIn() { - bg.FadeIn(transition_duration); + background.FadeIn(transition_duration); icon.FadeIn(transition_duration); } private void fadeOut() { - bg.FadeOut(); + background.FadeOut(); icon.FadeTo(0.7f, transition_duration); } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + backgroundBox.Colour = colourProvider.Background6; + } } private class Statistic : FillFlowContainer @@ -314,13 +320,13 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.CentreLeft, Icon = icon, Shadow = true, - Size = new Vector2(13), + Size = new Vector2(12), }, text = new OsuSpriteText { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true) + Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold, italics: true), }, }; } diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs index 53003b0488..e64256b850 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderDownloadButton.cs @@ -22,6 +22,8 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons { public class HeaderDownloadButton : BeatmapDownloadTrackingComposite, IHasTooltip { + private const int text_size = 12; + private readonly bool noVideo; public string TooltipText => button.Enabled.Value ? "download this beatmap" : "login to download"; @@ -80,8 +82,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Icon = FontAwesome.Solid.Download, - Size = new Vector2(16), - Margin = new MarginPadding { Right = 5 }, + Size = new Vector2(18), }, } }, @@ -120,7 +121,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons new OsuSpriteText { Text = "Downloading...", - Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) }, }; break; @@ -131,7 +132,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons new OsuSpriteText { Text = "Importing...", - Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) }, }; break; @@ -146,12 +147,12 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons new OsuSpriteText { Text = "Download", - Font = OsuFont.GetFont(size: 13, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: text_size, weight: FontWeight.Bold) }, new OsuSpriteText { Text = getVideoSuffixText(), - Font = OsuFont.GetFont(size: 11, weight: FontWeight.Bold) + Font = OsuFont.GetFont(size: text_size - 2, weight: FontWeight.Bold) }, }; this.FadeIn(200); diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index 488e181fa2..680487ffbb 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -74,7 +74,7 @@ namespace osu.Game.Overlays.BeatmapSet { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Vertical = 10 }, + Padding = new MarginPadding { Vertical = 10 } }, }, new DetailBox diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 29f09a1ad8..c1e9ce2008 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -144,12 +144,15 @@ namespace osu.Game.Overlays.BeatmapSet }, } }, - artist = new OsuSpriteText { Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true) }, + artist = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true), + Margin = new MarginPadding { Bottom = 20 } + }, new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 20 }, Child = author = new AuthorInfo(), }, beatmapAvailability = new BeatmapAvailability(), diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 85e871baca..0f2d6a9e35 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -20,8 +20,9 @@ namespace osu.Game.Overlays.BeatmapSet public class Info : Container { private const float transition_duration = 250; - private const float metadata_width = 225; + private const float metadata_width = 175; private const float spacing = 20; + private const float base_height = 220; private readonly Box successRateBackground; private readonly Box background; @@ -41,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapSet OsuSpriteText unrankedPlaceholder; RelativeSizeAxes = Axes.X; - Height = 220; + Height = base_height; Masking = true; EdgeEffect = new EdgeEffectParameters { @@ -135,6 +136,7 @@ namespace osu.Game.Overlays.BeatmapSet var setHasLeaderboard = b.NewValue?.OnlineInfo?.Status > 0; successRate.Alpha = setHasLeaderboard ? 1 : 0; unrankedPlaceholder.Alpha = setHasLeaderboard ? 0 : 1; + Height = setHasLeaderboard ? 270 : base_height; }; } @@ -176,8 +178,8 @@ namespace osu.Game.Overlays.BeatmapSet new OsuSpriteText { Text = title, - Font = OsuFont.GetFont(size: 14, weight: FontWeight.Black), - Margin = new MarginPadding { Top = 20 }, + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold), + Margin = new MarginPadding { Top = 15 }, }, textFlow = new OsuTextFlowContainer { diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index 20a3b09db4..48062ef3f0 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -37,7 +37,6 @@ namespace osu.Game.Overlays.BeatmapSet public ScopeSelectorTabItem(BeatmapLeaderboardScope value) : base(value) { - Text.Font = OsuFont.GetFont(size: 16); } protected override bool OnHover(HoverEvent e) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index bb85b4a37b..382155117e 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -23,7 +23,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores AutoSizeAxes = Axes.Y; Masking = true; - CornerRadius = 5; + CornerRadius = 4; EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, @@ -46,7 +46,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Vertical = 10, Left = 10, - Right = 25, + Right = 30, }, Children = new Drawable[] { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/NotSupporterPlaceholder.cs b/osu.Game/Overlays/BeatmapSet/Scores/NotSupporterPlaceholder.cs index ba08a78a61..b2c87a1477 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/NotSupporterPlaceholder.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/NotSupporterPlaceholder.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 10), + Spacing = new Vector2(0, 20), Children = new Drawable[] { new OsuSpriteText @@ -29,9 +29,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = @"You need to be an osu!supporter to access the friend and country rankings!", - Font = OsuFont.GetFont(weight: FontWeight.Bold), + Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold), }, - text = new LinkFlowContainer(t => t.Font = t.Font.With(size: 12)) + text = new LinkFlowContainer(t => t.Font = t.Font.With(size: 11)) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 99b3870bc1..9c886dfa75 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public class ScoreTable : TableContainer { private const float horizontal_inset = 20; - private const float row_height = 25; + private const float row_height = 22; private const int text_size = 12; private readonly FillFlowContainer backgroundFlow; @@ -63,7 +63,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores return; for (int i = 0; i < value.Count; i++) - backgroundFlow.Add(new ScoreTableRowBackground(i, value[i])); + backgroundFlow.Add(new ScoreTableRowBackground(i, value[i], row_height)); Columns = createHeaders(value[0]); Content = value.Select((s, i) => createContent(i, s)).ToArray().ToRectangular(); @@ -99,6 +99,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private Drawable[] createContent(int index, ScoreInfo score) { + var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: text_size)) { AutoSizeAxes = Axes.Both }; + username.AddUserLink(score.User); + var content = new List { new OsuSpriteText @@ -108,7 +111,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }, new UpdateableRank(score.Rank) { - Size = new Vector2(30, 20) + Size = new Vector2(28, 14) }, new OsuSpriteText { @@ -123,35 +126,18 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Font = OsuFont.GetFont(size: text_size), Colour = score.Accuracy == 1 ? highAccuracyColour : Color4.White }, - }; - - var username = new LinkFlowContainer(t => t.Font = OsuFont.GetFont(size: text_size)) { AutoSizeAxes = Axes.Both }; - username.AddUserLink(score.User); - - content.AddRange(new Drawable[] - { - new FillFlowContainer + new UpdateableFlag(score.User.Country) { - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Margin = new MarginPadding { Right = horizontal_inset }, - Spacing = new Vector2(5, 0), - Children = new Drawable[] - { - new UpdateableFlag(score.User.Country) - { - Size = new Vector2(20, 13), - ShowPlaceholderOnNull = false, - }, - username - } + Size = new Vector2(19, 13), + ShowPlaceholderOnNull = false, }, + username, new OsuSpriteText { Text = $@"{score.MaxCombo:N0}x", Font = OsuFont.GetFont(size: text_size) } - }); + }; foreach (var kvp in score.SortedStatistics) { diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs index 83271efe09..d84e1eff8c 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTableRowBackground.cs @@ -22,13 +22,13 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly int index; private readonly ScoreInfo score; - public ScoreTableRowBackground(int index, ScoreInfo score) + public ScoreTableRowBackground(int index, ScoreInfo score, float height) { this.index = index; this.score = score; RelativeSizeAxes = Axes.X; - Height = 25; + Height = height; CornerRadius = 5; Masking = true; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 8560232209..3cb77c6450 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -90,9 +90,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Width = 0.95f, Direction = FillDirection.Vertical, - Margin = new MarginPadding { Vertical = spacing }, + Padding = new MarginPadding { Horizontal = 50 }, + Margin = new MarginPadding { Vertical = 20 }, Children = new Drawable[] { new FillFlowContainer @@ -121,7 +121,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Margin = new MarginPadding { Vertical = spacing }, + Margin = new MarginPadding { Top = spacing }, Children = new Drawable[] { noScoresPlaceholder = new NoScoresPlaceholder diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs index a7066c4827..a15dc57d23 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreStatisticsSection.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private const float bottom_columns_min_width = 45; private readonly FontUsage smallFont = OsuFont.GetFont(size: 16); - private readonly FontUsage largeFont = OsuFont.GetFont(size: 22); + private readonly FontUsage largeFont = OsuFont.GetFont(size: 22, weight: FontWeight.Light); private readonly TextColumn totalScoreColumn; private readonly TextColumn accuracyColumn; @@ -47,7 +47,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Vertical, - Spacing = new Vector2(10, 8), Children = new Drawable[] { new FillFlowContainer @@ -117,6 +116,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public InfoColumn(string title, Drawable content, float? minWidth = null) { AutoSizeAxes = Axes.Both; + Margin = new MarginPadding { Vertical = 5 }; InternalChild = new GridContainer { @@ -128,7 +128,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Absolute, 4), + new Dimension(GridSizeMode.Absolute, 2), new Dimension(GridSizeMode.AutoSize) }, Content = new[] @@ -138,21 +138,24 @@ namespace osu.Game.Overlays.BeatmapSet.Scores text = new OsuSpriteText { Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), - Text = title.ToUpper() + Text = title.ToUpper(), + // 2px padding bottom + 1px vertical to compensate for the additional spacing because of 1.25 line-height in osu-web + Padding = new MarginPadding { Top = 1, Bottom = 3 } } }, new Drawable[] { separator = new Box { - Anchor = Anchor.CentreLeft, + Anchor = Anchor.TopLeft, RelativeSizeAxes = Axes.X, - Height = 2 - } + Height = 2, + }, }, new[] { - content + // osu-web has 4px margin here but also uses 0.9 line-height, reducing margin to 2px seems like a good alternative to that + content.With(c => c.Margin = new MarginPadding { Top = 2 }) } } }; @@ -194,9 +197,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores public ModsInfoColumn() : this(new FillFlowContainer { - AutoSizeAxes = Axes.Both, + AutoSizeAxes = Axes.X, Direction = FillDirection.Horizontal, Spacing = new Vector2(1), + Height = 18f }) { } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 8a368aa535..4e253018c3 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -67,7 +67,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores Origin = Anchor.Centre, Size = new Vector2(70), Masking = true, - CornerRadius = 5, + CornerRadius = 4, EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Shadow, diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs index 15216b6e69..3bb36545cd 100644 --- a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs @@ -65,7 +65,7 @@ namespace osu.Game.Overlays.BeatmapSet Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = "Success Rate", - Font = OsuFont.GetFont(size: 13) + Font = OsuFont.GetFont(size: 12) }, successRate = new Bar { @@ -82,7 +82,7 @@ namespace osu.Game.Overlays.BeatmapSet { Anchor = Anchor.TopRight, Origin = Anchor.TopCentre, - Font = OsuFont.GetFont(size: 13), + Font = OsuFont.GetFont(size: 12), }, }, new OsuSpriteText @@ -90,7 +90,7 @@ namespace osu.Game.Overlays.BeatmapSet Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = "Points of Failure", - Font = OsuFont.GetFont(size: 13), + Font = OsuFont.GetFont(size: 12), Margin = new MarginPadding { Vertical = 20 }, }, }, diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 7ab91677a9..44fac32360 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -51,7 +51,6 @@ namespace osu.Game.Screens.Select.Details { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Spacing = new Vector2(4f), Children = new[] { FirstValue = new StatisticRow(), //circle size/key amount @@ -199,6 +198,7 @@ namespace osu.Game.Screens.Select.Details this.forceDecimalPlaces = forceDecimalPlaces; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + Padding = new MarginPadding { Vertical = 2.5f }; Children = new Drawable[] { @@ -206,9 +206,11 @@ namespace osu.Game.Screens.Select.Details { Width = name_width, AutoSizeAxes = Axes.Y, + // osu-web uses 1.25 line-height, which at 12px font size makes the element 14px tall - this compentates that difference + Padding = new MarginPadding { Vertical = 1 }, Child = name = new OsuSpriteText { - Font = OsuFont.GetFont(size: 13) + Font = OsuFont.GetFont(size: 12) }, }, bar = new Bar @@ -239,7 +241,7 @@ namespace osu.Game.Screens.Select.Details { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Font = OsuFont.GetFont(size: 13) + Font = OsuFont.GetFont(size: 12) }, }, }; diff --git a/osu.Game/Screens/Select/Details/UserRatings.cs b/osu.Game/Screens/Select/Details/UserRatings.cs index c1e01e3572..cf5e3ba1b3 100644 --- a/osu.Game/Screens/Select/Details/UserRatings.cs +++ b/osu.Game/Screens/Select/Details/UserRatings.cs @@ -71,31 +71,32 @@ namespace osu.Game.Screens.Select.Details Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = "User Rating", - Font = OsuFont.GetFont(size: 13) + Font = OsuFont.GetFont(size: 12), + Margin = new MarginPadding { Bottom = 5 }, }, ratingsBar = new Bar { RelativeSizeAxes = Axes.X, Height = 5, - Margin = new MarginPadding { Top = 5 }, }, new Container { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, + Margin = new MarginPadding { Bottom = 10 }, Children = new[] { negativeRatings = new OsuSpriteText { Text = "0", - Font = OsuFont.GetFont(size: 13) + Font = OsuFont.GetFont(size: 12) }, positiveRatings = new OsuSpriteText { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Text = @"0", - Font = OsuFont.GetFont(size: 13) + Font = OsuFont.GetFont(size: 12) }, }, }, @@ -104,8 +105,8 @@ namespace osu.Game.Screens.Select.Details Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, Text = "Rating Spread", - Font = OsuFont.GetFont(size: 13), - Margin = new MarginPadding { Top = 10, Bottom = 5 }, + Font = OsuFont.GetFont(size: 12), + Margin = new MarginPadding { Bottom = 5 }, }, }, }, From 64a9b9c6fbea86aaf1cf2ead68fa8797dc1f9aa1 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Sun, 16 Feb 2020 21:52:08 +0100 Subject: [PATCH 032/127] Remove redundant using directives --- osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs | 1 - osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 2 -- osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs | 1 - osu.Game/Screens/Select/Details/AdvancedStats.cs | 1 - 4 files changed, 5 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs index 182ab055b3..c60bd0286e 100644 --- a/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs +++ b/osu.Game/Beatmaps/Drawables/UpdateableBeatmapSetCover.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 265e2d32f9..66886b0882 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework; 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; @@ -19,7 +18,6 @@ using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; using osuTK; -using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapSet { diff --git a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs index 48062ef3f0..607355b7bf 100644 --- a/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs +++ b/osu.Game/Overlays/BeatmapSet/LeaderboardScopeSelector.cs @@ -3,7 +3,6 @@ using osu.Game.Screens.Select.Leaderboards; using osu.Game.Graphics.UserInterface; -using osu.Game.Graphics; using osu.Framework.Allocation; using osuTK.Graphics; using osu.Framework.Graphics.UserInterface; diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index 44fac32360..af0d36ea9a 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.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 osuTK; using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; From f7f8622436e56f5072d336d06c639312644859a8 Mon Sep 17 00:00:00 2001 From: mcendu Date: Mon, 17 Feb 2020 15:42:52 +0800 Subject: [PATCH 033/127] make TestSceneDrawableJudgement use scene from osu.Game.Tests --- .../SkinnableTestScene.cs | 46 ------------------- .../TestSceneDrawableJudgement.cs | 1 + 2 files changed, 1 insertion(+), 46 deletions(-) delete mode 100644 osu.Game.Rulesets.Mania.Tests/SkinnableTestScene.cs diff --git a/osu.Game.Rulesets.Mania.Tests/SkinnableTestScene.cs b/osu.Game.Rulesets.Mania.Tests/SkinnableTestScene.cs deleted file mode 100644 index 80b1b3df8e..0000000000 --- a/osu.Game.Rulesets.Mania.Tests/SkinnableTestScene.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using System; -using osu.Framework.Allocation; -using osu.Framework.Audio; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Skinning; -using osu.Game.Tests.Visual; - -namespace osu.Game.Rulesets.Mania.Tests -{ - public abstract class SkinnableTestScene : OsuGridTestScene - { - private Skin defaultSkin; - - protected SkinnableTestScene() - : base(1, 2) - { - } - - [BackgroundDependencyLoader] - private void load(AudioManager audio, SkinManager skinManager) - { - defaultSkin = skinManager.GetSkin(DefaultLegacySkin.Info); - } - - public void SetContents(Func creationFunction) - { - Cell(0).Child = createProvider(null, creationFunction); - Cell(1).Child = createProvider(defaultSkin, creationFunction); - } - - private Drawable createProvider(Skin skin, Func creationFunction) - { - var mainProvider = new SkinProvidingContainer(skin); - - return mainProvider - .WithChild(new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider)) - { - Child = creationFunction() - }); - } - } -} diff --git a/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs index eea1a36a19..692d079c16 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions; using osu.Framework.Graphics; +using osu.Game.Tests.Visual; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; From 5ca93758dc40e50094897877749391ec9dea0d5b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 17 Feb 2020 16:59:35 +0900 Subject: [PATCH 034/127] Fix music playlist being enumerated asynchronously --- osu.Game/Overlays/Music/PlaylistOverlay.cs | 8 ++++-- osu.Game/Overlays/MusicController.cs | 30 +++++++++++++++++----- osu.Game/Overlays/NowPlayingOverlay.cs | 11 +++++--- 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 8f753fd3aa..b878aba489 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -75,8 +75,6 @@ namespace osu.Game.Overlays.Music }, }; - list.Items.BindTo(beatmapSets); - filter.Search.OnCommit = (sender, newText) => { BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); @@ -87,7 +85,13 @@ namespace osu.Game.Overlays.Music beatmap.Value.Track.Restart(); } }; + } + protected override void LoadComplete() + { + base.LoadComplete(); + + list.Items.BindTo(beatmapSets); beatmap.BindValueChanged(working => list.SelectedSet.Value = working.NewValue.BeatmapSetInfo, true); } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 7c7daf6eb9..d788929739 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -25,7 +25,16 @@ namespace osu.Game.Overlays [Resolved] private BeatmapManager beatmaps { get; set; } - public IBindableList BeatmapSets => beatmapSets; + public IBindableList BeatmapSets + { + get + { + if (LoadState < LoadState.Ready) + throw new InvalidOperationException($"{nameof(BeatmapSets)} should not be accessed before the music controller is loaded."); + + return beatmapSets; + } + } /// /// Point in time after which the current track will be restarted on triggering a "previous track" action. @@ -54,16 +63,18 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - beatmapSets.AddRange(beatmaps.GetAllUsableBeatmapSets().OrderBy(_ => RNG.Next())); beatmaps.ItemAdded += handleBeatmapAdded; beatmaps.ItemRemoved += handleBeatmapRemoved; + + beatmapSets.AddRange(beatmaps.GetAllUsableBeatmapSets().OrderBy(_ => RNG.Next())); } protected override void LoadComplete() { + base.LoadComplete(); + beatmap.BindValueChanged(beatmapChanged, true); mods.BindValueChanged(_ => ResetTrackAdjustments(), true); - base.LoadComplete(); } /// @@ -82,11 +93,16 @@ namespace osu.Game.Overlays /// public bool IsPlaying => current?.Track.IsRunning ?? false; - private void handleBeatmapAdded(BeatmapSetInfo set) => - Schedule(() => beatmapSets.Add(set)); + private void handleBeatmapAdded(BeatmapSetInfo set) => Schedule(() => + { + if (!beatmapSets.Contains(set)) + beatmapSets.Add(set); + }); - private void handleBeatmapRemoved(BeatmapSetInfo set) => - Schedule(() => beatmapSets.RemoveAll(s => s.ID == set.ID)); + private void handleBeatmapRemoved(BeatmapSetInfo set) => Schedule(() => + { + beatmapSets.RemoveAll(s => s.ID == set.ID); + }); private ScheduledDelegate seekDelegate; diff --git a/osu.Game/Overlays/NowPlayingOverlay.cs b/osu.Game/Overlays/NowPlayingOverlay.cs index dfcf99d30c..118cb037cb 100644 --- a/osu.Game/Overlays/NowPlayingOverlay.cs +++ b/osu.Game/Overlays/NowPlayingOverlay.cs @@ -58,6 +58,9 @@ namespace osu.Game.Overlays [Resolved] private Bindable beatmap { get; set; } + [Resolved] + private OsuColour colours { get; set; } + public NowPlayingOverlay() { Width = 400; @@ -65,7 +68,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { Children = new Drawable[] { @@ -182,15 +185,15 @@ namespace osu.Game.Overlays } } }; - - playlist.BeatmapSets.BindTo(musicController.BeatmapSets); - playlist.State.ValueChanged += s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); } protected override void LoadComplete() { base.LoadComplete(); + playlist.BeatmapSets.BindTo(musicController.BeatmapSets); + playlist.State.BindValueChanged(s => playlistButton.FadeColour(s.NewValue == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint), true); + beatmap.BindDisabledChanged(beatmapDisabledChanged, true); musicController.TrackChanged += trackChanged; From 7ce00bebf0cbc94cba6624690089037fb07558d5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Feb 2020 18:47:22 +0900 Subject: [PATCH 035/127] Add basic structure for skinning fruits --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 4 + .../CatchSkinComponents.cs | 5 + .../Objects/Drawable/DrawableFruit.cs | 259 ++--------------- .../Objects/Drawable/FruitPiece.cs | 269 ++++++++++++++++++ .../Skinning/CatchLegacySkinTransformer.cs | 47 +++ 5 files changed, 346 insertions(+), 238 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs create mode 100644 osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index e5c3647f99..b9d791fdb1 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -21,6 +21,8 @@ using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; using System; +using osu.Game.Rulesets.Catch.Skinning; +using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch { @@ -141,6 +143,8 @@ namespace osu.Game.Rulesets.Catch public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap); + public override ISkin CreateLegacySkinProvider(ISkinSource source) => new CatchLegacySkinTransformer(source); + public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score); public int LegacyID => 2; diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs index 7e482d4045..f64902b8e5 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs @@ -5,5 +5,10 @@ namespace osu.Game.Rulesets.Catch { public enum CatchSkinComponents { + FruitBananas, + FruitApple, + FruitGrapes, + FruitOrange, + FruitPear, } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 53a018c9f4..0953293dcd 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -3,13 +3,9 @@ using System; 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.Utils; -using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -17,21 +13,19 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableFruit : PalpableCatchHitObject { - private Circle border; - - private const float drawable_radius = (float)CatchHitObject.OBJECT_RADIUS * radius_adjust; + public const float DRAWABLE_RADIUS = (float)CatchHitObject.OBJECT_RADIUS * RADIUS_ADJUST; /// /// Because we're adding a border around the fruit, we need to scale down some. /// - private const float radius_adjust = 1.1f; + public const float RADIUS_ADJUST = 1.1f; public DrawableFruit(Fruit h) : base(h) { Origin = Anchor.Centre; - Size = new Vector2(drawable_radius); + Size = new Vector2(DRAWABLE_RADIUS); Masking = false; Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; @@ -40,247 +34,36 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable [BackgroundDependencyLoader] private void load() { - // todo: this should come from the skin. + AddInternal(new SkinnableDrawable( + new CatchSkinComponent(getComponent(HitObject.VisualRepresentation)), _ => new FruitPiece())); + AccentColour.Value = colourForRepresentation(HitObject.VisualRepresentation); - - AddRangeInternal(new[] - { - createPulp(HitObject.VisualRepresentation), - border = new Circle - { - EdgeEffect = new EdgeEffectParameters - { - Hollow = !HitObject.HyperDash, - Type = EdgeEffectType.Glow, - Radius = 4 * radius_adjust, - Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Value.Darken(1).Opacity(0.6f) - }, - Size = new Vector2(Height), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - BorderColour = Color4.White, - BorderThickness = 3f * radius_adjust, - Children = new Framework.Graphics.Drawable[] - { - new Box - { - AlwaysPresent = true, - Colour = AccentColour.Value, - Alpha = 0, - RelativeSizeAxes = Axes.Both - } - } - }, - }); - - if (HitObject.HyperDash) - { - AddInternal(new Pulp - { - RelativePositionAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AccentColour = Color4.Red, - Blending = BlendingParameters.Additive, - Alpha = 0.5f, - Scale = new Vector2(1.333f) - }); - } } - private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation) + private CatchSkinComponents getComponent(FruitVisualRepresentation hitObjectVisualRepresentation) { - const float large_pulp_3 = 8f * radius_adjust; - const float distance_from_centre_3 = 0.15f; - - const float large_pulp_4 = large_pulp_3 * 0.925f; - const float distance_from_centre_4 = distance_from_centre_3 / 0.925f; - - const float small_pulp = large_pulp_3 / 2; - - static Vector2 positionAt(float angle, float distance) => new Vector2( - distance * MathF.Sin(angle * MathF.PI / 180), - distance * MathF.Cos(angle * MathF.PI / 180)); - - switch (representation) + switch (hitObjectVisualRepresentation) { - default: - return new Container(); - - case FruitVisualRepresentation.Raspberry: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] - { - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(small_pulp), - Y = -0.34f, - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_4), - Position = positionAt(0, distance_from_centre_4), - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_4), - Position = positionAt(90, distance_from_centre_4), - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_4), - Position = positionAt(180, distance_from_centre_4), - }, - new Pulp - { - Size = new Vector2(large_pulp_4), - AccentColour = AccentColour.Value, - Position = positionAt(270, distance_from_centre_4), - }, - } - }; - - case FruitVisualRepresentation.Pineapple: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] - { - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(small_pulp), - Y = -0.3f, - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_4), - Position = positionAt(45, distance_from_centre_4), - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_4), - Position = positionAt(135, distance_from_centre_4), - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_4), - Position = positionAt(225, distance_from_centre_4), - }, - new Pulp - { - Size = new Vector2(large_pulp_4), - AccentColour = AccentColour.Value, - Position = positionAt(315, distance_from_centre_4), - }, - } - }; - case FruitVisualRepresentation.Pear: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] - { - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(small_pulp), - Y = -0.33f, - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_3), - Position = positionAt(60, distance_from_centre_3), - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_3), - Position = positionAt(180, distance_from_centre_3), - }, - new Pulp - { - Size = new Vector2(large_pulp_3), - AccentColour = AccentColour.Value, - Position = positionAt(300, distance_from_centre_3), - }, - } - }; + return CatchSkinComponents.FruitPear; case FruitVisualRepresentation.Grape: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] - { - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(small_pulp), - Y = -0.25f, - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_3), - Position = positionAt(0, distance_from_centre_3), - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_3), - Position = positionAt(120, distance_from_centre_3), - }, - new Pulp - { - Size = new Vector2(large_pulp_3), - AccentColour = AccentColour.Value, - Position = positionAt(240, distance_from_centre_3), - }, - } - }; + return CatchSkinComponents.FruitGrapes; + + case FruitVisualRepresentation.Raspberry: + return CatchSkinComponents.FruitOrange; + + case FruitVisualRepresentation.Pineapple: + return CatchSkinComponents.FruitApple; case FruitVisualRepresentation.Banana: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] - { - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(small_pulp), - Y = -0.3f - }, - new Pulp - { - AccentColour = AccentColour.Value, - Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f), - Y = 0.05f, - }, - } - }; + return CatchSkinComponents.FruitBananas; + + default: + throw new ArgumentOutOfRangeException(nameof(hitObjectVisualRepresentation), hitObjectVisualRepresentation, null); } } - protected override void Update() - { - base.Update(); - - border.Alpha = (float)Math.Clamp((HitObject.StartTime - Time.Current) / 500, 0, 1); - } - private Color4 colourForRepresentation(FruitVisualRepresentation representation) { switch (representation) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs new file mode 100644 index 0000000000..c59cac8de3 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs @@ -0,0 +1,269 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using osu.Game.Rulesets.Objects.Drawables; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + internal class FruitPiece : CompositeDrawable + { + private Circle border; + + private CatchHitObject hitObject; + + private readonly IBindable accentColour = new Bindable(); + + public FruitPiece() + { + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableObject) + { + DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; + hitObject = drawableCatchObject.HitObject; + + accentColour.BindTo(drawableCatchObject.AccentColour); + + AddRangeInternal(new[] + { + createPulp(drawableCatchObject.HitObject.VisualRepresentation), + border = new Circle + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + BorderColour = Color4.White, + BorderThickness = 3f * DrawableFruit.RADIUS_ADJUST, + Children = new Framework.Graphics.Drawable[] + { + new Box + { + AlwaysPresent = true, + Colour = drawableCatchObject.AccentColour.Value, + Alpha = 0, + RelativeSizeAxes = Axes.Both + } + } + }, + }); + + if (hitObject.HyperDash) + { + AddInternal(new Pulp + { + RelativePositionAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AccentColour = Color4.Red, + Blending = BlendingParameters.Additive, + Alpha = 0.5f, + Scale = new Vector2(1.333f) + }); + } + } + + protected override void Update() + { + base.Update(); + + border.Alpha = (float)Math.Clamp((hitObject.StartTime - Time.Current) / 500, 0, 1); + } + + private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation) + { + const float large_pulp_3 = 8f * DrawableFruit.RADIUS_ADJUST; + const float distance_from_centre_3 = 0.15f; + + const float large_pulp_4 = large_pulp_3 * 0.925f; + const float distance_from_centre_4 = distance_from_centre_3 / 0.925f; + + const float small_pulp = large_pulp_3 / 2; + + static Vector2 positionAt(float angle, float distance) => new Vector2( + distance * MathF.Sin(angle * MathF.PI / 180), + distance * MathF.Cos(angle * MathF.PI / 180)); + + switch (representation) + { + default: + return new Container(); + + case FruitVisualRepresentation.Raspberry: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(small_pulp), + Y = -0.34f, + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_4), + Position = positionAt(0, distance_from_centre_4), + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_4), + Position = positionAt(90, distance_from_centre_4), + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_4), + Position = positionAt(180, distance_from_centre_4), + }, + new Pulp + { + Size = new Vector2(large_pulp_4), + AccentColour = accentColour.Value, + Position = positionAt(270, distance_from_centre_4), + }, + } + }; + + case FruitVisualRepresentation.Pineapple: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(small_pulp), + Y = -0.3f, + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_4), + Position = positionAt(45, distance_from_centre_4), + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_4), + Position = positionAt(135, distance_from_centre_4), + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_4), + Position = positionAt(225, distance_from_centre_4), + }, + new Pulp + { + Size = new Vector2(large_pulp_4), + AccentColour = accentColour.Value, + Position = positionAt(315, distance_from_centre_4), + }, + } + }; + + case FruitVisualRepresentation.Pear: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(small_pulp), + Y = -0.33f, + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_3), + Position = positionAt(60, distance_from_centre_3), + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_3), + Position = positionAt(180, distance_from_centre_3), + }, + new Pulp + { + Size = new Vector2(large_pulp_3), + AccentColour = accentColour.Value, + Position = positionAt(300, distance_from_centre_3), + }, + } + }; + + case FruitVisualRepresentation.Grape: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(small_pulp), + Y = -0.25f, + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_3), + Position = positionAt(0, distance_from_centre_3), + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_3), + Position = positionAt(120, distance_from_centre_3), + }, + new Pulp + { + Size = new Vector2(large_pulp_3), + AccentColour = accentColour.Value, + Position = positionAt(240, distance_from_centre_3), + }, + } + }; + + case FruitVisualRepresentation.Banana: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(small_pulp), + Y = -0.3f + }, + new Pulp + { + AccentColour = accentColour.Value, + Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f), + Y = 0.05f, + }, + } + }; + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs new file mode 100644 index 0000000000..c1e164ed5b --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -0,0 +1,47 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using Humanizer; +using osu.Framework.Audio.Sample; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Textures; +using osu.Game.Audio; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Catch.Skinning +{ + public class CatchLegacySkinTransformer : ISkin + { + private readonly ISkin source; + + public CatchLegacySkinTransformer(ISkinSource source) + { + this.source = source; + } + + public Drawable GetDrawableComponent(ISkinComponent component) + { + if (!(component is CatchSkinComponent catchSkinComponent)) + return null; + + switch (catchSkinComponent.Component) + { + case CatchSkinComponents.FruitApple: + case CatchSkinComponents.FruitBananas: + case CatchSkinComponents.FruitOrange: + case CatchSkinComponents.FruitGrapes: + case CatchSkinComponents.FruitPear: + return this.GetAnimation(catchSkinComponent.Component.ToString().Underscore().Hyphenate(), true, false, true); + } + + return null; + } + + public Texture GetTexture(string componentName) => source.GetTexture(componentName); + + public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample); + + public IBindable GetConfig(TLookup lookup) => source.GetConfig(lookup); + } +} From 2133ba38e5caadf1698fec032caff5ed8c6bea25 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Feb 2020 19:06:08 +0900 Subject: [PATCH 036/127] Add overlay layer --- .../Skinning/CatchLegacySkinTransformer.cs | 6 ++- .../Skinning/LegacyFruitPiece.cs | 53 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs index c1e164ed5b..20bd086199 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -32,7 +32,11 @@ namespace osu.Game.Rulesets.Catch.Skinning case CatchSkinComponents.FruitOrange: case CatchSkinComponents.FruitGrapes: case CatchSkinComponents.FruitPear: - return this.GetAnimation(catchSkinComponent.Component.ToString().Underscore().Hyphenate(), true, false, true); + var lookupName = catchSkinComponent.Component.ToString().Underscore().Hyphenate(); + if (GetTexture(lookupName) != null) + return new LegacyFruitPiece(lookupName); + + break; } return null; diff --git a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs new file mode 100644 index 0000000000..fbe682e512 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs @@ -0,0 +1,53 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Skinning; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Skinning +{ + internal class LegacyFruitPiece : CompositeDrawable + { + private readonly string lookupName; + + private readonly IBindable accentColour = new Bindable(); + + public LegacyFruitPiece(string lookupName) + { + this.lookupName = lookupName; + RelativeSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableObject, ISkinSource skin) + { + DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; + + accentColour.BindTo(drawableCatchObject.AccentColour); + + InternalChildren = new Drawable[] + { + new Sprite + { + Texture = skin.GetTexture(lookupName), + Colour = drawableObject.AccentColour.Value, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + new Sprite + { + Texture = skin.GetTexture($"{lookupName}-overlay"), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }, + }; + } + } +} From 89bff32274af6bc46a14df879c2baae911ba9458 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 17 Feb 2020 19:16:40 +0900 Subject: [PATCH 037/127] Fix metrics not matching between skins and lazer --- .../Objects/CatchHitObject.cs | 2 +- .../Objects/Drawable/DrawableDroplet.cs | 2 +- .../Objects/Drawable/DrawableFruit.cs | 24 +++++++++++++++---- .../Objects/Drawable/DrawableTinyDroplet.cs | 2 +- .../Objects/Drawable/FruitPiece.cs | 4 ++-- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index e4ad49ea50..6cb524ca7a 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Objects { public abstract class CatchHitObject : HitObject, IHasXPosition, IHasComboInformation { - public const double OBJECT_RADIUS = 44; + public const float OBJECT_RADIUS = 64; private float x; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 059310d671..6f5bcb70cf 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable : base(h) { Origin = Anchor.Centre; - Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS) / 4; + Size = new Vector2(CatchHitObject.OBJECT_RADIUS) / 4; Masking = false; } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 0953293dcd..5ab0858f75 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -4,6 +4,7 @@ using System; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Utils; using osu.Game.Skinning; using osuTK; @@ -13,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableFruit : PalpableCatchHitObject { - public const float DRAWABLE_RADIUS = (float)CatchHitObject.OBJECT_RADIUS * RADIUS_ADJUST; + private Container scaleContainer; /// /// Because we're adding a border around the fruit, we need to scale down some. @@ -25,7 +26,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { Origin = Anchor.Centre; - Size = new Vector2(DRAWABLE_RADIUS); + Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2); + Masking = false; Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; @@ -34,10 +36,24 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable [BackgroundDependencyLoader] private void load() { - AddInternal(new SkinnableDrawable( - new CatchSkinComponent(getComponent(HitObject.VisualRepresentation)), _ => new FruitPiece())); + AddRangeInternal(new Framework.Graphics.Drawable[] + { + scaleContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Children = new Framework.Graphics.Drawable[] + { + new SkinnableDrawable( + new CatchSkinComponent(getComponent(HitObject.VisualRepresentation)), _ => new FruitPiece()) + } + } + }); AccentColour.Value = colourForRepresentation(HitObject.VisualRepresentation); + + scaleContainer.Scale = new Vector2(HitObject.Scale); } private CatchSkinComponents getComponent(FruitVisualRepresentation hitObjectVisualRepresentation) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs index d41aea1e7b..ab5df5c44c 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableTinyDroplet(TinyDroplet h) : base(h) { - Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS) / 8; + Size = new Vector2(CatchHitObject.OBJECT_RADIUS / 8); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs index c59cac8de3..2b24f25e8b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs @@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Anchor = Anchor.Centre, Origin = Anchor.Centre, BorderColour = Color4.White, - BorderThickness = 3f * DrawableFruit.RADIUS_ADJUST, + BorderThickness = 6f * DrawableFruit.RADIUS_ADJUST, Children = new Framework.Graphics.Drawable[] { new Box @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation) { - const float large_pulp_3 = 8f * DrawableFruit.RADIUS_ADJUST; + const float large_pulp_3 = 16f * DrawableFruit.RADIUS_ADJUST; const float distance_from_centre_3 = 0.15f; const float large_pulp_4 = large_pulp_3 * 0.925f; From 2f4c252fc09df0325c7c6d9c459222b3b395443b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 18 Feb 2020 19:19:04 +0900 Subject: [PATCH 038/127] Fix playlist items potentially not updating to the correct selected state --- osu.Game/Overlays/Music/PlaylistItem.cs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 8cafbc694a..de2f916946 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -26,8 +26,9 @@ namespace osu.Game.Overlays.Music private TextFlowContainer text; private IEnumerable titleSprites; - private ILocalisedBindableString titleBind; - private ILocalisedBindableString artistBind; + + private ILocalisedBindableString title; + private ILocalisedBindableString artist; private Color4 selectedColour; private Color4 artistColour; @@ -47,24 +48,24 @@ namespace osu.Game.Overlays.Music artistColour = colours.Gray9; HandleColour = colours.Gray5; - titleBind = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.TitleUnicode, Model.Metadata.Title))); - artistBind = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.ArtistUnicode, Model.Metadata.Artist))); + title = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.TitleUnicode, Model.Metadata.Title))); + artist = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.ArtistUnicode, Model.Metadata.Artist))); } protected override void LoadComplete() { base.LoadComplete(); + artist.BindValueChanged(_ => recreateText(), true); + SelectedSet.BindValueChanged(set => { - if (set.OldValue != Model && set.NewValue != Model) + if (set.OldValue?.Equals(Model) != true && set.NewValue?.Equals(Model) != true) return; foreach (Drawable s in titleSprites) - s.FadeColour(set.NewValue == Model ? selectedColour : Color4.White, FADE_DURATION); + s.FadeColour(set.NewValue.Equals(Model) ? selectedColour : Color4.White, FADE_DURATION); }, true); - - artistBind.BindValueChanged(_ => recreateText(), true); } protected override Drawable CreateContent() => text = new OsuTextFlowContainer @@ -78,9 +79,9 @@ namespace osu.Game.Overlays.Music text.Clear(); //space after the title to put a space between the title and artist - titleSprites = text.AddText(titleBind.Value + @" ", sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular)).OfType(); + titleSprites = text.AddText(title.Value + @" ", sprite => sprite.Font = OsuFont.GetFont(weight: FontWeight.Regular)).OfType(); - text.AddText(artistBind.Value, sprite => + text.AddText(artist.Value, sprite => { sprite.Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold); sprite.Colour = artistColour; From 7228900361b1f753b3b8e07e0d195eb7675c27e7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Feb 2020 17:25:12 +0300 Subject: [PATCH 039/127] Implement BeatmapListingSearchSection component --- .../TestSceneBeatmapListingSearchSection.cs | 61 ++++++++++ .../BeatmapListingSearchSection.cs | 114 ++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs create mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs new file mode 100644 index 0000000000..24dc013940 --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs @@ -0,0 +1,61 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Overlays; +using osu.Game.Overlays.BeatmapListing; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneBeatmapListingSearchSection : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(BeatmapListingSearchSection), + }; + + [Cached] + private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + + public TestSceneBeatmapListingSearchSection() + { + BeatmapListingSearchSection section; + + Add(section = new BeatmapListingSearchSection + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + + var beatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = "https://assets.ppy.sh/beatmaps/1094296/covers/cover@2x.jpg?1581416305" + } + } + }; + + var noCoverBeatmapSet = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = string.Empty + } + } + }; + + AddStep("Set beatmap", () => section.BeatmapSet = beatmapSet); + AddStep("Set beatmap (no cover)", () => section.BeatmapSet = noCoverBeatmapSet); + AddStep("Set null beatmap", () => section.BeatmapSet = null); + } + } +} diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs new file mode 100644 index 0000000000..16204c3e38 --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs @@ -0,0 +1,114 @@ +// 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.Online.API.Requests; +using osu.Game.Rulesets; +using osuTK; +using osu.Framework.Bindables; +using osu.Game.Beatmaps.Drawables; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.BeatmapListing +{ + public class BeatmapListingSearchSection : CompositeDrawable + { + public Bindable Query => textBox.Current; + + public Bindable Ruleset => modeFilter.Current; + + public Bindable Category => categoryFilter.Current; + + public BeatmapSetInfo BeatmapSet + { + set + { + if (value == null) + { + beatmapCover.FadeOut(600, Easing.OutQuint); + return; + } + + beatmapCover.BeatmapSet = value; + beatmapCover.FadeTo(0.1f, 200, Easing.OutQuint); + } + } + + private readonly SearchTextBox textBox; + private readonly BeatmapSearchRulesetFilterRow modeFilter; + private readonly BeatmapSearchFilterRow categoryFilter; + + private readonly Box background; + private readonly UpdateableBeatmapSetCover beatmapCover; + + public BeatmapListingSearchSection() + { + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + AddRangeInternal(new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = beatmapCover = new UpdateableBeatmapSetCover + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + } + }, + new Container + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Padding = new MarginPadding + { + Vertical = 20, + Horizontal = 40, + }, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + textBox = new SearchTextBox + { + RelativeSizeAxes = Axes.X, + }, + new ReverseChildIDFillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Padding = new MarginPadding { Horizontal = 10 }, + Children = new Drawable[] + { + modeFilter = new BeatmapSearchRulesetFilterRow(), + categoryFilter = new BeatmapSearchFilterRow(@"Categories"), + } + } + } + } + } + }); + } + + [BackgroundDependencyLoader] + private void load(OverlayColourProvider colourProvider) + { + background.Colour = colourProvider.Dark6; + } + } +} From b6423dd92ed8d30469fd335cc320de9589a5cb6b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Feb 2020 17:40:12 +0300 Subject: [PATCH 040/127] Small textbox adjustments --- .../Graphics/UserInterface/SearchTextBox.cs | 16 +++++++--------- .../BeatmapListingSearchSection.cs | 17 ++++++++++++++--- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index fe8756a4d2..fe92054d25 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -17,18 +17,16 @@ namespace osu.Game.Graphics.UserInterface public SearchTextBox() { Height = 35; - AddRange(new Drawable[] + Add(new SpriteIcon { - new SpriteIcon - { - Icon = FontAwesome.Solid.Search, - Origin = Anchor.CentreRight, - Anchor = Anchor.CentreRight, - Margin = new MarginPadding { Right = 10 }, - Size = new Vector2(20), - } + Icon = FontAwesome.Solid.Search, + Origin = Anchor.CentreRight, + Anchor = Anchor.CentreRight, + Margin = new MarginPadding { Right = 10 }, + Size = new Vector2(20), }); + TextFlow.Padding = new MarginPadding { Right = 35 }; PlaceholderText = "type to search"; } diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs index 16204c3e38..f47144e5d8 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; +using osuTK.Graphics; namespace osu.Game.Overlays.BeatmapListing { @@ -28,7 +29,7 @@ namespace osu.Game.Overlays.BeatmapListing { set { - if (value == null) + if (value == null || string.IsNullOrEmpty(value.OnlineInfo.Covers.Cover)) { beatmapCover.FadeOut(600, Easing.OutQuint); return; @@ -39,7 +40,7 @@ namespace osu.Game.Overlays.BeatmapListing } } - private readonly SearchTextBox textBox; + private readonly BeatmapSearchTextBox textBox; private readonly BeatmapSearchRulesetFilterRow modeFilter; private readonly BeatmapSearchFilterRow categoryFilter; @@ -83,7 +84,7 @@ namespace osu.Game.Overlays.BeatmapListing Spacing = new Vector2(0, 20), Children = new Drawable[] { - textBox = new SearchTextBox + textBox = new BeatmapSearchTextBox { RelativeSizeAxes = Axes.X, }, @@ -110,5 +111,15 @@ namespace osu.Game.Overlays.BeatmapListing { background.Colour = colourProvider.Dark6; } + + private class BeatmapSearchTextBox : SearchTextBox + { + protected override Color4 SelectionColour => Color4.Gray; + + public BeatmapSearchTextBox() + { + PlaceholderText = @"type in keywords..."; + } + } } } From bb22243903bdbaeee9efaca0d2a8fbc41f7657ac Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Feb 2020 17:47:44 +0300 Subject: [PATCH 041/127] TestScene improvements --- .../TestSceneBeatmapListingSearchSection.cs | 69 +++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs index 24dc013940..8e9123fe8d 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs @@ -3,11 +3,15 @@ using System; using System.Collections.Generic; +using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.BeatmapListing; +using osuTK; namespace osu.Game.Tests.Visual.UserInterface { @@ -21,9 +25,13 @@ namespace osu.Game.Tests.Visual.UserInterface [Cached] private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue); + private readonly BeatmapListingSearchSection section; + public TestSceneBeatmapListingSearchSection() { - BeatmapListingSearchSection section; + OsuSpriteText query; + OsuSpriteText ruleset; + OsuSpriteText category; Add(section = new BeatmapListingSearchSection { @@ -31,31 +39,52 @@ namespace osu.Game.Tests.Visual.UserInterface Origin = Anchor.Centre, }); - var beatmapSet = new BeatmapSetInfo + Add(new FillFlowContainer { - OnlineInfo = new BeatmapSetOnlineInfo + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] { - Covers = new BeatmapSetOnlineCovers - { - Cover = "https://assets.ppy.sh/beatmaps/1094296/covers/cover@2x.jpg?1581416305" - } + query = new OsuSpriteText(), + ruleset = new OsuSpriteText(), + category = new OsuSpriteText(), } - }; + }); - var noCoverBeatmapSet = new BeatmapSetInfo - { - OnlineInfo = new BeatmapSetOnlineInfo - { - Covers = new BeatmapSetOnlineCovers - { - Cover = string.Empty - } - } - }; + section.Query.BindValueChanged(q => query.Text = $"Query: {q.NewValue}", true); + section.Ruleset.BindValueChanged(r => ruleset.Text = $"Ruleset: {r.NewValue}", true); + section.Category.BindValueChanged(c => category.Text = $"Category: {c.NewValue}", true); + } - AddStep("Set beatmap", () => section.BeatmapSet = beatmapSet); - AddStep("Set beatmap (no cover)", () => section.BeatmapSet = noCoverBeatmapSet); + [Test] + public void TestCovers() + { + AddStep("Set beatmap", () => section.BeatmapSet = beatmap_set); + AddStep("Set beatmap (no cover)", () => section.BeatmapSet = no_cover_beatmap_set); AddStep("Set null beatmap", () => section.BeatmapSet = null); } + + private static BeatmapSetInfo beatmap_set = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = "https://assets.ppy.sh/beatmaps/1094296/covers/cover@2x.jpg?1581416305" + } + } + }; + + private static BeatmapSetInfo no_cover_beatmap_set = new BeatmapSetInfo + { + OnlineInfo = new BeatmapSetOnlineInfo + { + Covers = new BeatmapSetOnlineCovers + { + Cover = string.Empty + } + } + }; } } From 37003e11b98ca1f70215c9e7706b0d6d1d0478c8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Feb 2020 18:04:39 +0300 Subject: [PATCH 042/127] Make fields readonly --- .../UserInterface/TestSceneBeatmapListingSearchSection.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs index 8e9123fe8d..1d8db71527 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneBeatmapListingSearchSection.cs @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.UserInterface AddStep("Set null beatmap", () => section.BeatmapSet = null); } - private static BeatmapSetInfo beatmap_set = new BeatmapSetInfo + private static readonly BeatmapSetInfo beatmap_set = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo { @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.UserInterface } }; - private static BeatmapSetInfo no_cover_beatmap_set = new BeatmapSetInfo + private static readonly BeatmapSetInfo no_cover_beatmap_set = new BeatmapSetInfo { OnlineInfo = new BeatmapSetOnlineInfo { From 5347119a857fa86545dc2231039bd2dc3be6fab7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Feb 2020 21:26:25 +0300 Subject: [PATCH 043/127] Various RankingsOverlay fixes --- .../Rankings/RankingsOverlayHeader.cs | 17 ++++----- osu.Game/Overlays/RankingsOverlay.cs | 38 +++++++++++-------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 2674b3a81e..164585de38 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -11,23 +11,20 @@ namespace osu.Game.Overlays.Rankings { public class RankingsOverlayHeader : TabControlOverlayHeader { - public readonly Bindable Ruleset = new Bindable(); - public readonly Bindable Country = new Bindable(); + public Bindable Ruleset => rulesetSelector.Current; + public Bindable Country => countryFilter.Current; + + private OverlayRulesetSelector rulesetSelector; + private CountryFilter countryFilter; protected override ScreenTitle CreateTitle() => new RankingsTitle { Scope = { BindTarget = Current } }; - protected override Drawable CreateTitleContent() => new OverlayRulesetSelector - { - Current = Ruleset - }; + protected override Drawable CreateTitleContent() => rulesetSelector = new OverlayRulesetSelector(); - protected override Drawable CreateContent() => new CountryFilter - { - Current = Country - }; + protected override Drawable CreateContent() => countryFilter = new CountryFilter(); private class RankingsTitle : ScreenTitle { diff --git a/osu.Game/Overlays/RankingsOverlay.cs b/osu.Game/Overlays/RankingsOverlay.cs index f3215d07fa..2c5ea61315 100644 --- a/osu.Game/Overlays/RankingsOverlay.cs +++ b/osu.Game/Overlays/RankingsOverlay.cs @@ -19,14 +19,17 @@ namespace osu.Game.Overlays { public class RankingsOverlay : FullscreenOverlay { - protected readonly Bindable Country = new Bindable(); - protected readonly Bindable Scope = new Bindable(); - private readonly Bindable ruleset = new Bindable(); + protected Bindable Country => header.Country; + + protected Bindable Scope => header.Current; + + private Bindable ruleset => header.Ruleset; private readonly BasicScrollContainer scrollFlow; private readonly Container contentContainer; private readonly DimmedLoadingLayer loading; private readonly Box background; + private readonly RankingsOverlayHeader header; private APIRequest lastRequest; private CancellationTokenSource cancellationToken; @@ -54,14 +57,11 @@ namespace osu.Game.Overlays Direction = FillDirection.Vertical, Children = new Drawable[] { - new RankingsOverlayHeader + header = new RankingsOverlayHeader { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - Depth = -float.MaxValue, - Country = { BindTarget = Country }, - Current = { BindTarget = Scope }, - Ruleset = { BindTarget = ruleset } + Depth = -float.MaxValue }, new Container { @@ -94,6 +94,8 @@ namespace osu.Game.Overlays protected override void LoadComplete() { + base.LoadComplete(); + Country.BindValueChanged(_ => { // if a country is requested, force performance scope. @@ -101,7 +103,7 @@ namespace osu.Game.Overlays Scope.Value = RankingsScope.Performance; Scheduler.AddOnce(loadNewContent); - }, true); + }); Scope.BindValueChanged(_ => { @@ -110,7 +112,7 @@ namespace osu.Game.Overlays Country.Value = null; Scheduler.AddOnce(loadNewContent); - }, true); + }); ruleset.BindValueChanged(_ => { @@ -118,9 +120,7 @@ namespace osu.Game.Overlays return; Scheduler.AddOnce(loadNewContent); - }, true); - - base.LoadComplete(); + }); } public void ShowCountry(Country requested) @@ -158,8 +158,8 @@ namespace osu.Game.Overlays return; } - request.Success += () => loadContent(createTableFromResponse(request)); - request.Failure += _ => loadContent(null); + request.Success += () => Schedule(() => loadContent(createTableFromResponse(request))); + request.Failure += _ => Schedule(() => loadContent(null)); api.Queue(request); } @@ -221,5 +221,13 @@ namespace osu.Game.Overlays contentContainer.Child = loaded; }, (cancellationToken = new CancellationTokenSource()).Token); } + + protected override void Dispose(bool isDisposing) + { + lastRequest?.Cancel(); + cancellationToken?.Cancel(); + + base.Dispose(isDisposing); + } } } From e9003346d4f538377a613acd2e2dc6fc42ce6bdd Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Tue, 18 Feb 2020 21:28:38 +0300 Subject: [PATCH 044/127] Add missing blank line --- osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs index 164585de38..a89360bd3c 100644 --- a/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs +++ b/osu.Game/Overlays/Rankings/RankingsOverlayHeader.cs @@ -12,6 +12,7 @@ namespace osu.Game.Overlays.Rankings public class RankingsOverlayHeader : TabControlOverlayHeader { public Bindable Ruleset => rulesetSelector.Current; + public Bindable Country => countryFilter.Current; private OverlayRulesetSelector rulesetSelector; From 73e5018696332580c0c4208a4da80610b19b1b35 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 09:39:56 +0900 Subject: [PATCH 045/127] Move radius adjust local to fruit piece --- .../Objects/Drawable/DrawableFruit.cs | 5 ----- osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs | 9 +++++++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 5ab0858f75..0790e0234c 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -16,11 +16,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { private Container scaleContainer; - /// - /// Because we're adding a border around the fruit, we need to scale down some. - /// - public const float RADIUS_ADJUST = 1.1f; - public DrawableFruit(Fruit h) : base(h) { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs index 2b24f25e8b..e4c110802b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs @@ -16,6 +16,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { internal class FruitPiece : CompositeDrawable { + /// + /// Because we're adding a border around the fruit, we need to scale down some. + /// + private const float radius_adjust = 1.1f; + private Circle border; private CatchHitObject hitObject; @@ -44,7 +49,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Anchor = Anchor.Centre, Origin = Anchor.Centre, BorderColour = Color4.White, - BorderThickness = 6f * DrawableFruit.RADIUS_ADJUST, + BorderThickness = 6f * radius_adjust, Children = new Framework.Graphics.Drawable[] { new Box @@ -82,7 +87,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation) { - const float large_pulp_3 = 16f * DrawableFruit.RADIUS_ADJUST; + const float large_pulp_3 = 16f * radius_adjust; const float distance_from_centre_3 = 0.15f; const float large_pulp_4 = large_pulp_3 * 0.925f; From ab863cdfd98c681c1fb0a6c7fdb1b5e2205735a3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 09:52:29 +0900 Subject: [PATCH 046/127] Fix incorrect scaling factor being applied --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 6cb524ca7a..4abb9e61aa 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Catch.Objects TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450); - Scale = 1.0f - 0.7f * (difficulty.CircleSize - 5) / 5; + Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; } protected override HitWindows CreateHitWindows() => HitWindows.Empty; From f245fe59345e5b0b35aad2aadd9351774921dfac Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 10:28:20 +0900 Subject: [PATCH 047/127] Fix catch combo colouring --- .../Objects/Drawable/DrawableFruit.cs | 35 ------------------- .../Objects/Drawable/FruitPiece.cs | 23 ++++++++++-- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 0790e0234c..73ca58fd0a 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Utils; using osu.Game.Skinning; using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -46,8 +45,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } }); - AccentColour.Value = colourForRepresentation(HitObject.VisualRepresentation); - scaleContainer.Scale = new Vector2(HitObject.Scale); } @@ -74,37 +71,5 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable throw new ArgumentOutOfRangeException(nameof(hitObjectVisualRepresentation), hitObjectVisualRepresentation, null); } } - - private Color4 colourForRepresentation(FruitVisualRepresentation representation) - { - switch (representation) - { - default: - case FruitVisualRepresentation.Pear: - return new Color4(17, 136, 170, 255); - - case FruitVisualRepresentation.Grape: - return new Color4(204, 102, 0, 255); - - case FruitVisualRepresentation.Raspberry: - return new Color4(121, 9, 13, 255); - - case FruitVisualRepresentation.Pineapple: - return new Color4(102, 136, 0, 255); - - case FruitVisualRepresentation.Banana: - switch (RNG.Next(0, 3)) - { - default: - return new Color4(255, 240, 0, 255); - - case 1: - return new Color4(255, 192, 0, 255); - - case 2: - return new Color4(214, 221, 28, 255); - } - } - } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs index e4c110802b..4098103569 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs @@ -7,6 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Utils; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using osu.Game.Rulesets.Objects.Drawables; using osuTK; @@ -249,6 +250,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }; case FruitVisualRepresentation.Banana: + + Color4 bananaColour = getBananaColour(); + return new Container { RelativeSizeAxes = Axes.Both, @@ -256,13 +260,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { new Pulp { - AccentColour = accentColour.Value, + AccentColour = bananaColour, Size = new Vector2(small_pulp), Y = -0.3f }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = bananaColour, Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f), Y = 0.05f, }, @@ -270,5 +274,20 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }; } } + + private Color4 getBananaColour() + { + switch (RNG.Next(0, 3)) + { + default: + return new Color4(255, 240, 0, 255); + + case 1: + return new Color4(255, 192, 0, 255); + + case 2: + return new Color4(214, 221, 28, 255); + } + } } } From 0f85e812408884c7d90e325ddb97441febccbccb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 11:23:45 +0900 Subject: [PATCH 048/127] Fix handling of bindable changes in accent colour --- .../Objects/Drawable/DrawableDroplet.cs | 10 ++--- .../Objects/Drawable/DrawableJuiceStream.cs | 5 ++- .../Objects/Drawable/FruitPiece.cs | 43 +++++++++---------- .../Objects/Drawable/Pieces/Pulp.cs | 27 ++++-------- .../Skinning/LegacyFruitPiece.cs | 10 ++++- 5 files changed, 47 insertions(+), 48 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 6f5bcb70cf..94d417961f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -10,8 +10,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableDroplet : PalpableCatchHitObject { - private Pulp pulp; - public override bool StaysOnPlate => false; public DrawableDroplet(Droplet h) @@ -25,9 +23,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable [BackgroundDependencyLoader] private void load() { - AddInternal(pulp = new Pulp { Size = Size }); - - AccentColour.BindValueChanged(colour => { pulp.AccentColour = colour.NewValue; }, true); + AddInternal(new Pulp + { + Size = Size, + AccentColour = { BindTarget = AccentColour } + }); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index a24821b3ce..f76055e1ea 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -42,10 +42,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable switch (hitObject) { case CatchHitObject catchObject: - return createDrawableRepresentation?.Invoke(catchObject)?.With(o => ((DrawableCatchHitObject)o).CheckPosition = p => CheckPosition?.Invoke(p) ?? false); + return createDrawableRepresentation?.Invoke(catchObject)?.With(o => + ((DrawableCatchHitObject)o).CheckPosition = p => CheckPosition?.Invoke(p) ?? false); } - return base.CreateNestedHitObject(hitObject); + return null; } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs index 4098103569..0898c90bc8 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs @@ -56,7 +56,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable new Box { AlwaysPresent = true, - Colour = drawableCatchObject.AccentColour.Value, Alpha = 0, RelativeSizeAxes = Axes.Both } @@ -71,7 +70,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable RelativePositionAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, - AccentColour = Color4.Red, + AccentColour = { Value = Color4.Red }, Blending = BlendingParameters.Additive, Alpha = 0.5f, Scale = new Vector2(1.333f) @@ -113,32 +112,32 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(small_pulp), Y = -0.34f, }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_4), Position = positionAt(0, distance_from_centre_4), }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_4), Position = positionAt(90, distance_from_centre_4), }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_4), Position = positionAt(180, distance_from_centre_4), }, new Pulp { Size = new Vector2(large_pulp_4), - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Position = positionAt(270, distance_from_centre_4), }, } @@ -152,32 +151,32 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(small_pulp), Y = -0.3f, }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_4), Position = positionAt(45, distance_from_centre_4), }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_4), Position = positionAt(135, distance_from_centre_4), }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_4), Position = positionAt(225, distance_from_centre_4), }, new Pulp { Size = new Vector2(large_pulp_4), - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Position = positionAt(315, distance_from_centre_4), }, } @@ -191,26 +190,26 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(small_pulp), Y = -0.33f, }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_3), Position = positionAt(60, distance_from_centre_3), }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_3), Position = positionAt(180, distance_from_centre_3), }, new Pulp { Size = new Vector2(large_pulp_3), - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Position = positionAt(300, distance_from_centre_3), }, } @@ -224,26 +223,26 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(small_pulp), Y = -0.25f, }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_3), Position = positionAt(0, distance_from_centre_3), }, new Pulp { - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_3), Position = positionAt(120, distance_from_centre_3), }, new Pulp { Size = new Vector2(large_pulp_3), - AccentColour = accentColour.Value, + AccentColour = { BindTarget = accentColour }, Position = positionAt(240, distance_from_centre_3), }, } @@ -260,13 +259,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { new Pulp { - AccentColour = bananaColour, + AccentColour = { Value = bananaColour }, Size = new Vector2(small_pulp), Y = -0.3f }, new Pulp { - AccentColour = bananaColour, + AccentColour = { Value = bananaColour }, Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f), Y = 0.05f, }, diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs index 1e9daf18db..517978eb07 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -1,16 +1,16 @@ // 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.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces { - public class Pulp : Circle, IHasAccentColour + public class Pulp : Circle { public Pulp() { @@ -22,32 +22,23 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces Colour = Color4.White.Opacity(0.9f); } - private Color4 accentColour; + public readonly Bindable AccentColour = new Bindable(); - public Color4 AccentColour + protected override void LoadComplete() { - get => accentColour; - set - { - accentColour = value; - if (IsLoaded) updateAccentColour(); - } + base.LoadComplete(); + + AccentColour.BindValueChanged(updateAccentColour, true); } - private void updateAccentColour() + private void updateAccentColour(ValueChangedEvent colour) { EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, Radius = Size.X / 2, - Colour = accentColour.Darken(0.2f).Opacity(0.75f) + Colour = colour.NewValue.Darken(0.2f).Opacity(0.75f) }; } - - protected override void LoadComplete() - { - base.LoadComplete(); - updateAccentColour(); - } } } diff --git a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs index fbe682e512..909db41736 100644 --- a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs @@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Catch.Skinning private readonly string lookupName; private readonly IBindable accentColour = new Bindable(); + private Sprite colouredSprite; public LegacyFruitPiece(string lookupName) { @@ -34,7 +35,7 @@ namespace osu.Game.Rulesets.Catch.Skinning InternalChildren = new Drawable[] { - new Sprite + colouredSprite = new Sprite { Texture = skin.GetTexture(lookupName), Colour = drawableObject.AccentColour.Value, @@ -49,5 +50,12 @@ namespace osu.Game.Rulesets.Catch.Skinning }, }; } + + protected override void LoadComplete() + { + base.LoadComplete(); + + accentColour.BindValueChanged(colour => colouredSprite.Colour = colour.NewValue, true); + } } } From ce1a57550fcaef0572530990b29a97537fd5e2b0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 13:27:15 +0900 Subject: [PATCH 049/127] Add droplet skinning support --- .../CatchSkinComponents.cs | 1 + .../Objects/Drawable/DrawableDroplet.cs | 28 ++++++++++++++++--- .../Objects/Drawable/DrawableTinyDroplet.cs | 2 +- .../Skinning/CatchLegacySkinTransformer.cs | 6 ++++ 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs index f64902b8e5..02c045f363 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs @@ -10,5 +10,6 @@ namespace osu.Game.Rulesets.Catch FruitGrapes, FruitOrange, FruitPear, + Droplet } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 94d417961f..99f0277482 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -3,8 +3,11 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using osu.Game.Skinning; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -16,18 +19,35 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable : base(h) { Origin = Anchor.Centre; - Size = new Vector2(CatchHitObject.OBJECT_RADIUS) / 4; + Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2) / 4; Masking = false; } + private Container scaleContainer; + [BackgroundDependencyLoader] private void load() { - AddInternal(new Pulp + AddRangeInternal(new Framework.Graphics.Drawable[] { - Size = Size, - AccentColour = { BindTarget = AccentColour } + scaleContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + Children = new Framework.Graphics.Drawable[] + { + new SkinnableDrawable( + new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp + { + Size = Size, + AccentColour = { Value = Color4.White } + }) + } + } }); + + scaleContainer.Scale = new Vector2(HitObject.Scale); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs index ab5df5c44c..3f90334727 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableTinyDroplet(TinyDroplet h) : base(h) { - Size = new Vector2(CatchHitObject.OBJECT_RADIUS / 8); + Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2) / 8; } } } diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs index 20bd086199..5db5ca2e03 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -37,6 +37,12 @@ namespace osu.Game.Rulesets.Catch.Skinning return new LegacyFruitPiece(lookupName); break; + + case CatchSkinComponents.Droplet: + if (GetTexture("fruit-drop") != null) + return new LegacyFruitPiece("fruit-drop"); + + break; } return null; From 3eeb60f60f8a4ba228f960bda5af1ca8883d7f3d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 14:31:14 +0900 Subject: [PATCH 050/127] Centralise and fix scaling --- .../Objects/Drawable/DrawableCatchHitObject.cs | 6 ++++-- .../Objects/Drawable/DrawableDroplet.cs | 9 +++------ .../Objects/Drawable/DrawableFruit.cs | 6 ------ .../Objects/Drawable/DrawableTinyDroplet.cs | 9 +++++++-- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index b7c05392f3..bfef1ba605 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -2,11 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using System; -using osuTK; using osu.Framework.Graphics; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; +using osuTK; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -18,7 +18,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected PalpableCatchHitObject(TObject hitObject) : base(hitObject) { - Scale = new Vector2(HitObject.Scale); + Origin = Anchor.Centre; + Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2); + Masking = false; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 99f0277482..e645b17c05 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -18,19 +18,16 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableDroplet(Droplet h) : base(h) { - Origin = Anchor.Centre; - Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2) / 4; - Masking = false; } - private Container scaleContainer; + protected Container ScaleContainer; [BackgroundDependencyLoader] private void load() { AddRangeInternal(new Framework.Graphics.Drawable[] { - scaleContainer = new Container + ScaleContainer = new Container { RelativeSizeAxes = Axes.Both, Origin = Anchor.Centre, @@ -47,7 +44,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } }); - scaleContainer.Scale = new Vector2(HitObject.Scale); + ScaleContainer.Scale = new Vector2(HitObject.Scale); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 73ca58fd0a..2befb5dfd0 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -18,12 +18,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableFruit(Fruit h) : base(h) { - Origin = Anchor.Centre; - - Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2); - - Masking = false; - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs index 3f90334727..4fe1f86f2b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs @@ -1,7 +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 osuTK; +using osu.Framework.Allocation; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -10,7 +10,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableTinyDroplet(TinyDroplet h) : base(h) { - Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2) / 8; + } + + [BackgroundDependencyLoader] + private void load() + { + Scale /= 2; } } } From 24e33abcbf281135415f2e7122c0529fb9c3c8e5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 14:31:32 +0900 Subject: [PATCH 051/127] Fix banana colouring for skins --- .../Objects/Drawable/DrawableBanana.cs | 34 +++++++++++++++++++ .../Objects/Drawable/FruitPiece.cs | 22 ++---------- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs index 5afdb14888..4b4e381efd 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs @@ -1,6 +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 osu.Framework.Bindables; +using osu.Framework.Utils; +using osuTK.Graphics; + namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableBanana : DrawableFruit @@ -9,5 +13,35 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable : base(h) { } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AccentColour.BindValueChanged(accentChanged, true); + } + + private Color4? colour; + + private void accentChanged(ValueChangedEvent obj) + { + // override any external colour changes with banananana + AccentColour.Value = (colour ??= getBananaColour()); + } + + private Color4 getBananaColour() + { + switch (RNG.Next(0, 3)) + { + default: + return new Color4(255, 240, 0, 255); + + case 1: + return new Color4(255, 192, 0, 255); + + case 2: + return new Color4(214, 221, 28, 255); + } + } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs index 0898c90bc8..24f558db78 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs @@ -7,7 +7,6 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Utils; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using osu.Game.Rulesets.Objects.Drawables; using osuTK; @@ -250,8 +249,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable case FruitVisualRepresentation.Banana: - Color4 bananaColour = getBananaColour(); - return new Container { RelativeSizeAxes = Axes.Both, @@ -259,13 +256,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { new Pulp { - AccentColour = { Value = bananaColour }, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(small_pulp), Y = -0.3f }, new Pulp { - AccentColour = { Value = bananaColour }, + AccentColour = { BindTarget = accentColour }, Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f), Y = 0.05f, }, @@ -273,20 +270,5 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }; } } - - private Color4 getBananaColour() - { - switch (RNG.Next(0, 3)) - { - default: - return new Color4(255, 240, 0, 255); - - case 1: - return new Color4(255, 192, 0, 255); - - case 2: - return new Color4(214, 221, 28, 255); - } - } } } From aeb45c8442b34e8ef485ee3d2b5d91befd9d7095 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 14:31:43 +0900 Subject: [PATCH 052/127] Fix ordering of fruits to match stable --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 +- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 4abb9e61aa..02979f8aa0 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -100,8 +100,8 @@ namespace osu.Game.Rulesets.Catch.Objects { Pear, Grape, - Raspberry, Pineapple, + Raspberry, Banana // banananananannaanana } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 2befb5dfd0..edcb5eb13d 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -52,12 +52,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable case FruitVisualRepresentation.Grape: return CatchSkinComponents.FruitGrapes; - case FruitVisualRepresentation.Raspberry: - return CatchSkinComponents.FruitOrange; - case FruitVisualRepresentation.Pineapple: return CatchSkinComponents.FruitApple; + case FruitVisualRepresentation.Raspberry: + return CatchSkinComponents.FruitOrange; + case FruitVisualRepresentation.Banana: return CatchSkinComponents.FruitBananas; From 26fe15b0385ca4403b9a5d08e254c7ec201f0454 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 14:41:25 +0900 Subject: [PATCH 053/127] Fix fruit representation not cycling as often as it should --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 02979f8aa0..f3b566f340 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.Objects public int IndexInBeatmap { get; set; } - public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(ComboIndex % 4); + public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(IndexInBeatmap % 4); public virtual bool NewCombo { get; set; } From 618fb4ccfbaa9de0946813efc852fb9554469f5d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:05:04 +0900 Subject: [PATCH 054/127] Move combo colour update logic to osu! ruleset --- .../Objects/Drawables/DrawableOsuHitObject.cs | 3 +++ .../Rulesets/Objects/Drawables/DrawableHitObject.cs | 12 ++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index a677cb6a72..fcc4c58619 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Graphics.Containers; +using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -54,6 +55,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } + protected override void UpdateComboColour(Color4 comboColour) => AccentColour.Value = comboColour; + protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement); } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 6f20bcf595..306c59e880 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Objects.Drawables if (HitObject is IHasComboInformation combo) { comboIndexBindable = combo.ComboIndexBindable.GetBoundCopy(); - comboIndexBindable.BindValueChanged(_ => updateAccentColour(), true); + comboIndexBindable.BindValueChanged(_ => updateComboColour(), true); } samplesBindable = HitObject.SamplesBindable.GetBoundCopy(); @@ -336,7 +336,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { base.SkinChanged(skin, allowFallback); - updateAccentColour(); + updateComboColour(); ApplySkin(skin, allowFallback); @@ -344,15 +344,19 @@ namespace osu.Game.Rulesets.Objects.Drawables updateState(State.Value, true); } - private void updateAccentColour() + private void updateComboColour() { if (HitObject is IHasComboInformation combo) { var comboColours = CurrentSkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; - AccentColour.Value = comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White; + UpdateComboColour(comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White); } } + protected virtual void UpdateComboColour(Color4 comboColour) + { + } + /// /// Called when a change is made to the skin. /// From fec5c4a73aea7e493afbfc708f656ca214cb0c3c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:16:07 +0900 Subject: [PATCH 055/127] Move combo colour to accent propagation logic to osu! ruleset --- .../Objects/Drawables/DrawableOsuHitObject.cs | 3 ++- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index fcc4c58619..1bb72a3176 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; @@ -55,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } - protected override void UpdateComboColour(Color4 comboColour) => AccentColour.Value = comboColour; + protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) => AccentColour.Value = proposedColour; protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement); } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 306c59e880..c5ce490845 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -349,11 +349,16 @@ namespace osu.Game.Rulesets.Objects.Drawables if (HitObject is IHasComboInformation combo) { var comboColours = CurrentSkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; - UpdateComboColour(comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White); + UpdateComboColour(comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White, comboColours); } } - protected virtual void UpdateComboColour(Color4 comboColour) + /// + /// Called when a combo colour change is proposed. + /// + /// The proposed combo colour, based off the combo index. + /// A list of combo colours provided by the beatmap or skin. Can be null if not available. + protected virtual void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) { } From 3f99d25e37f2eefebda45ff5ac9e43ffdb2866c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:16:19 +0900 Subject: [PATCH 056/127] Use new UpdateComboColour method to simplify colouring --- .../Objects/Drawable/DrawableBanana.cs | 11 ++--------- .../Objects/Drawable/DrawableDroplet.cs | 11 +++++++++-- .../Objects/Drawable/DrawableFruit.cs | 8 ++++++++ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs index 4b4e381efd..8625b93786 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs @@ -1,7 +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.Bindables; +using System.Collections.Generic; using osu.Framework.Utils; using osuTK.Graphics; @@ -14,16 +14,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { } - protected override void LoadComplete() - { - base.LoadComplete(); - - AccentColour.BindValueChanged(accentChanged, true); - } - private Color4? colour; - private void accentChanged(ValueChangedEvent obj) + protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) { // override any external colour changes with banananana AccentColour.Value = (colour ??= getBananaColour()); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index e645b17c05..fc5a8b2938 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,13 +16,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public override bool StaysOnPlate => false; + protected Container ScaleContainer; + public DrawableDroplet(Droplet h) : base(h) { } - protected Container ScaleContainer; - [BackgroundDependencyLoader] private void load() { @@ -46,5 +47,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable ScaleContainer.Scale = new Vector2(HitObject.Scale); } + + protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) + { + // ignore the incoming combo colour as we use a custom lookup + AccentColour.Value = comboColours[HitObject.IndexInBeatmap % comboColours.Count]; + } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index edcb5eb13d..99f7e9386e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -2,12 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Utils; using osu.Game.Skinning; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -42,6 +44,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable scaleContainer.Scale = new Vector2(HitObject.Scale); } + protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) + { + // ignore the incoming combo colour as we use a custom lookup + AccentColour.Value = comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count]; + } + private CatchSkinComponents getComponent(FruitVisualRepresentation hitObjectVisualRepresentation) { switch (hitObjectVisualRepresentation) From 69b5d5606a4d96913817073b9e06541ab10b4125 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:32:24 +0900 Subject: [PATCH 057/127] Fix nested catch objects not having a correct IndexInBeatmap --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index db52fbac1b..1872d71532 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -35,6 +35,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps foreach (var obj in Beatmap.HitObjects.OfType()) { obj.IndexInBeatmap = index++; + foreach (var nested in obj.NestedHitObjects.OfType()) + nested.IndexInBeatmap = obj.IndexInBeatmap; + if (obj.LastInCombo && obj.NestedHitObjects.LastOrDefault() is IHasComboInformation lastNested) lastNested.LastInCombo = true; } From 52615795313a3b90bbb9f82c5c74f0c76a7a25e5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:37:12 +0900 Subject: [PATCH 058/127] Fix indices in beatmap not being transferred to children (and being off by one) --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 6 ++++-- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 1872d71532..1a5d0f983b 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -34,12 +34,14 @@ namespace osu.Game.Rulesets.Catch.Beatmaps foreach (var obj in Beatmap.HitObjects.OfType()) { - obj.IndexInBeatmap = index++; + obj.IndexInBeatmap = index; foreach (var nested in obj.NestedHitObjects.OfType()) - nested.IndexInBeatmap = obj.IndexInBeatmap; + nested.IndexInBeatmap = index; if (obj.LastInCombo && obj.NestedHitObjects.LastOrDefault() is IHasComboInformation lastNested) lastNested.LastInCombo = true; + + index++; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index fc5a8b2938..90ec250e29 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) { // ignore the incoming combo colour as we use a custom lookup - AccentColour.Value = comboColours[HitObject.IndexInBeatmap % comboColours.Count]; + AccentColour.Value = comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count]; } } } From 4c4140ae54752652a40264d5157c93ac011ff8a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:55:22 +0900 Subject: [PATCH 059/127] Adjust droplets to match stable --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs | 2 +- osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 90ec250e29..d0160f8cce 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable new SkinnableDrawable( new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp { - Size = Size, + Size = Size / 4, AccentColour = { Value = Color4.White } }) } diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs index 5db5ca2e03..f8d0880c72 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; using osu.Game.Audio; using osu.Game.Skinning; +using osuTK; namespace osu.Game.Rulesets.Catch.Skinning { @@ -40,7 +41,7 @@ namespace osu.Game.Rulesets.Catch.Skinning case CatchSkinComponents.Droplet: if (GetTexture("fruit-drop") != null) - return new LegacyFruitPiece("fruit-drop"); + return new LegacyFruitPiece("fruit-drop") { Scale = new Vector2(0.8f) }; break; } From afbf3a3a798b22502402f30b385b43ed1d6d72ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:57:15 +0900 Subject: [PATCH 060/127] Fix regressing tests --- osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 17dc27543d..7469771e0b 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -76,6 +76,8 @@ namespace osu.Game.Tests.Gameplay : base(new TestHitObjectWithCombo()) { } + + protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) => AccentColour.Value = proposedColour; } private class TestHitObjectWithCombo : HitObject, IHasComboInformation From 5340d1de59d5d332b55ce1790fceda94c515f79f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:05:04 +0900 Subject: [PATCH 061/127] Move combo colour update logic to osu! ruleset --- .../Objects/Drawables/DrawableOsuHitObject.cs | 4 ++++ .../Objects/Drawables/DrawableHitObject.cs | 17 +++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index a677cb6a72..1bb72a3176 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -1,11 +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.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Graphics.Containers; +using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -54,6 +56,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } + protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) => AccentColour.Value = proposedColour; + protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement); } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 6f20bcf595..c5ce490845 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -121,7 +121,7 @@ namespace osu.Game.Rulesets.Objects.Drawables if (HitObject is IHasComboInformation combo) { comboIndexBindable = combo.ComboIndexBindable.GetBoundCopy(); - comboIndexBindable.BindValueChanged(_ => updateAccentColour(), true); + comboIndexBindable.BindValueChanged(_ => updateComboColour(), true); } samplesBindable = HitObject.SamplesBindable.GetBoundCopy(); @@ -336,7 +336,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { base.SkinChanged(skin, allowFallback); - updateAccentColour(); + updateComboColour(); ApplySkin(skin, allowFallback); @@ -344,15 +344,24 @@ namespace osu.Game.Rulesets.Objects.Drawables updateState(State.Value, true); } - private void updateAccentColour() + private void updateComboColour() { if (HitObject is IHasComboInformation combo) { var comboColours = CurrentSkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; - AccentColour.Value = comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White; + UpdateComboColour(comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White, comboColours); } } + /// + /// Called when a combo colour change is proposed. + /// + /// The proposed combo colour, based off the combo index. + /// A list of combo colours provided by the beatmap or skin. Can be null if not available. + protected virtual void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) + { + } + /// /// Called when a change is made to the skin. /// From 345eaff76ddadab913eba031eba6c744ac06f694 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:57:15 +0900 Subject: [PATCH 062/127] Fix regressing tests --- osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 17dc27543d..7469771e0b 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -76,6 +76,8 @@ namespace osu.Game.Tests.Gameplay : base(new TestHitObjectWithCombo()) { } + + protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) => AccentColour.Value = proposedColour; } private class TestHitObjectWithCombo : HitObject, IHasComboInformation From 14ebcc95fbf0f34383f8c3b39b0f59aa087e64d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 16:33:49 +0900 Subject: [PATCH 063/127] Fix test scene dynamic compilation --- osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs index 51c821a1e8..b106ee2f77 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs @@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Catch.Tests { typeof(CatchHitObject), typeof(Fruit), + typeof(FruitPiece), typeof(Droplet), typeof(Banana), typeof(BananaShower), From 1938dd04cf320b556663c1c1f904eaa30fa759cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 15:37:12 +0900 Subject: [PATCH 064/127] Fix indices in beatmap not being transferred to children (and being off by one) --- osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index db52fbac1b..1a5d0f983b 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -34,9 +34,14 @@ namespace osu.Game.Rulesets.Catch.Beatmaps foreach (var obj in Beatmap.HitObjects.OfType()) { - obj.IndexInBeatmap = index++; + obj.IndexInBeatmap = index; + foreach (var nested in obj.NestedHitObjects.OfType()) + nested.IndexInBeatmap = index; + if (obj.LastInCombo && obj.NestedHitObjects.LastOrDefault() is IHasComboInformation lastNested) lastNested.LastInCombo = true; + + index++; } } From dff218afd1f9c5b28ae9375fec288b529a5d4759 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 14:31:43 +0900 Subject: [PATCH 065/127] Fix ordering of fruits to match stable --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index e4ad49ea50..e287797137 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -100,8 +100,8 @@ namespace osu.Game.Rulesets.Catch.Objects { Pear, Grape, - Raspberry, Pineapple, + Raspberry, Banana // banananananannaanana } } From d3844f912abd7b88b3391c1190422851b04dbb5c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 14:41:25 +0900 Subject: [PATCH 066/127] Fix fruit representation not cycling as often as it should --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index e287797137..5243091625 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.Objects public int IndexInBeatmap { get; set; } - public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(ComboIndex % 4); + public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(IndexInBeatmap % 4); public virtual bool NewCombo { get; set; } From e1140d7c91a26ba1e462b119fe9d1c1441d54337 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 17:28:40 +0900 Subject: [PATCH 067/127] Fix caught fruit radius being incorrect due to moved scale --- .../Drawable/DrawableCatchHitObject.cs | 30 ++++++++++++++++ .../Objects/Drawable/DrawableDroplet.cs | 36 +++---------------- .../Objects/Drawable/DrawableFruit.cs | 31 ++-------------- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 8 ++--- 4 files changed, 41 insertions(+), 64 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index bfef1ba605..188de6a6ae 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -2,11 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osuTK; +using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -15,6 +19,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public override bool CanBePlated => true; + protected Container ScaleContainer; + protected PalpableCatchHitObject(TObject hitObject) : base(hitObject) { @@ -22,6 +28,28 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2); Masking = false; } + + [BackgroundDependencyLoader] + private void load() + { + AddRangeInternal(new Framework.Graphics.Drawable[] + { + ScaleContainer = new Container + { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.Centre, + Anchor = Anchor.Centre, + } + }); + + ScaleContainer.Scale = new Vector2(HitObject.Scale); + } + + protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) + { + // ignore the incoming combo colour as we use a custom lookup + AccentColour.Value = comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count]; + } } public abstract class DrawableCatchHitObject : DrawableCatchHitObject @@ -43,6 +71,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public virtual bool StaysOnPlate => CanBePlated; + public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale; + protected DrawableCatchHitObject(CatchHitObject hitObject) : base(hitObject) { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index d0160f8cce..4e8faed091 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -1,13 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using osu.Game.Skinning; -using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable @@ -16,8 +12,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public override bool StaysOnPlate => false; - protected Container ScaleContainer; - public DrawableDroplet(Droplet h) : base(h) { @@ -26,32 +20,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable [BackgroundDependencyLoader] private void load() { - AddRangeInternal(new Framework.Graphics.Drawable[] - { - ScaleContainer = new Container + ScaleContainer.Child = new SkinnableDrawable( + new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp { - RelativeSizeAxes = Axes.Both, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Children = new Framework.Graphics.Drawable[] - { - new SkinnableDrawable( - new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp - { - Size = Size / 4, - AccentColour = { Value = Color4.White } - }) - } - } - }); - - ScaleContainer.Scale = new Vector2(HitObject.Scale); - } - - protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) - { - // ignore the incoming combo colour as we use a custom lookup - AccentColour.Value = comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count]; + Size = Size / 4, + AccentColour = { Value = Color4.White } + }); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 99f7e9386e..daa84f1057 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -2,21 +2,14 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Utils; using osu.Game.Skinning; -using osuTK; -using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableFruit : PalpableCatchHitObject { - private Container scaleContainer; - public DrawableFruit(Fruit h) : base(h) { @@ -26,28 +19,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable [BackgroundDependencyLoader] private void load() { - AddRangeInternal(new Framework.Graphics.Drawable[] - { - scaleContainer = new Container - { - RelativeSizeAxes = Axes.Both, - Origin = Anchor.Centre, - Anchor = Anchor.Centre, - Children = new Framework.Graphics.Drawable[] - { - new SkinnableDrawable( - new CatchSkinComponent(getComponent(HitObject.VisualRepresentation)), _ => new FruitPiece()) - } - } - }); - - scaleContainer.Scale = new Vector2(HitObject.Scale); - } - - protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) - { - // ignore the incoming combo colour as we use a custom lookup - AccentColour.Value = comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count]; + ScaleContainer.Child = new SkinnableDrawable( + new CatchSkinComponent(getComponent(HitObject.VisualRepresentation)), _ => new FruitPiece()); } private CatchSkinComponents getComponent(FruitVisualRepresentation hitObjectVisualRepresentation) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 1ad12dc4ad..9ded0ff891 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -74,11 +74,11 @@ namespace osu.Game.Rulesets.Catch.UI caughtFruit.Anchor = Anchor.TopCentre; caughtFruit.Origin = Anchor.Centre; - caughtFruit.Scale *= 0.7f; + caughtFruit.Scale *= 0.5f; caughtFruit.LifetimeStart = caughtFruit.HitObject.StartTime; caughtFruit.LifetimeEnd = double.MaxValue; - MovableCatcher.Add(caughtFruit); + MovableCatcher.PlaceOnPlate(caughtFruit); lastPlateableFruit = caughtFruit; if (!fruit.StaysOnPlate) @@ -221,9 +221,9 @@ namespace osu.Game.Rulesets.Catch.UI /// Add a caught fruit to the catcher's stack. /// /// The fruit that was caught. - public void Add(DrawableHitObject fruit) + public void PlaceOnPlate(DrawableHitObject fruit) { - float ourRadius = fruit.DrawSize.X / 2 * fruit.Scale.X; + float ourRadius = ((DrawableCatchHitObject)fruit).DisplayRadius; float theirRadius = 0; const float allowance = 6; From e3d37b808d6dad9f2a6916a3632d56970e11e320 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Feb 2020 17:33:09 +0900 Subject: [PATCH 068/127] Move overlined displays to a higher namespace --- .../Visual/Multiplayer/TestSceneOverlinedParticipants.cs | 2 +- .../Visual/Multiplayer/TestSceneOverlinedPlaylist.cs | 2 +- .../Screens/Multi/{Match => }/Components/OverlinedDisplay.cs | 2 +- .../Multi/{Match => }/Components/OverlinedParticipants.cs | 3 +-- .../Screens/Multi/{Match => }/Components/OverlinedPlaylist.cs | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) rename osu.Game/Screens/Multi/{Match => }/Components/OverlinedDisplay.cs (98%) rename osu.Game/Screens/Multi/{Match => }/Components/OverlinedParticipants.cs (90%) rename osu.Game/Screens/Multi/{Match => }/Components/OverlinedPlaylist.cs (95%) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs index e07ebc1454..575602d787 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs @@ -3,7 +3,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Screens.Multi.Components; using osuTK; namespace osu.Game.Tests.Visual.Multiplayer diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs index cf4897be50..4e38f6d2c2 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs @@ -5,7 +5,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets.Osu; -using osu.Game.Screens.Multi.Match.Components; +using osu.Game.Screens.Multi.Components; using osu.Game.Tests.Beatmaps; using osuTK; diff --git a/osu.Game/Screens/Multi/Match/Components/OverlinedDisplay.cs b/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs similarity index 98% rename from osu.Game/Screens/Multi/Match/Components/OverlinedDisplay.cs rename to osu.Game/Screens/Multi/Components/OverlinedDisplay.cs index 854877bd1c..844337aed4 100644 --- a/osu.Game/Screens/Multi/Match/Components/OverlinedDisplay.cs +++ b/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs @@ -9,7 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osuTK; -namespace osu.Game.Screens.Multi.Match.Components +namespace osu.Game.Screens.Multi.Components { public abstract class OverlinedDisplay : MultiplayerComposite { diff --git a/osu.Game/Screens/Multi/Match/Components/OverlinedParticipants.cs b/osu.Game/Screens/Multi/Components/OverlinedParticipants.cs similarity index 90% rename from osu.Game/Screens/Multi/Match/Components/OverlinedParticipants.cs rename to osu.Game/Screens/Multi/Components/OverlinedParticipants.cs index 7a4290a9a1..fbf2bb91c5 100644 --- a/osu.Game/Screens/Multi/Match/Components/OverlinedParticipants.cs +++ b/osu.Game/Screens/Multi/Components/OverlinedParticipants.cs @@ -3,9 +3,8 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Game.Screens.Multi.Components; -namespace osu.Game.Screens.Multi.Match.Components +namespace osu.Game.Screens.Multi.Components { public class OverlinedParticipants : OverlinedDisplay { diff --git a/osu.Game/Screens/Multi/Match/Components/OverlinedPlaylist.cs b/osu.Game/Screens/Multi/Components/OverlinedPlaylist.cs similarity index 95% rename from osu.Game/Screens/Multi/Match/Components/OverlinedPlaylist.cs rename to osu.Game/Screens/Multi/Components/OverlinedPlaylist.cs index eea85d9d64..4fe79b40a0 100644 --- a/osu.Game/Screens/Multi/Match/Components/OverlinedPlaylist.cs +++ b/osu.Game/Screens/Multi/Components/OverlinedPlaylist.cs @@ -6,7 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.Multiplayer; -namespace osu.Game.Screens.Multi.Match.Components +namespace osu.Game.Screens.Multi.Components { public class OverlinedPlaylist : OverlinedDisplay { From 380d200b46e417db260bb5ca3613dfb107c9615b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Feb 2020 17:34:47 +0900 Subject: [PATCH 069/127] Allow different sizing modes for OverlinedDisplay --- .../Multi/Components/OverlinedDisplay.cs | 59 ++++++++++++++----- .../Screens/Multi/Match/MatchSubScreen.cs | 3 +- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs b/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs index 844337aed4..600fa99a9a 100644 --- a/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs +++ b/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs @@ -15,6 +15,26 @@ namespace osu.Game.Screens.Multi.Components { protected readonly Container Content; + public override Axes RelativeSizeAxes + { + get => base.RelativeSizeAxes; + set + { + base.RelativeSizeAxes = value; + updateDimensions(); + } + } + + public override Axes AutoSizeAxes + { + get => base.AutoSizeAxes; + protected set + { + base.AutoSizeAxes = value; + updateDimensions(); + } + } + protected string Details { set => details.Text = value; @@ -22,14 +42,12 @@ namespace osu.Game.Screens.Multi.Components private readonly Circle line; private readonly OsuSpriteText details; + private readonly GridContainer grid; protected OverlinedDisplay(string title) { - RelativeSizeAxes = Axes.Both; - - InternalChild = new GridContainer + InternalChild = grid = new GridContainer { - RelativeSizeAxes = Axes.Both, Content = new[] { new Drawable[] @@ -62,19 +80,12 @@ namespace osu.Game.Screens.Multi.Components }, new Drawable[] { - Content = new Container - { - Margin = new MarginPadding { Top = 5 }, - RelativeSizeAxes = Axes.Both - } + Content = new Container { Margin = new MarginPadding { Top = 5 } } } - }, - RowDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), } }; + + updateDimensions(); } [BackgroundDependencyLoader] @@ -83,5 +94,25 @@ namespace osu.Game.Screens.Multi.Components line.Colour = colours.Yellow; details.Colour = colours.Yellow; } + + private void updateDimensions() + { + grid.RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(AutoSizeAxes.HasFlag(Axes.Y) ? GridSizeMode.AutoSize : GridSizeMode.Distributed), + }; + + grid.AutoSizeAxes = Axes.None; + grid.RelativeSizeAxes = Axes.None; + grid.AutoSizeAxes = AutoSizeAxes; + grid.RelativeSizeAxes = ~AutoSizeAxes; + + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.None; + Content.AutoSizeAxes = grid.AutoSizeAxes; + Content.RelativeSizeAxes = grid.RelativeSizeAxes; + } } } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index a8630b79b1..caa88a06e0 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -114,7 +114,7 @@ namespace osu.Game.Screens.Multi.Match { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 5 }, - Child = new OverlinedParticipants() + Child = new OverlinedParticipants { RelativeSizeAxes = Axes.Both } }, new Container { @@ -122,6 +122,7 @@ namespace osu.Game.Screens.Multi.Match Padding = new MarginPadding { Horizontal = 5 }, Child = new OverlinedPlaylist(true) // Temporarily always allow selection { + RelativeSizeAxes = Axes.Both, SelectedItem = { BindTarget = SelectedItem } } }, From ec73e8f0c717e6baf11367a6b7ba4291652a958a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Feb 2020 17:37:01 +0900 Subject: [PATCH 070/127] Allow different sizing modes for OverlinedParticipants --- .../TestSceneOverlinedParticipants.cs | 42 ++++++++++++++++--- .../Graphics/Containers/OsuScrollContainer.cs | 7 ++-- .../Multi/Components/OverlinedParticipants.cs | 32 +++++++++++++- .../Multi/Components/ParticipantsList.cs | 41 ++++++++++++------ .../Multi/Lounge/Components/RoomInspector.cs | 11 ++++- .../Screens/Multi/Match/MatchSubScreen.cs | 2 +- 6 files changed, 110 insertions(+), 25 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs index 575602d787..1fc258a225 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedParticipants.cs @@ -1,8 +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.Collections.Generic; +using NUnit.Framework; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Game.Screens.Multi.Components; using osuTK; @@ -10,18 +12,46 @@ namespace osu.Game.Tests.Visual.Multiplayer { public class TestSceneOverlinedParticipants : MultiplayerTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(OverlinedParticipants), + typeof(OverlinedDisplay), + typeof(ParticipantsList) + }; + protected override bool UseOnlineAPI => true; public TestSceneOverlinedParticipants() { Room.RoomID.Value = 7; + } - Add(new Container + [Test] + public void TestHorizontalLayout() + { + AddStep("create component", () => { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(500), - Child = new OverlinedParticipants() + Child = new OverlinedParticipants(Direction.Horizontal) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 500, + AutoSizeAxes = Axes.Y, + }; + }); + } + + [Test] + public void TestVerticalLayout() + { + AddStep("create component", () => + { + Child = new OverlinedParticipants(Direction.Vertical) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(500) + }; }); } } diff --git a/osu.Game/Graphics/Containers/OsuScrollContainer.cs b/osu.Game/Graphics/Containers/OsuScrollContainer.cs index 6d531887ed..1824fcd878 100644 --- a/osu.Game/Graphics/Containers/OsuScrollContainer.cs +++ b/osu.Game/Graphics/Containers/OsuScrollContainer.cs @@ -14,6 +14,9 @@ namespace osu.Game.Graphics.Containers { public class OsuScrollContainer : ScrollContainer { + public const float SCROLL_BAR_HEIGHT = 10; + public const float SCROLL_BAR_PADDING = 3; + /// /// Allows controlling the scroll bar from any position in the container using the right mouse button. /// Uses the value of to smoothly scroll to the dragged location. @@ -96,8 +99,6 @@ namespace osu.Game.Graphics.Containers protected class OsuScrollbar : ScrollbarContainer { - private const float dim_size = 10; - private Color4 hoverColour; private Color4 defaultColour; private Color4 highlightColour; @@ -135,7 +136,7 @@ namespace osu.Game.Graphics.Containers public override void ResizeTo(float val, int duration = 0, Easing easing = Easing.None) { - Vector2 size = new Vector2(dim_size) + Vector2 size = new Vector2(SCROLL_BAR_HEIGHT) { [(int)ScrollDirection] = val }; diff --git a/osu.Game/Screens/Multi/Components/OverlinedParticipants.cs b/osu.Game/Screens/Multi/Components/OverlinedParticipants.cs index fbf2bb91c5..a709c6a57a 100644 --- a/osu.Game/Screens/Multi/Components/OverlinedParticipants.cs +++ b/osu.Game/Screens/Multi/Components/OverlinedParticipants.cs @@ -3,15 +3,43 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Multi.Components { public class OverlinedParticipants : OverlinedDisplay { - public OverlinedParticipants() + public new Axes AutoSizeAxes + { + get => base.AutoSizeAxes; + set => base.AutoSizeAxes = value; + } + + public OverlinedParticipants(Direction direction) : base("Participants") { - Content.Add(new ParticipantsList { RelativeSizeAxes = Axes.Both }); + OsuScrollContainer scroll; + ParticipantsList list; + + Content.Add(scroll = new OsuScrollContainer(direction) + { + Child = list = new ParticipantsList() + }); + + switch (direction) + { + case Direction.Horizontal: + scroll.RelativeSizeAxes = Axes.X; + scroll.Height = ParticipantsList.TILE_SIZE + OsuScrollContainer.SCROLL_BAR_HEIGHT + OsuScrollContainer.SCROLL_BAR_PADDING * 2; + list.AutoSizeAxes = Axes.Both; + break; + + case Direction.Vertical: + scroll.RelativeSizeAxes = Axes.Both; + list.RelativeSizeAxes = Axes.X; + list.AutoSizeAxes = Axes.Y; + break; + } } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Components/ParticipantsList.cs b/osu.Game/Screens/Multi/Components/ParticipantsList.cs index 2ef36b2795..81d530ce68 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantsList.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantsList.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Users; @@ -19,21 +18,39 @@ namespace osu.Game.Screens.Multi.Components { public class ParticipantsList : MultiplayerComposite { + public const float TILE_SIZE = 70; + + public override Axes RelativeSizeAxes + { + get => base.RelativeSizeAxes; + set + { + base.RelativeSizeAxes = value; + fill.RelativeSizeAxes = value; + } + } + + public new Axes AutoSizeAxes + { + get => base.AutoSizeAxes; + set + { + base.AutoSizeAxes = value; + fill.AutoSizeAxes = value; + } + } + + public FillDirection Direction + { + get => fill.Direction; + set => fill.Direction = value; + } + private readonly FillFlowContainer fill; public ParticipantsList() { - InternalChild = new OsuScrollContainer - { - RelativeSizeAxes = Axes.Both, - Child = fill = new FillFlowContainer - { - Spacing = new Vector2(10), - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Full, - } - }; + InternalChild = fill = new FillFlowContainer { Spacing = new Vector2(10) }; } [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index cb6bbf6731..b86495784a 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Components; @@ -157,7 +158,15 @@ namespace osu.Game.Screens.Multi.Lounge.Components { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Horizontal = 10 }, - Child = new ParticipantsList { RelativeSizeAxes = Axes.Both } + Child = new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + Child = new ParticipantsList + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y + } + } } } } diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index caa88a06e0..422aeb3298 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -114,7 +114,7 @@ namespace osu.Game.Screens.Multi.Match { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 5 }, - Child = new OverlinedParticipants { RelativeSizeAxes = Axes.Both } + Child = new OverlinedParticipants(Direction.Vertical) { RelativeSizeAxes = Axes.Both } }, new Container { From ac416ae743b825705baf45608b40b0bfb34225e9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Feb 2020 17:47:59 +0900 Subject: [PATCH 071/127] Implement new room inspector redesign --- .../Multiplayer/TestSceneLoungeRoomInfo.cs | 59 +++++ .../Multi/Lounge/Components/RoomInfo.cs | 89 ++++++++ .../Multi/Lounge/Components/RoomInspector.cs | 203 +++--------------- 3 files changed, 176 insertions(+), 175 deletions(-) create mode 100644 osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomInfo.cs create mode 100644 osu.Game/Screens/Multi/Lounge/Components/RoomInfo.cs diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomInfo.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomInfo.cs new file mode 100644 index 0000000000..1e1bc9725c --- /dev/null +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneLoungeRoomInfo.cs @@ -0,0 +1,59 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Online.Multiplayer; +using osu.Game.Online.Multiplayer.RoomStatuses; +using osu.Game.Screens.Multi.Lounge.Components; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.Multiplayer +{ + public class TestSceneLoungeRoomInfo : MultiplayerTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(RoomInfo) + }; + + [SetUp] + public void Setup() => Schedule(() => + { + Room.CopyFrom(new Room()); + + Child = new RoomInfo + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 500 + }; + }); + + public override void SetUpSteps() + { + // Todo: Temp + } + + [Test] + public void TestNonSelectedRoom() + { + AddStep("set null room", () => Room.RoomID.Value = null); + } + + [Test] + public void TestOpenRoom() + { + AddStep("set open room", () => + { + Room.RoomID.Value = 0; + Room.Name.Value = "Room 0"; + Room.Host.Value = new User { Username = "peppy", Id = 2 }; + Room.EndDate.Value = DateTimeOffset.Now.AddMonths(1); + Room.Status.Value = new RoomStatusOpen(); + }); + } + } +} diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInfo.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInfo.cs new file mode 100644 index 0000000000..02f2667802 --- /dev/null +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInfo.cs @@ -0,0 +1,89 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Screens.Multi.Components; +using osuTK; + +namespace osu.Game.Screens.Multi.Lounge.Components +{ + public class RoomInfo : MultiplayerComposite + { + private readonly List statusElements = new List(); + private readonly SpriteText roomName; + + public RoomInfo() + { + AutoSizeAxes = Axes.Y; + + RoomStatusInfo statusInfo; + ModeTypeInfo typeInfo; + ParticipantInfo participantInfo; + + InternalChild = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 4), + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Children = new Drawable[] + { + roomName = new OsuSpriteText { Font = OsuFont.GetFont(size: 30) }, + statusInfo = new RoomStatusInfo(), + } + }, + typeInfo = new ModeTypeInfo + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight + } + } + }, + participantInfo = new ParticipantInfo(), + } + }; + + statusElements.AddRange(new Drawable[] { statusInfo, typeInfo, participantInfo }); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (RoomID.Value == null) + statusElements.ForEach(e => e.FadeOut()); + + RoomID.BindValueChanged(id => + { + if (id.NewValue == null) + statusElements.ForEach(e => e.FadeOut(100)); + else + statusElements.ForEach(e => e.FadeIn(100)); + }, true); + + RoomName.BindValueChanged(name => + { + roomName.Text = name.NewValue ?? "No room selected"; + }, true); + } + } +} diff --git a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs index b86495784a..891853dee5 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/RoomInspector.cs @@ -2,19 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using osu.Game.Online.Multiplayer; using osu.Game.Screens.Multi.Components; -using osuTK; using osuTK.Graphics; namespace osu.Game.Screens.Multi.Lounge.Components @@ -25,16 +18,9 @@ namespace osu.Game.Screens.Multi.Lounge.Components private readonly MarginPadding contentPadding = new MarginPadding { Horizontal = 20, Vertical = 10 }; - private ParticipantCountDisplay participantCount; - private OsuSpriteText name; - private BeatmapTypeInfo beatmapTypeInfo; - private ParticipantInfo participantInfo; - [Resolved] private BeatmapManager beatmaps { get; set; } - private readonly Bindable status = new Bindable(new RoomStatusNoneSelected()); - [BackgroundDependencyLoader] private void load(OsuColour colours) { @@ -43,185 +29,52 @@ namespace osu.Game.Screens.Multi.Lounge.Components new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"343138"), + Colour = Color4.Black, + Alpha = 0.25f }, - new GridContainer + new Container { RelativeSizeAxes = Axes.Both, - RowDimensions = new[] + Padding = new MarginPadding { Horizontal = 30 }, + Child = new GridContainer { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Distributed), - }, - Content = new[] - { - new Drawable[] + RelativeSizeAxes = Axes.Both, + Content = new[] { - new FillFlowContainer + new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Children = new Drawable[] + new FillFlowContainer { - new Container + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - Height = 200, - Masking = true, - Children = new Drawable[] + new RoomInfo { - new MultiplayerBackgroundSprite { RelativeSizeAxes = Axes.Both }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.5f), Color4.Black.Opacity(0)), - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding(20), - Children = new Drawable[] - { - participantCount = new ParticipantCountDisplay - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - }, - name = new OsuSpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Font = OsuFont.GetFont(size: 30), - Current = RoomName - }, - }, - }, + RelativeSizeAxes = Axes.X, + Margin = new MarginPadding { Vertical = 60 }, }, - }, - new StatusColouredContainer(transition_duration) - { - RelativeSizeAxes = Axes.X, - Height = 5, - Child = new Box { RelativeSizeAxes = Axes.Both } - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + new OverlinedParticipants(Direction.Horizontal) { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"28242d"), - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - LayoutDuration = transition_duration, - Padding = contentPadding, - Spacing = new Vector2(0f, 5f), - Children = new Drawable[] - { - new StatusColouredContainer(transition_duration) - { - AutoSizeAxes = Axes.Both, - Child = new StatusText - { - Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 14), - } - }, - beatmapTypeInfo = new BeatmapTypeInfo(), - }, - }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y }, - }, - new Container - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = contentPadding, - Children = new Drawable[] - { - participantInfo = new ParticipantInfo(), - }, - }, - }, - }, - }, - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Horizontal = 10 }, - Child = new OsuScrollContainer - { - RelativeSizeAxes = Axes.Both, - Child = new ParticipantsList - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y } } - } + }, + new Drawable[] + { + new OverlinedPlaylist(false) { RelativeSizeAxes = Axes.Both }, + }, + }, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), } } } }; - - Status.BindValueChanged(_ => updateStatus(), true); - RoomID.BindValueChanged(_ => updateStatus(), true); - } - - protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) - { - var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); - dependencies.CacheAs(status, new CacheInfo(nameof(Room.Status), typeof(Room))); - return dependencies; - } - - private void updateStatus() - { - if (RoomID.Value == null) - { - status.Value = new RoomStatusNoneSelected(); - - participantCount.FadeOut(transition_duration); - beatmapTypeInfo.FadeOut(transition_duration); - name.FadeOut(transition_duration); - participantInfo.FadeOut(transition_duration); - } - else - { - status.Value = Status.Value; - - participantCount.FadeIn(transition_duration); - beatmapTypeInfo.FadeIn(transition_duration); - name.FadeIn(transition_duration); - participantInfo.FadeIn(transition_duration); - } - } - - private class RoomStatusNoneSelected : RoomStatus - { - public override string Message => @"No Room Selected"; - public override Color4 GetAppropriateColour(OsuColour colours) => colours.Gray8; - } - - private class StatusText : OsuSpriteText - { - [Resolved(typeof(Room), nameof(Room.Status))] - private Bindable status { get; set; } - - [BackgroundDependencyLoader] - private void load() - { - status.BindValueChanged(s => Text = s.NewValue.Message, true); - } } } } From 7b27f6b37829e98a6643e737227eb0616032aa2b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 17:55:40 +0900 Subject: [PATCH 072/127] Add droplet rotation animation --- .../Objects/Drawable/DrawableDroplet.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 4e8faed091..b7a097eb71 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -2,6 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Utils; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using osu.Game.Skinning; using osuTK.Graphics; @@ -27,5 +29,16 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable AccentColour = { Value = Color4.White } }); } + + protected override void UpdateInitialTransforms() + { + base.UpdateInitialTransforms(); + + // roughly matches osu-stable + float startRotation = RNG.NextSingle() * 20; + double duration = HitObject.TimePreempt + 2000; + + this.RotateTo(startRotation).RotateTo(startRotation + 720, duration); + } } } From ea0bbd29260f6db326d1ad44aa8acaaa42197f02 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 18:01:59 +0900 Subject: [PATCH 073/127] Rename drawable namespace to avoid clashes with framework class --- .../TestSceneBananaShower.cs | 2 +- .../TestSceneDrawableHitObjects.cs | 2 +- .../TestSceneFruitObjects.cs | 4 ++-- osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs | 2 +- .../{Drawable => Drawables}/DrawableBanana.cs | 2 +- .../DrawableBananaShower.cs | 2 +- .../DrawableCatchHitObject.cs | 4 ++-- .../{Drawable => Drawables}/DrawableDroplet.cs | 4 ++-- .../{Drawable => Drawables}/DrawableFruit.cs | 2 +- .../DrawableJuiceStream.cs | 2 +- .../DrawableTinyDroplet.cs | 2 +- .../{Drawable => Drawables}/FruitPiece.cs | 18 +++++++++--------- .../{Drawable => Drawables}/Pieces/Pulp.cs | 2 +- .../Skinning/LegacyFruitPiece.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 2 +- .../UI/DrawableCatchRuleset.cs | 2 +- 17 files changed, 28 insertions(+), 28 deletions(-) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/DrawableBanana.cs (95%) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/DrawableBananaShower.cs (97%) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/DrawableCatchHitObject.cs (97%) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/DrawableDroplet.cs (88%) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/DrawableFruit.cs (96%) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/DrawableJuiceStream.cs (97%) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/DrawableTinyDroplet.cs (89%) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/FruitPiece.cs (94%) rename osu.Game.Rulesets.Catch/Objects/{Drawable => Drawables}/Pieces/Pulp.cs (95%) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs index 0ad72412fc..56e378d19e 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using NUnit.Framework; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.UI; using osu.Game.Tests.Visual; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs index 1eb913e900..070847c0c1 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs @@ -10,7 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs index b106ee2f77..b65313edf5 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs @@ -6,8 +6,8 @@ using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Catch.Objects.Drawable; -using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using osu.Game.Rulesets.Catch.Objects.Drawables; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; using osu.Game.Tests.Visual; using osuTK; diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs index 606a935229..ee88edbea1 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs @@ -3,7 +3,7 @@ using System.Linq; using osu.Framework.Graphics; -using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs similarity index 95% rename from osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs index 8625b93786..60e4ff8946 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using osu.Framework.Utils; using osuTK.Graphics; -namespace osu.Game.Rulesets.Catch.Objects.Drawable +namespace osu.Game.Rulesets.Catch.Objects.Drawables { public class DrawableBanana : DrawableFruit { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs similarity index 97% rename from osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs index ea415e18fa..4ce80aceb8 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBananaShower.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; -namespace osu.Game.Rulesets.Catch.Objects.Drawable +namespace osu.Game.Rulesets.Catch.Objects.Drawables { public class DrawableBananaShower : DrawableCatchHitObject { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs similarity index 97% rename from osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs index 188de6a6ae..dcf9405e2e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableCatchHitObject.cs @@ -12,7 +12,7 @@ using osu.Game.Rulesets.Scoring; using osuTK; using osuTK.Graphics; -namespace osu.Game.Rulesets.Catch.Objects.Drawable +namespace osu.Game.Rulesets.Catch.Objects.Drawables { public abstract class PalpableCatchHitObject : DrawableCatchHitObject where TObject : CatchHitObject @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable [BackgroundDependencyLoader] private void load() { - AddRangeInternal(new Framework.Graphics.Drawable[] + AddRangeInternal(new Drawable[] { ScaleContainer = new Container { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs similarity index 88% rename from osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs index 4e8faed091..bfa63b503e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs @@ -2,11 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; using osu.Game.Skinning; using osuTK.Graphics; -namespace osu.Game.Rulesets.Catch.Objects.Drawable +namespace osu.Game.Rulesets.Catch.Objects.Drawables { public class DrawableDroplet : PalpableCatchHitObject { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs similarity index 96% rename from osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs index daa84f1057..197ad41247 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs @@ -6,7 +6,7 @@ using osu.Framework.Allocation; using osu.Framework.Utils; using osu.Game.Skinning; -namespace osu.Game.Rulesets.Catch.Objects.Drawable +namespace osu.Game.Rulesets.Catch.Objects.Drawables { public class DrawableFruit : PalpableCatchHitObject { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs similarity index 97% rename from osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs index f76055e1ea..1399539cdd 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableJuiceStream.cs @@ -7,7 +7,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; -namespace osu.Game.Rulesets.Catch.Objects.Drawable +namespace osu.Game.Rulesets.Catch.Objects.Drawables { public class DrawableJuiceStream : DrawableCatchHitObject { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs similarity index 89% rename from osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs index 4fe1f86f2b..bb55a39186 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableTinyDroplet.cs @@ -3,7 +3,7 @@ using osu.Framework.Allocation; -namespace osu.Game.Rulesets.Catch.Objects.Drawable +namespace osu.Game.Rulesets.Catch.Objects.Drawables { public class DrawableTinyDroplet : DrawableDroplet { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs similarity index 94% rename from osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs index 24f558db78..c6fa5290e9 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs @@ -7,12 +7,12 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; using osu.Game.Rulesets.Objects.Drawables; using osuTK; using osuTK.Graphics; -namespace osu.Game.Rulesets.Catch.Objects.Drawable +namespace osu.Game.Rulesets.Catch.Objects.Drawables { internal class FruitPiece : CompositeDrawable { @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Origin = Anchor.Centre, BorderColour = Color4.White, BorderThickness = 6f * radius_adjust, - Children = new Framework.Graphics.Drawable[] + Children = new Drawable[] { new Box { @@ -84,7 +84,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable border.Alpha = (float)Math.Clamp((hitObject.StartTime - Time.Current) / 500, 0, 1); } - private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation) + private Drawable createPulp(FruitVisualRepresentation representation) { const float large_pulp_3 = 16f * radius_adjust; const float distance_from_centre_3 = 0.15f; @@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable return new Container { RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] + Children = new Drawable[] { new Pulp { @@ -146,7 +146,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable return new Container { RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] + Children = new Drawable[] { new Pulp { @@ -185,7 +185,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable return new Container { RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] + Children = new Drawable[] { new Pulp { @@ -218,7 +218,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable return new Container { RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] + Children = new Drawable[] { new Pulp { @@ -252,7 +252,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable return new Container { RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] + Children = new Drawable[] { new Pulp { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/Pieces/Pulp.cs similarity index 95% rename from osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs rename to osu.Game.Rulesets.Catch/Objects/Drawables/Pieces/Pulp.cs index 517978eb07..1e7506a257 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/Pieces/Pulp.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osuTK.Graphics; -namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces +namespace osu.Game.Rulesets.Catch.Objects.Drawables.Pieces { public class Pulp : Circle { diff --git a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs index 909db41736..2631fe5487 100644 --- a/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Skinning/LegacyFruitPiece.cs @@ -6,7 +6,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; -using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Skinning; using osuTK.Graphics; diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 2d71fb93fb..2319c5ac1f 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI.Scrolling; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 9ded0ff891..32053b861f 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -11,7 +11,7 @@ using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Judgements; using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; diff --git a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs index fdd820b891..fd8a1d175d 100644 --- a/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs @@ -8,7 +8,7 @@ using osu.Game.Configuration; using osu.Game.Input.Handlers; using osu.Game.Replays; using osu.Game.Rulesets.Catch.Objects; -using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; From e96668904406abd2d81c9a0c988835ffaf264152 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Feb 2020 19:42:25 +0900 Subject: [PATCH 074/127] Add beatmap background to multiplayer --- .../Multi/Lounge/Components/FilterControl.cs | 3 +- .../Screens/Multi/Match/MatchSubScreen.cs | 21 ----- osu.Game/Screens/Multi/Multiplayer.cs | 92 +++++++++++++++---- 3 files changed, 73 insertions(+), 43 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index 9f93afec9d..666051ba8e 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -5,7 +5,6 @@ using System.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Threading; -using osu.Game.Graphics; using osu.Game.Overlays.SearchableList; using osu.Game.Rulesets; using osuTK.Graphics; @@ -14,7 +13,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components { public class FilterControl : SearchableListFilterControl { - protected override Color4 BackgroundColour => OsuColour.FromHex(@"362e42"); + protected override Color4 BackgroundColour => Color4.Transparent; protected override PrimaryFilter DefaultTab => PrimaryFilter.Open; protected override SecondaryFilter DefaultCategory => SecondaryFilter.Public; diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index a8630b79b1..5258d8429e 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -5,22 +5,17 @@ using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; -using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Audio; using osu.Game.Beatmaps; -using osu.Game.Beatmaps.Drawables; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Rulesets.Mods; -using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; using osu.Game.Screens.Select; -using osuTK.Graphics; using Footer = osu.Game.Screens.Multi.Match.Components.Footer; namespace osu.Game.Screens.Multi.Match @@ -64,12 +59,6 @@ namespace osu.Game.Screens.Multi.Match { InternalChildren = new Drawable[] { - new HeaderBackgroundSprite - { - RelativeSizeAxes = Axes.X, - Height = 200, - Colour = ColourInfo.GradientVertical(Color4.White.Opacity(0.4f), Color4.White.Opacity(0)) - }, new GridContainer { RelativeSizeAxes = Axes.Both, @@ -252,15 +241,5 @@ namespace osu.Game.Screens.Multi.Match if (beatmapManager != null) beatmapManager.ItemAdded -= beatmapAdded; } - - private class HeaderBackgroundSprite : MultiplayerBackgroundSprite - { - protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both }; - - private class BackgroundSprite : UpdateableBeatmapBackgroundSprite - { - protected override double TransformDuration => 200; - } - } } } diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 2277157134..13537e2be8 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -4,14 +4,16 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Logging; using osu.Framework.Screens; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; -using osu.Game.Graphics.Backgrounds; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Input; @@ -19,6 +21,7 @@ using osu.Game.Online.API; using osu.Game.Online.Multiplayer; using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Screens.Menu; +using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Lounge; using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Screens.Multi.Match; @@ -62,6 +65,9 @@ namespace osu.Game.Screens.Multi [Resolved(CanBeNull = true)] private OsuLogo logo { get; set; } + private readonly Drawable header; + private readonly Drawable headerBackground; + public Multiplayer() { Anchor = Anchor.Centre; @@ -74,31 +80,51 @@ namespace osu.Game.Screens.Multi RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new Container + new Box { RelativeSizeAxes = Axes.Both, - Masking = true, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"3e3a44"), - }, - new Triangles - { - RelativeSizeAxes = Axes.Both, - ColourLight = OsuColour.FromHex(@"3c3842"), - ColourDark = OsuColour.FromHex(@"393540"), - TriangleScale = 5, - }, - }, + Colour = OsuColour.FromHex(@"3e3a44"), }, new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Top = Header.HEIGHT }, - Child = screenStack = new MultiplayerSubScreenStack { RelativeSizeAxes = Axes.Both } + Children = new[] + { + header = new Container + { + RelativeSizeAxes = Axes.X, + Height = 400, + Children = new[] + { + headerBackground = new Container + { + RelativeSizeAxes = Axes.Both, + Width = 1.25f, + Masking = true, + Children = new Drawable[] + { + new HeaderBackgroundSprite + { + RelativeSizeAxes = Axes.X, + Height = 400 // Keep a static height so the header doesn't change as it's resized + }, + } + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Bottom = -1 }, // 1px padding to avoid a 1px gap due to masking + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(OsuColour.FromHex(@"3e3a44").Opacity(0.6f), OsuColour.FromHex(@"3e3a44")) + }, + } + } + }, + screenStack = new MultiplayerSubScreenStack { RelativeSizeAxes = Axes.Both } + } }, new Header(screenStack), createButton = new HeaderButton @@ -259,7 +285,10 @@ namespace osu.Game.Screens.Multi Beatmap.ValueChanged -= updateTrack; } - private void screenPushed(IScreen lastScreen, IScreen newScreen) => subScreenChanged(newScreen); + private void screenPushed(IScreen lastScreen, IScreen newScreen) + { + subScreenChanged(newScreen); + } private void screenExited(IScreen lastScreen, IScreen newScreen) { @@ -271,6 +300,19 @@ namespace osu.Game.Screens.Multi private void subScreenChanged(IScreen newScreen) { + switch (newScreen) + { + case LoungeSubScreen _: + header.ResizeHeightTo(400, WaveContainer.APPEAR_DURATION, Easing.OutQuint); + headerBackground.MoveToX(0, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); + break; + + case MatchSubScreen _: + header.ResizeHeightTo(135, WaveContainer.APPEAR_DURATION, Easing.OutQuint); + headerBackground.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); + break; + } + updatePollingRate(isIdle.Value); createButton.FadeTo(newScreen is LoungeSubScreen ? 1 : 0, 200); @@ -327,5 +369,15 @@ namespace osu.Game.Screens.Multi FourthWaveColour = OsuColour.FromHex(@"392850"); } } + + private class HeaderBackgroundSprite : MultiplayerBackgroundSprite + { + protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both }; + + private class BackgroundSprite : UpdateableBeatmapBackgroundSprite + { + protected override double TransformDuration => 200; + } + } } } From 33382416327e95b1bb0ddfee86fe1f32d1f4a0bd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Feb 2020 19:48:34 +0900 Subject: [PATCH 075/127] Add back filter control background, adjust opacity --- osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs | 3 ++- osu.Game/Screens/Multi/Multiplayer.cs | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs index 666051ba8e..300418441e 100644 --- a/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs +++ b/osu.Game/Screens/Multi/Lounge/Components/FilterControl.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Threading; using osu.Game.Overlays.SearchableList; using osu.Game.Rulesets; @@ -13,7 +14,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components { public class FilterControl : SearchableListFilterControl { - protected override Color4 BackgroundColour => Color4.Transparent; + protected override Color4 BackgroundColour => Color4.Black.Opacity(0.5f); protected override PrimaryFilter DefaultTab => PrimaryFilter.Open; protected override SecondaryFilter DefaultCategory => SecondaryFilter.Public; diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 13537e2be8..07d930fa75 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -75,6 +75,8 @@ namespace osu.Game.Screens.Multi RelativeSizeAxes = Axes.Both; Padding = new MarginPadding { Horizontal = -HORIZONTAL_OVERFLOW_PADDING }; + var backgroundColour = OsuColour.FromHex(@"3e3a44"); + InternalChild = waves = new MultiplayerWaveContainer { RelativeSizeAxes = Axes.Both, @@ -83,7 +85,7 @@ namespace osu.Game.Screens.Multi new Box { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"3e3a44"), + Colour = backgroundColour, }, new Container { @@ -118,7 +120,7 @@ namespace osu.Game.Screens.Multi Child = new Box { RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(OsuColour.FromHex(@"3e3a44").Opacity(0.6f), OsuColour.FromHex(@"3e3a44")) + Colour = ColourInfo.GradientVertical(backgroundColour.Opacity(0.7f), backgroundColour) }, } } From f53349ac9d83dd65bed12cf3feba6ca82ad0509d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Feb 2020 19:54:07 +0900 Subject: [PATCH 076/127] Reduce size of participants tiles --- osu.Game/Screens/Multi/Components/ParticipantsList.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/ParticipantsList.cs b/osu.Game/Screens/Multi/Components/ParticipantsList.cs index 81d530ce68..e383e0414b 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantsList.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantsList.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Multi.Components { public class ParticipantsList : MultiplayerComposite { - public const float TILE_SIZE = 70; + public const float TILE_SIZE = 35; public override Axes RelativeSizeAxes { @@ -113,7 +113,7 @@ namespace osu.Game.Screens.Multi.Components public UserTile(User user) { this.user = user; - Size = new Vector2(70f); + Size = new Vector2(TILE_SIZE); CornerRadius = 5f; Masking = true; From 7b0c3281c29938ef01ff40949a954884bea87357 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 16:49:39 +0300 Subject: [PATCH 077/127] Make country names clickable --- .../Rankings/Tables/CountriesTable.cs | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs index 32ac1404bc..0b9a48ce0e 100644 --- a/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/CountriesTable.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Graphics; using System.Collections.Generic; using osu.Framework.Allocation; +using osu.Game.Graphics.Containers; namespace osu.Game.Overlays.Rankings.Tables { @@ -61,18 +62,35 @@ namespace osu.Game.Overlays.Rankings.Tables } }; - private class CountryName : OsuSpriteText + private class CountryName : OsuHoverContainer { + protected override IEnumerable EffectTargets => new[] { text }; + + [Resolved(canBeNull: true)] + private RankingsOverlay rankings { get; set; } + + private readonly OsuSpriteText text; + private readonly Country country; + public CountryName(Country country) { - Font = OsuFont.GetFont(size: 12); - Text = country.FullName ?? string.Empty; + this.country = country; + + AutoSizeAxes = Axes.Both; + Add(text = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 12), + Text = country.FullName ?? string.Empty, + }); } [BackgroundDependencyLoader] private void load(OverlayColourProvider colourProvider) { - Colour = colourProvider.Light2; + IdleColour = colourProvider.Light2; + HoverColour = colourProvider.Content2; + + Action = () => rankings?.ShowCountry(country); } } } From a79398ddbd698d165ee7b0e35242c7c4bd3f4641 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 17:09:22 +0300 Subject: [PATCH 078/127] Fix incorrect caching in TestSceneRankingsOverlay --- osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs index a769ebe4a9..47582e5486 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs @@ -29,8 +29,9 @@ namespace osu.Game.Tests.Visual.Online typeof(RankingsOverlayHeader) }; - [Cached] - private RankingsOverlay rankingsOverlay; + [Cached(typeof(RankingsOverlay))] + + private readonly RankingsOverlay rankingsOverlay; private readonly Bindable countryBindable = new Bindable(); private readonly Bindable scope = new Bindable(); From 1417c901738a5be99f56629d02f055f91598e996 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 17:24:44 +0300 Subject: [PATCH 079/127] Remove redundant blank line --- osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs index 47582e5486..83e5cd0fe7 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneRankingsOverlay.cs @@ -30,7 +30,6 @@ namespace osu.Game.Tests.Visual.Online }; [Cached(typeof(RankingsOverlay))] - private readonly RankingsOverlay rankingsOverlay; private readonly Bindable countryBindable = new Bindable(); From 98654586de78a3d4ace7cd3ef4d60d7af26580b4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 17:28:14 +0300 Subject: [PATCH 080/127] Implement BeatmapListingHeader component --- .../BeatmapListing/BeatmapListingHeader.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs new file mode 100644 index 0000000000..5af92914de --- /dev/null +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingHeader.cs @@ -0,0 +1,24 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Overlays.BeatmapListing +{ + public class BeatmapListingHeader : OverlayHeader + { + protected override ScreenTitle CreateTitle() => new BeatmapListingTitle(); + + private class BeatmapListingTitle : ScreenTitle + { + public BeatmapListingTitle() + { + Title = @"beatmap"; + Section = @"listing"; + } + + protected override Drawable CreateIcon() => new ScreenTitleTextureIcon(@"Icons/changelog"); + } + } +} From 1442f5e0db37185c88fae5744d30e2c130904249 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 17:30:26 +0300 Subject: [PATCH 081/127] Use DirectSortCriteria for BeatmapListingSortTabControl --- .../BeatmapListingSortTabControl.cs | 24 ++++++------------- osu.Game/Overlays/Direct/FilterControl.cs | 3 +-- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs index cb41b33bc4..27c43b092a 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSortTabControl.cs @@ -8,16 +8,17 @@ using osu.Framework.Graphics; using osuTK.Graphics; using osuTK; using osu.Framework.Input.Events; +using osu.Game.Overlays.Direct; namespace osu.Game.Overlays.BeatmapListing { - public class BeatmapListingSortTabControl : OverlaySortTabControl + public class BeatmapListingSortTabControl : OverlaySortTabControl { public readonly Bindable SortDirection = new Bindable(Overlays.SortDirection.Descending); public BeatmapListingSortTabControl() { - Current.Value = BeatmapSortCriteria.Ranked; + Current.Value = DirectSortCriteria.Ranked; } protected override SortTabControl CreateControl() => new BeatmapSortTabControl @@ -29,7 +30,7 @@ namespace osu.Game.Overlays.BeatmapListing { public readonly Bindable SortDirection = new Bindable(); - protected override TabItem CreateTabItem(BeatmapSortCriteria value) => new BeatmapSortTabItem(value) + protected override TabItem CreateTabItem(DirectSortCriteria value) => new BeatmapSortTabItem(value) { SortDirection = { BindTarget = SortDirection } }; @@ -39,12 +40,12 @@ namespace osu.Game.Overlays.BeatmapListing { public readonly Bindable SortDirection = new Bindable(); - public BeatmapSortTabItem(BeatmapSortCriteria value) + public BeatmapSortTabItem(DirectSortCriteria value) : base(value) { } - protected override TabButton CreateTabButton(BeatmapSortCriteria value) => new BeatmapTabButton(value) + protected override TabButton CreateTabButton(DirectSortCriteria value) => new BeatmapTabButton(value) { Active = { BindTarget = Active }, SortDirection = { BindTarget = SortDirection } @@ -66,7 +67,7 @@ namespace osu.Game.Overlays.BeatmapListing private readonly SpriteIcon icon; - public BeatmapTabButton(BeatmapSortCriteria value) + public BeatmapTabButton(DirectSortCriteria value) : base(value) { Add(icon = new SpriteIcon @@ -104,15 +105,4 @@ namespace osu.Game.Overlays.BeatmapListing } } } - - public enum BeatmapSortCriteria - { - Title, - Artist, - Difficulty, - Ranked, - Rating, - Plays, - Favourites, - } } diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 8b04bf0387..70a3ab54fb 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -34,14 +34,13 @@ namespace osu.Game.Overlays.Direct public enum DirectSortCriteria { - Relevance, Title, Artist, - Creator, Difficulty, Ranked, Rating, Plays, Favourites, + Relevance, } } From 01202f09bec882209c314a34cf05543c3acaa0a0 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 17:32:43 +0300 Subject: [PATCH 082/127] Expand SearchBeatmapSetsResponse --- osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs index 28863cb0e0..845c84430f 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs @@ -2,12 +2,20 @@ // 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 SearchBeatmapSetsResponse : ResponseWithCursor { + [JsonProperty("beatmapsets")] public IEnumerable BeatmapSets; + + [JsonProperty("error")] + public string Error; + + [JsonProperty("total")] + public int Total; } } From 13873ff1b6dc95bf0290ba98450c08c62a295701 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 19 Feb 2020 23:32:56 +0900 Subject: [PATCH 083/127] Split out pulp formations into own piece classes --- .../Objects/Drawables/BananaPiece.cs | 31 +++ .../Objects/Drawables/FruitPiece.cs | 193 ++---------------- .../Objects/Drawables/GrapePiece.cs | 43 ++++ .../Objects/Drawables/PearPiece.cs | 43 ++++ .../Objects/Drawables/PineapplePiece.cs | 49 +++++ .../Objects/Drawables/PulpFormation.cs | 43 ++++ .../Objects/Drawables/RaspberryPiece.cs | 49 +++++ 7 files changed, 272 insertions(+), 179 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawables/BananaPiece.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawables/GrapePiece.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawables/PearPiece.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawables/PineapplePiece.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawables/PulpFormation.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawables/RaspberryPiece.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/BananaPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/BananaPiece.cs new file mode 100644 index 0000000000..ebb0bf0f2c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/BananaPiece.cs @@ -0,0 +1,31 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Objects.Drawables +{ + public class BananaPiece : PulpFormation + { + public BananaPiece() + { + InternalChildren = new Drawable[] + { + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(SMALL_PULP), + Y = -0.3f + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_4 * 0.8f, LARGE_PULP_4 * 2.5f), + Y = 0.05f, + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs index c6fa5290e9..0f5044eda7 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/FruitPiece.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables /// /// Because we're adding a border around the fruit, we need to scale down some. /// - private const float radius_adjust = 1.1f; + public const float RADIUS_ADJUST = 1.1f; private Circle border; @@ -42,14 +42,14 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables AddRangeInternal(new[] { - createPulp(drawableCatchObject.HitObject.VisualRepresentation), + getFruitFor(drawableCatchObject.HitObject.VisualRepresentation), border = new Circle { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, BorderColour = Color4.White, - BorderThickness = 6f * radius_adjust, + BorderThickness = 6f * RADIUS_ADJUST, Children = new Drawable[] { new Box @@ -80,195 +80,30 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables protected override void Update() { base.Update(); - border.Alpha = (float)Math.Clamp((hitObject.StartTime - Time.Current) / 500, 0, 1); } - private Drawable createPulp(FruitVisualRepresentation representation) + private Drawable getFruitFor(FruitVisualRepresentation representation) { - const float large_pulp_3 = 16f * radius_adjust; - const float distance_from_centre_3 = 0.15f; - - const float large_pulp_4 = large_pulp_3 * 0.925f; - const float distance_from_centre_4 = distance_from_centre_3 / 0.925f; - - const float small_pulp = large_pulp_3 / 2; - - static Vector2 positionAt(float angle, float distance) => new Vector2( - distance * MathF.Sin(angle * MathF.PI / 180), - distance * MathF.Cos(angle * MathF.PI / 180)); - switch (representation) { - default: - return new Container(); - - case FruitVisualRepresentation.Raspberry: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(small_pulp), - Y = -0.34f, - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_4), - Position = positionAt(0, distance_from_centre_4), - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_4), - Position = positionAt(90, distance_from_centre_4), - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_4), - Position = positionAt(180, distance_from_centre_4), - }, - new Pulp - { - Size = new Vector2(large_pulp_4), - AccentColour = { BindTarget = accentColour }, - Position = positionAt(270, distance_from_centre_4), - }, - } - }; - - case FruitVisualRepresentation.Pineapple: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(small_pulp), - Y = -0.3f, - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_4), - Position = positionAt(45, distance_from_centre_4), - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_4), - Position = positionAt(135, distance_from_centre_4), - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_4), - Position = positionAt(225, distance_from_centre_4), - }, - new Pulp - { - Size = new Vector2(large_pulp_4), - AccentColour = { BindTarget = accentColour }, - Position = positionAt(315, distance_from_centre_4), - }, - } - }; - case FruitVisualRepresentation.Pear: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(small_pulp), - Y = -0.33f, - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_3), - Position = positionAt(60, distance_from_centre_3), - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_3), - Position = positionAt(180, distance_from_centre_3), - }, - new Pulp - { - Size = new Vector2(large_pulp_3), - AccentColour = { BindTarget = accentColour }, - Position = positionAt(300, distance_from_centre_3), - }, - } - }; + return new PearPiece(); case FruitVisualRepresentation.Grape: - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(small_pulp), - Y = -0.25f, - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_3), - Position = positionAt(0, distance_from_centre_3), - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_3), - Position = positionAt(120, distance_from_centre_3), - }, - new Pulp - { - Size = new Vector2(large_pulp_3), - AccentColour = { BindTarget = accentColour }, - Position = positionAt(240, distance_from_centre_3), - }, - } - }; + return new GrapePiece(); + + case FruitVisualRepresentation.Pineapple: + return new PineapplePiece(); case FruitVisualRepresentation.Banana: + return new BananaPiece(); - return new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(small_pulp), - Y = -0.3f - }, - new Pulp - { - AccentColour = { BindTarget = accentColour }, - Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f), - Y = 0.05f, - }, - } - }; + case FruitVisualRepresentation.Raspberry: + return new RaspberryPiece(); } + + return Empty(); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/GrapePiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/GrapePiece.cs new file mode 100644 index 0000000000..1d1faf893b --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/GrapePiece.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Objects.Drawables +{ + public class GrapePiece : PulpFormation + { + public GrapePiece() + { + InternalChildren = new Drawable[] + { + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(SMALL_PULP), + Y = -0.25f, + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_3), + Position = PositionAt(0, DISTANCE_FROM_CENTRE_3), + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_3), + Position = PositionAt(120, DISTANCE_FROM_CENTRE_3), + }, + new Pulp + { + Size = new Vector2(LARGE_PULP_3), + AccentColour = { BindTarget = AccentColour }, + Position = PositionAt(240, DISTANCE_FROM_CENTRE_3), + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/PearPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/PearPiece.cs new file mode 100644 index 0000000000..7f14217cda --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/PearPiece.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Graphics; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Objects.Drawables +{ + public class PearPiece : PulpFormation + { + public PearPiece() + { + InternalChildren = new Drawable[] + { + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(SMALL_PULP), + Y = -0.33f, + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_3), + Position = PositionAt(60, DISTANCE_FROM_CENTRE_3), + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_3), + Position = PositionAt(180, DISTANCE_FROM_CENTRE_3), + }, + new Pulp + { + Size = new Vector2(LARGE_PULP_3), + AccentColour = { BindTarget = AccentColour }, + Position = PositionAt(300, DISTANCE_FROM_CENTRE_3), + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/PineapplePiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/PineapplePiece.cs new file mode 100644 index 0000000000..c328ba1837 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/PineapplePiece.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.Graphics; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Objects.Drawables +{ + public class PineapplePiece : PulpFormation + { + public PineapplePiece() + { + InternalChildren = new Drawable[] + { + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(SMALL_PULP), + Y = -0.3f, + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_4), + Position = PositionAt(45, DISTANCE_FROM_CENTRE_4), + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_4), + Position = PositionAt(135, DISTANCE_FROM_CENTRE_4), + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_4), + Position = PositionAt(225, DISTANCE_FROM_CENTRE_4), + }, + new Pulp + { + Size = new Vector2(LARGE_PULP_4), + AccentColour = { BindTarget = AccentColour }, + Position = PositionAt(315, DISTANCE_FROM_CENTRE_4), + }, + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/PulpFormation.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/PulpFormation.cs new file mode 100644 index 0000000000..be70c3400c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/PulpFormation.cs @@ -0,0 +1,43 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Objects.Drawables; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects.Drawables +{ + public abstract class PulpFormation : CompositeDrawable + { + protected readonly IBindable AccentColour = new Bindable(); + + protected const float LARGE_PULP_3 = 16f * FruitPiece.RADIUS_ADJUST; + protected const float DISTANCE_FROM_CENTRE_3 = 0.15f; + + protected const float LARGE_PULP_4 = LARGE_PULP_3 * 0.925f; + protected const float DISTANCE_FROM_CENTRE_4 = DISTANCE_FROM_CENTRE_3 / 0.925f; + + protected const float SMALL_PULP = LARGE_PULP_3 / 2; + + protected PulpFormation() + { + RelativeSizeAxes = Axes.Both; + } + + protected static Vector2 PositionAt(float angle, float distance) => new Vector2( + distance * MathF.Sin(angle * MathF.PI / 180), + distance * MathF.Cos(angle * MathF.PI / 180)); + + [BackgroundDependencyLoader] + private void load(DrawableHitObject drawableObject) + { + DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; + AccentColour.BindTo(drawableCatchObject.AccentColour); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/RaspberryPiece.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/RaspberryPiece.cs new file mode 100644 index 0000000000..22ce3ba5b3 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawables/RaspberryPiece.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.Graphics; +using osu.Game.Rulesets.Catch.Objects.Drawables.Pieces; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Objects.Drawables +{ + public class RaspberryPiece : PulpFormation + { + public RaspberryPiece() + { + InternalChildren = new Drawable[] + { + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(SMALL_PULP), + Y = -0.34f, + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_4), + Position = PositionAt(0, DISTANCE_FROM_CENTRE_4), + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_4), + Position = PositionAt(90, DISTANCE_FROM_CENTRE_4), + }, + new Pulp + { + AccentColour = { BindTarget = AccentColour }, + Size = new Vector2(LARGE_PULP_4), + Position = PositionAt(180, DISTANCE_FROM_CENTRE_4), + }, + new Pulp + { + Size = new Vector2(LARGE_PULP_4), + AccentColour = { BindTarget = AccentColour }, + Position = PositionAt(270, DISTANCE_FROM_CENTRE_4), + }, + }; + } + } +} From 255c8d3a1306149ff396c96a1a7997ba6a3e9912 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 17:33:48 +0300 Subject: [PATCH 084/127] Adjust SearchBeatmapSetsRequest for new usage --- .../API/Requests/SearchBeatmapSetsRequest.cs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index 5652b8d2bd..930ca8fdf1 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.ComponentModel; +using osu.Framework.IO.Network; using osu.Game.Overlays; using osu.Game.Overlays.Direct; using osu.Game.Rulesets; @@ -26,8 +27,21 @@ namespace osu.Game.Online.API.Requests this.direction = direction; } - // ReSharper disable once ImpureMethodCallOnReadonlyValueField - protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={searchCategory.ToString().ToLowerInvariant()}&sort={sortCriteria.ToString().ToLowerInvariant()}_{directionString}"; + protected override WebRequest CreateWebRequest() + { + var req = base.CreateWebRequest(); + req.AddParameter("q", query); + + if (ruleset.ID.HasValue) + req.AddParameter("m", ruleset.ID.Value.ToString()); + + req.AddParameter("s", searchCategory.ToString().ToLowerInvariant()); + req.AddParameter("sort", $"{sortCriteria.ToString().ToLowerInvariant()}_{directionString}"); + + return req; + } + + protected override string Target => @"beatmapsets/search"; } public enum BeatmapSearchCategory From 8fcfb73d722b54380bd9b8b525eb38c38197b0ce Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 17:40:54 +0300 Subject: [PATCH 085/127] Implement BeatmapListingOverlay --- .../Online/TestSceneBeatmapListingOverlay.cs | 39 +++ osu.Game/Overlays/BeatmapListingOverlay.cs | 229 ++++++++++++++++++ 2 files changed, 268 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs create mode 100644 osu.Game/Overlays/BeatmapListingOverlay.cs diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs new file mode 100644 index 0000000000..7c05d99c59 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs @@ -0,0 +1,39 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using osu.Game.Overlays; +using NUnit.Framework; + +namespace osu.Game.Tests.Visual.Online +{ + public class TestSceneBeatmapListingOverlay : OsuTestScene + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(BeatmapListingOverlay), + }; + + protected override bool UseOnlineAPI => true; + + private readonly BeatmapListingOverlay overlay; + + public TestSceneBeatmapListingOverlay() + { + Add(overlay = new BeatmapListingOverlay()); + } + + [Test] + public void TestShow() + { + AddStep("Show", overlay.Show); + } + + [Test] + public void TestHide() + { + AddStep("Hide", overlay.Hide); + } + } +} diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs new file mode 100644 index 0000000000..971a1b46d2 --- /dev/null +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -0,0 +1,229 @@ +// 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.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Threading; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.Online.API.Requests; +using osu.Game.Overlays.BeatmapListing; +using osu.Game.Overlays.Direct; +using osu.Game.Rulesets; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays +{ + public class BeatmapListingOverlay : FullscreenOverlay + { + [Resolved] + private PreviewTrackManager previewTrackManager { get; set; } + + [Resolved] + private RulesetStore rulesets { get; set; } + + private SearchBeatmapSetsRequest getSetsRequest; + private Container panelsPlaceholder; + private BeatmapListingSearchSection searchSection; + private BeatmapListingSortTabControl sortControl; + + public BeatmapListingOverlay() + : base(OverlayColourScheme.Blue) + { + } + + [BackgroundDependencyLoader] + private void load() + { + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourProvider.Background6 + }, + new BasicScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollbarVisible = false, + Child = new ReverseChildIDFillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 10), + Children = new Drawable[] + { + new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Masking = true, + EdgeEffect = new EdgeEffectParameters + { + Colour = Color4.Black.Opacity(0.25f), + Type = EdgeEffectType.Shadow, + Radius = 3, + Offset = new Vector2(0f, 1f), + }, + Children = new Drawable[] + { + new BeatmapListingHeader(), + searchSection = new BeatmapListingSearchSection(), + } + }, + new Container + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourProvider.Background4, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + Height = 40, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourProvider.Background5 + }, + sortControl = new BeatmapListingSortTabControl + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 20 } + } + } + }, + panelsPlaceholder = new Container + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Padding = new MarginPadding { Vertical = 15, Horizontal = 20 }, + } + } + } + } + } + } + } + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + var sortCriteria = sortControl.Current; + var sortDirection = sortControl.SortDirection; + + searchSection.Query.BindValueChanged(query => + { + sortCriteria.Value = string.IsNullOrEmpty(query.NewValue) ? DirectSortCriteria.Ranked : DirectSortCriteria.Relevance; + sortDirection.Value = SortDirection.Descending; + + Scheduler.AddOnce(updateSearch); + }); + + searchSection.Query.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); + searchSection.Ruleset.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); + searchSection.Category.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); + sortCriteria.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); + sortDirection.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); + } + + private void updateSearch() + { + if (!IsLoaded) + return; + + if (State.Value == Visibility.Hidden) + return; + + if (API == null) + return; + + getSetsRequest?.Cancel(); + previewTrackManager.StopAnyPlaying(this); + + panelsPlaceholder.FadeColour(Color4.DimGray, 400, Easing.OutQuint); + + getSetsRequest = new SearchBeatmapSetsRequest( + searchSection.Query.Value, + searchSection.Ruleset.Value, + searchSection.Category.Value, + sortControl.Current.Value, + sortControl.SortDirection.Value); + + getSetsRequest.Success += response => Schedule(() => recreatePanels(response)); + + API.Queue(getSetsRequest); + } + + private void recreatePanels(SearchBeatmapSetsResponse response) + { + var beatmaps = response.BeatmapSets.Select(r => r.ToBeatmapSet(rulesets)).ToList(); + + var hasError = !string.IsNullOrEmpty(response.Error); + + if (response.Total == 0 || hasError) + { + searchSection.BeatmapSet = null; + panelsPlaceholder.Clear(); + panelsPlaceholder.FadeColour(Color4.White); + panelsPlaceholder.Add(new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = hasError ? response.Error : @"... nope, nothing found." + }); + return; + } + + var newPanels = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(10), + Alpha = 0, + ChildrenEnumerable = beatmaps.Select(b => new DirectGridPanel(b) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + }) + }; + + LoadComponentAsync(newPanels, loaded => + { + panelsPlaceholder.Clear(); + panelsPlaceholder.FadeColour(Color4.White); + panelsPlaceholder.Add(loaded); + loaded.FadeIn(600, Easing.OutQuint); + searchSection.BeatmapSet = beatmaps.First(); + }); + } + } +} From 0c78c8cb4f19283c2b680e1db1d173fbc8fef07d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 17:44:15 +0300 Subject: [PATCH 086/127] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b9b127309a..b9ef783b2a 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -53,7 +53,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index bd5219b872..6b8f8fee8c 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -22,7 +22,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 2c1aff7d3c..f68bedc57f 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -73,7 +73,7 @@ - + From 237be50e37159c0a7f3f97fc434c76a2f1e0c4aa Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 18:17:02 +0300 Subject: [PATCH 087/127] Implement DrawableErrorHandler component --- osu.Game/Overlays/BeatmapListingOverlay.cs | 90 ++++++++++++++++++---- 1 file changed, 76 insertions(+), 14 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 971a1b46d2..eacf883339 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -2,12 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; +using System.Threading; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; using osu.Framework.Threading; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -31,6 +34,8 @@ namespace osu.Game.Overlays private RulesetStore rulesets { get; set; } private SearchBeatmapSetsRequest getSetsRequest; + private CancellationTokenSource cancellationToken; + private Container panelsPlaceholder; private BeatmapListingSearchSection searchSection; private BeatmapListingSortTabControl sortControl; @@ -121,7 +126,7 @@ namespace osu.Game.Overlays { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - Padding = new MarginPadding { Vertical = 15, Horizontal = 20 }, + Padding = new MarginPadding { Horizontal = 20 }, } } } @@ -167,6 +172,7 @@ namespace osu.Game.Overlays return; getSetsRequest?.Cancel(); + cancellationToken?.Cancel(); previewTrackManager.StopAnyPlaying(this); panelsPlaceholder.FadeColour(Color4.DimGray, 400, Easing.OutQuint); @@ -185,30 +191,28 @@ namespace osu.Game.Overlays private void recreatePanels(SearchBeatmapSetsResponse response) { - var beatmaps = response.BeatmapSets.Select(r => r.ToBeatmapSet(rulesets)).ToList(); - var hasError = !string.IsNullOrEmpty(response.Error); if (response.Total == 0 || hasError) { searchSection.BeatmapSet = null; - panelsPlaceholder.Clear(); - panelsPlaceholder.FadeColour(Color4.White); - panelsPlaceholder.Add(new OsuSpriteText + + LoadComponentAsync(new DrawableErrorHandler(hasError ? response.Error : @"... nope, nothing found."), loaded => { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Text = hasError ? response.Error : @"... nope, nothing found." - }); + addContentToPlaceholder(loaded); + }, (cancellationToken = new CancellationTokenSource()).Token); return; } + var beatmaps = response.BeatmapSets.Select(r => r.ToBeatmapSet(rulesets)).ToList(); + var newPanels = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Spacing = new Vector2(10), Alpha = 0, + Margin = new MarginPadding { Vertical = 15 }, ChildrenEnumerable = beatmaps.Select(b => new DirectGridPanel(b) { Anchor = Anchor.TopCentre, @@ -218,12 +222,70 @@ namespace osu.Game.Overlays LoadComponentAsync(newPanels, loaded => { - panelsPlaceholder.Clear(); - panelsPlaceholder.FadeColour(Color4.White); - panelsPlaceholder.Add(loaded); + addContentToPlaceholder(loaded); loaded.FadeIn(600, Easing.OutQuint); searchSection.BeatmapSet = beatmaps.First(); - }); + }, (cancellationToken = new CancellationTokenSource()).Token); + } + + private void addContentToPlaceholder(Drawable content) + { + panelsPlaceholder.Clear(); + panelsPlaceholder.FadeColour(Color4.White); + panelsPlaceholder.Add(content); + } + + protected override void Dispose(bool isDisposing) + { + getSetsRequest?.Cancel(); + cancellationToken?.Cancel(); + + base.Dispose(isDisposing); + } + + private class DrawableErrorHandler : CompositeDrawable + { + private readonly string error; + + public DrawableErrorHandler(string error) + { + this.error = error; + + RelativeSizeAxes = Axes.X; + Height = 250; + Margin = new MarginPadding { Top = 15 }; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + AddInternal(new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10, 0), + Children = new Drawable[] + { + new Sprite + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + FillMode = FillMode.Fit, + Texture = textures.Get(@"Online/not-found") + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Text = error, + } + } + }); + } } } } From 2ef3c7873605f8dcb7b61bacc5cf90bfe2359b3a Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 18:19:15 +0300 Subject: [PATCH 088/127] Remove query binding duplicate --- osu.Game/Overlays/BeatmapListingOverlay.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index eacf883339..143e20d69f 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -153,7 +153,6 @@ namespace osu.Game.Overlays Scheduler.AddOnce(updateSearch); }); - searchSection.Query.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); searchSection.Ruleset.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); searchSection.Category.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); sortCriteria.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); From edef84d9c388588749a390be116240653f80bd8c Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Wed, 19 Feb 2020 19:15:18 +0300 Subject: [PATCH 089/127] CI fixes --- osu.Game/Overlays/BeatmapListingOverlay.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 143e20d69f..546d0bc9bb 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -11,7 +11,6 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; -using osu.Framework.Threading; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; @@ -196,10 +195,9 @@ namespace osu.Game.Overlays { searchSection.BeatmapSet = null; - LoadComponentAsync(new DrawableErrorHandler(hasError ? response.Error : @"... nope, nothing found."), loaded => - { - addContentToPlaceholder(loaded); - }, (cancellationToken = new CancellationTokenSource()).Token); + LoadComponentAsync(new DrawableErrorHandler(hasError ? response.Error : @"... nope, nothing found."), + addContentToPlaceholder, + (cancellationToken = new CancellationTokenSource()).Token); return; } From 62227ad856efb44cf4cb26c31d2965b9e30e277e Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 19 Feb 2020 17:58:10 +0100 Subject: [PATCH 090/127] Add MaxCombo to BeatmapInfo --- osu.Game/Beatmaps/BeatmapInfo.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index bcc9ab885e..68d113ce40 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -51,6 +51,9 @@ namespace osu.Game.Beatmaps [NotMapped] public BeatmapOnlineInfo OnlineInfo { get; set; } + [NotMapped] + public int? MaxCombo { get; set; } + /// /// The playable length in milliseconds of this beatmap. /// From 23c9782f509c5af8f543bedcf57a7c5d1c8e2154 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 19 Feb 2020 17:58:41 +0100 Subject: [PATCH 091/127] Add maxCombo to APIBeatmap --- osu.Game/Online/API/Requests/Responses/APIBeatmap.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index f4d67a56aa..e023a2502f 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -61,6 +61,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"failtimes")] private BeatmapMetrics metrics { get; set; } + [JsonProperty(@"max_combo")] + private int? maxCombo { get; set; } + public BeatmapInfo ToBeatmap(RulesetStore rulesets) { var set = BeatmapSet?.ToBeatmapSet(rulesets); @@ -76,6 +79,7 @@ namespace osu.Game.Online.API.Requests.Responses Status = Status, BeatmapSet = set, Metrics = metrics, + MaxCombo = maxCombo, BaseDifficulty = new BeatmapDifficulty { DrainRate = drainRate, From 7ea67aa6726428198498d299e17f7a16c360caad Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 19 Feb 2020 17:58:59 +0100 Subject: [PATCH 092/127] Highlight max combo on beatmap leaderboards --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 43a45bd2fc..cf7ecd7408 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -146,7 +146,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores new OsuSpriteText { Text = $@"{score.MaxCombo:N0}x", - Font = OsuFont.GetFont(size: text_size) + Font = OsuFont.GetFont(size: text_size), + Colour = score.MaxCombo == score.Beatmap.MaxCombo ? highAccuracyColour : Color4.White } }); From 84d6a8ae2ade456f1f4b4e71f2c43b1e4fe980b4 Mon Sep 17 00:00:00 2001 From: TheWildTree Date: Wed, 19 Feb 2020 19:42:56 +0100 Subject: [PATCH 093/127] Add null check --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index cf7ecd7408..954eada612 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -147,7 +147,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { Text = $@"{score.MaxCombo:N0}x", Font = OsuFont.GetFont(size: text_size), - Colour = score.MaxCombo == score.Beatmap.MaxCombo ? highAccuracyColour : Color4.White + Colour = score.MaxCombo == score.Beatmap?.MaxCombo ? highAccuracyColour : Color4.White } }); From b2d9004212c5221f751d4bba813f2d4630acf375 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Feb 2020 08:37:23 +0900 Subject: [PATCH 094/127] Fix possible test failures due to async loads --- .../TestSceneDrawableRoomPlaylist.cs | 57 ++++++++++++------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index 4f54e451b7..9fbe8f7ffe 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tests.Visual.Multiplayer typeof(DrawableRoomPlaylistItem) }; - private DrawableRoomPlaylist playlist; + private TestPlaylist playlist; [Test] public void TestNonEditableNonSelectable() @@ -211,30 +211,45 @@ namespace osu.Game.Tests.Visual.Multiplayer private void assertDeleteButtonVisibility(int index, bool visible) => AddAssert($"delete button {index} {(visible ? "is" : "is not")} visible", () => (playlist.ChildrenOfType().ElementAt(2 + index * 2).Alpha > 0) == visible); - private void createPlaylist(bool allowEdit, bool allowSelection) => AddStep("create playlist", () => + private void createPlaylist(bool allowEdit, bool allowSelection) { - Child = playlist = new DrawableRoomPlaylist(allowEdit, allowSelection) + AddStep("create playlist", () => { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Size = new Vector2(500, 300) - }; - - for (int i = 0; i < 20; i++) - { - playlist.Items.Add(new PlaylistItem + Child = playlist = new TestPlaylist(allowEdit, allowSelection) { - ID = i, - Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, - Ruleset = { Value = new OsuRuleset().RulesetInfo }, - RequiredMods = + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(500, 300) + }; + + for (int i = 0; i < 20; i++) + { + playlist.Items.Add(new PlaylistItem { - new OsuModHardRock(), - new OsuModDoubleTime(), - new OsuModAutoplay() - } - }); + ID = i, + Beatmap = { Value = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo }, + Ruleset = { Value = new OsuRuleset().RulesetInfo }, + RequiredMods = + { + new OsuModHardRock(), + new OsuModDoubleTime(), + new OsuModAutoplay() + } + }); + } + }); + + AddUntilStep("wait for items to load", () => playlist.ItemMap.Values.All(i => i.IsLoaded)); + } + + private class TestPlaylist : DrawableRoomPlaylist + { + public new IReadOnlyDictionary> ItemMap => base.ItemMap; + + public TestPlaylist(bool allowEdit, bool allowSelection) + : base(allowEdit, allowSelection) + { } - }); + } } } From 7550685a614eaff25adef260a5344e254944be69 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 20 Feb 2020 02:43:13 +0300 Subject: [PATCH 095/127] DrawableErrorHandler -> NotFoundDrawable --- .../API/Requests/SearchBeatmapSetsResponse.cs | 3 --- osu.Game/Overlays/BeatmapListingOverlay.cs | 18 +++++------------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs index 845c84430f..3c4fb11ed1 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsResponse.cs @@ -12,9 +12,6 @@ namespace osu.Game.Online.API.Requests [JsonProperty("beatmapsets")] public IEnumerable BeatmapSets; - [JsonProperty("error")] - public string Error; - [JsonProperty("total")] public int Total; } diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 546d0bc9bb..414e911f2e 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -189,15 +189,11 @@ namespace osu.Game.Overlays private void recreatePanels(SearchBeatmapSetsResponse response) { - var hasError = !string.IsNullOrEmpty(response.Error); - - if (response.Total == 0 || hasError) + if (response.Total == 0) { searchSection.BeatmapSet = null; - LoadComponentAsync(new DrawableErrorHandler(hasError ? response.Error : @"... nope, nothing found."), - addContentToPlaceholder, - (cancellationToken = new CancellationTokenSource()).Token); + LoadComponentAsync(new NotFoundDrawable(), addContentToPlaceholder, (cancellationToken = new CancellationTokenSource()).Token); return; } @@ -240,14 +236,10 @@ namespace osu.Game.Overlays base.Dispose(isDisposing); } - private class DrawableErrorHandler : CompositeDrawable + private class NotFoundDrawable : CompositeDrawable { - private readonly string error; - - public DrawableErrorHandler(string error) + public NotFoundDrawable() { - this.error = error; - RelativeSizeAxes = Axes.X; Height = 250; Margin = new MarginPadding { Top = 15 }; @@ -278,7 +270,7 @@ namespace osu.Game.Overlays { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Text = error, + Text = @"... nope, nothing found.", } } }); From 66ea7949358fe9ae9a7dd0c4e5839c39e63ca903 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 20 Feb 2020 02:54:35 +0300 Subject: [PATCH 096/127] Add debounce to the querying --- osu.Game/Overlays/BeatmapListingOverlay.cs | 32 +++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 414e911f2e..2a812ddf96 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using System.Threading; using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; @@ -11,6 +10,7 @@ using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Threading; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; @@ -33,7 +33,6 @@ namespace osu.Game.Overlays private RulesetStore rulesets { get; set; } private SearchBeatmapSetsRequest getSetsRequest; - private CancellationTokenSource cancellationToken; private Container panelsPlaceholder; private BeatmapListingSearchSection searchSection; @@ -149,13 +148,23 @@ namespace osu.Game.Overlays sortCriteria.Value = string.IsNullOrEmpty(query.NewValue) ? DirectSortCriteria.Ranked : DirectSortCriteria.Relevance; sortDirection.Value = SortDirection.Descending; - Scheduler.AddOnce(updateSearch); + queueUpdateSearch(true); }); - searchSection.Ruleset.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); - searchSection.Category.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); - sortCriteria.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); - sortDirection.BindValueChanged(_ => Scheduler.AddOnce(updateSearch)); + searchSection.Ruleset.BindValueChanged(_ => queueUpdateSearch()); + searchSection.Category.BindValueChanged(_ => queueUpdateSearch()); + sortCriteria.BindValueChanged(_ => queueUpdateSearch()); + sortDirection.BindValueChanged(_ => queueUpdateSearch()); + } + + private ScheduledDelegate queryChangedDebounce; + + private void queueUpdateSearch(bool queryTextChanged = false) + { + getSetsRequest?.Cancel(); + + queryChangedDebounce?.Cancel(); + queryChangedDebounce = Scheduler.AddDelayed(updateSearch, queryTextChanged ? 500 : 100); } private void updateSearch() @@ -169,8 +178,6 @@ namespace osu.Game.Overlays if (API == null) return; - getSetsRequest?.Cancel(); - cancellationToken?.Cancel(); previewTrackManager.StopAnyPlaying(this); panelsPlaceholder.FadeColour(Color4.DimGray, 400, Easing.OutQuint); @@ -192,8 +199,7 @@ namespace osu.Game.Overlays if (response.Total == 0) { searchSection.BeatmapSet = null; - - LoadComponentAsync(new NotFoundDrawable(), addContentToPlaceholder, (cancellationToken = new CancellationTokenSource()).Token); + LoadComponentAsync(new NotFoundDrawable(), addContentToPlaceholder); return; } @@ -218,7 +224,7 @@ namespace osu.Game.Overlays addContentToPlaceholder(loaded); loaded.FadeIn(600, Easing.OutQuint); searchSection.BeatmapSet = beatmaps.First(); - }, (cancellationToken = new CancellationTokenSource()).Token); + }); } private void addContentToPlaceholder(Drawable content) @@ -231,7 +237,7 @@ namespace osu.Game.Overlays protected override void Dispose(bool isDisposing) { getSetsRequest?.Cancel(); - cancellationToken?.Cancel(); + queryChangedDebounce?.Cancel(); base.Dispose(isDisposing); } From a8c735b66d7268f1eadeee59cacf8ae345839010 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 20 Feb 2020 04:19:50 +0300 Subject: [PATCH 097/127] Change default category value --- osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs index f47144e5d8..f9799d8a6b 100644 --- a/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs +++ b/osu.Game/Overlays/BeatmapListing/BeatmapListingSearchSection.cs @@ -104,6 +104,8 @@ namespace osu.Game.Overlays.BeatmapListing } } }); + + Category.Value = BeatmapSearchCategory.Leaderboard; } [BackgroundDependencyLoader] From 907c1b3d1c73d9eaca1c2d022ee27653ce13c111 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 10:48:12 +0900 Subject: [PATCH 098/127] Add missing test banana resources --- .../old-skin/fruit-bananas-overlay.png | Bin 0 -> 7823 bytes .../Resources/old-skin/fruit-bananas.png | Bin 0 -> 14274 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 osu.Game.Rulesets.Catch.Tests/Resources/old-skin/fruit-bananas-overlay.png create mode 100644 osu.Game.Rulesets.Catch.Tests/Resources/old-skin/fruit-bananas.png diff --git a/osu.Game.Rulesets.Catch.Tests/Resources/old-skin/fruit-bananas-overlay.png b/osu.Game.Rulesets.Catch.Tests/Resources/old-skin/fruit-bananas-overlay.png new file mode 100644 index 0000000000000000000000000000000000000000..3a6612378e5cc655ec5d9d8ea7c53486c5a6270b GIT binary patch literal 7823 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 a2zU=&wPGnM{AV5mfVTP*wOSSX=>GxIE#JKW literal 0 HcmV?d00001 diff --git a/osu.Game.Rulesets.Catch.Tests/Resources/old-skin/fruit-bananas.png b/osu.Game.Rulesets.Catch.Tests/Resources/old-skin/fruit-bananas.png new file mode 100644 index 0000000000000000000000000000000000000000..afb8698b2d8ff7285d53e140bcf0c5379ef8a6c6 GIT binary patch literal 14274 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 literal 0 HcmV?d00001 From 1935a14288c3c9fedb9e73e45ffd1d7a77a20c92 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 20 Feb 2020 05:08:42 +0300 Subject: [PATCH 099/127] Adjust animations to be much smoother --- osu.Game/Overlays/BeatmapListingOverlay.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index 2a812ddf96..da67226eac 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -35,6 +35,7 @@ namespace osu.Game.Overlays private SearchBeatmapSetsRequest getSetsRequest; private Container panelsPlaceholder; + private Drawable currentContent; private BeatmapListingSearchSection searchSection; private BeatmapListingSortTabControl sortControl; @@ -124,6 +125,8 @@ namespace osu.Game.Overlays { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, + AutoSizeEasing = Easing.Out, + AutoSizeDuration = 200, Padding = new MarginPadding { Horizontal = 20 }, } } @@ -180,7 +183,7 @@ namespace osu.Game.Overlays previewTrackManager.StopAnyPlaying(this); - panelsPlaceholder.FadeColour(Color4.DimGray, 400, Easing.OutQuint); + currentContent?.FadeColour(Color4.DimGray, 400, Easing.OutQuint); getSetsRequest = new SearchBeatmapSetsRequest( searchSection.Query.Value, @@ -222,16 +225,15 @@ namespace osu.Game.Overlays LoadComponentAsync(newPanels, loaded => { addContentToPlaceholder(loaded); - loaded.FadeIn(600, Easing.OutQuint); searchSection.BeatmapSet = beatmaps.First(); }); } private void addContentToPlaceholder(Drawable content) { - panelsPlaceholder.Clear(); - panelsPlaceholder.FadeColour(Color4.White); - panelsPlaceholder.Add(content); + currentContent?.FadeOut(100, Easing.OutQuint).Expire(); + panelsPlaceholder.Add(currentContent = content); + currentContent.FadeIn(200, Easing.OutQuint); } protected override void Dispose(bool isDisposing) @@ -248,6 +250,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.X; Height = 250; + Alpha = 0; Margin = new MarginPadding { Top = 15 }; } From 00d8be92356065111503c18f444e6a5c5b5d9931 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Feb 2020 13:48:34 +0900 Subject: [PATCH 100/127] Adjust height transition --- osu.Game/Overlays/BeatmapListingOverlay.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListingOverlay.cs b/osu.Game/Overlays/BeatmapListingOverlay.cs index da67226eac..213e9a4244 100644 --- a/osu.Game/Overlays/BeatmapListingOverlay.cs +++ b/osu.Game/Overlays/BeatmapListingOverlay.cs @@ -125,8 +125,6 @@ namespace osu.Game.Overlays { AutoSizeAxes = Axes.Y, RelativeSizeAxes = Axes.X, - AutoSizeEasing = Easing.Out, - AutoSizeDuration = 200, Padding = new MarginPadding { Horizontal = 20 }, } } @@ -231,7 +229,19 @@ namespace osu.Game.Overlays private void addContentToPlaceholder(Drawable content) { - currentContent?.FadeOut(100, Easing.OutQuint).Expire(); + Drawable lastContent = currentContent; + + if (lastContent != null) + { + lastContent.FadeOut(100, Easing.OutQuint).Expire(); + + // Consider the case when the new content is smaller than the last content. + // If the auto-size computation is delayed until fade out completes, the background remain high for too long making the resulting transition to the smaller height look weird. + // At the same time, if the last content's height is bypassed immediately, there is a period where the new content is at Alpha = 0 when the auto-sized height will be 0. + // To resolve both of these issues, the bypass is delayed until a point when the content transitions (fade-in and fade-out) overlap and it looks good to do so. + lastContent.Delay(25).Schedule(() => lastContent.BypassAutoSizeAxes = Axes.Y); + } + panelsPlaceholder.Add(currentContent = content); currentContent.FadeIn(200, Easing.OutQuint); } From 51f03d0f075489ecb67c4946d55a8cab5cd07ecd Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Thu, 20 Feb 2020 14:28:38 +0900 Subject: [PATCH 101/127] Adjust 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/Multi/Multiplayer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 07d930fa75..54af8ab107 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -109,7 +109,7 @@ namespace osu.Game.Screens.Multi new HeaderBackgroundSprite { RelativeSizeAxes = Axes.X, - Height = 400 // Keep a static height so the header doesn't change as it's resized + Height = 400 // Keep a static height so the header doesn't change as it's resized between subscreens }, } }, From 17b669fdf74c456515dbd1daca4d0a1a86625c75 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Feb 2020 14:32:16 +0900 Subject: [PATCH 102/127] Refactor to detail the sizing mode setting --- .../Screens/Multi/Components/OverlinedDisplay.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs b/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs index 600fa99a9a..71cabd8b50 100644 --- a/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs +++ b/osu.Game/Screens/Multi/Components/OverlinedDisplay.cs @@ -104,15 +104,13 @@ namespace osu.Game.Screens.Multi.Components new Dimension(AutoSizeAxes.HasFlag(Axes.Y) ? GridSizeMode.AutoSize : GridSizeMode.Distributed), }; - grid.AutoSizeAxes = Axes.None; - grid.RelativeSizeAxes = Axes.None; - grid.AutoSizeAxes = AutoSizeAxes; - grid.RelativeSizeAxes = ~AutoSizeAxes; + // Assigning to none is done so that setting auto and relative size modes doesn't cause exceptions to be thrown + grid.AutoSizeAxes = Content.AutoSizeAxes = Axes.None; + grid.RelativeSizeAxes = Content.RelativeSizeAxes = Axes.None; - Content.AutoSizeAxes = Axes.None; - Content.RelativeSizeAxes = Axes.None; - Content.AutoSizeAxes = grid.AutoSizeAxes; - Content.RelativeSizeAxes = grid.RelativeSizeAxes; + // Auto-size when required, otherwise eagerly relative-size + grid.AutoSizeAxes = Content.AutoSizeAxes = AutoSizeAxes; + grid.RelativeSizeAxes = Content.RelativeSizeAxes = ~AutoSizeAxes; } } } From c5fd969568c1c9c2e22acde5559007d55d5325ba Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Feb 2020 14:33:13 +0900 Subject: [PATCH 103/127] Fix 0 size in test scene --- .../Visual/Multiplayer/TestSceneOverlinedPlaylist.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs index 4e38f6d2c2..9a6273d075 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs @@ -27,12 +27,11 @@ namespace osu.Game.Tests.Visual.Multiplayer }); } - Add(new Container + Add(new OverlinedPlaylist(false) { Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(500), - Child = new OverlinedPlaylist(false) }); } } From 177935d644be16be513d48b9baa724aaf4b64a10 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Feb 2020 14:45:35 +0900 Subject: [PATCH 104/127] Remove unused using --- osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs index 9a6273d075..14b7934dc7 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneOverlinedPlaylist.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Game.Online.Multiplayer; using osu.Game.Rulesets.Osu; using osu.Game.Screens.Multi.Components; From 1a689231c2d14326d5b9b5525e9669e11d1fdaa7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Feb 2020 14:51:25 +0900 Subject: [PATCH 105/127] Support null leaderboard position --- .../SongSelect/TestSceneBeatmapLeaderboard.cs | 27 +++++++++++++++++++ .../API/Requests/Responses/APILegacyScores.cs | 2 +- .../Online/Leaderboards/LeaderboardScore.cs | 6 ++--- .../BeatmapSet/Scores/ScoresContainer.cs | 6 ++++- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs index 3eff75b020..1198488bda 100644 --- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs +++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapLeaderboard.cs @@ -59,6 +59,33 @@ namespace osu.Game.Tests.Visual.SongSelect AddStep(@"None selected", () => leaderboard.SetRetrievalState(PlaceholderState.NoneSelected)); foreach (BeatmapSetOnlineStatus status in Enum.GetValues(typeof(BeatmapSetOnlineStatus))) AddStep($"{status} beatmap", () => showBeatmapWithStatus(status)); + AddStep("null personal best position", showPersonalBestWithNullPosition); + } + + private void showPersonalBestWithNullPosition() + { + leaderboard.TopScore = new APILegacyUserTopScoreInfo + { + Position = null, + Score = new APILegacyScoreInfo + { + Rank = ScoreRank.XH, + Accuracy = 1, + MaxCombo = 244, + TotalScore = 1707827, + Mods = new[] { new OsuModHidden().Acronym, new OsuModHardRock().Acronym, }, + User = new User + { + Id = 6602580, + Username = @"waaiiru", + Country = new Country + { + FullName = @"Spain", + FlagName = @"ES", + }, + }, + } + }; } private void showPersonalBest() diff --git a/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs b/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs index 318fcb00de..75be9171b0 100644 --- a/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs +++ b/osu.Game/Online/API/Requests/Responses/APILegacyScores.cs @@ -18,7 +18,7 @@ namespace osu.Game.Online.API.Requests.Responses public class APILegacyUserTopScoreInfo { [JsonProperty(@"position")] - public int Position; + public int? Position; [JsonProperty(@"score")] public APILegacyScoreInfo Score; diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs index 1f52a4481b..ba92b993a2 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs @@ -41,7 +41,7 @@ namespace osu.Game.Online.Leaderboards protected Container RankContainer { get; private set; } private readonly ScoreInfo score; - private readonly int rank; + private readonly int? rank; private readonly bool allowHighlight; private Box background; @@ -58,7 +58,7 @@ namespace osu.Game.Online.Leaderboards [Resolved(CanBeNull = true)] private DialogOverlay dialogOverlay { get; set; } - public LeaderboardScore(ScoreInfo score, int rank, bool allowHighlight = true) + public LeaderboardScore(ScoreInfo score, int? rank, bool allowHighlight = true) { this.score = score; this.rank = rank; @@ -90,7 +90,7 @@ namespace osu.Game.Online.Leaderboards Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = OsuFont.GetFont(size: 20, italics: true), - Text = rank.ToMetric(decimals: rank < 100000 ? 1 : 0), + Text = rank == null ? "-" : rank.Value.ToMetric(decimals: rank < 100000 ? 1 : 0), }, }, }, diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 2d8bd10b13..0d0dd08a0f 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.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.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -70,7 +71,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores topScoresContainer.Add(new DrawableTopScore(topScore)); if (userScoreInfo != null && userScoreInfo.OnlineScoreID != topScore.OnlineScoreID) - topScoresContainer.Add(new DrawableTopScore(userScoreInfo, userScore.Position)); + { + Debug.Assert(userScore.Position != null); + topScoresContainer.Add(new DrawableTopScore(userScoreInfo, userScore.Position.Value)); + } }); } From d79ca97fe901affe1c91172d18e246a78a840c2c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 20 Feb 2020 15:04:12 +0900 Subject: [PATCH 106/127] Make beatmap scores also support null position --- .../Visual/Online/TestSceneScoresContainer.cs | 29 +++++++++++++++++++ .../BeatmapSet/Scores/DrawableTopScore.cs | 2 +- .../BeatmapSet/Scores/ScoresContainer.cs | 6 +--- .../BeatmapSet/Scores/TopScoreUserSection.cs | 4 +-- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs index 3c959e05c1..51f4089058 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs @@ -195,6 +195,29 @@ namespace osu.Game.Tests.Visual.Online Position = 1337, }; + var myBestScoreWithNullPosition = new APILegacyUserTopScoreInfo + { + Score = new APILegacyScoreInfo + { + User = new User + { + Id = 7151382, + Username = @"Mayuri Hana", + Country = new Country + { + FullName = @"Thailand", + FlagName = @"TH", + }, + }, + Rank = ScoreRank.D, + PP = 160, + MaxCombo = 1234, + TotalScore = 123456, + Accuracy = 0.6543, + }, + Position = null, + }; + var oneScore = new APILegacyScores { Scores = new List @@ -250,6 +273,12 @@ namespace osu.Game.Tests.Visual.Online allScores.UserScore = myBestScore; scoresContainer.Scores = allScores; }); + + AddStep("Load scores with null my best position", () => + { + allScores.UserScore = myBestScoreWithNullPosition; + scoresContainer.Scores = allScores; + }); } private class TestScoresContainer : ScoresContainer diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index bb85b4a37b..cad37dd082 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -17,7 +17,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores { private readonly Box background; - public DrawableTopScore(ScoreInfo score, int position = 1) + public DrawableTopScore(ScoreInfo score, int? position = 1) { RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 0d0dd08a0f..2d8bd10b13 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.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.Diagnostics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -71,10 +70,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores topScoresContainer.Add(new DrawableTopScore(topScore)); if (userScoreInfo != null && userScoreInfo.OnlineScoreID != topScore.OnlineScoreID) - { - Debug.Assert(userScore.Position != null); - topScoresContainer.Add(new DrawableTopScore(userScoreInfo, userScore.Position.Value)); - } + topScoresContainer.Add(new DrawableTopScore(userScoreInfo, userScore.Position)); }); } diff --git a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs index 8a368aa535..9a67ea2b24 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/TopScoreUserSection.cs @@ -112,9 +112,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }; } - public int ScorePosition + public int? ScorePosition { - set => rankText.Text = $"#{value}"; + set => rankText.Text = value == null ? "-" : $"#{value}"; } /// From 5970c102b4e25f7573d4375358a51a79cc4617c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 15:14:40 +0900 Subject: [PATCH 107/127] Change API to be easier to understand --- .../Objects/Drawables/DrawableOsuHitObject.cs | 4 ---- .../Objects/Drawables/DrawableHitObject.cs | 23 ++++++++++++------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 1bb72a3176..a677cb6a72 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.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.Collections.Generic; using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Graphics.Containers; -using osuTK.Graphics; namespace osu.Game.Rulesets.Osu.Objects.Drawables { @@ -56,8 +54,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } - protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) => AccentColour.Value = proposedColour; - protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(HitObject, judgement); } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index c5ce490845..67fe18e8dd 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -346,20 +346,27 @@ namespace osu.Game.Rulesets.Objects.Drawables private void updateComboColour() { - if (HitObject is IHasComboInformation combo) - { - var comboColours = CurrentSkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; - UpdateComboColour(comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White, comboColours); - } + if (!(HitObject is IHasComboInformation)) return; + + var comboColours = CurrentSkin.GetConfig>(GlobalSkinColours.ComboColours)?.Value; + + AccentColour.Value = GetComboColour(comboColours); } /// - /// Called when a combo colour change is proposed. + /// Called to retrieve the combo colour. Automatically assigned to . + /// Defaults to using to decide on a colour. /// - /// The proposed combo colour, based off the combo index. + /// + /// This will only be called if the implements . + /// /// A list of combo colours provided by the beatmap or skin. Can be null if not available. - protected virtual void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) + protected virtual Color4 GetComboColour(IReadOnlyList comboColours) { + if (!(HitObject is IHasComboInformation combo)) + throw new InvalidOperationException($"{nameof(HitObject)} must implement {nameof(IHasComboInformation)}"); + + return comboColours?.Count > 0 ? comboColours[combo.ComboIndex % comboColours.Count] : Color4.White; } /// From 337a7986cf7ca5492bf9a0eaf1616e616faee12d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 15:19:12 +0900 Subject: [PATCH 108/127] Fix reference in test scene --- osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs index 7469771e0b..17dc27543d 100644 --- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs +++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs @@ -76,8 +76,6 @@ namespace osu.Game.Tests.Gameplay : base(new TestHitObjectWithCombo()) { } - - protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) => AccentColour.Value = proposedColour; } private class TestHitObjectWithCombo : HitObject, IHasComboInformation From 2869128e1165b1436c6ee4140dfa9e68554ed6b3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 15:37:15 +0900 Subject: [PATCH 109/127] Update in line with combo colour API changes --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs | 4 ++-- .../Objects/Drawable/DrawableCatchHitObject.cs | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs index 8625b93786..672ff2cb3a 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs @@ -16,10 +16,10 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable private Color4? colour; - protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) + protected override Color4 GetComboColour(IReadOnlyList comboColours) { // override any external colour changes with banananana - AccentColour.Value = (colour ??= getBananaColour()); + return colour ??= getBananaColour(); } private Color4 getBananaColour() diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index 188de6a6ae..3293f41eab 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -45,11 +45,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable ScaleContainer.Scale = new Vector2(HitObject.Scale); } - protected override void UpdateComboColour(Color4 proposedColour, IReadOnlyList comboColours) - { - // ignore the incoming combo colour as we use a custom lookup - AccentColour.Value = comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count]; - } + protected override Color4 GetComboColour(IReadOnlyList comboColours) => + comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count]; } public abstract class DrawableCatchHitObject : DrawableCatchHitObject From 5551343cf34c235326c75547234dab714f73a7ce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 15:45:25 +0900 Subject: [PATCH 110/127] Throw instead of null return --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index f76055e1ea..e1e6708bd8 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable ((DrawableCatchHitObject)o).CheckPosition = p => CheckPosition?.Invoke(p) ?? false); } - return null; + throw new ArgumentException($"{nameof(hitObject)} must be of type {nameof(CatchHitObject)}."); } } } From 8f5d3896f65f2ee79d0d18b18ee66b0f378b87c8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 15:45:47 +0900 Subject: [PATCH 111/127] Remove unnecessary cast by changing method siganture --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 9ded0ff891..49e535890d 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -221,9 +221,9 @@ namespace osu.Game.Rulesets.Catch.UI /// Add a caught fruit to the catcher's stack. /// /// The fruit that was caught. - public void PlaceOnPlate(DrawableHitObject fruit) + public void PlaceOnPlate(DrawableCatchHitObject fruit) { - float ourRadius = ((DrawableCatchHitObject)fruit).DisplayRadius; + float ourRadius = fruit.DisplayRadius; float theirRadius = 0; const float allowance = 6; From 049975b5a46bce96baee5132d12157a01d2a7653 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 15:45:54 +0900 Subject: [PATCH 112/127] Use kebaberize shorthand --- osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs index f8d0880c72..36164c5543 100644 --- a/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/CatchLegacySkinTransformer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.Skinning case CatchSkinComponents.FruitOrange: case CatchSkinComponents.FruitGrapes: case CatchSkinComponents.FruitPear: - var lookupName = catchSkinComponent.Component.ToString().Underscore().Hyphenate(); + var lookupName = catchSkinComponent.Component.ToString().Kebaberize(); if (GetTexture(lookupName) != null) return new LegacyFruitPiece(lookupName); From a11862ba0da03fa909642d770a0450c48b4bd1ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 18:03:53 +0900 Subject: [PATCH 113/127] Improve transition between multiplayer screens (and share constants) --- osu.Game/Screens/Multi/Multiplayer.cs | 8 ++--- .../Screens/Multi/MultiplayerSubScreen.cs | 29 ++++++++++++------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 54af8ab107..27ad7c9bc1 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -305,13 +305,13 @@ namespace osu.Game.Screens.Multi switch (newScreen) { case LoungeSubScreen _: - header.ResizeHeightTo(400, WaveContainer.APPEAR_DURATION, Easing.OutQuint); - headerBackground.MoveToX(0, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); + header.Delay(MultiplayerSubScreen.RESUME_TRANSITION_DELAY).ResizeHeightTo(400, MultiplayerSubScreen.APPEAR_DURATION, Easing.OutQuint); + headerBackground.MoveToX(0, MultiplayerSubScreen.X_MOVE_DURATION, Easing.OutQuint); break; case MatchSubScreen _: - header.ResizeHeightTo(135, WaveContainer.APPEAR_DURATION, Easing.OutQuint); - headerBackground.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); + header.ResizeHeightTo(135, MultiplayerSubScreen.APPEAR_DURATION, Easing.OutQuint); + headerBackground.MoveToX(-MultiplayerSubScreen.X_SHIFT, MultiplayerSubScreen.X_MOVE_DURATION, Easing.OutQuint); break; } diff --git a/osu.Game/Screens/Multi/MultiplayerSubScreen.cs b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs index ff94f63f01..8e46de1a95 100644 --- a/osu.Game/Screens/Multi/MultiplayerSubScreen.cs +++ b/osu.Game/Screens/Multi/MultiplayerSubScreen.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Screens; -using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Multi { @@ -24,31 +23,41 @@ namespace osu.Game.Screens.Multi RelativeSizeAxes = Axes.Both; } + public const float X_SHIFT = 200; + + public const double X_MOVE_DURATION = 800; + + public const double RESUME_TRANSITION_DELAY = DISAPPEAR_DURATION / 2; + + public const double APPEAR_DURATION = 800; + + public const double DISAPPEAR_DURATION = 500; + public override void OnEntering(IScreen last) { - this.FadeInFromZero(WaveContainer.APPEAR_DURATION, Easing.OutQuint); - this.FadeInFromZero(WaveContainer.APPEAR_DURATION, Easing.OutQuint); - this.MoveToX(200).MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint); + this.FadeInFromZero(APPEAR_DURATION, Easing.OutQuint); + this.FadeInFromZero(APPEAR_DURATION, Easing.OutQuint); + this.MoveToX(X_SHIFT).MoveToX(0, X_MOVE_DURATION, Easing.OutQuint); } public override bool OnExiting(IScreen next) { - this.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); - this.MoveToX(200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); + this.FadeOut(DISAPPEAR_DURATION, Easing.OutQuint); + this.MoveToX(X_SHIFT, X_MOVE_DURATION, Easing.OutQuint); return false; } public override void OnResuming(IScreen last) { - this.FadeIn(WaveContainer.APPEAR_DURATION, Easing.OutQuint); - this.MoveToX(0, WaveContainer.APPEAR_DURATION, Easing.OutQuint); + this.Delay(RESUME_TRANSITION_DELAY).FadeIn(APPEAR_DURATION, Easing.OutQuint); + this.MoveToX(0, X_MOVE_DURATION, Easing.OutQuint); } public override void OnSuspending(IScreen next) { - this.FadeOut(WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); - this.MoveToX(-200, WaveContainer.DISAPPEAR_DURATION, Easing.OutQuint); + this.FadeOut(DISAPPEAR_DURATION, Easing.OutQuint); + this.MoveToX(-X_SHIFT, X_MOVE_DURATION, Easing.OutQuint); } public override string ToString() => Title; From 063fe191ef3ade3f2dff7f62ec33d29cb61a4859 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 18:15:40 +0900 Subject: [PATCH 114/127] Add back missing using --- osu.Game/Screens/Multi/Match/MatchSubScreen.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs index 38a1e8092c..eef53126c0 100644 --- a/osu.Game/Screens/Multi/Match/MatchSubScreen.cs +++ b/osu.Game/Screens/Multi/Match/MatchSubScreen.cs @@ -13,6 +13,7 @@ using osu.Game.Beatmaps; using osu.Game.Online.Multiplayer; using osu.Game.Online.Multiplayer.GameTypes; using osu.Game.Rulesets.Mods; +using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Multi.Play; using osu.Game.Screens.Select; From 973093b5220ff8cee9b02f5e11ee43447466551d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 18:32:28 +0900 Subject: [PATCH 115/127] Fix non-selectable playlist items not forwarding clicks to children --- osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs index ca85aec4e4..a7ed1f5846 100644 --- a/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/Multi/DrawableRoomPlaylistItem.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Multi private readonly bool allowEdit; private readonly bool allowSelection; - protected override bool ShouldBeConsideredForInput(Drawable child) => allowEdit || SelectedItem.Value == Model; + protected override bool ShouldBeConsideredForInput(Drawable child) => allowEdit || !allowSelection || SelectedItem.Value == Model; public DrawableRoomPlaylistItem(PlaylistItem item, bool allowEdit, bool allowSelection) : base(item) From 76c57a695bec92daa773801203f130f2daf54a2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 18:28:20 +0900 Subject: [PATCH 116/127] Change create room button colouring to match design --- osu.Game/Screens/Multi/Multiplayer.cs | 45 ++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 27ad7c9bc1..235ca9ec04 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -19,7 +19,6 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Input; using osu.Game.Online.API; using osu.Game.Online.Multiplayer; -using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Screens.Menu; using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Lounge; @@ -129,22 +128,11 @@ namespace osu.Game.Screens.Multi } }, new Header(screenStack), - createButton = new HeaderButton + createButton = new CreateRoomButton { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.None, - Size = new Vector2(150, Header.HEIGHT - 20), - Margin = new MarginPadding - { - Top = 10, - Right = 10 + HORIZONTAL_OVERFLOW_PADDING, - }, - Text = "Create room", - Action = () => loungeSubScreen.Open(new Room - { - Name = { Value = $"{api.LocalUser}'s awesome room" } - }), + Action = createRoom }, roomManager = new RoomManager() } @@ -276,6 +264,11 @@ namespace osu.Game.Screens.Multi logo.Delay(WaveContainer.DISAPPEAR_DURATION / 2).FadeOut(); } + private void createRoom() + { + loungeSubScreen.Open(new Room { Name = { Value = $"{api.LocalUser}'s awesome room" } }); + } + private void beginHandlingTrack() { Beatmap.BindValueChanged(updateTrack, true); @@ -381,5 +374,29 @@ namespace osu.Game.Screens.Multi protected override double TransformDuration => 200; } } + + public class CreateRoomButton : TriangleButton + { + public CreateRoomButton() + { + Size = new Vector2(150, Header.HEIGHT - 20); + Margin = new MarginPadding + { + Top = 10, + Right = 10 + HORIZONTAL_OVERFLOW_PADDING, + }; + } + + [BackgroundDependencyLoader] + private void load() + { + BackgroundColour = OsuColour.FromHex(@"593790"); + Triangles.ColourLight = OsuColour.FromHex(@"7247b6"); + Triangles.ColourDark = OsuColour.FromHex(@"593790"); + Triangles.TriangleScale = 1.5f; + + Text = "Create room"; + } + } } } From e7fca689b1ec13bf4ec0d4581badabb992dd598b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 18:34:24 +0900 Subject: [PATCH 117/127] Change text on playlist add button to be nicer --- osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs b/osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs index 8e085d6979..2c5fd2d397 100644 --- a/osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs +++ b/osu.Game/Screens/Multi/Components/MatchBeatmapDetailArea.cs @@ -53,7 +53,7 @@ namespace osu.Game.Screens.Multi.Components { new TriangleButton { - Text = "create new item", + Text = "Add new playlist entry", RelativeSizeAxes = Axes.Both, Size = Vector2.One, Action = () => CreateNewItem?.Invoke() From a0b578082e459e706ebec315109324b6f1ffffc3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 18:39:10 +0900 Subject: [PATCH 118/127] Make ready button also have triangles --- osu.Game/Screens/Multi/Match/Components/Footer.cs | 1 - osu.Game/Screens/Multi/Match/Components/ReadyButton.cs | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Multi/Match/Components/Footer.cs b/osu.Game/Screens/Multi/Match/Components/Footer.cs index 93430d9131..199563c698 100644 --- a/osu.Game/Screens/Multi/Match/Components/Footer.cs +++ b/osu.Game/Screens/Multi/Match/Components/Footer.cs @@ -47,7 +47,6 @@ namespace osu.Game.Screens.Multi.Match.Components private void load(OsuColour colours) { background.Colour = OsuColour.FromHex(@"28242d"); - startButton.BackgroundColour = colours.Green; } } } diff --git a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs index d39217db5d..8f484d3672 100644 --- a/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs +++ b/osu.Game/Screens/Multi/Match/Components/ReadyButton.cs @@ -6,12 +6,13 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Game.Beatmaps; +using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; namespace osu.Game.Screens.Multi.Match.Components { - public class ReadyButton : OsuButton + public class ReadyButton : TriangleButton { public readonly Bindable SelectedItem = new Bindable(); @@ -32,12 +33,16 @@ namespace osu.Game.Screens.Multi.Match.Components } [BackgroundDependencyLoader] - private void load() + private void load(OsuColour colours) { beatmaps.ItemAdded += beatmapAdded; beatmaps.ItemRemoved += beatmapRemoved; SelectedItem.BindValueChanged(item => updateSelectedItem(item.NewValue), true); + + BackgroundColour = colours.Green; + Triangles.ColourDark = colours.Green; + Triangles.ColourLight = colours.GreenLight; } private void updateSelectedItem(PlaylistItem item) From 4a3f281855784ffaf7bf67f3c1ce5eaa335b8445 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 18:43:47 +0900 Subject: [PATCH 119/127] Make buttons purple --- .../Screens/Multi/Match/Components/Footer.cs | 4 +--- .../Match/Components/MatchSettingsOverlay.cs | 7 ++----- .../Match/Components/PurpleTriangleButton.cs | 20 +++++++++++++++++++ osu.Game/Screens/Multi/Multiplayer.cs | 6 ++---- 4 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 osu.Game/Screens/Multi/Match/Components/PurpleTriangleButton.cs diff --git a/osu.Game/Screens/Multi/Match/Components/Footer.cs b/osu.Game/Screens/Multi/Match/Components/Footer.cs index 199563c698..c0c866d815 100644 --- a/osu.Game/Screens/Multi/Match/Components/Footer.cs +++ b/osu.Game/Screens/Multi/Match/Components/Footer.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; using osu.Game.Online.Multiplayer; using osuTK; @@ -22,7 +21,6 @@ namespace osu.Game.Screens.Multi.Match.Components public readonly Bindable SelectedItem = new Bindable(); private readonly Drawable background; - private readonly OsuButton startButton; public Footer() { @@ -32,7 +30,7 @@ namespace osu.Game.Screens.Multi.Match.Components InternalChildren = new[] { background = new Box { RelativeSizeAxes = Axes.Both }, - startButton = new ReadyButton + new ReadyButton { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index e3110cdfc8..97485cd5a1 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -226,7 +226,7 @@ namespace osu.Game.Screens.Multi.Match.Components }, new Drawable[] { - new OsuButton + new PurpleTriangleButton { RelativeSizeAxes = Axes.X, Height = 40, @@ -447,10 +447,7 @@ namespace osu.Game.Screens.Multi.Match.Components Menu.MaxHeight = 100; } - protected override string GenerateItemText(TimeSpan item) - { - return item.Humanize(); - } + protected override string GenerateItemText(TimeSpan item) => item.Humanize(); } } } diff --git a/osu.Game/Screens/Multi/Match/Components/PurpleTriangleButton.cs b/osu.Game/Screens/Multi/Match/Components/PurpleTriangleButton.cs new file mode 100644 index 0000000000..8a0369ceba --- /dev/null +++ b/osu.Game/Screens/Multi/Match/Components/PurpleTriangleButton.cs @@ -0,0 +1,20 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Multi.Match.Components +{ + public class PurpleTriangleButton : TriangleButton + { + [BackgroundDependencyLoader] + private void load() + { + BackgroundColour = OsuColour.FromHex(@"593790"); + Triangles.ColourLight = OsuColour.FromHex(@"7247b6"); + Triangles.ColourDark = OsuColour.FromHex(@"593790"); + } + } +} diff --git a/osu.Game/Screens/Multi/Multiplayer.cs b/osu.Game/Screens/Multi/Multiplayer.cs index 235ca9ec04..1219919425 100644 --- a/osu.Game/Screens/Multi/Multiplayer.cs +++ b/osu.Game/Screens/Multi/Multiplayer.cs @@ -24,6 +24,7 @@ using osu.Game.Screens.Multi.Components; using osu.Game.Screens.Multi.Lounge; using osu.Game.Screens.Multi.Lounge.Components; using osu.Game.Screens.Multi.Match; +using osu.Game.Screens.Multi.Match.Components; using osu.Game.Screens.Play; using osuTK; @@ -375,7 +376,7 @@ namespace osu.Game.Screens.Multi } } - public class CreateRoomButton : TriangleButton + public class CreateRoomButton : PurpleTriangleButton { public CreateRoomButton() { @@ -390,9 +391,6 @@ namespace osu.Game.Screens.Multi [BackgroundDependencyLoader] private void load() { - BackgroundColour = OsuColour.FromHex(@"593790"); - Triangles.ColourLight = OsuColour.FromHex(@"7247b6"); - Triangles.ColourDark = OsuColour.FromHex(@"593790"); Triangles.TriangleScale = 1.5f; Text = "Create room"; From 3380dbbd71ed950d07c006947c1d7b1ef0cec227 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 20 Feb 2020 19:47:50 +0900 Subject: [PATCH 120/127] Improve visual appearance of ProcessingOverlay --- .../TestSceneProcessingOverlay.cs | 86 +++++ .../UserInterface/ProcessingOverlay.cs | 58 ++- .../Overlays/AccountCreation/ScreenEntry.cs | 6 +- .../Screens/Multi/Lounge/LoungeSubScreen.cs | 6 +- .../Match/Components/MatchSettingsOverlay.cs | 359 +++++++++--------- 5 files changed, 323 insertions(+), 192 deletions(-) create mode 100644 osu.Game.Tests/Visual/UserInterface/TestSceneProcessingOverlay.cs diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneProcessingOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneProcessingOverlay.cs new file mode 100644 index 0000000000..2424078e5a --- /dev/null +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneProcessingOverlay.cs @@ -0,0 +1,86 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Tests.Visual.UserInterface +{ + public class TestSceneProcessingOverlay : OsuTestScene + { + private Drawable dimContent; + private ProcessingOverlay overlay; + + [SetUp] + public void SetUp() => Schedule(() => + { + Children = new[] + { + new Container + { + Size = new Vector2(300), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new[] + { + new Box + { + Colour = Color4.SlateGray, + RelativeSizeAxes = Axes.Both, + }, + dimContent = new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Direction = FillDirection.Vertical, + Spacing = new Vector2(10), + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.9f), + Children = new Drawable[] + { + new OsuSpriteText { Text = "Sample content" }, + new TriangleButton { Text = "can't puush me", Width = 200, }, + new TriangleButton { Text = "puush me", Width = 200, Action = () => { } }, + } + }, + overlay = new ProcessingOverlay(dimContent), + } + }, + }; + }); + + [Test] + public void ShowHide() + { + AddAssert("not visible", () => !overlay.IsPresent); + + AddStep("show", () => overlay.Show()); + + AddUntilStep("wait for content dim", () => dimContent.Colour != Color4.White); + + AddStep("hide", () => overlay.Hide()); + + AddUntilStep("wait for content restore", () => dimContent.Colour == Color4.White); + } + + [Test] + public void ContentRestoreOnDispose() + { + AddAssert("not visible", () => !overlay.IsPresent); + + AddStep("show", () => overlay.Show()); + + AddUntilStep("wait for content dim", () => dimContent.Colour != Color4.White); + + AddStep("hide", () => overlay.Expire()); + + AddUntilStep("wait for content restore", () => dimContent.Colour == Color4.White); + } + } +} diff --git a/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs b/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs index d75e78e2d9..181cfd831e 100644 --- a/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs +++ b/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs @@ -6,20 +6,27 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osuTK; using osuTK.Graphics; namespace osu.Game.Graphics.UserInterface { /// - /// An overlay that will consume all available space and block input when required. + /// An overlay that will show a loading overlay and completely block input to an area. + /// Also optionally dims target elements. /// Useful for disabling all elements in a form and showing we are waiting on a response, for instance. /// public class ProcessingOverlay : VisibilityContainer { - private const float transition_duration = 200; + private readonly Drawable dimTarget; - public ProcessingOverlay() + private Container loadingBox; + + private const float transition_duration = 600; + + public ProcessingOverlay(Drawable dimTarget = null) { + this.dimTarget = dimTarget; RelativeSizeAxes = Axes.Both; } @@ -28,29 +35,54 @@ namespace osu.Game.Graphics.UserInterface { InternalChildren = new Drawable[] { - new Box + loadingBox = new Container { - Colour = Color4.Black, - RelativeSizeAxes = Axes.Both, - Alpha = 0.9f, + Size = new Vector2(80), + Scale = new Vector2(0.8f), + Masking = true, + CornerRadius = 15, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + new Box + { + Colour = Color4.Black, + RelativeSizeAxes = Axes.Both, + }, + new LoadingAnimation { State = { Value = Visibility.Visible } } + } }, - new LoadingAnimation { State = { Value = Visibility.Visible } } }; } - protected override bool Handle(UIEvent e) - { - return true; - } + protected override bool Handle(UIEvent e) => true; protected override void PopIn() { - this.FadeIn(transition_duration * 2, Easing.OutQuint); + this.FadeIn(transition_duration, Easing.OutQuint); + loadingBox.ScaleTo(1, transition_duration, Easing.OutElastic); + + dimTarget?.FadeColour(OsuColour.Gray(0.5f), transition_duration, Easing.OutQuint); } protected override void PopOut() { this.FadeOut(transition_duration, Easing.OutQuint); + loadingBox.ScaleTo(0.8f, transition_duration / 2, Easing.In); + + dimTarget?.FadeColour(Color4.White, transition_duration, Easing.OutQuint); + } + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (State.Value == Visibility.Visible) + { + // ensure we don't leave the targetin a bad state. + dimTarget?.FadeColour(Color4.White, transition_duration); + } } } } diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs index be3a84ca00..454fce0261 100644 --- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs +++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs @@ -48,9 +48,11 @@ namespace osu.Game.Overlays.AccountCreation [BackgroundDependencyLoader] private void load(OsuColour colours) { + FillFlowContainer mainContent; + InternalChildren = new Drawable[] { - new FillFlowContainer + mainContent = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, @@ -122,7 +124,7 @@ namespace osu.Game.Overlays.AccountCreation }, }, }, - processingOverlay = new ProcessingOverlay { Alpha = 0 } + processingOverlay = new ProcessingOverlay(mainContent) }; textboxes = new[] { usernameTextBox, emailTextBox, passwordTextBox }; diff --git a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs index 3709b85fcb..58e4548ee2 100644 --- a/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/Multi/Lounge/LoungeSubScreen.cs @@ -30,6 +30,8 @@ namespace osu.Game.Screens.Multi.Lounge public LoungeSubScreen() { + SearchContainer searchContainer; + InternalChildren = new Drawable[] { Filter = new FilterControl { Depth = -1 }, @@ -49,14 +51,14 @@ namespace osu.Game.Screens.Multi.Lounge RelativeSizeAxes = Axes.Both, ScrollbarOverlapsContent = false, Padding = new MarginPadding(10), - Child = new SearchContainer + Child = searchContainer = new SearchContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Child = new RoomsContainer { JoinRequested = joinRequested } }, }, - processingOverlay = new ProcessingOverlay { Alpha = 0 } + processingOverlay = new ProcessingOverlay(searchContainer), } }, new RoomInspector diff --git a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs index 97485cd5a1..8c005a2647 100644 --- a/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs +++ b/osu.Game/Screens/Multi/Match/Components/MatchSettingsOverlay.cs @@ -79,226 +79,235 @@ namespace osu.Game.Screens.Multi.Match.Components [BackgroundDependencyLoader] private void load(OsuColour colours) { + Container dimContent; + InternalChildren = new Drawable[] { - new Box + dimContent = new Container { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"28242d"), - }, - new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] + Children = new Drawable[] { - new Dimension(GridSizeMode.Distributed), - new Dimension(GridSizeMode.AutoSize), - }, - Content = new[] - { - new Drawable[] + new Box { - new OsuScrollContainer + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"28242d"), + }, + new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] { - Padding = new MarginPadding + new Dimension(GridSizeMode.Distributed), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] { - Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING, - Vertical = 10 - }, - RelativeSizeAxes = Axes.Both, - Children = new[] - { - new Container + new OsuScrollContainer { - Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] + Padding = new MarginPadding { - new SectionContainer + Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING, + Vertical = 10 + }, + RelativeSizeAxes = Axes.Both, + Children = new[] + { + new Container { - Padding = new MarginPadding { Right = field_padding / 2 }, - Children = new[] + Padding = new MarginPadding { Horizontal = SearchableListOverlay.WIDTH_PADDING }, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] { - new Section("Room name") + new SectionContainer { - Child = NameField = new SettingsTextBox + Padding = new MarginPadding { Right = field_padding / 2 }, + Children = new[] { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - OnCommit = (sender, text) => apply(), - }, - }, - new Section("Duration") - { - Child = DurationField = new DurationDropdown - { - RelativeSizeAxes = Axes.X, - Items = new[] + new Section("Room name") { - TimeSpan.FromMinutes(30), - TimeSpan.FromHours(1), - TimeSpan.FromHours(2), - TimeSpan.FromHours(4), - TimeSpan.FromHours(8), - TimeSpan.FromHours(12), - //TimeSpan.FromHours(16), - TimeSpan.FromHours(24), - TimeSpan.FromDays(3), - TimeSpan.FromDays(7) - } - } - }, - new Section("Room visibility") - { - Alpha = disabled_alpha, - Child = AvailabilityPicker = new RoomAvailabilityPicker - { - Enabled = { Value = false } - }, - }, - new Section("Game type") - { - Alpha = disabled_alpha, - Child = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Direction = FillDirection.Vertical, - Spacing = new Vector2(7), - Children = new Drawable[] - { - TypePicker = new GameTypePicker + Child = NameField = new SettingsTextBox { RelativeSizeAxes = Axes.X, - Enabled = { Value = false } - }, - typeLabel = new OsuSpriteText - { - Font = OsuFont.GetFont(size: 14), - Colour = colours.Yellow + TabbableContentContainer = this, + OnCommit = (sender, text) => apply(), }, }, - }, - }, - new Section("Max participants") - { - Alpha = disabled_alpha, - Child = MaxParticipantsField = new SettingsNumberTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - ReadOnly = true, - OnCommit = (sender, text) => apply() - }, - }, - new Section("Password (optional)") - { - Alpha = disabled_alpha, - Child = new SettingsPasswordTextBox - { - RelativeSizeAxes = Axes.X, - TabbableContentContainer = this, - ReadOnly = true, - OnCommit = (sender, text) => apply() - }, - }, - }, - }, - new SectionContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Padding = new MarginPadding { Left = field_padding / 2 }, - Children = new[] - { - new Section("Playlist") - { - Child = new GridContainer - { - RelativeSizeAxes = Axes.X, - Height = 300, - Content = new[] + new Section("Duration") { - new Drawable[] + Child = DurationField = new DurationDropdown { - playlist = new DrawableRoomPlaylist(true, true) { RelativeSizeAxes = Axes.Both } - }, - new Drawable[] - { - new PurpleTriangleButton + RelativeSizeAxes = Axes.X, + Items = new[] { - RelativeSizeAxes = Axes.X, - Height = 40, - Text = "Edit playlist", - Action = () => EditPlaylist?.Invoke() + TimeSpan.FromMinutes(30), + TimeSpan.FromHours(1), + TimeSpan.FromHours(2), + TimeSpan.FromHours(4), + TimeSpan.FromHours(8), + TimeSpan.FromHours(12), + //TimeSpan.FromHours(16), + TimeSpan.FromHours(24), + TimeSpan.FromDays(3), + TimeSpan.FromDays(7) } } }, - RowDimensions = new[] + new Section("Room visibility") { - new Dimension(), - new Dimension(GridSizeMode.AutoSize), - } - } + Alpha = disabled_alpha, + Child = AvailabilityPicker = new RoomAvailabilityPicker + { + Enabled = { Value = false } + }, + }, + new Section("Game type") + { + Alpha = disabled_alpha, + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Direction = FillDirection.Vertical, + Spacing = new Vector2(7), + Children = new Drawable[] + { + TypePicker = new GameTypePicker + { + RelativeSizeAxes = Axes.X, + Enabled = { Value = false } + }, + typeLabel = new OsuSpriteText + { + Font = OsuFont.GetFont(size: 14), + Colour = colours.Yellow + }, + }, + }, + }, + new Section("Max participants") + { + Alpha = disabled_alpha, + Child = MaxParticipantsField = new SettingsNumberTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + ReadOnly = true, + OnCommit = (sender, text) => apply() + }, + }, + new Section("Password (optional)") + { + Alpha = disabled_alpha, + Child = new SettingsPasswordTextBox + { + RelativeSizeAxes = Axes.X, + TabbableContentContainer = this, + ReadOnly = true, + OnCommit = (sender, text) => apply() + }, + }, + }, + }, + new SectionContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Padding = new MarginPadding { Left = field_padding / 2 }, + Children = new[] + { + new Section("Playlist") + { + Child = new GridContainer + { + RelativeSizeAxes = Axes.X, + Height = 300, + Content = new[] + { + new Drawable[] + { + playlist = new DrawableRoomPlaylist(true, true) { RelativeSizeAxes = Axes.Both } + }, + new Drawable[] + { + new PurpleTriangleButton + { + RelativeSizeAxes = Axes.X, + Height = 40, + Text = "Edit playlist", + Action = () => EditPlaylist?.Invoke() + } + } + }, + RowDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + } + } + }, + }, }, }, - }, + } }, - } - }, - }, - }, - new Drawable[] - { - new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Y = 2, - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex(@"28242d").Darken(0.5f).Opacity(1f), }, - new FillFlowContainer + }, + new Drawable[] + { + new Container { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Y = 2, RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Margin = new MarginPadding { Vertical = 20 }, - Padding = new MarginPadding { Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, Children = new Drawable[] { - ApplyButton = new CreateRoomButton + new Box { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Size = new Vector2(230, 55), - Enabled = { Value = false }, - Action = apply, + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex(@"28242d").Darken(0.5f).Opacity(1f), }, - ErrorText = new OsuSpriteText + new FillFlowContainer { - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - Alpha = 0, - Depth = 1, - Colour = colours.RedDark + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Margin = new MarginPadding { Vertical = 20 }, + Padding = new MarginPadding { Horizontal = OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, + Children = new Drawable[] + { + ApplyButton = new CreateRoomButton + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(230, 55), + Enabled = { Value = false }, + Action = apply, + }, + ErrorText = new OsuSpriteText + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Alpha = 0, + Depth = 1, + Colour = colours.RedDark + } + } } } } } } - } + }, } }, - processingOverlay = new ProcessingOverlay { Alpha = 0 } + processingOverlay = new ProcessingOverlay(dimContent) }; TypePicker.Current.BindValueChanged(type => typeLabel.Text = type.NewValue?.Name ?? string.Empty, true); From 7adedcb7b973a59ead594a0fdfa1d74035ff2405 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Fri, 21 Feb 2020 08:34:51 +0900 Subject: [PATCH 121/127] Fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Bartłomiej Dach --- osu.Game/Graphics/UserInterface/ProcessingOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs b/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs index 181cfd831e..8109f3bd94 100644 --- a/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs +++ b/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs @@ -80,7 +80,7 @@ namespace osu.Game.Graphics.UserInterface if (State.Value == Visibility.Visible) { - // ensure we don't leave the targetin a bad state. + // ensure we don't leave the target in a bad state. dimTarget?.FadeColour(Color4.White, transition_duration); } } From 6c21cc3926f2b0d523a08dadb6cc74dc43d61a21 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Feb 2020 08:55:12 +0900 Subject: [PATCH 122/127] Adjust easing type to match in disposal clause Co-Authored-By: Dan Balasescu --- osu.Game/Graphics/UserInterface/ProcessingOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs b/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs index 8109f3bd94..c65801a82e 100644 --- a/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs +++ b/osu.Game/Graphics/UserInterface/ProcessingOverlay.cs @@ -81,7 +81,7 @@ namespace osu.Game.Graphics.UserInterface if (State.Value == Visibility.Visible) { // ensure we don't leave the target in a bad state. - dimTarget?.FadeColour(Color4.White, transition_duration); + dimTarget?.FadeColour(Color4.White, transition_duration, Easing.OutQuint); } } } From 6468bfa54324231bae6325e149ea445c3eddfb07 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Feb 2020 10:01:38 +0900 Subject: [PATCH 123/127] Apply adjustments --- .../Objects/Drawable/DrawableCatchHitObject.cs | 2 +- .../Objects/Drawable/DrawableDroplet.cs | 12 +++++------- .../Objects/Drawable/DrawableTinyDroplet.cs | 2 +- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index 3293f41eab..ed9e797154 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public override bool CanBePlated => true; - protected Container ScaleContainer; + protected Container ScaleContainer { get; private set; } protected PalpableCatchHitObject(TObject hitObject) : base(hitObject) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 4e8faed091..ef3be7e2ba 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using osu.Game.Skinning; -using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -20,12 +19,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable [BackgroundDependencyLoader] private void load() { - ScaleContainer.Child = new SkinnableDrawable( - new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp - { - Size = Size / 4, - AccentColour = { Value = Color4.White } - }); + ScaleContainer.Child = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.Droplet), _ => new Pulp + { + Size = Size / 4, + AccentColour = { BindTarget = AccentColour } + }); } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs index 4fe1f86f2b..873e5a3ebb 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable [BackgroundDependencyLoader] private void load() { - Scale /= 2; + ScaleContainer.Scale /= 2; } } } From d275bc8a6150125f9423e2cb0d831c3fd0651e7b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Feb 2020 10:44:48 +0900 Subject: [PATCH 124/127] Add test steps for droplet / tiny droplet --- .../TestSceneFruitObjects.cs | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs index b106ee2f77..78339de380 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs @@ -38,9 +38,51 @@ namespace osu.Game.Rulesets.Catch.Tests foreach (FruitVisualRepresentation rep in Enum.GetValues(typeof(FruitVisualRepresentation))) AddStep($"show {rep}", () => SetContents(() => createDrawable(rep))); + + AddStep("show droplet", () => SetContents(createDrawableDroplet)); + + AddStep("show tiny droplet", () => SetContents(createDrawableTinyDroplet)); } - private DrawableFruit createDrawable(FruitVisualRepresentation rep) + private Drawable createDrawableTinyDroplet() + { + var droplet = new TinyDroplet + { + StartTime = Clock.CurrentTime, + Scale = 1.5f, + }; + + return new DrawableTinyDroplet(droplet) + { + Anchor = Anchor.Centre, + RelativePositionAxes = Axes.None, + Position = Vector2.Zero, + Alpha = 1, + LifetimeStart = double.NegativeInfinity, + LifetimeEnd = double.PositiveInfinity, + }; + } + + private Drawable createDrawableDroplet() + { + var droplet = new Droplet + { + StartTime = Clock.CurrentTime, + Scale = 1.5f, + }; + + return new DrawableDroplet(droplet) + { + Anchor = Anchor.Centre, + RelativePositionAxes = Axes.None, + Position = Vector2.Zero, + Alpha = 1, + LifetimeStart = double.NegativeInfinity, + LifetimeEnd = double.PositiveInfinity, + }; + } + + private Drawable createDrawable(FruitVisualRepresentation rep) { Fruit fruit = new TestCatchFruit(rep) { From 0f088cc2c2705bb4dda0ef45d44cf705e9633371 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2020 03:10:48 +0000 Subject: [PATCH 125/127] Bump ppy.osu.Game.Resources from 2020.219.0 to 2020.221.0 Bumps [ppy.osu.Game.Resources](https://github.com/ppy/osu-resources) from 2020.219.0 to 2020.221.0. - [Release notes](https://github.com/ppy/osu-resources/releases) - [Commits](https://github.com/ppy/osu-resources/compare/2020.219.0...2020.221.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index b9ef783b2a..1774ea0bb4 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -53,7 +53,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6b8f8fee8c..c034fb6567 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -22,7 +22,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index f68bedc57f..7f99338c6e 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -73,7 +73,7 @@ - + From b7e14569eb42046a9adf257023ec70abdbb4a5f8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2020 03:11:10 +0000 Subject: [PATCH 126/127] Bump DiscordRichPresence from 1.0.147 to 1.0.150 Bumps [DiscordRichPresence](https://github.com/Lachee/discord-rpc-csharp) from 1.0.147 to 1.0.150. - [Release notes](https://github.com/Lachee/discord-rpc-csharp/releases) - [Commits](https://github.com/Lachee/discord-rpc-csharp/commits) Signed-off-by: dependabot-preview[bot] --- osu.Desktop/osu.Desktop.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index b9294088f4..c34e1e1221 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -29,7 +29,7 @@ - + From 5acaf9b371d9b64d73040673670f7bb3f6ecb71d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Feb 2020 12:33:49 +0900 Subject: [PATCH 127/127] Privatise setter --- osu.Game/Overlays/Comments/CommentEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Comments/CommentEditor.cs b/osu.Game/Overlays/Comments/CommentEditor.cs index f7e53addbe..2fa4cb68f3 100644 --- a/osu.Game/Overlays/Comments/CommentEditor.cs +++ b/osu.Game/Overlays/Comments/CommentEditor.cs @@ -36,7 +36,7 @@ namespace osu.Game.Overlays.Comments protected abstract string TextBoxPlaceholder { get; } - protected FillFlowContainer ButtonsContainer; + protected FillFlowContainer ButtonsContainer { get; private set; } protected readonly Bindable Current = new Bindable();