From d55875800067ec90f60f55e492a26c2a30dc0ca3 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 19:14:07 +0300 Subject: [PATCH 01/21] Add PreviousUsernames field to the User --- osu.Game/Users/User.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 34bd4bbaae..22c0a4fcd0 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -20,6 +20,9 @@ namespace osu.Game.Users [JsonProperty(@"username")] public string Username; + [JsonProperty(@"previous_usernames")] + public string[] PreviousUsernames; + [JsonProperty(@"country")] public Country Country; From 90c59ab39d3058189e530ed25e3597284ea27b5b Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 21:26:59 +0300 Subject: [PATCH 02/21] implement PreviousUsernamesContainer --- .../TestScenePreviousUsernamesContainer.cs | 52 +++++ .../Header/PreviousUsernamesContainer.cs | 179 ++++++++++++++++++ 2 files changed, 231 insertions(+) create mode 100644 osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs create mode 100644 osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs new file mode 100644 index 0000000000..0469c230d0 --- /dev/null +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -0,0 +1,52 @@ +// 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.Bindables; +using osu.Framework.Graphics; +using osu.Game.Overlays.Profile.Header; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual.Online +{ + [TestFixture] + public class TestScenePreviousUsernamesContainer : OsuTestScene + { + public TestScenePreviousUsernamesContainer() + { + Bindable user = new Bindable(); + + Child = new PreviousUsernamesContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + User = { BindTarget = user }, + }; + + AddStep("single username", () => user.Value = new User + { + PreviousUsernames = new[] { "username1" }, + }); + + AddStep("two usernames", () => user.Value = new User + { + PreviousUsernames = new[] { "longusername", "longerusername" }, + }); + + AddStep("three usernames", () => user.Value = new User + { + PreviousUsernames = new[] { "test", "angelsim", "verylongusername" }, + }); + + AddStep("four usernames", () => user.Value = new User + { + PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext" , "anylonger" }, + }); + + AddStep("no username", () => user.Value = new User + { + PreviousUsernames = new string[0], + }); + } + } +} diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs new file mode 100644 index 0000000000..39bd2388a4 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -0,0 +1,179 @@ +// 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.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics; +using osu.Game.Users; +using osuTK; +using System; +using System.Linq; + +namespace osu.Game.Overlays.Profile.Header +{ + public class PreviousUsernamesContainer : Container + { + private const int duration = 200; + private const int margin = 10; + private const int width = 350; + private const int move_offset = 30; + + public readonly Bindable User = new Bindable(); + + private readonly HoverIconContainer hoverIcon; + private readonly ContentContainer contentContainer; + + public PreviousUsernamesContainer() + { + AutoSizeAxes = Axes.Y; + Width = width; + Children = new Drawable[] + { + contentContainer = new ContentContainer(), + hoverIcon = new HoverIconContainer(), + }; + + hoverIcon.ActivateHover += () => + { + contentContainer.Show(); + this.MoveToY(-move_offset, duration, Easing.OutQuint); + }; + + User.BindValueChanged(onUserChanged); + } + + private void onUserChanged(ValueChangedEvent user) + { + contentContainer.Clear(); + + var usernames = user.NewValue.PreviousUsernames; + + if (usernames.Any()) + { + var amount = usernames.Count(); + + for (int i = 0; i < amount; i++) + { + string text = (i + 1 == amount) ? usernames[i] : $@"{usernames[i]},"; + + contentContainer.Usernames.AddText(new SpriteText + { + Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), + Text = text, + }); + } + + Show(); + return; + } + + Hide(); + } + + protected override void OnHoverLost(HoverLostEvent e) + { + base.OnHoverLost(e); + contentContainer.Hide(); + this.MoveToY(0, duration, Easing.OutQuint); + } + + private class ContentContainer : VisibilityContainer + { + private const int header_height = 25; + private const int content_padding = 60; + + public readonly TextFlowContainer Usernames; + + private readonly Box background; + + public ContentContainer() + { + AutoSizeAxes = Axes.Y; + RelativeSizeAxes = Axes.X; + Masking = true; + AlwaysPresent = true; + CornerRadius = 5; + Children = new Drawable[] + { + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.X, + Height = header_height, + Children = new Drawable[] + { + new SpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Padding = new MarginPadding { Left = content_padding }, + Text = @"formerly known as", + Font = OsuFont.GetFont(size: 14, italics: true) + } + } + }, + Usernames = new TextFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Full, + Spacing = new Vector2(5, 5), + Padding = new MarginPadding { Left = content_padding, Bottom = margin }, + }, + } + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoamDarker; + } + + public override void Clear(bool disposeChildren) => Usernames.Clear(disposeChildren); + + protected override void PopIn() => this.FadeIn(duration, Easing.OutQuint); + + protected override void PopOut() => this.FadeOut(duration, Easing.OutQuint); + } + + private class HoverIconContainer : Container + { + public Action ActivateHover; + + public HoverIconContainer() + { + AutoSizeAxes = Axes.Both; + Child = new SpriteIcon + { + Margin = new MarginPadding(margin) { Top = 7 }, + Size = new Vector2(20), + Icon = FontAwesome.Solid.IdCard, + }; + } + + protected override bool OnHover(HoverEvent e) + { + ActivateHover?.Invoke(); + return base.OnHover(e); + } + } + } +} From 13fe1732d8cf8b76aa689a585ad6c3fe63128119 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 21:32:04 +0300 Subject: [PATCH 03/21] adjust height values to avoid random jumps --- .../Overlays/Profile/Header/PreviousUsernamesContainer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 39bd2388a4..67b9bcb651 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.Profile.Header private const int duration = 200; private const int margin = 10; private const int width = 350; - private const int move_offset = 30; + private const int move_offset = 20; public readonly Bindable User = new Bindable(); @@ -163,7 +163,7 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Both; Child = new SpriteIcon { - Margin = new MarginPadding(margin) { Top = 7 }, + Margin = new MarginPadding(margin) { Top = 6 }, Size = new Vector2(20), Icon = FontAwesome.Solid.IdCard, }; From e66a3494b9fbd43c9f49d718af1683106d86dc93 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 22:50:01 +0300 Subject: [PATCH 04/21] make the container hidden by default --- osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 67b9bcb651..5165f0d0df 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -45,6 +45,7 @@ namespace osu.Game.Overlays.Profile.Header }; User.BindValueChanged(onUserChanged); + Hide(); } private void onUserChanged(ValueChangedEvent user) From 55475927685aee49e5686899d6898ff8093fc7d4 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Thu, 1 Aug 2019 23:04:18 +0300 Subject: [PATCH 05/21] CI fixes --- .../Visual/Online/TestScenePreviousUsernamesContainer.cs | 2 +- .../Overlays/Profile/Header/PreviousUsernamesContainer.cs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index 0469c230d0..a33de887d7 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Online AddStep("four usernames", () => user.Value = new User { - PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext" , "anylonger" }, + PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" }, }); AddStep("no username", () => user.Value = new User diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 5165f0d0df..1c98cff616 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -25,11 +25,12 @@ namespace osu.Game.Overlays.Profile.Header public readonly Bindable User = new Bindable(); - private readonly HoverIconContainer hoverIcon; private readonly ContentContainer contentContainer; public PreviousUsernamesContainer() { + HoverIconContainer hoverIcon; + AutoSizeAxes = Axes.Y; Width = width; Children = new Drawable[] @@ -56,7 +57,7 @@ namespace osu.Game.Overlays.Profile.Header if (usernames.Any()) { - var amount = usernames.Count(); + var amount = usernames.Length; for (int i = 0; i < amount; i++) { From de96e5dfc605f559269a2e045652ab2453267d2d Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 2 Aug 2019 07:41:11 +0300 Subject: [PATCH 06/21] Apply suggested changes --- .../TestScenePreviousUsernamesContainer.cs | 5 ++ .../Header/PreviousUsernamesContainer.cs | 58 +++++++++---------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index a33de887d7..4f3a2e47c6 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -43,6 +43,11 @@ namespace osu.Game.Tests.Visual.Online PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" }, }); + AddStep("many usernames", () => user.Value = new User + { + PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger", "but", "ican", "try", "tomake", "this" }, + }); + AddStep("no username", () => user.Value = new User { PreviousUsernames = new string[0], diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 1c98cff616..e8443dff1b 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -16,12 +16,12 @@ using System.Linq; namespace osu.Game.Overlays.Profile.Header { - public class PreviousUsernamesContainer : Container + public class PreviousUsernamesContainer : CompositeDrawable { private const int duration = 200; private const int margin = 10; - private const int width = 350; - private const int move_offset = 20; + private const int width = 310; + private const int move_offset = 15; public readonly Bindable User = new Bindable(); @@ -33,43 +33,35 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Y; Width = width; - Children = new Drawable[] + + AddRangeInternal(new Drawable[] { contentContainer = new ContentContainer(), hoverIcon = new HoverIconContainer(), - }; + }); hoverIcon.ActivateHover += () => { contentContainer.Show(); this.MoveToY(-move_offset, duration, Easing.OutQuint); }; + } - User.BindValueChanged(onUserChanged); - Hide(); + protected override void LoadComplete() + { + base.LoadComplete(); + User.BindValueChanged(onUserChanged, true); } private void onUserChanged(ValueChangedEvent user) { - contentContainer.Clear(); + contentContainer.Text = string.Empty; - var usernames = user.NewValue.PreviousUsernames; + var usernames = user.NewValue?.PreviousUsernames; - if (usernames.Any()) + if (usernames?.Any() ?? false) { - var amount = usernames.Length; - - for (int i = 0; i < amount; i++) - { - string text = (i + 1 == amount) ? usernames[i] : $@"{usernames[i]},"; - - contentContainer.Usernames.AddText(new SpriteText - { - Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true), - Text = text, - }); - } - + contentContainer.Text = string.Join(", ", usernames); Show(); return; } @@ -86,11 +78,15 @@ namespace osu.Game.Overlays.Profile.Header private class ContentContainer : VisibilityContainer { - private const int header_height = 25; - private const int content_padding = 60; + private const int header_height = 20; + private const int content_padding = 40; - public readonly TextFlowContainer Usernames; + public string Text + { + set => usernames.Text = value; + } + private readonly TextFlowContainer usernames; private readonly Box background; public ContentContainer() @@ -126,16 +122,16 @@ namespace osu.Game.Overlays.Profile.Header Origin = Anchor.BottomLeft, Padding = new MarginPadding { Left = content_padding }, Text = @"formerly known as", - Font = OsuFont.GetFont(size: 14, italics: true) + Font = OsuFont.GetFont(size: 10, italics: true) } } }, - Usernames = new TextFlowContainer + usernames = new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold, italics: true)) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Full, - Spacing = new Vector2(5, 5), + Spacing = new Vector2(0, 5), Padding = new MarginPadding { Left = content_padding, Bottom = margin }, }, } @@ -149,8 +145,6 @@ namespace osu.Game.Overlays.Profile.Header background.Colour = colours.GreySeafoamDarker; } - public override void Clear(bool disposeChildren) => Usernames.Clear(disposeChildren); - protected override void PopIn() => this.FadeIn(duration, Easing.OutQuint); protected override void PopOut() => this.FadeOut(duration, Easing.OutQuint); @@ -166,7 +160,7 @@ namespace osu.Game.Overlays.Profile.Header Child = new SpriteIcon { Margin = new MarginPadding(margin) { Top = 6 }, - Size = new Vector2(20), + Size = new Vector2(15), Icon = FontAwesome.Solid.IdCard, }; } From 4c0a9aeab701381ad602cde155b636327ba979f7 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Fri, 2 Aug 2019 07:44:09 +0300 Subject: [PATCH 07/21] Add null user step --- .../Visual/Online/TestScenePreviousUsernamesContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index 4f3a2e47c6..4a3b3403b2 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -52,6 +52,8 @@ namespace osu.Game.Tests.Visual.Online { PreviousUsernames = new string[0], }); + + AddStep("null user", () => user.Value = null); } } } From f81238b8b18b38546615c2992df68ca35a19baa8 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Aug 2019 04:45:41 +0300 Subject: [PATCH 08/21] Add online test --- .../TestScenePreviousUsernamesContainer.cs | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index 4a3b3403b2..dafc1870e4 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -2,8 +2,11 @@ // See the LICENCE file in the repository root for full licence text. using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Game.Online.API; +using osu.Game.Online.API.Requests; using osu.Game.Overlays.Profile.Header; using osu.Game.Users; @@ -12,10 +15,13 @@ namespace osu.Game.Tests.Visual.Online [TestFixture] public class TestScenePreviousUsernamesContainer : OsuTestScene { + [Resolved] + private IAPIProvider api { get; set; } + + private readonly Bindable user = new Bindable(); + public TestScenePreviousUsernamesContainer() { - Bindable user = new Bindable(); - Child = new PreviousUsernamesContainer { Anchor = Anchor.Centre, @@ -55,5 +61,17 @@ namespace osu.Game.Tests.Visual.Online AddStep("null user", () => user.Value = null); } + + protected override void LoadComplete() + { + base.LoadComplete(); + + AddStep("online user (Angelsim)", () => + { + var request = new GetUserRequest(1777162); + request.Success += user => this.user.Value = user; + api.Queue(request); + }); + } } } From 37be4fbf1622d0f80271b5400a497b0bfdfb9984 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Aug 2019 05:34:14 +0300 Subject: [PATCH 09/21] Use GridContainer for layout --- .../TestScenePreviousUsernamesContainer.cs | 43 ++--- .../Header/PreviousUsernamesContainer.cs | 159 +++++++++--------- 2 files changed, 90 insertions(+), 112 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index dafc1870e4..5636f8756d 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -29,37 +29,22 @@ namespace osu.Game.Tests.Visual.Online User = { BindTarget = user }, }; - AddStep("single username", () => user.Value = new User + User[] users = new[] { - PreviousUsernames = new[] { "username1" }, - }); + new User { PreviousUsernames = new[] { "username1" } }, + new User { PreviousUsernames = new[] { "longusername", "longerusername" } }, + new User { PreviousUsernames = new[] { "test", "angelsim", "verylongusername" } }, + new User { PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" } }, + new User { PreviousUsernames = new string[0] }, + null + }; - AddStep("two usernames", () => user.Value = new User - { - PreviousUsernames = new[] { "longusername", "longerusername" }, - }); - - AddStep("three usernames", () => user.Value = new User - { - PreviousUsernames = new[] { "test", "angelsim", "verylongusername" }, - }); - - AddStep("four usernames", () => user.Value = new User - { - PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger" }, - }); - - AddStep("many usernames", () => user.Value = new User - { - PreviousUsernames = new[] { "ihavenoidea", "howcani", "makethistext", "anylonger", "but", "ican", "try", "tomake", "this" }, - }); - - AddStep("no username", () => user.Value = new User - { - PreviousUsernames = new string[0], - }); - - AddStep("null user", () => user.Value = null); + AddStep("single username", () => user.Value = users[0]); + AddStep("two usernames", () => user.Value = users[1]); + AddStep("three usernames", () => user.Value = users[2]); + AddStep("four usernames", () => user.Value = users[3]); + AddStep("no username", () => user.Value = users[4]); + AddStep("null user", () => user.Value = users[5]); } protected override void LoadComplete() diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index e8443dff1b..36034fe8db 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -25,7 +25,9 @@ namespace osu.Game.Overlays.Profile.Header public readonly Bindable User = new Bindable(); - private readonly ContentContainer contentContainer; + private readonly TextFlowContainer text; + private readonly Box background; + private readonly SpriteText header; public PreviousUsernamesContainer() { @@ -33,18 +35,68 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Y; Width = width; + Masking = true; + CornerRadius = 5; AddRangeInternal(new Drawable[] { - contentContainer = new ContentContainer(), - hoverIcon = new HoverIconContainer(), + background = new Box + { + RelativeSizeAxes = Axes.Both, + }, + new GridContainer + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + RowDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize) + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed) + }, + Content = new[] + { + new Drawable[] + { + hoverIcon = new HoverIconContainer(), + header = new SpriteText + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Text = @"formerly known as", + Font = OsuFont.GetFont(size: 10, italics: true) + } + }, + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Both, + }, + text = new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold, italics: true)) + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Full, + Margin = new MarginPadding { Bottom = margin, Top = margin / 2 } + } + } + } + } }); - hoverIcon.ActivateHover += () => - { - contentContainer.Show(); - this.MoveToY(-move_offset, duration, Easing.OutQuint); - }; + hoverIcon.ActivateHover += showContent; + hideContent(); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + background.Colour = colours.GreySeafoamDarker; } protected override void LoadComplete() @@ -55,13 +107,13 @@ namespace osu.Game.Overlays.Profile.Header private void onUserChanged(ValueChangedEvent user) { - contentContainer.Text = string.Empty; + text.Text = string.Empty; var usernames = user.NewValue?.PreviousUsernames; if (usernames?.Any() ?? false) { - contentContainer.Text = string.Join(", ", usernames); + text.Text = string.Join(", ", usernames); Show(); return; } @@ -72,82 +124,23 @@ namespace osu.Game.Overlays.Profile.Header protected override void OnHoverLost(HoverLostEvent e) { base.OnHoverLost(e); - contentContainer.Hide(); - this.MoveToY(0, duration, Easing.OutQuint); + hideContent(); } - private class ContentContainer : VisibilityContainer + private void showContent() { - private const int header_height = 20; - private const int content_padding = 40; + text.FadeIn(duration, Easing.OutQuint); + header.FadeIn(duration, Easing.OutQuint); + background.FadeIn(duration, Easing.OutQuint); + this.MoveToY(-move_offset, duration, Easing.OutQuint); + } - public string Text - { - set => usernames.Text = value; - } - - private readonly TextFlowContainer usernames; - private readonly Box background; - - public ContentContainer() - { - AutoSizeAxes = Axes.Y; - RelativeSizeAxes = Axes.X; - Masking = true; - AlwaysPresent = true; - CornerRadius = 5; - Children = new Drawable[] - { - background = new Box - { - RelativeSizeAxes = Axes.Both, - }, - new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 5), - Children = new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.X, - Height = header_height, - Children = new Drawable[] - { - new SpriteText - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - Padding = new MarginPadding { Left = content_padding }, - Text = @"formerly known as", - Font = OsuFont.GetFont(size: 10, italics: true) - } - } - }, - usernames = new TextFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold, italics: true)) - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Full, - Spacing = new Vector2(0, 5), - Padding = new MarginPadding { Left = content_padding, Bottom = margin }, - }, - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - background.Colour = colours.GreySeafoamDarker; - } - - protected override void PopIn() => this.FadeIn(duration, Easing.OutQuint); - - protected override void PopOut() => this.FadeOut(duration, Easing.OutQuint); + private void hideContent() + { + text.FadeOut(duration, Easing.OutQuint); + header.FadeOut(duration, Easing.OutQuint); + background.FadeOut(duration, Easing.OutQuint); + this.MoveToY(0, duration, Easing.OutQuint); } private class HoverIconContainer : Container @@ -159,7 +152,7 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Both; Child = new SpriteIcon { - Margin = new MarginPadding(margin) { Top = 6 }, + Margin = new MarginPadding { Top = 6, Left = margin, Right = margin * 2 }, Size = new Vector2(15), Icon = FontAwesome.Solid.IdCard, }; From 416f9d89dba59a8cc85e020e643506f4f02b1b44 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Sat, 3 Aug 2019 05:49:01 +0300 Subject: [PATCH 10/21] CI fixes --- .../Visual/Online/TestScenePreviousUsernamesContainer.cs | 2 +- osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index 5636f8756d..b891fda0f4 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -29,7 +29,7 @@ namespace osu.Game.Tests.Visual.Online User = { BindTarget = user }, }; - User[] users = new[] + User[] users = { new User { PreviousUsernames = new[] { "username1" } }, new User { PreviousUsernames = new[] { "longusername", "longerusername" } }, diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs index 36034fe8db..b53ac8eb80 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs @@ -82,7 +82,7 @@ namespace osu.Game.Overlays.Profile.Header RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, Direction = FillDirection.Full, - Margin = new MarginPadding { Bottom = margin, Top = margin / 2 } + Margin = new MarginPadding { Bottom = margin, Top = margin / 2f } } } } From cb0cd7ed589ef56f1b9a3cedae662a709397a022 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 20:05:28 +0900 Subject: [PATCH 11/21] Add triangles intro --- .../Visual/Menus/TestSceneIntroTriangles.cs | 15 + osu.Game/Configuration/IntroSequence.cs | 11 + osu.Game/Configuration/OsuConfigManager.cs | 5 +- .../Sections/Audio/MainMenuSettings.cs | 11 +- osu.Game/Screens/BackgroundScreen.cs | 16 +- .../Backgrounds/BackgroundScreenDefault.cs | 5 + osu.Game/Screens/Loader.cs | 19 +- osu.Game/Screens/Menu/IntroTriangles.cs | 413 ++++++++++++++++++ 8 files changed, 486 insertions(+), 9 deletions(-) create mode 100644 osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs create mode 100644 osu.Game/Configuration/IntroSequence.cs create mode 100644 osu.Game/Screens/Menu/IntroTriangles.cs diff --git a/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs b/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs new file mode 100644 index 0000000000..df79584167 --- /dev/null +++ b/osu.Game.Tests/Visual/Menus/TestSceneIntroTriangles.cs @@ -0,0 +1,15 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using NUnit.Framework; +using osu.Framework.Screens; +using osu.Game.Screens.Menu; + +namespace osu.Game.Tests.Visual.Menus +{ + [TestFixture] + public class TestSceneIntroTriangles : IntroTestScene + { + protected override IScreen CreateScreen() => new IntroTriangles(); + } +} diff --git a/osu.Game/Configuration/IntroSequence.cs b/osu.Game/Configuration/IntroSequence.cs new file mode 100644 index 0000000000..1eb953be36 --- /dev/null +++ b/osu.Game/Configuration/IntroSequence.cs @@ -0,0 +1,11 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Configuration +{ + public enum IntroSequence + { + Circles, + Triangles + } +} diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 1da7c7ec1d..19f46c1d6a 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -105,6 +105,8 @@ namespace osu.Game.Configuration Set(OsuSetting.ScalingPositionY, 0.5f, 0f, 1f); Set(OsuSetting.UIScale, 1f, 0.8f, 1.6f, 0.01f); + + Set(OsuSetting.IntroSequence, IntroSequence.Triangles); } public OsuConfigManager(Storage storage) @@ -167,6 +169,7 @@ namespace osu.Game.Configuration ScalingPositionY, ScalingSizeX, ScalingSizeY, - UIScale + UIScale, + IntroSequence } } diff --git a/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs b/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs index 4e43caff23..5ccdc952ba 100644 --- a/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Audio/MainMenuSettings.cs @@ -1,7 +1,10 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Graphics; using osu.Game.Configuration; namespace osu.Game.Overlays.Settings.Sections.Audio @@ -13,7 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - Children = new[] + Children = new Drawable[] { new SettingsCheckbox { @@ -25,6 +28,12 @@ namespace osu.Game.Overlays.Settings.Sections.Audio LabelText = "osu! music theme", Bindable = config.GetBindable(OsuSetting.MenuMusic) }, + new SettingsDropdown + { + LabelText = "Intro sequence", + Bindable = config.GetBindable(OsuSetting.IntroSequence), + Items = Enum.GetValues(typeof(IntroSequence)).Cast() + }, }; } } diff --git a/osu.Game/Screens/BackgroundScreen.cs b/osu.Game/Screens/BackgroundScreen.cs index bbe162cf7c..5dfaceccf5 100644 --- a/osu.Game/Screens/BackgroundScreen.cs +++ b/osu.Game/Screens/BackgroundScreen.cs @@ -11,8 +11,11 @@ namespace osu.Game.Screens { public abstract class BackgroundScreen : Screen, IEquatable { - protected BackgroundScreen() + private readonly bool animateOnEnter; + + protected BackgroundScreen(bool animateOnEnter = true) { + this.animateOnEnter = animateOnEnter; Anchor = Anchor.Centre; Origin = Anchor.Centre; } @@ -39,11 +42,14 @@ namespace osu.Game.Screens public override void OnEntering(IScreen last) { - this.FadeOut(); - this.MoveToX(x_movement_amount); + if (animateOnEnter) + { + this.FadeOut(); + this.MoveToX(x_movement_amount); - this.FadeIn(transition_length, Easing.InOutQuart); - this.MoveToX(0, transition_length, Easing.InOutQuart); + this.FadeIn(transition_length, Easing.InOutQuart); + this.MoveToX(0, transition_length, Easing.InOutQuart); + } base.OnEntering(last); } diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs index 55338ea01a..2d7fe6a6a3 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenDefault.cs @@ -25,6 +25,11 @@ namespace osu.Game.Screens.Backgrounds private Bindable user; private Bindable skin; + public BackgroundScreenDefault(bool animateOnEnter = true) + : base(animateOnEnter) + { + } + [BackgroundDependencyLoader] private void load(IAPIProvider api, SkinManager skinManager) { diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index de00ba2e9f..850349272e 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -9,6 +9,8 @@ using osu.Framework.Graphics.Shaders; using osu.Game.Screens.Menu; using osuTK; using osu.Framework.Screens; +using osu.Game.Configuration; +using IntroSequence = osu.Game.Configuration.IntroSequence; namespace osu.Game.Screens { @@ -45,6 +47,8 @@ namespace osu.Game.Screens private OsuScreen loadableScreen; private ShaderPrecompiler precompiler; + private IntroSequence introSequence; + protected virtual OsuScreen CreateLoadableScreen() { if (showDisclaimer) @@ -53,7 +57,17 @@ namespace osu.Game.Screens return getIntroSequence(); } - private IntroScreen getIntroSequence() => new IntroCircles(); + private IntroScreen getIntroSequence() + { + switch (introSequence) + { + case IntroSequence.Circles: + return new IntroCircles(); + + default: + return new IntroTriangles(); + } + } protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler(); @@ -79,9 +93,10 @@ namespace osu.Game.Screens } [BackgroundDependencyLoader] - private void load(OsuGameBase game) + private void load(OsuGameBase game, OsuConfigManager config) { showDisclaimer = game.IsDeployedBuild; + introSequence = config.Get(OsuSetting.IntroSequence); } /// diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs new file mode 100644 index 0000000000..87d6012205 --- /dev/null +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -0,0 +1,413 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Collections.Generic; +using System.IO; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Framework.Audio.Track; +using osu.Framework.Bindables; +using osu.Framework.Screens; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.Video; +using osu.Framework.MathUtils; +using osu.Framework.Timing; +using osu.Game.Beatmaps; +using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.Sprites; +using osu.Game.IO.Archives; +using osu.Game.Rulesets; +using osu.Game.Screens.Backgrounds; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Screens.Menu +{ + public class IntroTriangles : IntroScreen + { + private const string menu_music_beatmap_hash = "a1556d0801b3a6b175dda32ef546f0ec812b400499f575c44fccbe9c67f9b1e5"; + + private SampleChannel welcome; + + protected override BackgroundScreen CreateBackground() => background = new BackgroundScreenDefault(false) + { + Alpha = 0, + }; + + [Resolved] + private AudioManager audio { get; set; } + + private Bindable menuMusic; + private Track track; + private WorkingBeatmap introBeatmap; + + private BackgroundScreenDefault background; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) + { + menuMusic = config.GetBindable(OsuSetting.MenuMusic); + + BeatmapSetInfo setInfo = null; + + if (!menuMusic.Value) + { + var sets = beatmaps.GetAllUsableBeatmapSets(); + if (sets.Count > 0) + setInfo = beatmaps.QueryBeatmapSet(s => s.ID == sets[RNG.Next(0, sets.Count - 1)].ID); + } + + if (setInfo == null) + { + setInfo = beatmaps.QueryBeatmapSet(b => b.Hash == menu_music_beatmap_hash); + + if (setInfo == null) + { + // we need to import the default menu background beatmap + setInfo = beatmaps.Import(new ZipArchiveReader(game.Resources.GetStream(@"Tracks/triangles.osz"), "triangles.osz")).Result; + + setInfo.Protected = true; + beatmaps.Update(setInfo); + } + } + + introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); + + track = introBeatmap.Track; + track.Reset(); + + if (config.Get(OsuSetting.MenuVoice) && !menuMusic.Value) + // triangles has welcome sound included in the track. only play this if the user doesn't want menu music. + welcome = audio.Samples.Get(@"welcome"); + } + + protected override void LogoArriving(OsuLogo logo, bool resuming) + { + base.LogoArriving(logo, resuming); + + logo.Triangles = true; + + if (!resuming) + { + Beatmap.Value = introBeatmap; + introBeatmap = null; + + PrepareMenuLoad(); + + LoadComponentAsync(new TrianglesIntroSequence(logo, background) + { + RelativeSizeAxes = Axes.Both, + Clock = new FramedClock(track), + LoadMenu = LoadMenu + }, t => + { + AddInternal(t); + welcome?.Play(); + + // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. + if (menuMusic.Value) + track.Start(); + }); + } + } + + public override void OnResuming(IScreen last) + { + base.OnResuming(last); + background.FadeOut(100); + } + + public override void OnSuspending(IScreen next) + { + track = null; + base.OnSuspending(next); + } + + private class TrianglesIntroSequence : CompositeDrawable + { + private readonly OsuLogo logo; + private readonly BackgroundScreenDefault background; + private OsuSpriteText welcomeText; + + private RulesetFlow rulesets; + private Container rulesetsScale; + private Drawable logoContainerSecondary; + private Drawable logoContainer; + + private GlitchingTriangles triangles; + + public Action LoadMenu; + + public TrianglesIntroSequence(OsuLogo logo, BackgroundScreenDefault background) + { + this.logo = logo; + this.background = background; + } + + private OsuGameBase game; + + [BackgroundDependencyLoader] + private void load(TextureStore textures, OsuGameBase game) + { + this.game = game; + + InternalChildren = new[] + { + triangles = new GlitchingTriangles + { + Alpha = 0, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(0.4f, 0.16f) + }, + welcomeText = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Padding = new MarginPadding { Bottom = 10 }, + Font = OsuFont.GetFont(weight: FontWeight.Light, size: 42), + Alpha = 1, + Spacing = new Vector2(5), + }, + rulesetsScale = new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + rulesets = new RulesetFlow() + } + }, + logoContainerSecondary = new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Child = logoContainer = new LazerLogo(textures.GetStream("Menu/logo-triangles.mp4")) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + } + }, + }; + } + + private const double text_1 = 200; + private const double text_2 = 400; + private const double text_3 = 700; + private const double text_4 = 900; + private const double text_glitch = 1060; + + private const double rulesets_1 = 1450; + private const double rulesets_2 = 1650; + private const double rulesets_3 = 1850; + + private const double logo_scale_duration = 920; + private const double logo_1 = 2080; + private const double logo_2 = logo_1 + logo_scale_duration; + + protected override void LoadComplete() + { + base.LoadComplete(); + + const float scale_start = 1.2f; + const float scale_adjust = 0.8f; + + rulesets.Hide(); + logoContainer.Hide(); + background.Hide(); + + using (BeginAbsoluteSequence(0, true)) + { + using (BeginDelayedSequence(text_1, true)) + welcomeText.FadeIn().OnComplete(t => t.Text = "wel"); + + using (BeginDelayedSequence(text_2, true)) + welcomeText.FadeIn().OnComplete(t => t.Text = "welcome"); + + using (BeginDelayedSequence(text_3, true)) + welcomeText.FadeIn().OnComplete(t => t.Text = "welcome to"); + + using (BeginDelayedSequence(text_4, true)) + { + welcomeText.FadeIn().OnComplete(t => t.Text = "welcome to osu!"); + welcomeText.TransformTo(nameof(welcomeText.Spacing), new Vector2(50, 0), 5000); + } + + using (BeginDelayedSequence(text_glitch, true)) + triangles.FadeIn(); + + using (BeginDelayedSequence(rulesets_1, true)) + { + rulesetsScale.ScaleTo(0.8f, 1000); + rulesets.FadeIn().ScaleTo(1).TransformSpacingTo(new Vector2(200, 0)); + welcomeText.FadeOut(); + triangles.FadeOut(); + } + + using (BeginDelayedSequence(rulesets_2, true)) + { + rulesets.ScaleTo(2).TransformSpacingTo(new Vector2(30, 0)); + } + + using (BeginDelayedSequence(rulesets_3, true)) + { + rulesets.ScaleTo(4).TransformSpacingTo(new Vector2(10, 0)); + rulesetsScale.ScaleTo(1.3f, 1000); + } + + using (BeginDelayedSequence(logo_1, true)) + { + rulesets.FadeOut(); + + // matching flyte curve y = 0.25x^2 + (max(0, x - 0.7) / 0.3) ^ 5 + logoContainer.FadeIn().ScaleTo(scale_start).Then().Delay(logo_scale_duration * 0.7f).ScaleTo(scale_start - scale_adjust, logo_scale_duration * 0.3f, Easing.InQuint); + logoContainerSecondary.ScaleTo(scale_start).Then().ScaleTo(scale_start - scale_adjust * 0.25f, logo_scale_duration, Easing.InQuad); + } + + using (BeginDelayedSequence(logo_2, true)) + { + logoContainer.FadeOut().OnComplete(_ => + { + logo.FadeIn(); + background.FadeIn(); + + game.Add(new GameWideFlash()); + + LoadMenu(); + }); + } + } + } + + private class GameWideFlash : Box + { + private const double flash_length = 1000; + + public GameWideFlash() + { + Colour = Color4.White; + RelativeSizeAxes = Axes.Both; + Blending = BlendingMode.Additive; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeOutFromOne(flash_length, Easing.Out); + } + } + + private class LazerLogo : CompositeDrawable + { + public LazerLogo(Stream videoStream) + { + Size = new Vector2(960); + + InternalChild = new VideoSprite(videoStream) + { + RelativeSizeAxes = Axes.Both, + Clock = new FramedOffsetClock(Clock) { Offset = -logo_1 } + }; + } + } + + private class RulesetFlow : FillFlowContainer + { + [BackgroundDependencyLoader] + private void load(RulesetStore rulesets) + { + var modes = new List(); + + foreach (var ruleset in rulesets.AvailableRulesets) + { + var icon = new ConstrainedIconContainer + { + Icon = ruleset.CreateInstance().CreateIcon(), + Size = new Vector2(30), + }; + + modes.Add(icon); + } + + AutoSizeAxes = Axes.Both; + Children = modes; + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + } + } + + private class GlitchingTriangles : CompositeDrawable + { + public GlitchingTriangles() + { + RelativeSizeAxes = Axes.Both; + } + + private double? lastGenTime; + + private const double time_between_triangles = 22; + + protected override void Update() + { + base.Update(); + + if (lastGenTime == null || Time.Current - lastGenTime > time_between_triangles) + { + lastGenTime = (lastGenTime ?? Time.Current) + time_between_triangles; + + Drawable triangle = new OutlineTriangle(RNG.NextBool(), (RNG.NextSingle() + 0.2f) * 80) + { + RelativePositionAxes = Axes.Both, + Position = new Vector2(RNG.NextSingle(), RNG.NextSingle()), + }; + + AddInternal(triangle); + + triangle.FadeOutFromOne(120); + } + } + + /// + /// Represents a sprite that is drawn in a triangle shape, instead of a rectangle shape. + /// + public class OutlineTriangle : BufferedContainer + { + public OutlineTriangle(bool outlineOnly, float size) + { + Size = new Vector2(size); + + InternalChildren = new Drawable[] + { + new Triangle { RelativeSizeAxes = Axes.Both }, + }; + + if (outlineOnly) + { + AddInternal(new Triangle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Colour = Color4.Black, + Size = new Vector2(size - 5), + Blending = BlendingMode.None, + }); + } + + Blending = BlendingMode.Additive; + CacheDrawnFrameBuffer = true; + } + } + } + } + } +} From 8e6a3162ab3bfead6842379973fd671f927e39c7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Aug 2019 20:05:36 +0900 Subject: [PATCH 12/21] 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 40c15a1162..4ec67ab30d 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -62,7 +62,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 8ee325c2ac..fb9269e5f0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -14,7 +14,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index b46438f766..1532e2d71b 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -104,7 +104,7 @@ - + From 359261d4a47353221ac5ca15f86b71f7253a8087 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Aug 2019 02:04:06 +0900 Subject: [PATCH 13/21] Fix game not starting if intro music is disabled --- osu.Game/Screens/Menu/IntroTriangles.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs index 87d6012205..ba0d624959 100644 --- a/osu.Game/Screens/Menu/IntroTriangles.cs +++ b/osu.Game/Screens/Menu/IntroTriangles.cs @@ -1,4 +1,4 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; @@ -104,14 +104,14 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(new TrianglesIntroSequence(logo, background) { RelativeSizeAxes = Axes.Both, - Clock = new FramedClock(track), + Clock = new FramedClock(menuMusic.Value ? track : null), LoadMenu = LoadMenu }, t => { AddInternal(t); welcome?.Play(); - // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. + // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Menu. if (menuMusic.Value) track.Start(); }); From 0c0c4052168e9cba36bcd096c359c9c89c1e4a1a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 12:27:49 +0900 Subject: [PATCH 14/21] Add note to README about ffmpeg requirement on linux --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c4d676f4be..5dc4da12a4 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,9 @@ Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh ## Requirements - A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed. +- When running on linux, please have a system-wide ffmpeg installation available to support video decoding. +- When running on Windows 7 or 8.1, there are **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. - When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio 2017+](https://visualstudio.microsoft.com/vs/), [Jetbrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/). -- Note that there are **[additional requirements for Windows 7 and Windows 8.1](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** which you may need to manually install if your operating system is not up-to-date. ## Running osu! From 33a119b7263501823c8f2c1f71a0d881bfd602fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Aug 2019 12:35:06 +0900 Subject: [PATCH 15/21] Fix double grammar Co-Authored-By: Dan Balasescu --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5dc4da12a4..56491a4be4 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh - A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed. - When running on linux, please have a system-wide ffmpeg installation available to support video decoding. -- When running on Windows 7 or 8.1, there are **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. +- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs. - When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio 2017+](https://visualstudio.microsoft.com/vs/), [Jetbrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/). ## Running osu! From 5681d1097c107c4cbbe060c36997c08cc19ebe74 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 13 Aug 2019 14:07:40 +0900 Subject: [PATCH 16/21] Move into components namespace --- .../Visual/Online/TestScenePreviousUsernamesContainer.cs | 2 +- .../Header/{ => Components}/PreviousUsernamesContainer.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Overlays/Profile/Header/{ => Components}/PreviousUsernamesContainer.cs (99%) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs index b891fda0f4..43373f872a 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs @@ -7,7 +7,7 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Online.API; using osu.Game.Online.API.Requests; -using osu.Game.Overlays.Profile.Header; +using osu.Game.Overlays.Profile.Header.Components; using osu.Game.Users; namespace osu.Game.Tests.Visual.Online diff --git a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs similarity index 99% rename from osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs index b53ac8eb80..ef9c01e12b 100644 --- a/osu.Game/Overlays/Profile/Header/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -11,10 +13,8 @@ using osu.Framework.Input.Events; using osu.Game.Graphics; using osu.Game.Users; using osuTK; -using System; -using System.Linq; -namespace osu.Game.Overlays.Profile.Header +namespace osu.Game.Overlays.Profile.Header.Components { public class PreviousUsernamesContainer : CompositeDrawable { From 8d3f2f76459d062cd2ee54afa747d96981794e9a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 13 Aug 2019 14:09:10 +0900 Subject: [PATCH 17/21] Drop container from name --- ....cs => TestSceneUserProfilePreviousUsernames.cs} | 13 ++++++++++--- ...usUsernamesContainer.cs => PreviousUsernames.cs} | 4 ++-- 2 files changed, 12 insertions(+), 5 deletions(-) rename osu.Game.Tests/Visual/Online/{TestScenePreviousUsernamesContainer.cs => TestSceneUserProfilePreviousUsernames.cs} (85%) rename osu.Game/Overlays/Profile/Header/Components/{PreviousUsernamesContainer.cs => PreviousUsernames.cs} (98%) diff --git a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs similarity index 85% rename from osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs rename to osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs index 43373f872a..d09a50b12c 100644 --- a/osu.Game.Tests/Visual/Online/TestScenePreviousUsernamesContainer.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfilePreviousUsernames.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; +using System.Collections.Generic; using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -13,16 +15,21 @@ using osu.Game.Users; namespace osu.Game.Tests.Visual.Online { [TestFixture] - public class TestScenePreviousUsernamesContainer : OsuTestScene + public class TestSceneUserProfilePreviousUsernames : OsuTestScene { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(PreviousUsernames) + }; + [Resolved] private IAPIProvider api { get; set; } private readonly Bindable user = new Bindable(); - public TestScenePreviousUsernamesContainer() + public TestSceneUserProfilePreviousUsernames() { - Child = new PreviousUsernamesContainer + Child = new PreviousUsernames { Anchor = Anchor.Centre, Origin = Anchor.Centre, diff --git a/osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs similarity index 98% rename from osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs rename to osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs index ef9c01e12b..f18f319e27 100644 --- a/osu.Game/Overlays/Profile/Header/Components/PreviousUsernamesContainer.cs +++ b/osu.Game/Overlays/Profile/Header/Components/PreviousUsernames.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Overlays.Profile.Header.Components { - public class PreviousUsernamesContainer : CompositeDrawable + public class PreviousUsernames : CompositeDrawable { private const int duration = 200; private const int margin = 10; @@ -29,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header.Components private readonly Box background; private readonly SpriteText header; - public PreviousUsernamesContainer() + public PreviousUsernames() { HoverIconContainer hoverIcon; From f2e596de1640c4939ada0d6c18d2b71e89295679 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2019 08:54:17 +0000 Subject: [PATCH 18/21] Bump ppy.osu.Framework from 2019.809.0 to 2019.813.0 Bumps [ppy.osu.Framework](https://github.com/ppy/osu-framework) from 2019.809.0 to 2019.813.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.809.0...2019.813.0) Signed-off-by: dependabot-preview[bot] --- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b5266fd75d..e149c4338d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,7 +15,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 103d89cadc..2bb95d0772 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -105,7 +105,7 @@ - + From fe7bc824df6b2eda0b52e48517b37535363f4537 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2019 09:00:20 +0000 Subject: [PATCH 19/21] Bump ppy.osu.Framework.NativeLibs from 2019.307.0 to 2019.813.0 Bumps [ppy.osu.Framework.NativeLibs](https://github.com/ppy/osu-framework) from 2019.307.0 to 2019.813.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.307.0...2019.813.0) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index 103d89cadc..09b9da142c 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -111,6 +111,6 @@ - + From 6b3eeb88fc9dac58b70f60991aceb147aab67895 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2019 09:00:43 +0000 Subject: [PATCH 20/21] Bump ppy.osu.Framework.iOS from 2019.809.0 to 2019.813.0 Bumps [ppy.osu.Framework.iOS](https://github.com/ppy/osu-framework) from 2019.809.0 to 2019.813.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.809.0...2019.813.0) Signed-off-by: dependabot-preview[bot] --- osu.iOS.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.iOS.props b/osu.iOS.props index 103d89cadc..d444a5893f 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -106,7 +106,7 @@ - + From 91068dc5709585c1c4175acd45fca05f581ff583 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2019 09:01:00 +0000 Subject: [PATCH 21/21] Bump ppy.osu.Framework.Android from 2019.809.0 to 2019.813.0 Bumps [ppy.osu.Framework.Android](https://github.com/ppy/osu-framework) from 2019.809.0 to 2019.813.0. - [Release notes](https://github.com/ppy/osu-framework/releases) - [Commits](https://github.com/ppy/osu-framework/compare/2019.809.0...2019.813.0) Signed-off-by: dependabot-preview[bot] --- osu.Android.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Android.props b/osu.Android.props index 721d341c08..85741fcf84 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -63,6 +63,6 @@ - +